From 3e1a22eb2b3f8a623be851467a80848834e660ec Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sun, 26 Jul 2026 14:04:29 +0800 Subject: [PATCH] fix(client-runtime): settle-only dispatch windows carry null callTime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Responding to ds-review-bot on #664 (root cause lives here): when a history window carries a tool/code-dispatch settle without its paired start, the runtime fabricated callTime = settle time, so downstream duration views presented a measured 0 ms. Match the native tool-result contract instead — callTime: null = unknown — and pin it; the trajectory cell already renders null as the em dash, and the waterfall gains explicit unknown handling in its own PR. --- packages/client/runtime/src/client/sessions/session.ts | 6 ++++-- packages/client/runtime/tests/session.spec.ts | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/client/runtime/src/client/sessions/session.ts b/packages/client/runtime/src/client/sessions/session.ts index 146612e70f..643cf5ac64 100644 --- a/packages/client/runtime/src/client/sessions/session.ts +++ b/packages/client/runtime/src/client/sessions/session.ts @@ -661,8 +661,10 @@ export class Session implements ObservableSnapshot { kind: 'tool-result', seq: event.seq, time: event.time, callId: data.subCallId, call: { name: data.name, argsRaw: JSON.stringify(data.arguments) }, - // Duration source: the paired start's time when observed. - callTime: started === undefined ? event.time : started.time, + // Duration source: the paired start's time when observed; null = + // unknown (settle-only window), matching the native tool-result + // contract so views never present a fabricated zero duration. + callTime: started === undefined ? null : started.time, content: data.content, isError: data.isError, callView: null, resultView: null, } diff --git a/packages/client/runtime/tests/session.spec.ts b/packages/client/runtime/tests/session.spec.ts index 21c3e47fb8..43745a8324 100644 --- a/packages/client/runtime/tests/session.spec.ts +++ b/packages/client/runtime/tests/session.spec.ts @@ -688,6 +688,9 @@ describe('run_code sub-dispatch indexing', () => { isError: false, content: [{ type: 'text', text: 'demo.txt' }], }) expect(subs?.[1]).toMatchObject({ callId: 'p1:code:2', isError: true }) + // No paired start in the window: duration is UNKNOWN (null), never a + // fabricated zero-duration span. + expect(subs?.[0]).toMatchObject({ callTime: null }) // Sub-dispatches never join the surface flow. expect(session.getSnapshot().nodes.some(n => n.kind === 'tool-result' && n.callId.includes(':code:'))).toBe(false) })