From 7eb62b09e2e479eeb4595d652373f08e1503a500 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:55:41 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=20code=20=E7=9A=84=E4=B8=89=E7=A7=8D=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E6=8B=86=E6=88=90=E7=8B=AC=E7=AB=8B=E5=8F=98?= =?UTF-8?q?=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - EditorExecuteError 的 CodeInvalid 拆成 CodeEmpty / CodeContainsNul / CodeTooLong{got_bytes,max_bytes},每个 case 一个变体 - editor_execute/error.rs 新增 EDITOR_CODE_MAX_BYTES 常量,direct_tool_bridge 的校验改用该常量并分别返回对应变体 - 模型能从文案看出具体违反了哪条规则,不再只看到一句话笼统覆盖三种失败 --- .../src-tauri/src/agent/direct_tool_bridge.rs | 17 +++++++++++++--- .../src/agent/tool/editor_execute/error.rs | 20 +++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs index d419920b2..922b4cacb 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs @@ -14,7 +14,9 @@ use crate::agent::tool::edit_image::error::EditImageError; target_arch = "x86_64", any(feature = "unity-editor-execute", feature = "godot-editor-execute") ))] -use crate::agent::tool::editor_execute::error::{EditorExecuteError, EditorKind}; +use crate::agent::tool::editor_execute::error::{ + EditorExecuteError, EditorKind, EDITOR_CODE_MAX_BYTES, +}; use crate::agent::tool::environment_check::error::EnvironmentCheckError; use crate::agent::tool::error::{ bounded_echo, DirectExecutionGateRejection, DirectTurnGateRejection, ProjectManifestRejection, @@ -3663,8 +3665,17 @@ pub(in crate::agent) fn editor_execute_code_input( .get("code") .and_then(Value::as_str) .ok_or(EditorExecuteError::CodeNotText { editor })?; - if code.trim().is_empty() || code.len() > 131072 || code.contains('\0') { - return Err(EditorExecuteError::CodeInvalid); + if code.trim().is_empty() { + return Err(EditorExecuteError::CodeEmpty); + } + if code.len() > EDITOR_CODE_MAX_BYTES { + return Err(EditorExecuteError::CodeTooLong { + got_bytes: code.len(), + max_bytes: EDITOR_CODE_MAX_BYTES, + }); + } + if code.contains('\0') { + return Err(EditorExecuteError::CodeContainsNul); } Ok(code.to_string()) } diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/editor_execute/error.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/editor_execute/error.rs index 51db61dee..55e0f0138 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/tool/editor_execute/error.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/tool/editor_execute/error.rs @@ -5,6 +5,9 @@ use crate::agent::tool::error::{ProjectPermissionRejection, ToolArgumentsRejection, ToolFailure}; use serde_json::Value; +/// `code` 的长度上限(字节):编辑器适配器按 UTF-8 字节数收代码。 +pub(crate) const EDITOR_CODE_MAX_BYTES: usize = 131_072; + /// 两个编辑器执行工具之间的差异:插件身份、给用户看的编辑器名、代码语言名。 /// /// 差异做成枚举,错误变体只带 `EditorKind`,不在文案里手写编辑器名。 @@ -48,7 +51,15 @@ pub(crate) enum EditorExecuteError { CodeNotText { editor: EditorKind, }, - CodeInvalid, + /// `code` 只有空白。 + CodeEmpty, + /// `code` 含 NUL:适配器与传输层都不接受。 + CodeContainsNul, + /// `code` 超过 [`EDITOR_CODE_MAX_BYTES`]。 + CodeTooLong { + got_bytes: usize, + max_bytes: usize, + }, /// 编辑器适配器拒绝了这次执行,或回执不可用。 EditorRejected { cause: String, @@ -87,7 +98,12 @@ impl ToolFailure for EditorExecuteError { Self::CodeNotText { editor } => { format!("code 必须是 {}。", editor.language()) } - Self::CodeInvalid => "code 不能为空、包含 NUL 或超过 128 KiB。".to_string(), + Self::CodeEmpty => "code 不能为空。".to_string(), + Self::CodeContainsNul => "code 不能包含 NUL。".to_string(), + Self::CodeTooLong { + got_bytes, + max_bytes, + } => format!("code 有 {got_bytes} 字节,超过上限 {max_bytes} 字节。"), Self::EditorRejected { cause } => cause.to_string(), Self::ExecutionNotCompleted { editor, report } => { format!("{} 执行未完成:{report}", editor.label())