From 7d51504e091748ccbea762f8e0a8e475e76f1ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 1 Oct 2026 17:50:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E8=AE=A4=E8=AF=86=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=90=8D=E5=9B=9E=E6=98=BE=E9=99=90=E9=95=BF=E5=88=B0?= =?UTF-8?q?=20120=20=E5=AD=97=E7=AC=A6=EF=BC=8C=E5=9B=9E=E6=98=BE=E5=8F=A3?= =?UTF-8?q?=E5=BE=84=E6=94=B6=E8=BF=9B=20tool/error.rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ToolArgumentsRejection::check 构造 UnknownField 时改成 bounded_echo(field),超长键名不再整份进文案与诊断 - 有界回显的常量与 bounded_echo 从 arguments.rs 移到公共 tool/error.rs(BOUNDED_ECHO_MAX_CHARS=120),not_text_repr 变成它的 JSON 值封装,实现仍只有一份 验证:cargo check --bin genarrative-ai-game-creator-shell --tests 通过;cargo fmt --check 通过 --- .../src-tauri/src/agent/tool/arguments.rs | 11 ++--------- .../src-tauri/src/agent/tool/error.rs | 13 ++++++++++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/arguments.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/arguments.rs index 0fb89c724..7d05a2772 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/arguments.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/arguments.rs @@ -5,21 +5,14 @@ use serde_json::Value; -use super::error::ToolPageRejection; -use crate::agent::runtime_state::truncate_agent_runtime_text; - -/// 字段给了非字符串值时,回显进诊断的那个值最多保留多少字符。 -/// -/// 类型错只需要让模型看出「传进来的是什么」,不必把整个对象或数组原样带进工具结果与 -/// 诊断 sidecar;`got` 会同时出现在 `to_user_msg` 和序列化后的 `error` 里。 -const NOT_TEXT_GOT_MAX_CHARS: usize = 120; +use super::error::{bounded_echo, ToolPageRejection}; /// 把「本该是字符串、实际给了别的类型」的值压成有界回显,供各工具的 `*NotText` 变体拼文案。 /// /// 走共享 [`ToolTextField::not_text`] 的字段自动走这里;像抠图 `backgroundMode`、美术准备 /// `mode`、生成图片 `kind` 这类在解析里内联判类型的字段,也要用同一份口径。 pub(crate) fn not_text_repr(value: &Value) -> String { - truncate_agent_runtime_text(&value.to_string(), NOT_TEXT_GOT_MAX_CHARS) + bounded_echo(&value.to_string()) } /// 一个会被边界校验的文本字段。 diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/error.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/error.rs index ca8e95977..8355e1812 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/error.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/error.rs @@ -6,6 +6,17 @@ use serde_json::Value; +/// 不受信回显(字段名、工具名、给错类型的值)在错误文案与诊断里允许保留的字符数。 +/// +/// 这些都是模型或客户端给的原文:错误只需要让对方看出「传了什么」,不必把整份原文 +/// 带进工具结果与诊断 sidecar。 +pub(crate) const BOUNDED_ECHO_MAX_CHARS: usize = 120; + +/// 把不受信文本压成有界回显;JSON 值用 [`crate::agent::tool::arguments::not_text_repr`] 包一层。 +pub(crate) fn bounded_echo(text: &str) -> String { + crate::agent::runtime_state::truncate_agent_runtime_text(text, BOUNDED_ECHO_MAX_CHARS) +} + /// `sourceLocalAssetId` 不在当前项目 manifest 时的完整指引:模型要知道下一步做什么, /// 只报「不属于已登记资源」会让它原地重试。 /// @@ -52,7 +63,7 @@ impl ToolArgumentsRejection { .find(|field| !allowed.contains(&field.as_str())) { Some(field) => Err(Self::UnknownField { - field: field.to_string(), + field: bounded_echo(field), }), None => Ok(()), }