From 1c9b92e791c08682a952f45baecc404cd9f8a783 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Thu, 10 Sep 2026 14:24:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=20Agent=20=E8=B5=84=E6=BA=90=E6=A3=80?= =?UTF-8?q?=E7=B4=A2=E6=8A=95=E5=BD=B1=E4=B8=AD=E6=9A=B4=E9=9C=B2=E5=88=86?= =?UTF-8?q?=E7=B1=BB=E4=B8=8E=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - agent/direct_tool_bridge.rs:bridge_registered_resource 投影新增 category 与 tags,位置固定在 mediaType 之后,保持稳定字段顺序 - agent/direct_tool_bridge.rs:category 直接取 manifest 条目已解析的功能分类(显式合法值原样保留,历史缺字段时已按 kind 派生),tags 缺失时为空数组,不改变 manifest 结构与对外契约 - agent/direct_tools_mcp.rs:agc_list_registered_assets 工具描述补上功能分类与自定义标签,与新增输出字段保持一致 - agent/direct_tool_bridge.rs:既有序列帧投影测试补充 category 与 tags 默认值断言 - agent/direct_tool_bridge.rs:新增 bridge_registered_resource_projects_manifest_classification_verbatim,锁定显式分类与标签原样透出且不泄漏 prompt / model --- .../src-tauri/src/agent/direct_tool_bridge.rs | 40 +++++++++++++++++++ .../src-tauri/src/agent/direct_tools_mcp.rs | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) 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 6b148deed..6923b0761 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 @@ -1161,6 +1161,8 @@ fn bridge_registered_resource( "localPath": asset.local_path, "kind": asset.kind, "mediaType": asset.media_type, + "category": asset.category, + "tags": asset.tags, "canvasProjectId": asset.source.canvas_project_id, "resourceId": asset.source.resource_id, "assetObjectId": asset.source.asset_object_id, @@ -2867,6 +2869,8 @@ mod tests { projection["imageSequenceFrames"][0]["objectKey"], "animations/frame-01.png" ); + assert_eq!(projection["category"], "character"); + assert_eq!(projection["tags"], json!([])); let serialized = projection.to_string(); assert!(!serialized.contains("signed.invalid")); assert!(!serialized.contains("private prompt")); @@ -2874,6 +2878,42 @@ mod tests { assert!(!serialized.contains("private.invalid")); } + #[test] + fn bridge_registered_resource_projects_manifest_classification_verbatim() { + let asset = GameCreationAppAssetManifestEntry { + id: "spec-1".to_string(), + kind: "spec".to_string(), + media_type: "application/json".to_string(), + local_path: "assets/specs/hero.json".to_string(), + image_sequence_frames: None, + image_sequence_duration_ms: None, + category: + shared_contracts::game_creation_app::GameCreationAppAssetCategory::UiInteraction, + tags: vec!["主角".to_string(), "第一版".to_string()], + source: GameCreationAppAssetSource { + kind: GameCreationAppAssetSourceKind::Generated, + canvas_project_id: None, + resource_id: None, + asset_object_id: None, + task_id: None, + prompt: Some("private prompt".to_string()), + model: Some("private model".to_string()), + generation_route: None, + generation_kind: None, + reference_resource_ids: Vec::new(), + }, + }; + + let projection = bridge_registered_resource(&asset, false); + assert_eq!(projection["kind"], "spec"); + assert_eq!(projection["category"], "ui-interaction"); + assert_eq!(projection["tags"], json!(["主角", "第一版"])); + assert_eq!(projection["imageSequenceFrames"], Value::Null); + let serialized = projection.to_string(); + assert!(!serialized.contains("private prompt")); + assert!(!serialized.contains("private model")); + } + #[test] fn bridge_success_warnings_are_redacted_before_serialization() { let root = tempfile::tempdir().expect("warning redaction root"); diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs index 3dde7a64a..11e028cb4 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs @@ -256,7 +256,7 @@ fn direct_tools_mcp_specs_for(controlled_web_search: bool) -> Value { }), json!({ "name": "agc_list_registered_assets", - "description": "查询当前项目由客户端权威 manifest 登记的资源与未完成资源 operation。结果有界且只包含项目相对路径、稳定资源身份、序列帧身份和恢复状态,不返回 prompt、模型、签名 URL、宿主路径或凭据。", + "description": "查询当前项目由客户端权威 manifest 登记的资源与未完成资源 operation。结果有界且只包含项目相对路径、稳定资源身份、功能分类与自定义标签、序列帧身份和恢复状态,不返回 prompt、模型、签名 URL、宿主路径或凭据。", "inputSchema": { "type": "object", "properties": {