合并 master:引用粘贴解析与渠道产品名等上游变更
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m21s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 45s
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Frontend tests (pull_request) Successful in 1m58s
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m21s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 45s
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Frontend tests (pull_request) Successful in 1m58s
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
- 合并 origin/master(引用名归一化与粘贴解析 #473 系列、客户端渠道产品名统一 ebb288a6a、#500 等)到本分支,保持 PR #497 可合并。
- 冲突仍只在 `docs/project-memory/shared-memory/decision-log.md` 顶部新增条目:按「新条目在上」保留双方内容,本分支的运行视窗条目在前。
- 上游改动落在 `features/project-workspace` 的引用链路与渠道命名脚本上,未触及本分支的运行页 chrome 与预览适配文件。
- 合并后 `apps/ai-game-creator-shell:check:web` 有 1 条红:`tests/WindowChrome.test.tsx` 仍断言标题栏品牌名为 `陶泥儿 GameAgent`,而 ebb288a6a 把该处改成读取 `APP_NAME`(未注入 `VITE_AGC_PRODUCT_NAME` 时回退 `陶泥儿开发版`),测试未同步。已验证与本分支无关:把这两个文件的合并前版本换回来 5/5 通过,换回合入版本即 1 条红。等上游修,本分支不动。
This commit is contained in:
@@ -47,3 +47,10 @@
|
||||
- 风险:非默认渠道首次以新身份安装,老 `dev` 用户不会自动迁移本地数据。回滚点:渠道身份只影响非默认渠道构建,撤销该渠道的构建产物即可,仓库侧无数据迁移。
|
||||
- 风险:窗口标题改为构建期产品名后,标题不再等于配置里的字面量。回滚点:去掉 `main.rs` 的标题覆盖调用,行为回到配置标题。
|
||||
- 风险:ACL managed 识别放宽到前缀族。回滚点:`is_game_creator_packaged_app_data_leaf` 收紧回单一直线值,但非默认渠道的提权修复会重新失败关闭。
|
||||
|
||||
## 2026-09-23 追加:dev 渠道展示名统一
|
||||
|
||||
- `dev` 渠道继续复用 `world.genarrative.ai-game-creator`,保证既有安装、升级链和 AppData 路径不变;展示名统一为 `陶泥儿开发版`。
|
||||
- `channel-identity.mjs` 是展示名单一来源。发布构建将同一 `productName` 同时注入 Tauri 安装配置、原生窗口标题和 `VITE_AGC_PRODUCT_NAME`;React 自绘标题栏及关于/运行时配置展示从该注入值读取。
|
||||
- 因此 Windows NSIS 默认生成的快捷方式、开始菜单/卸载注册表展示名随 Tauri `productName` 变为 `陶泥儿开发版`;未新增自定义注册表或快捷方式实现。
|
||||
- 静态 Tauri 基线配置同步为 `陶泥儿开发版`,本地壳与正式 `dev` 包的显示名保持一致。
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 引用粘贴解析实施计划
|
||||
|
||||
对应:[引用候选由宿主注入](../../adr/【ADR】引用候选由宿主注入-2026-09-22.md)(含 2026-09-22 修订节);决策记录见 `docs/project-memory/shared-memory/decision-log.md` 的 2026-09-22 条目。上一步的重构计划见 [引用输入区重构与宿主注入](【实施计划】引用输入区重构与宿主注入-2026-09-22.md),那份明确不含本项。
|
||||
|
||||
## 一句话交付与验收判据
|
||||
|
||||
把从用户消息气泡(或任何同口径文本)复制出来的 `@显示名` / `$名称` 粘贴进引用输入区时,原位重建同顺序的引用芯片;其余文字逐字保留。
|
||||
|
||||
验收判据:
|
||||
|
||||
1. 粘贴文本 → 引用:`@显示名` 与 `$名称` 逐字命中当前宿主注入的 provider 候选时原位换成芯片,一次 Ctrl+Z 整体回退,token 之外的每个字符(含换行与空白)原样保留。
|
||||
2. 逐字一致、不做兼容别名:不认 `@hero.png`、`resourceId`、大小写变体、全角 `@`;token 前后必须是行首 / 行尾或空白。
|
||||
3. 宁可不成芯片也不能认错:同名多候选(同一个 token 对应多条引用身份)一律按文本保留;未命中的 token 静默保留,不提示、不猜路径或文件名。
|
||||
4. 只有真的解析出引用时才接管:同 namespace 的 `application/x-lexical-editor` 负载、不含 token 的纯文本、图片文件粘贴一律放行编辑器默认导入,现有粘贴行为逐字不变。
|
||||
5. 附件与运行画面区域不参与粘贴解析(静默 provider 没有候选),它们的 token 粘贴时按文本保留。
|
||||
6. Skill 目录冷启动不阻塞粘贴:`lookup()` 是纯函数,目录没到就是空数组——冷启动时粘贴 `$名称` 保留为文本(不等待、不补读),用户敲过一次 `$` 后即可解析。
|
||||
|
||||
## 流程判定
|
||||
|
||||
本次是共享组件的一处行为增量 + provider 契约加两个可选能力,不动 schema、不动公开 API/DTO、不动后端;按轻量流程只建本实施计划,不新建主规范与里程碑规范(与上一步重构同一判定)。
|
||||
|
||||
## 提交切分
|
||||
|
||||
1. **反解析口径**:`resourceReferences.ts` 新增 `buildContentFromPastedText(text, references)`(粘贴侧唯一反解析;与 `buildContentFromTextTokens` 同一套边界规则),配规则矩阵单测。
|
||||
2. **provider 契约**:`reference-source/types.ts` 把菜单查询改名为 `fuzzyLookup(query)`、新增精确查找 `lookup()`(两者共用同一份候选来源);`resourceReferenceProvider` 给全量可提及候选,`skillReferenceProvider` 给去重后的 Skill 候选。
|
||||
3. **输入区接管**:`ResourceReferenceInput` 注册 `COMMAND_PRIORITY_CRITICAL` 的 `PASTE_COMMAND`,只在解析出引用时 `preventDefault` 并在一次 `editor.update`(`PASTE_TAG`)内按选区插入;配集成用例。
|
||||
4. **文档**:`CONTEXT.md` 术语、本计划、ADR 修订节、`docs/【功能说明】AGC聊天素材引用-2026-09-08.md` 与决策记录。
|
||||
|
||||
## 验证
|
||||
|
||||
定向:`npx vitest run apps/ai-game-creator-shell/tests/resourceReferences.test.ts apps/ai-game-creator-shell/tests/referenceSourceProviders.test.ts apps/ai-game-creator-shell/tests/resourceReferenceInput.test.tsx`;全量:`npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。真实客户端手感(粘贴时的候选菜单位置、大段文本粘贴观感、Tauri 剪贴板只带图片时的行为)留待真机验收。
|
||||
|
||||
## 风险与回滚
|
||||
|
||||
- 解析接管会绕过 Lexical 的 `text/html` 富文本导入:只在文本里真的解析出引用时接管,取舍已在上一条判据里限定;要完全避开富文本场景可以后续按 `clipboardData.types` 再收窄。
|
||||
- 气泡里若出现与素材同名的 `@区域标签` / `@附件名`,粘贴会被认成素材引用——纯文本无法区分,属已知取舍。
|
||||
- 回滚按提交粒度 revert;canonical content 形状、provider 的既有能力与出站文本口径都不变。
|
||||
|
||||
## 执行状态(2026-09-22)
|
||||
|
||||
已完成:`buildContentFromPastedText` 与规则矩阵单测(命中 / 未命中 / 相邻中文 / 扩展名 / 大小写 / 全角 / 同名歧义 / 重复出现 / 换行 / 与显示口径互为逆运算);provider 的 `fuzzyLookup` / `lookup` 及用例;输入区 `PASTE_COMMAND` 接管与 5 条集成用例(粘贴重建芯片、未命中保持字面、纯文本走默认导入、Lexical 负载让位、Skill 冷启动保持字面且敲过 `$` 后可解析);文档同步。
|
||||
|
||||
未做(本次范围外):斜杠命令 `/` 解析、拖拽文本(drop)、附件 / 运行画面区域 / 文件路径 / URL / 剪贴板图片的解析、复制侧 `text/plain` 形态调整、扩展安装卸载后的目录即时失效。
|
||||
|
||||
## 追加执行状态(2026-09-23):前缀重叠按「引用名无空白」收口
|
||||
|
||||
自动评审留下的唯一破坏性项(`@hero` 与 `@hero v2` 互为前缀时粘贴会多插一枚短名芯片)不改反解析,改为把不变量前移到引用名:
|
||||
|
||||
- `resourceReferences.ts` 新增共享 `normalizeMentionName(value)`(内部空白折 `-`、裁首尾),素材显示名(`resourceDisplayName`)、Skill 名(目录读入与 `toReference` / `mentionToken`)、附件名(导入映射与 `toReference` / `mentionToken`)与两个 token 投影(`chatReferenceMentionToken`、`directCodexContentToPromptText`)统一过这一份;token 层重复归一化是幂等的。
|
||||
- 名称里不做 `resourceId` 兜底这一条按评审校正:词干为空(`.env` / `.gitignore` 这类整名就是扩展名的文件)时 `resourceDisplayName` 回退 `asset.id`,回退值同样过 `normalizeMentionName`;`normalizeMentionName` 自己仍只做归一化。
|
||||
- 代价与取舍:`hero v2` 与 `hero-v2` 归一化后同名时走既有的「同名多候选按文本保留」;改动前生成的旧文本里的 `@hero v2` 不再解析。
|
||||
- 验证:`normalizeMentionName` / 显示名 / token 口径单测 + 前缀重叠回归用例(归一化后粘贴只剩正确的那一枚芯片)+ provider 两处用例;把 `normalizeMentionName` 变异成恒等后新增用例全红。
|
||||
|
||||
## 追加执行状态(2026-09-23 第二轮自动评审):空名字与插入兜底收口
|
||||
|
||||
第二轮自动评审的四个问题逐个提交处理,落点都在 `apps/ai-game-creator-shell`:
|
||||
|
||||
- 显示名不再可能为空:`resourceDisplayName` 在文件名词干为空(`.env` / `.gitignore`)时回退 `asset.id`,回退值同样过 `normalizeMentionName`(提交 `4e90465c4`)。这条校正了上一节「不做兜底」的写法,决策记录与功能说明同步。
|
||||
- 粘贴解析跳过退化 token:`buildContentFromPastedText` 组装候选时跳过 `token.length <= 1` 的条目,裸 `@` / `$` 不再认领正文里的触发符(提交 `3f9c698a6`)。
|
||||
- 粘贴接管改成「插入真的发生之后」才 `preventDefault`:`$insertContentAtSelection` 返回「插进去没有」,插入为空时放行默认粘贴;编辑器已在更新中(回调被排队)时按原口径先接管(提交 `3391ecf7d`)。
|
||||
- 插入兜底不再留空:provider 的 `toReference` 与 `mentionToken` 都答不出来的 part 退到新增的 `contentPartText`(通用文本形态,资源落 `@resourceId`)。此前这一支会什么都不插,是「粘贴内容逐字保留」唯一的例外分支;现在没有例外。新增单测覆盖四类 part 的文本形态,新增输入区集成用例证明被破坏的 provider 契约下这段粘贴仍按文本落下,去掉兜底即变红。
|
||||
- 归一化撞名(`hero v2` 与 `hero-v2` 折成同一个 token)只在解析侧兜住、候选菜单不提示冲突,这一条涉及「哪些素材能被 @ 到」的产品取舍,未改代码,留给下一轮决定。
|
||||
- 润色回写与粘贴共用同一条落点兜底:新增 `mentionTokenOrText`(provider 的 `mentionToken`,拿不到就退 `contentPartText` 的通用文本形态),润色回写的候选扫描、整根替换的落点与粘贴插入的兜底都走它。由此润色回写不再有「provider 答不出 token 的 part 直接消失」和「整根替换时 part 解析不出引用就整条吃掉」两条静默丢弃路径;初始草稿(`applyContent`)与润色回写(`applyPolishedTextToRoot`)共用 `applyContentToRoot`,所以恢复出来的草稿里已解析不出的引用现在落成 `@resourceId` 文本而不是被吃掉。
|
||||
@@ -10,6 +10,30 @@
|
||||
- 决策四的残余边界(明确不修):若某个**固定尺寸**页面恰好等于它被接受时的容器尺寸,且缩小容器后它上报的内容尺寸再不变,就会一直按容器取画布(页面自身溢出被裁)。评审提过「内容尺寸没变也把这条记录改认新容器」,我实现后又**实测回退**了:那条过渡期上报(内容还是放大前的旧值、视口已是缩小后的容器)会被当成固有尺寸,全屏那类问题原样复现且同样永久(iframe 回到旧尺寸后桥不再上报)。两者在宿主拿到的数据上不可区分,按 AGC 常态(桥对自适应与「固定画布但自适应文档」两类页面实测都报「内容 = 视口」)选自适应优先;页面报告新内容尺寸时立即回到 `max(容器, 内容)` 等比缩小(用例 `refits to the reported content size after the container shrinks`)。根治方向在桥 / 协议侧:尺寸消息再带一个「本页是否视口耦合」的布尔(桥内部已有逐元素耦合采样与排除耦合后的边界),拟合直接按它判定,不必用两个数字相等去猜——属桥与协议的独立变更,本 PR 不做。
|
||||
- 验证:新增 `tests/runPreviewFullscreen.test.tsx`(补出 jsdom 缺失的 Fullscreen API:按钮住在画面那一格里、点击 → `requestFullscreen` → 退出全屏,以及宿主没有该 API 时不渲染);`tests/localGamePreviewFrame.test.ts` 抽出 `renderFittedFrame` 夹具并补上面两条用例;AGC 子集补「信息栏有内容自动展开 / 手动收起 / 再展开」,并把「没有内容时运行页仍渲染两张卡片」的旧断言改成整栏不渲染(`数值微调面板` 这条已随删除面消失的 label 断言同步删掉,避免恒真)。`apps/ai-game-creator-shell:check:web` 全量通过(`tsc` + 1812 项,合并上游退役提交后的口径)、编码检查与 `git diff --check` 通过;并用真实 Chromium(挂同一份组件 + 客户端真实注入的尺寸桥脚本,`fullbleed` 与 `fixed` 两种游戏页)冒烟:右下角按钮只把画面那一格送进全屏且可退出、退出后画布缩回容器尺寸、选中资源后信息栏自动展开(190px)、收起后画面变高(26px→636px)、再展开恢复。
|
||||
|
||||
## 2026-09-23 引用名不允许空白:素材 / Skill / 附件共用 `normalizeMentionName`
|
||||
|
||||
- 背景:自动评审发现 `buildContentFromTextTokens` 在前缀重叠时会多插一枚芯片——素材显示名 `hero` 与 `hero v2` 并存时,粘贴 `看 @hero v2 这一版` 得到 `[chip hero]` + `[chip hero-v2]`(短名先按 index 平局抢位,长名成了补到末尾的孤儿)。根因不是匹配算法,而是**引用名自己带空白**:token 的边界规则是「前后为空白或行首行尾」,`@hero␠` 在 `@hero v2` 内部也算一次合法命中。
|
||||
- 决策:把不变量前移到引用名——`@显示名` / `$名称` / `@附件名` 的名字内部不允许空白,统一经共享 `normalizeMentionName(value)`(内部空白折成 `-`、裁掉首尾)处理。落点是名字的产生处:`resourceDisplayName()`、Skill 目录读入与 `toReference` / `mentionToken`、附件导入映射与 `toReference` / `mentionToken`,外加两个 token 投影(`chatReferenceMentionToken`、`directCodexContentToPromptText`)——token 层幂等再折一次,「token 里没有空白」就是不变量本身的性质,不依赖上游数据干净。
|
||||
- 决策(不兜底):引用名假定非空,不做 `resourceId` 之类的兜底;`resourceDisplayName` 原来的 `|| asset.id` 一并去掉。
|
||||
- 校正(2026-09-23,评审项):`resourceDisplayName` 的空名字兜底不能一并去掉——整名就是扩展名时(`.env` / `.gitignore`)去掉扩展名得到空串,显示名成了空串,token 退化成只有触发符的裸 `@`(候选菜单里是空芯片,粘贴解析还会认领正文里任何一处裸 `@`)。改为词干为空时回退 `asset.id`(仍过 `normalizeMentionName`);`normalizeMentionName` 自己没有兜底、只做归一化这条不变。
|
||||
- 落点兜底(2026-09-23,评审项):part 落进正文的兜底链统一为 `mentionTokenOrText`(provider 的 `mentionToken`,拿不到就退 `contentPartText` 的通用文本形态,即 `@resourceId` / `$名称` / `@附件名` / `@区域标签`)。粘贴插入、润色回写的候选扫描与整根替换共用它,删掉两处静默丢弃路径(provider 答不出 token 的 part 在润色翻译里消失;整根替换时解析不出引用的 part 被吃掉)。副作用是恢复出来的初始草稿里已解析不出的引用落成 `@resourceId` 文本而不是消失——宁可留文本,也不让内容凭空少一段。
|
||||
- 原因:不改反解析是因为粘贴解析与润色回包共用 `buildContentFromTextTokens`,改匹配算法要冒回归润色的风险;而「名字里带空白的 token」本来就无法手敲(候选触发器 `allowWhitespace: false`,空格处菜单就关),显示口径与输入口径早就不一致。折成 `-` 之后 token 自带边界:`@hero` 不会命中 `@hero-v2`(后一个字符是 `-`,不是空白),前缀重叠不可能再发生。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src/features/project-workspace/{resourceReferences.ts,reference-source/{skillReferenceProvider.ts,attachmentReferenceProvider.ts}}`、`apps/ai-game-creator-shell/src/view/project-development/chat/conversation/directCodexTurnAttachments.ts`、`apps/ai-game-creator-shell/tests/{resourceReferences.test.ts,referenceSourceProviders.test.ts}`、`CONTEXT.md`、`docs/【功能说明】AGC聊天素材引用-2026-09-08.md`、`docs/project-memory/plans/【实施计划】引用粘贴解析-2026-09-22.md`。
|
||||
- 代价(已接受):归一化可能撞名(`hero v2` 与 `hero-v2` 同名),走既有的「同名多候选一律按文本保留」——不认错,但两者都成不了芯片;改动前生成的旧文本(历史回合 prompt、旧气泡)里的 `@hero v2` 不再解析,重试 / 润色回填时那条引用会退化成末尾孤儿(内容不丢、位置可能不对)。
|
||||
- 验证方式:`normalizeMentionName`、`resourceDisplayName`、`chatReferenceMentionToken` 的口径单测;「空白折 `-` 后 token 自带边界、前缀重叠只剩正确芯片」的回归用例;Skill 目录名带空白与附件名带空白的 provider 用例;把 `normalizeMentionName` 变异成恒等函数后以上新增用例全部变红。另跑受影响用例、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-09-22 引用粘贴解析:只认显示口径的 token,宁可不成芯片也不能认错
|
||||
|
||||
- 背景:引用输入区的 `@` / `$` 只由 `LexicalTypeaheadMenuPlugin` 的逐字敲击触发,粘贴走 Lexical 默认路径(`text/plain` → 纯文本),所以从用户消息气泡复制回来的 `@显示名` / `$名称` 粘进来就是死文本;同时 chip 的 `text/plain` 是占位符,复制出去再粘回来必然丢引用(气泡显示文本才是完整 token 的形态)。
|
||||
- 决策(口径):新增粘贴侧唯一反解析 `buildContentFromPastedText(text, references)`(`apps/ai-game-creator-shell/src/features/project-workspace/resourceReferences.ts`),候选由宿主注入的 provider 枚举,token 就是 `chatReferenceMentionToken`——与出站显示逐字同一个字符串,所以**不做任何兼容别名**:不认 `@hero.png`、`resourceId`、大小写变体、全角 `@`;边界仍是「行首 / 行尾或空白」(显示侧 token 前后补空白,两端自洽)。
|
||||
- 决策(宁可不成芯片也不能认错):同一个 token 对应多条引用身份(同名素材)时一律按文本保留;未命中的 token 静默保留、不提示、不猜文件名或路径;附件与运行画面区域不参与(静默 provider 没有候选,`@附件名` / `@区域标签` 按文本保留)。
|
||||
- 决策(provider 契约按「模糊 / 精确」分两个口):上一条里的 `match(query)` 改名 `fuzzyLookup(query)`(名字写明它是包含匹配 + 截断的模糊菜单查询),`candidates()` 改名 `lookup()`(精确查找用的、就绪的全量候选,不模糊不截断),两者共用同一份候选来源。粘贴解析只用 `lookup()` 此刻就绪的候选:不等待、不补读,也不为了解析去提前读盘;Skill 目录仍是「用户第一次敲出 `$` 才读」,冷启动时粘贴 `$名称` 保持字面文本,敲过一次 `$` 后即可重建芯片。曾一度加过的 `onPasteText` 补读钩子已删除——它既不改变本次粘贴的结果,又让输入区反过来关心 provider 的触发符。
|
||||
- 决策(接管范围):输入区在 `COMMAND_PRIORITY_CRITICAL` 注册 `PASTE_COMMAND`,**只在真的解析出引用时**接管(同 namespace 的 `application/x-lexical-editor` 负载、无 token 纯文本、图片文件一律 `return false` 走默认导入);接管时一次 `editor.update(..., { tag: PASTE_TAG })` 内按选区插入,所以一次 Ctrl+Z 整体回退,token 之外逐字保留。
|
||||
- 原因:粘贴是用户此刻的编辑,事后回头改写他的输入(例如清单到齐后再把文本改成芯片)等于前端替用户重写内容;而任何「多候选取其一」「按文件名猜资源」的启发式都会制造看不出错的错引用。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src/features/project-workspace/{resourceReferences.ts,ResourceReferenceInput.tsx,reference-source/{types.ts,resourceReferenceProvider.ts,skillReferenceProvider.ts}}`、`apps/ai-game-creator-shell/tests/{resourceReferences.test.ts,referenceSourceProviders.test.ts,resourceReferenceInput.test.tsx}`、`CONTEXT.md`、`docs/adr/【ADR】引用候选由宿主注入-2026-09-22.md`(修订节)、`docs/【功能说明】AGC聊天素材引用-2026-09-08.md`、本文件。
|
||||
- 未纳入本次:斜杠命令 `/` 解析、拖拽文本(drop)、附件 / 运行画面区域 / 文件路径 / URL / 剪贴板图片、复制侧 `text/plain` 形态调整、扩展安装卸载后的目录即时失效。
|
||||
- 验证方式:`buildContentFromPastedText` 规则矩阵单测(含「显示文本再粘贴回来得到同一份 content」这条逆运算)、provider 的 `fuzzyLookup` / `lookup` 用例、输入区集成用例(真 Lexical `paste` 事件 → 芯片、未命中等价于默认粘贴、Skill 冷启动保持字面且敲过 `$` 后可解析);另跑 `npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。
|
||||
|
||||
## 2026-09-23 最近项目检查失败不进终态
|
||||
|
||||
- 背景:最近项目列表把一次性的目录检查失败当成终态——5s 超时被吞成 `null`,增量投影又把上一轮的 `null` 原样搬进下一轮,且没有重试或重查入口。AGC 一次 IPC 停顿之后,整张列表会永久停在「检查失败 + 待识别」,首页「最近项目」同时因 `canOpen` 过滤变空,只能重启客户端恢复(issue #490)。
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 踩坑与排障记录
|
||||
|
||||
## Direct 宿主继续请求不能重发原始用户条目
|
||||
|
||||
原始 `direct_user_item` 同时参与历史持久化和模型输入转换;验收或错误反馈更新了 prompt 后,如果发送层仍优先转换原始条目,模型会收到重复的用户输入,而本地历史按 itemId 去重后只显示一次。首次请求与宿主继续必须显式区分:首次保留结构化输入,继续发送当次反馈,原始条目只保留历史与事件关联职责。GUI、CLI 的两条循环都要覆盖;只改反馈文本或清空原始条目不完整。见 [Direct 宿主继续请求输入修复](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md#2026-09-23-direct-宿主继续请求输入修复)。
|
||||
|
||||
## 最近项目一次失败会被钉成终态
|
||||
|
||||
- **现象**:AGC 卡住一次后,项目列表每一行都显示「检查失败 + 待识别」,首页「最近项目」变成「暂无最近项目」;现场在后端恢复后逐条复跑 `inspect_local_project_directory`(8 个项目)全部 0ms 成功,界面仍然全红(issue #490)。
|
||||
|
||||
Reference in New Issue
Block a user