From b43d8d83d29e64ab639835d4811f01436cd4cdd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cxiankai=E2=80=9D?= <316675245@qq.com> Date: Sat, 29 Aug 2026 12:32:03 +0800 Subject: [PATCH] fix(ai-agent): forward model-authored tool description from BackendOutputSink The BackendOutputSink hardcoded `description: None` when forwarding aionrs tool calls, so a model-authored description never reached the frontend and the step label always fell back to the raw command. Extract the optional `description` field from the tool input instead. --- .../src/capability/backend_output_sink.rs | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/crates/aionui-ai-agent/src/capability/backend_output_sink.rs b/crates/aionui-ai-agent/src/capability/backend_output_sink.rs index 9d0abb7b5..70c4f521e 100644 --- a/crates/aionui-ai-agent/src/capability/backend_output_sink.rs +++ b/crates/aionui-ai-agent/src/capability/backend_output_sink.rs @@ -52,6 +52,10 @@ impl OutputSink for BackendOutputSink { } let parsed_input = serde_json::from_str(input).unwrap_or(serde_json::Value::String(input.to_owned())); + let description = parsed_input + .get("description") + .and_then(serde_json::Value::as_str) + .map(str::to_owned); tracing::debug!( tool_use_id = %tool_use_id, @@ -75,7 +79,7 @@ impl OutputSink for BackendOutputSink { status: ToolCallStatus::Running, input: Some(parsed_input), output: None, - description: None, + description, parent_call_id: None, })); } @@ -334,6 +338,36 @@ mod tests { } } + #[test] + fn emit_tool_call_extracts_description_from_input() { + let (sink, mut rx) = make_sink(); + sink.emit_tool_call( + "call_bash_1", + "ExecCommand", + r#"{"cmd":"cargo build","description":"Build the project"}"#, + ); + let event = rx.try_recv().unwrap(); + match event { + AgentStreamEvent::ToolCall(data) => { + assert_eq!(data.description.as_deref(), Some("Build the project")); + } + other => panic!("Expected ToolCall, got {:?}", other), + } + } + + #[test] + fn emit_tool_call_without_description_keeps_none() { + let (sink, mut rx) = make_sink(); + sink.emit_tool_call("call_bash_1", "ExecCommand", r#"{"cmd":"cargo build"}"#); + let event = rx.try_recv().unwrap(); + match event { + AgentStreamEvent::ToolCall(data) => { + assert_eq!(data.description, None); + } + other => panic!("Expected ToolCall, got {:?}", other), + } + } + #[test] fn emit_tool_result_carries_output_and_matching_call_id() { let (sink, mut rx) = make_sink();