Skip to content

Commit 0e14edc

Browse files
committed
refactor(util): share session transcript formatter
1 parent c7c37c0 commit 0e14edc

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

packages/app/src/pages/session/use-session-commands.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { DialogFork } from "@/components/dialog-fork"
1919
import { showToast } from "@opencode-ai/ui/toast"
2020
import { findLast } from "@opencode-ai/util/array"
2121
import { extractPromptFromParts } from "@/utils/prompt"
22-
import { formatSessionTranscript } from "@/utils/session-transcript"
22+
import { formatSessionTranscript } from "@opencode-ai/util/session-transcript"
2323
import { type UserMessage } from "@opencode-ai/sdk/v2"
2424
import { canAddSelectionContext } from "@/pages/session/session-command-helpers"
2525

packages/app/src/utils/session-transcript.ts renamed to packages/util/src/session-transcript.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { type AssistantMessage, type Message, type Part } from "@opencode-ai/sdk/v2"
2-
31
type Session = {
42
id: string
53
title: string
@@ -9,18 +7,43 @@ type Session = {
97
}
108
}
119

10+
type Message = {
11+
role: "user" | "assistant"
12+
agent?: string
13+
modelID?: string
14+
time: {
15+
created?: number
16+
completed?: number
17+
}
18+
}
19+
20+
type Part = {
21+
type: string
22+
synthetic?: boolean
23+
text?: string
24+
tool?: string
25+
state?: {
26+
input?: unknown
27+
output?: string
28+
error?: string
29+
status: "pending" | "running" | "completed" | "error"
30+
}
31+
}
32+
1233
const titlecase = (value: string) => (value ? value.charAt(0).toUpperCase() + value.slice(1) : value)
1334

14-
const formatAssistant = (msg: AssistantMessage) => {
35+
const formatAssistant = (msg: Message) => {
1536
const duration =
1637
msg.time.completed && msg.time.created ? ((msg.time.completed - msg.time.created) / 1000).toFixed(1) + "s" : ""
17-
return `## Assistant (${titlecase(msg.agent)} · ${msg.modelID}${duration ? ` · ${duration}` : ""})\n\n`
38+
const agent = msg.agent ? titlecase(msg.agent) : "Assistant"
39+
const model = msg.modelID ?? ""
40+
return `## Assistant (${agent}${model ? ` · ${model}` : ""}${duration ? ` · ${duration}` : ""})\n\n`
1841
}
1942

2043
const formatPart = (part: Part) => {
21-
if (part.type === "text" && !part.synthetic) return `${part.text}\n\n`
22-
if (part.type === "reasoning") return `_Thinking:_\n\n${part.text}\n\n`
23-
if (part.type !== "tool") return ""
44+
if (part.type === "text" && part.text && !part.synthetic) return `${part.text}\n\n`
45+
if (part.type === "reasoning" && part.text) return `_Thinking:_\n\n${part.text}\n\n`
46+
if (part.type !== "tool" || !part.tool || !part.state) return ""
2447

2548
const input = part.state.input
2649
? `\n**Input:**\n\`\`\`json\n${JSON.stringify(part.state.input, null, 2)}\n\`\`\`\n`

0 commit comments

Comments
 (0)