mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
feat(desktop): better task tool rendering
This commit is contained in:
parent
d04a72a4ad
commit
986d12fd20
3 changed files with 167 additions and 11 deletions
|
|
@ -287,6 +287,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
[data-component="task-tools"] {
|
||||
padding: 8px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
|
||||
[data-slot="task-tool-item"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-weak);
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
flex-shrink: 0;
|
||||
color: var(--icon-weak);
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="task-tool-title"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--text-weak);
|
||||
}
|
||||
|
||||
[data-slot="task-tool-subtitle"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-regular);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--text-weaker);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="diagnostics"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,110 @@ function getDirectory(path: string | undefined) {
|
|||
return relativizeProjectPaths(_getDirectory(path), data.directory)
|
||||
}
|
||||
|
||||
export function getSessionToolParts(store: ReturnType<typeof useData>["store"], sessionId: string): ToolPart[] {
|
||||
const messages = store.message[sessionId]?.filter((m) => m.role === "assistant")
|
||||
if (!messages) return []
|
||||
|
||||
const parts: ToolPart[] = []
|
||||
for (const m of messages) {
|
||||
const msgParts = store.part[m.id]
|
||||
if (msgParts) {
|
||||
for (const p of msgParts) {
|
||||
if (p && p.type === "tool") parts.push(p as ToolPart)
|
||||
}
|
||||
}
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
import type { IconProps } from "./icon"
|
||||
|
||||
export type ToolInfo = {
|
||||
icon: IconProps["name"]
|
||||
title: string
|
||||
subtitle?: string
|
||||
}
|
||||
|
||||
export function getToolInfo(tool: string, input: Record<string, any> = {}): ToolInfo {
|
||||
switch (tool) {
|
||||
case "read":
|
||||
return {
|
||||
icon: "glasses",
|
||||
title: "Read",
|
||||
subtitle: input.filePath ? getFilename(input.filePath) : undefined,
|
||||
}
|
||||
case "list":
|
||||
return {
|
||||
icon: "bullet-list",
|
||||
title: "List",
|
||||
subtitle: input.path ? getFilename(input.path) : undefined,
|
||||
}
|
||||
case "glob":
|
||||
return {
|
||||
icon: "magnifying-glass-menu",
|
||||
title: "Glob",
|
||||
subtitle: input.pattern,
|
||||
}
|
||||
case "grep":
|
||||
return {
|
||||
icon: "magnifying-glass-menu",
|
||||
title: "Grep",
|
||||
subtitle: input.pattern,
|
||||
}
|
||||
case "webfetch":
|
||||
return {
|
||||
icon: "window-cursor",
|
||||
title: "Webfetch",
|
||||
subtitle: input.url,
|
||||
}
|
||||
case "task":
|
||||
return {
|
||||
icon: "task",
|
||||
title: `${input.subagent_type || "task"} Agent`,
|
||||
subtitle: input.description,
|
||||
}
|
||||
case "bash":
|
||||
return {
|
||||
icon: "console",
|
||||
title: "Shell",
|
||||
subtitle: input.description,
|
||||
}
|
||||
case "edit":
|
||||
return {
|
||||
icon: "code-lines",
|
||||
title: "Edit",
|
||||
subtitle: input.filePath ? getFilename(input.filePath) : undefined,
|
||||
}
|
||||
case "write":
|
||||
return {
|
||||
icon: "code-lines",
|
||||
title: "Write",
|
||||
subtitle: input.filePath ? getFilename(input.filePath) : undefined,
|
||||
}
|
||||
case "todowrite":
|
||||
return {
|
||||
icon: "checklist",
|
||||
title: "To-dos",
|
||||
}
|
||||
case "todoread":
|
||||
return {
|
||||
icon: "checklist",
|
||||
title: "Read to-dos",
|
||||
}
|
||||
default:
|
||||
return {
|
||||
icon: "mcp",
|
||||
title: tool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getToolPartInfo(part: ToolPart): ToolInfo {
|
||||
const state = part.state as any
|
||||
const input = state.input || {}
|
||||
return getToolInfo(part.tool, input)
|
||||
}
|
||||
|
||||
export function registerPartComponent(type: string, component: PartComponent) {
|
||||
PART_MAPPING[type] = component
|
||||
}
|
||||
|
|
@ -453,23 +557,37 @@ ToolRegistry.register({
|
|||
ToolRegistry.register({
|
||||
name: "task",
|
||||
render(props) {
|
||||
const summary = () =>
|
||||
(props.metadata.summary ?? []) as { id: string; tool: string; state: { status: string; title?: string } }[]
|
||||
|
||||
return (
|
||||
<BasicTool
|
||||
{...props}
|
||||
icon="task"
|
||||
defaultOpen={true}
|
||||
trigger={{
|
||||
title: `${props.input.subagent_type || props.tool} Agent`,
|
||||
titleClass: "capitalize",
|
||||
subtitle: props.input.description,
|
||||
}}
|
||||
>
|
||||
{/* <Show when={false && props.output}> */}
|
||||
{/* {(output) => ( */}
|
||||
{/* <div data-component="tool-output" data-scrollable> */}
|
||||
{/* <Markdown text={output()} /> */}
|
||||
{/* </div> */}
|
||||
{/* )} */}
|
||||
{/* </Show> */}
|
||||
<div data-component="tool-output" data-scrollable>
|
||||
<div data-component="task-tools">
|
||||
<For each={summary()}>
|
||||
{(item) => {
|
||||
const info = getToolInfo(item.tool)
|
||||
return (
|
||||
<div data-slot="task-tool-item">
|
||||
<Icon name={info.icon} size="small" />
|
||||
<span data-slot="task-tool-title">{info.title}</span>
|
||||
<Show when={item.state.title}>
|
||||
<span data-slot="task-tool-subtitle">{item.state.title}</span>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</BasicTool>
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@
|
|||
/* } */
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--theme-background-panel);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--theme-border-subtle);
|
||||
background-color: var(--surface-float-base);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-color: var(--theme-border-subtle) var(--theme-background-panel);
|
||||
scrollbar-color: var(--surface-float-base) transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue