文档:说明引用名归一化可能撞名,以及碰撞目前只在解析侧兜住
normalizeMentionName 的注释补上「归一化不保证名字唯一」:`hero v2` 与 `hero-v2` 折成同一个 token,候选菜单侧不做冲突检测、会显示同一个标签,碰撞由 buildContentFromPastedText 的「同名多候选一律按文本保留」兜住 同步 AGC 聊天素材引用功能说明的引用名空白不变量小节,写明这是已知残留
This commit is contained in:
@@ -165,6 +165,10 @@ export function resourceLabelResolver(
|
||||
*
|
||||
* 这里只做归一化、不做 `resourceId` 之类的兜底:兜底属于名字的来源侧(例如
|
||||
* `resourceDisplayName` 在文件名词干为空时回退 `asset.id`),归一化本身保持是个纯函数。
|
||||
*
|
||||
* 归一化不保证名字唯一:`hero v2` 与 `hero-v2` 会折成同一个 token,两条引用因此在候选菜单里
|
||||
* 显示同一个标签。归一化后的碰撞由 `buildContentFromPastedText` 的「同名多候选一律按文本保留」
|
||||
* 兜住(不认错,但两者都成不了 chip);候选菜单侧不做冲突检测,标签重复是这条取舍的可见残留。
|
||||
*/
|
||||
export function normalizeMentionName(value: string) {
|
||||
return value.trim().replace(/\s+/gu, '-');
|
||||
|
||||
@@ -50,6 +50,7 @@ AGC 聊天输入框支持以结构化引用标记当前项目已登记素材,
|
||||
- 归一化落在名字的产生处:`resourceDisplayName()`(素材显示名由文件名派生)、Skill 目录读入与 `toReference` / `mentionToken`、附件导入映射与 `toReference` / `mentionToken`、以及两个 token 投影(`chatReferenceMentionToken`、`directCodexContentToPromptText`)。token 层再折一次是幂等的,因此「token 里绝不会有空白」是这一层的性质,不依赖上游数据干净。
|
||||
- 为什么必须有这条不变量:token 的边界规则是「前后为空白或行首行尾」。名字里带空白时,`@hero v2` 会被反解析切成 `@hero` + 文本 `v2`,短名字抢先命中,真正的引用反而被当成孤儿补到正文末尾(粘贴回填会多出一枚错芯片)。折成 `-` 之后 token 自带边界,`@hero` 不会命中 `@hero-v2`(后一个字符是 `-`)。
|
||||
- 词干为空的素材名回退 `asset.id`:整名就是扩展名时(`.env` / `.gitignore`)文件名去掉扩展名会得到空串,空名字会让 token 退化成只有触发符的裸 `@`——候选菜单里是一枚空芯片,粘贴解析还会拿它认领正文里任何一处裸 `@`。所以 `resourceDisplayName()` 在这一种情况下回退 `asset.id`,回退值同样过一遍 `normalizeMentionName`;`normalizeMentionName` 自身仍然只做归一化、不做兜底。
|
||||
- 归一化不保证名字唯一:`hero v2` 与 `hero-v2` 会折成同一个 token,候选菜单里两条候选显示同一个标签,从气泡复制出来的那段文字也重建不成芯片(解析侧按「同名多候选一律按文本保留」处理,不认错)。菜单侧目前不做冲突检测,这是这条不变量的已知残留。
|
||||
- 已存在的老文本(本次改动前生成的回合 prompt、历史气泡)里的 `@hero v2` 不再解析——粘贴时按字面保留,重试 / 润色回填时该引用会退化成末尾孤儿。内容不丢,位置可能不对。
|
||||
|
||||
## 拖拽引用(2026-09-21)
|
||||
|
||||
Reference in New Issue
Block a user