summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorShoubhit Dash <[email protected]>2026-02-20 18:31:13 +0530
committerGitHub <[email protected]>2026-02-20 07:01:13 -0600
commit7e1051af0784693d7fc37ae31d6f513d47e0d24b (patch)
treea14ac1d1fdfa7ac72fa0fb9058ef1daaac83e674
parent93615bef28fe0e17f673ba0f90c171309f7d5f91 (diff)
downloadopencode-7e1051af0784693d7fc37ae31d6f513d47e0d24b.tar.gz
opencode-7e1051af0784693d7fc37ae31d6f513d47e0d24b.zip
fix(ui): show full turn duration in assistant meta (#14378)
-rw-r--r--packages/ui/src/components/message-part.tsx12
-rw-r--r--packages/ui/src/components/session-turn.tsx16
2 files changed, 26 insertions, 2 deletions
diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx
index 4b223bf35..92da5b625 100644
--- a/packages/ui/src/components/message-part.tsx
+++ b/packages/ui/src/components/message-part.tsx
@@ -104,6 +104,7 @@ export interface MessagePartProps {
hideDetails?: boolean
defaultOpen?: boolean
showAssistantCopyPartID?: string | null
+ turnDurationMs?: number
}
export type PartComponent = Component<MessagePartProps>
@@ -275,6 +276,7 @@ function renderable(part: PartType) {
export function AssistantParts(props: {
messages: AssistantMessage[]
showAssistantCopyPartID?: string | null
+ turnDurationMs?: number
working?: boolean
}) {
const data = useData()
@@ -365,6 +367,7 @@ export function AssistantParts(props: {
part={entry().part}
message={entry().message}
showAssistantCopyPartID={props.showAssistantCopyPartID}
+ turnDurationMs={props.turnDurationMs}
/>
)}
</Show>
@@ -849,6 +852,7 @@ export function Part(props: MessagePartProps) {
hideDetails={props.hideDetails}
defaultOpen={props.defaultOpen}
showAssistantCopyPartID={props.showAssistantCopyPartID}
+ turnDurationMs={props.turnDurationMs}
/>
</Show>
)
@@ -1060,8 +1064,12 @@ PART_MAPPING["text"] = function TextPartDisplay(props) {
if (props.message.role !== "assistant") return ""
const message = props.message as AssistantMessage
const completed = message.time.completed
- if (typeof completed !== "number") return ""
- const ms = completed - message.time.created
+ const ms =
+ typeof props.turnDurationMs === "number"
+ ? props.turnDurationMs
+ : typeof completed === "number"
+ ? completed - message.time.created
+ : -1
if (!(ms >= 0)) return ""
const total = Math.round(ms / 1000)
if (total < 60) return `${total}s`
diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx
index 2aed8279e..aa2769280 100644
--- a/packages/ui/src/components/session-turn.tsx
+++ b/packages/ui/src/components/session-turn.tsx
@@ -247,6 +247,21 @@ export function SessionTurn(
if (working()) return null
return showAssistantCopyPartID() ?? null
})
+ const turnDurationMs = createMemo(() => {
+ const start = message()?.time.created
+ if (typeof start !== "number") return undefined
+
+ const end = assistantMessages().reduce<number | undefined>((max, item) => {
+ const completed = item.time.completed
+ if (typeof completed !== "number") return max
+ if (max === undefined) return completed
+ return Math.max(max, completed)
+ }, undefined)
+
+ if (typeof end !== "number") return undefined
+ if (end < start) return undefined
+ return end - start
+ })
const assistantVisible = createMemo(() =>
assistantMessages().reduce((count, message) => {
const parts = list(data.store.part?.[message.id], emptyParts)
@@ -290,6 +305,7 @@ export function SessionTurn(
<AssistantParts
messages={assistantMessages()}
showAssistantCopyPartID={assistantCopyPartID()}
+ turnDurationMs={turnDurationMs()}
working={working()}
/>
</div>