From d4375300cde71320cdd2a012304603efe9eb5cf9 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 1 Oct 2026 06:03:19 +0000 Subject: [PATCH] Add thinking duration to message parts Why: The chat timeline needs a persisted thinking duration, and tool duration already lives on the tool call, so the thinking part had nowhere to put it. Evidence: go test ./... passes; the message golden now includes durationMs on the thinking part. Impact: Additive JSON field with omitempty. Existing clients ignore unknown fields. Refs: feature/chat-timeline-preview Co-authored-by: Cursor --- conformance_test.go | 2 +- model.go | 4 ++++ testdata/golden/message.json | 3 ++- ts/types.ts | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/conformance_test.go b/conformance_test.go index b8082f1..5e65262 100644 --- a/conformance_test.go +++ b/conformance_test.go @@ -42,7 +42,7 @@ func sampleMessage() Message { ID: "msg_abc123def456", ConversationID: "cnv_abc123def456", RunID: "run_abc123def456", Role: RoleAssistant, Parts: []Part{ - {Type: PartThinking, Text: "考虑先检索…", Process: true}, + {Type: PartThinking, Text: "考虑先检索…", Process: true, DurationMs: 1500}, {Type: PartToolCall, Process: true, ToolCall: &ToolCallPart{ID: "call_1", Name: "history_search", Arguments: `{"q":"部署"}`, Duration: 12.5}}, {Type: PartToolResult, Process: true, ToolResult: &ToolResultPart{CallID: "call_1", Status: "ok", Summary: "3 条命中"}}, {Type: PartText, Text: "根据历史记录……"}, diff --git a/model.go b/model.go index ddb4128..dbf0365 100644 --- a/model.go +++ b/model.go @@ -89,6 +89,10 @@ type Part struct { // 过程标记:true 的部件在 run 终态后由前端折叠为摘要行(4.2)。 Process bool `json:"process,omitempty"` + + // DurationMs 是 thinking 部件的思考时长(毫秒,从首个推理增量到最后一个)。 + // 工具耗时在 ToolCallPart.Duration,不复用本字段。 + DurationMs float64 `json:"durationMs,omitempty"` } type ToolCallPart struct { diff --git a/testdata/golden/message.json b/testdata/golden/message.json index a774ab6..11ece24 100644 --- a/testdata/golden/message.json +++ b/testdata/golden/message.json @@ -7,7 +7,8 @@ { "type": "thinking", "text": "考虑先检索…", - "process": true + "process": true, + "durationMs": 1500 }, { "type": "tool_call", diff --git a/ts/types.ts b/ts/types.ts index bd6b748..e127d6a 100644 --- a/ts/types.ts +++ b/ts/types.ts @@ -35,6 +35,7 @@ export interface Part { card?: { kind: string; data: UINode[]; cardId?: ID }; // cardId 非空 = 收件箱卡片引用部件(submit_card) error?: { code: string; message: string }; process?: boolean; // run 终态后折叠为摘要行 + durationMs?: number; // thinking 部件的思考时长(毫秒);工具耗时在 toolCall.durationMs } export interface Message {