diff options
| author | Adam <[email protected]> | 2025-10-29 11:55:25 -0500 |
|---|---|---|
| committer | opencode <[email protected]> | 2025-10-29 16:59:45 +0000 |
| commit | 0ff73ed8a6cfa2beb6ce436a921cb98f836677c3 (patch) | |
| tree | 499a823afa9d19a9a29eccd0e0f672249a105b6d /packages/desktop/src/components | |
| parent | 5e792d7ac5a67dc3185308fbcef95c4ca50513f0 (diff) | |
| download | opencode-0ff73ed8a6cfa2beb6ce436a921cb98f836677c3.tar.gz opencode-0ff73ed8a6cfa2beb6ce436a921cb98f836677c3.zip | |
wip: desktop work
Diffstat (limited to 'packages/desktop/src/components')
| -rw-r--r-- | packages/desktop/src/components/message.tsx (renamed from packages/desktop/src/components/assistant-message.tsx) | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/packages/desktop/src/components/assistant-message.tsx b/packages/desktop/src/components/message.tsx index 8c654660b..589ca3118 100644 --- a/packages/desktop/src/components/assistant-message.tsx +++ b/packages/desktop/src/components/message.tsx @@ -1,4 +1,4 @@ -import type { Part, AssistantMessage, ReasoningPart, TextPart, ToolPart, Message } from "@opencode-ai/sdk" +import type { Part, ReasoningPart, TextPart, ToolPart, Message, AssistantMessage, UserMessage } 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,7 +17,20 @@ 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[] }) { +export function Message(props: { message: Message; parts: Part[] }) { + return ( + <Switch> + <Match when={props.message.role === "user" && props.message}> + {(userMessage) => <UserMessage message={userMessage()} parts={props.parts} />} + </Match> + <Match when={props.message.role === "assistant" && props.message}> + {(assistantMessage) => <AssistantMessage message={assistantMessage()} parts={props.parts} />} + </Match> + </Switch> + ) +} + +function AssistantMessage(props: { message: AssistantMessage; parts: Part[] }) { const filteredParts = createMemo(() => { return props.parts?.filter((x) => { if (x.type === "reasoning") return false @@ -31,11 +44,26 @@ export function AssistantMessage(props: { message: AssistantMessage; parts: Part ) } -export function Part(props: { part: Part; message: Message; readonly?: boolean }) { +function UserMessage(props: { message: UserMessage; parts: Part[] }) { + const text = createMemo(() => + props.parts + ?.filter((p) => p.type === "text" && !p.synthetic) + ?.map((p) => (p as TextPart).text) + ?.join(""), + ) + return <div class="text-12-regular text-text-base line-clamp-3">{text()}</div> +} + +export function Part(props: { part: Part; message: Message; hideDetails?: 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} /> + <Dynamic + component={component()} + part={props.part as any} + message={props.message} + hideDetails={props.hideDetails} + /> </Show> ) } @@ -62,7 +90,7 @@ function TextPart(props: { part: TextPart; message: Message }) { ) } -function ToolPart(props: { part: ToolPart; message: Message; readonly?: boolean }) { +function ToolPart(props: { part: ToolPart; message: Message; hideDetails?: boolean }) { const component = createMemo(() => { const render = ToolRegistry.render(props.part.tool) ?? GenericTool const metadata = props.part.state.status === "pending" ? {} : (props.part.state.metadata ?? {}) @@ -75,7 +103,7 @@ function ToolPart(props: { part: ToolPart; message: Message; readonly?: boolean tool={props.part.tool} metadata={metadata} output={props.part.state.status === "completed" ? props.part.state.output : undefined} - readonly={props.readonly} + hideDetails={props.hideDetails} /> ) }) @@ -101,7 +129,7 @@ function BasicTool(props: { icon: IconProps["name"] trigger: TriggerTitle | JSX.Element children?: JSX.Element - readonly?: boolean + hideDetails?: boolean }) { const resolved = children(() => props.children) return ( @@ -157,12 +185,12 @@ function BasicTool(props: { </Switch> </div> </div> - <Show when={resolved() && !props.readonly}> + <Show when={resolved() && !props.hideDetails}> <Collapsible.Arrow /> </Show> </div> </Collapsible.Trigger> - <Show when={resolved() && !props.readonly}> + <Show when={resolved() && !props.hideDetails}> <Collapsible.Content>{resolved()}</Collapsible.Content> </Show> </Collapsible> @@ -173,7 +201,7 @@ function BasicTool(props: { } function GenericTool(props: ToolProps<any>) { - return <BasicTool icon="mcp" trigger={{ title: props.tool }} readonly={props.readonly} /> + return <BasicTool icon="mcp" trigger={{ title: props.tool }} hideDetails={props.hideDetails} /> } type ToolProps<T extends Tool.Info> = { @@ -181,7 +209,7 @@ type ToolProps<T extends Tool.Info> = { metadata: Partial<Tool.InferMetadata<T>> tool: string output?: string - readonly?: boolean + hideDetails?: boolean } const ToolRegistry = (() => { |
