diff --git a/README.md b/README.md index f47825a..49a40d8 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,9 @@ Args: [你的项目所在盘符]:/[项目路径]/packages/mcp-bridge/mcp-proxy.j 1. 如果属性期望组件类型但传入节点 UUID,插件会自动查找匹配组件。 2. 对于资源类属性(如 `cc.Prefab`, `cc.Material`),传递资源的 UUID,插件会自动处理异步加载与序列化。 3. **资产数组支持**: 针对 `materials` 等数组属性,支持传入 UUID 数组,插件将自动并发加载所有资源并同步更新编辑器 UI。 +- **防呆校验 (Safety Checks)**: + 1. **类型拦截**: 严格禁止将 `cc.Node` 或 `Node` 作为组件类型添加,插件将直接拦截并以中文提示正确工具(如 `create-node` 或 `set-property`)。 + 2. **合法性检查**: 严格校验传入的组件类必须继承自 `cc.Component`,防止非法类型引发底层报错。 - **操作规则 (Subject Validation Rule)**:赋值或更新前必须确保目标属性在组件上真实存在。 ### 9. manage_script diff --git a/UPDATE_LOG.md b/UPDATE_LOG.md index 943ff83..d9bb0cb 100644 --- a/UPDATE_LOG.md +++ b/UPDATE_LOG.md @@ -185,3 +185,11 @@ - **问题**: 现有的面板调试终端在记录 AI 工具调用时,只有指令头如 `REQ -> [manage_components]`,无法透视 AI 实际上到底提交了哪些参数。致使类似参数名称写错的幽灵 Bug 极难被常规察觉。 - **优化**: 修改了 `main.js` 中的 `/call-tool` 路由逻辑。现在系统拦截不仅会记录动作名称,还会将完整的 `arguments` 以 JSON 序列化的形态连同日志一并输出在面板中:例如 `参数: {"nodeId":"...","operation":"get"}`。 - **保护机制**: 为防止类似多边形顶点数据等过大的参数体撑爆编辑器控制台缓存或导致 UI 卡顿,日志处理对超过 500 个字符长度的序列化结果启用了自动截断显示 (`...[Truncated]`)。 + +### 3. `manage_components` 类型安全与防呆校验 + +- **问题**: 某些不聪明的 AI 会混淆节点树和组件系统,在调用 `manage_components` (action="add") 时错误地将 `cc.Node` 或其他不合法的类名当作组件名传入,导致底层引擎抛出 `Cannot read property 'constructor' of null` 的深层报错并引发 AI 陷入死循环重试。 +- **修复**: 在 `scene-script.js` 层加固了前置拦截规则: + 1. **直接拦截节点**: 当检测到传入 `cc.Node` 或 `Node` 作为组件类型时直接驳回,并返回富含指导意义的中文提示词(如“请使用 create-node 创建节点”)。 + 2. **继承链校验**: 提取引擎类定义后,强制要求通过 `cc.js.isChildClassOf` 判断该类必须继承自 `cc.Component`。若不合法则即时截断并提示。 +- **价值**: 通过将冰冷的底层异常翻译为“手把手教 AI 怎么重试”的指导性异常,彻底根治了 AI 在操作组件时乱认对象、反复撞墙的通病。 diff --git a/scene-script.js b/scene-script.js index a507ef4..1f54b86 100644 --- a/scene-script.js +++ b/scene-script.js @@ -544,6 +544,20 @@ module.exports = { return; } + // 【防呆设计】拦截 AI 错误地将 cc.Node 作为组件添加 + if (componentType === "cc.Node" || componentType === "Node") { + if (event.reply) { + event.reply( + new Error( + "【纠错提示】cc.Node 是节点而不是组件,无法被当做组件添加!\n" + + "- 如果你想创建带有名字的子节点,请不要使用 manage_components,而是使用 create-node (或相应的创建节点工具)。\n" + + "- 如果你想修改现有节点的 name 属性,请使用修改节点的 set-property 工具。", + ), + ); + } + return; + } + try { // 解析组件类型 let compClass = null; @@ -560,6 +574,18 @@ module.exports = { return; } + // 【防呆设计】确保获取到的类是一个组件 + if (!cc.js.isChildClassOf(compClass, cc.Component)) { + if (event.reply) { + event.reply( + new Error( + `【错误】'${componentType}' 不是一个合法的组件类型(必须继承自 cc.Component)。请确认你的意图。`, + ), + ); + } + return; + } + // 添加组件 const component = node.addComponent(compClass);