diff --git a/packages/desktop/src/components/assistant-message.tsx b/packages/desktop/src/components/message.tsx similarity index 88% rename from packages/desktop/src/components/assistant-message.tsx rename to packages/desktop/src/components/message.tsx index 8c654660b5..589ca3118a 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 ( + + + {(userMessage) => } + + + {(assistantMessage) => } + + + ) +} + +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
{text()}
+} + +export function Part(props: { part: Part; message: Message; hideDetails?: boolean }) { const component = createMemo(() => PART_MAPPING[props.part.type as keyof typeof PART_MAPPING]) return ( - + ) } @@ -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: { - + - + {resolved()} @@ -173,7 +201,7 @@ function BasicTool(props: { } function GenericTool(props: ToolProps) { - return + return } type ToolProps = { @@ -181,7 +209,7 @@ type ToolProps = { metadata: Partial> tool: string output?: string - readonly?: boolean + hideDetails?: boolean } const ToolRegistry = (() => { diff --git a/packages/desktop/src/pages/index.tsx b/packages/desktop/src/pages/index.tsx index 800f3651e3..ac6b6f9c8c 100644 --- a/packages/desktop/src/pages/index.tsx +++ b/packages/desktop/src/pages/index.tsx @@ -33,7 +33,7 @@ import { Code } from "@/components/code" import { useSync } from "@/context/sync" import { useSDK } from "@/context/sdk" import { ProgressCircle } from "@/components/progress-circle" -import { AssistantMessage, Part } from "@/components/assistant-message" +import { Message, Part } from "@/components/message" import { type AssistantMessage as AssistantMessageType } from "@opencode-ai/sdk" import { DiffChanges } from "@/components/diff-changes" @@ -198,6 +198,7 @@ export default function Page() { } if (!session) return + local.session.setActive(session.id) const toAbsolutePath = (path: string) => (path.startsWith("/") ? path : sync.absolute(path)) const text = parts.map((part) => part.content).join("") @@ -259,7 +260,6 @@ export default function Page() { ], }, }) - local.session.setActive(session.id) } const handleNewSession = () => { @@ -639,8 +639,9 @@ export default function Page() { {(message) => { const [expanded, setExpanded] = createSignal(false) - const title = createMemo(() => message.summary?.title) + const parts = createMemo(() => sync.data.part[message.id]) const prompt = createMemo(() => local.session.getMessageText(message)) + const title = createMemo(() => message.summary?.title) const summary = createMemo(() => message.summary?.body) const assistantMessages = createMemo(() => { return sync.data.message[activeSession().id]?.filter( @@ -665,7 +666,9 @@ export default function Page() { -
{prompt()}
+
+ +
{/* Response */}
@@ -686,7 +689,7 @@ export default function Page() { {(assistantMessage) => { const parts = createMemo(() => sync.data.part[assistantMessage.id]) - return + return }}
@@ -722,7 +725,9 @@ export default function Page() { const lastTextPart = createMemo(() => sync.data.part[last().id].findLast((p) => p.type === "text"), ) - return + return ( + + ) }} @@ -733,7 +738,11 @@ export default function Page() { ), ) return ( - + ) }} @@ -745,7 +754,7 @@ export default function Page() { (p) => p.type === "tool" && p.state.status === "completed", ), ) - return + return }}
diff --git a/packages/opencode/src/session/prompt/summarize.txt b/packages/opencode/src/session/prompt/summarize.txt index 4751c8d71a..6f6dd7c442 100644 --- a/packages/opencode/src/session/prompt/summarize.txt +++ b/packages/opencode/src/session/prompt/summarize.txt @@ -1,10 +1,12 @@ You are a helpful AI assistant tasked with summarizing conversations. -When asked to summarize, provide a detailed but concise summary of the conversation. +When asked to summarize, provide a detailed but concise summary of the conversation. Focus on information that would be helpful for continuing the conversation, including: - What was done - What is currently being worked on - Which files are being modified - What needs to be done next +- Preserve custom rules from AGENTS.md +- Maintain agent-specific constraints Your summary should be comprehensive enough to provide context but concise enough to be quickly understood.