From 4d6d98924758e6ef0d1f5c6a0b126a194688d032 Mon Sep 17 00:00:00 2001 From: oudecheng <13802883547@139.com> Date: Tue, 2 Jun 2026 16:52:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E6=97=B6=E9=95=BF=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=B6=88=E6=81=AF=E5=A4=84=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agent/agent_loop.rs | 7 +++++-- src/bus/message.rs | 13 +++++++++++++ src/gateway/ws.rs | 2 +- src/storage/mod.rs | 4 ++++ web/src/hooks/useChat.ts | 1 + 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/agent/agent_loop.rs b/src/agent/agent_loop.rs index 0126edd..36cdfc8 100644 --- a/src/agent/agent_loop.rs +++ b/src/agent/agent_loop.rs @@ -308,6 +308,7 @@ fn filter_images_by_age_and_count( tool_call_id: message.tool_call_id.clone(), tool_name: message.tool_name.clone(), tool_state: message.tool_state.clone(), + tool_duration_ms: message.tool_duration_ms, tool_calls: message.tool_calls.clone(), }); } @@ -1025,7 +1026,8 @@ impl AgentLoop { } else { ToolMessageState::Completed }, - ); + ) + .with_tool_duration(result.duration.as_millis() as u64); messages.push(tool_message.clone()); emitted_messages.push(tool_message.clone()); let duration_ms = Some(result.duration.as_millis() as u64); @@ -1041,7 +1043,8 @@ impl AgentLoop { } else { ToolMessageState::Completed }, - ); + ) + .with_tool_duration(result.duration.as_millis() as u64); messages.push(tool_message.clone()); emitted_messages.push(tool_message.clone()); let duration_ms = Some(result.duration.as_millis() as u64); diff --git a/src/bus/message.rs b/src/bus/message.rs index 43f6e22..5f2d3b7 100644 --- a/src/bus/message.rs +++ b/src/bus/message.rs @@ -62,6 +62,8 @@ pub struct ChatMessage { pub tool_name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tool_state: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tool_duration_ms: Option, #[serde(skip_serializing_if = "Option::is_none")] pub tool_calls: Option>, } @@ -78,6 +80,7 @@ impl ChatMessage { reasoning_content: None, tool_call_id: None, tool_name: None, + tool_duration_ms: None, tool_state: None, tool_calls: None, } @@ -94,6 +97,7 @@ impl ChatMessage { reasoning_content: None, tool_call_id: None, tool_name: None, + tool_duration_ms: None, tool_state: None, tool_calls: None, } @@ -110,6 +114,7 @@ impl ChatMessage { reasoning_content: None, tool_call_id: None, tool_name: None, + tool_duration_ms: None, tool_state: None, tool_calls: None, } @@ -138,6 +143,7 @@ impl ChatMessage { reasoning_content: None, tool_call_id: None, tool_name: None, + tool_duration_ms: None, tool_state: None, tool_calls: Some(tool_calls), } @@ -171,6 +177,7 @@ impl ChatMessage { reasoning_content: None, tool_call_id: None, tool_name: None, + tool_duration_ms: None, tool_state: None, tool_calls: None, } @@ -205,11 +212,17 @@ impl ChatMessage { reasoning_content: None, tool_call_id: Some(tool_call_id.into()), tool_name: Some(tool_name.into()), + tool_duration_ms: None, tool_state: Some(tool_state), tool_calls: None, } } + pub fn with_tool_duration(mut self, ms: u64) -> Self { + self.tool_duration_ms = Some(ms); + self + } + pub fn has_system_context(&self, expected: &str) -> bool { self.system_context.as_deref() == Some(expected) } diff --git a/src/gateway/ws.rs b/src/gateway/ws.rs index 1ce674e..71c49d0 100644 --- a/src/gateway/ws.rs +++ b/src/gateway/ws.rs @@ -662,7 +662,7 @@ fn chat_message_to_ws_outbound(msg: &crate::bus::ChatMessage) -> Option Some(WsOutbound::ToolPending { id: msg.id.clone(), diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 0b7af0f..378b111 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1455,6 +1455,7 @@ impl SessionStore { tool_call_id: row.get(7)?, tool_name: row.get(8)?, tool_state: None, + tool_duration_ms: None, tool_calls, }) })?; @@ -1780,6 +1781,7 @@ fn clone_message_for_compaction(message: &ChatMessage, timestamp: i64) -> ChatMe tool_call_id: message.tool_call_id.clone(), tool_name: message.tool_name.clone(), tool_state: message.tool_state.clone(), + tool_duration_ms: message.tool_duration_ms, tool_calls: message.tool_calls.clone(), } } @@ -1836,6 +1838,7 @@ fn load_messages_between( tool_call_id: row.get(7)?, tool_name: row.get(8)?, tool_state: None, + tool_duration_ms: None, tool_calls, }) }, @@ -1896,6 +1899,7 @@ fn load_messages_after( tool_call_id: row.get(7)?, tool_name: row.get(8)?, tool_state: None, + tool_duration_ms: None, tool_calls, }) })?; diff --git a/web/src/hooks/useChat.ts b/web/src/hooks/useChat.ts index 68cca92..72c910e 100644 --- a/web/src/hooks/useChat.ts +++ b/web/src/hooks/useChat.ts @@ -346,6 +346,7 @@ export function useChat(): UseChatReturn { toolName: msg.tool_name, toolCallId: msg.tool_call_id, subagentTaskId: msg.subagent_task_id, + durationMs: msg.duration_ms, }, ]) break