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.