diff options
| author | Adam <[email protected]> | 2025-10-29 07:31:57 -0500 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-10-29 07:32:01 -0500 |
| commit | 5b86fa91099d66cdc876cd4209a97ae2c903d510 (patch) | |
| tree | a00ea234769f9d68104791d69ec6bbf154c7cf2a /packages/desktop/src/components | |
| parent | aa7e008fe1ea1c1ee0e28915b61633865c304152 (diff) | |
| download | opencode-5b86fa91099d66cdc876cd4209a97ae2c903d510.tar.gz opencode-5b86fa91099d66cdc876cd4209a97ae2c903d510.zip | |
wip: desktop work
Diffstat (limited to 'packages/desktop/src/components')
| -rw-r--r-- | packages/desktop/src/components/assistant-message.tsx | 70 |
1 files changed, 33 insertions, 37 deletions
diff --git a/packages/desktop/src/components/assistant-message.tsx b/packages/desktop/src/components/assistant-message.tsx index 90f6e70fe..8c654660b 100644 --- a/packages/desktop/src/components/assistant-message.tsx +++ b/packages/desktop/src/components/assistant-message.tsx @@ -1,4 +1,4 @@ -import type { Part, AssistantMessage, ReasoningPart, TextPart, ToolPart } from "@opencode-ai/sdk" +import type { Part, AssistantMessage, ReasoningPart, TextPart, ToolPart, Message } from "@opencode-ai/sdk" import { children, Component, createMemo, For, Match, Show, Switch, type JSX } from "solid-js" import { Dynamic } from "solid-js/web" import { Markdown } from "./markdown" @@ -17,47 +17,44 @@ import type { WriteTool } from "opencode/tool/write" import type { TodoWriteTool } from "opencode/tool/todo" import { DiffChanges } from "./diff-changes" -export function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; lastToolOnly?: boolean }) { +export function AssistantMessage(props: { message: AssistantMessage; parts: Part[] }) { const filteredParts = createMemo(() => { - let tool = false return props.parts?.filter((x) => { - if (x.type === "tool" && props.lastToolOnly && tool) return false - if (x.type === "tool") tool = true + if (x.type === "reasoning") return false return x.type !== "tool" || x.tool !== "todoread" }) }) return ( <div class="w-full flex flex-col items-start gap-4"> - <For each={filteredParts()}> - {(part) => { - const component = createMemo(() => PART_MAPPING[part.type as keyof typeof PART_MAPPING]) - return ( - <Show when={component()}> - <Dynamic component={component()} part={part as any} message={props.message} /> - </Show> - ) - }} - </For> + <For each={filteredParts()}>{(part) => <Part part={part} message={props.message} />}</For> </div> ) } +export function Part(props: { part: Part; message: Message; readonly?: boolean }) { + const component = createMemo(() => PART_MAPPING[props.part.type as keyof typeof PART_MAPPING]) + return ( + <Show when={component()}> + <Dynamic component={component()} part={props.part as any} message={props.message} readonly={props.readonly} /> + </Show> + ) +} + const PART_MAPPING = { text: TextPart, tool: ToolPart, reasoning: ReasoningPart, } -function ReasoningPart(props: { part: ReasoningPart; message: AssistantMessage }) { - return null - // return ( - // <Show when={props.part.text.trim()}> - // <div>{props.part.text}</div> - // </Show> - // ) +function ReasoningPart(props: { part: ReasoningPart; message: Message }) { + return ( + <Show when={props.part.text.trim()}> + <Markdown text={props.part.text.trim()} /> + </Show> + ) } -function TextPart(props: { part: TextPart; message: AssistantMessage }) { +function TextPart(props: { part: TextPart; message: Message }) { return ( <Show when={props.part.text.trim()}> <Markdown text={props.part.text.trim()} /> @@ -65,17 +62,11 @@ function TextPart(props: { part: TextPart; message: AssistantMessage }) { ) } -function ToolPart(props: { part: ToolPart; message: AssistantMessage }) { - // const sync = useSync() - +function ToolPart(props: { part: ToolPart; message: Message; readonly?: boolean }) { const component = createMemo(() => { const render = ToolRegistry.render(props.part.tool) ?? GenericTool - const metadata = props.part.state.status === "pending" ? {} : (props.part.state.metadata ?? {}) const input = props.part.state.status === "completed" ? props.part.state.input : {} - // const permissions = sync.data.permission[props.message.sessionID] ?? [] - // const permissionIndex = permissions.findIndex((x) => x.callID === props.part.callID) - // const permission = permissions[permissionIndex] return ( <Dynamic @@ -83,8 +74,8 @@ function ToolPart(props: { part: ToolPart; message: AssistantMessage }) { input={input} tool={props.part.tool} metadata={metadata} - // permission={permission?.metadata ?? {}} output={props.part.state.status === "completed" ? props.part.state.output : undefined} + readonly={props.readonly} /> ) }) @@ -106,7 +97,12 @@ const isTriggerTitle = (val: any): val is TriggerTitle => { return typeof val === "object" && val !== null && "title" in val && !(val instanceof Node) } -function BasicTool(props: { icon: IconProps["name"]; trigger: TriggerTitle | JSX.Element; children?: JSX.Element }) { +function BasicTool(props: { + icon: IconProps["name"] + trigger: TriggerTitle | JSX.Element + children?: JSX.Element + readonly?: boolean +}) { const resolved = children(() => props.children) return ( <Collapsible> @@ -161,13 +157,13 @@ function BasicTool(props: { icon: IconProps["name"]; trigger: TriggerTitle | JSX </Switch> </div> </div> - <Show when={resolved()}> + <Show when={resolved() && !props.readonly}> <Collapsible.Arrow /> </Show> </div> </Collapsible.Trigger> - <Show when={props.children}> - <Collapsible.Content>{props.children}</Collapsible.Content> + <Show when={resolved() && !props.readonly}> + <Collapsible.Content>{resolved()}</Collapsible.Content> </Show> </Collapsible> // <> @@ -177,15 +173,15 @@ function BasicTool(props: { icon: IconProps["name"]; trigger: TriggerTitle | JSX } function GenericTool(props: ToolProps<any>) { - return <BasicTool icon="mcp" trigger={{ title: props.tool }} /> + return <BasicTool icon="mcp" trigger={{ title: props.tool }} readonly={props.readonly} /> } type ToolProps<T extends Tool.Info> = { input: Partial<Tool.InferParameters<T>> metadata: Partial<Tool.InferMetadata<T>> - // permission: Record<string, any> tool: string output?: string + readonly?: boolean } const ToolRegistry = (() => { |
