fix(app-shell): AI 卡片的出站文本随会话语言取值,不再读 UI 包 (#3896) - #3921
Merged
yinlianghui merged 1 commit intoAug 9, 2026
Conversation
#772 / #2884 立下的规则写在 `AiChatPage` 的门上:出站文本随**会话**语言,渲染 标签随 UI 语言。规则只实现了一半 —— 三条出站文本写作 `convZh ? '<中文字面量>' : t('console.ai.…')`,而 `t()` 读的是 **UI 包**,于是 「非中文」那一支答的是 UI 语言、不是英文;第四条 `planAnswerMessage` 连门都没过。 两个方向各一个已实测后果: - **zh 控制台 + 英文会话发出中文。** zh 包定义了全部四个 key,所以 `t()` 是命中 而非落到英文 defaultValue:点 Build it,进英文线程的是 `确认,开始搭建。`。cloud 确认门(`service-ai-studio` `confirm-gate.ts` `APPROVAL_RE`)两种语言都认,构建 照走,agent 随后把整条线程转成中文 —— 即 #2884 的症状、触发方向相反。 - **一键回答芯片两个方向都发 UI 语言。** 完全未门控:中文会话里发出 `For "…", go with: …`(#772 开头那句抱怨的字面重演),zh 控制台下的英文会话里 发出中文句子。 四个站点现在统一走一个取值器 `outboundAgentText.ts`:中文会话取 `zh` 包该 key, 其余会话取 `en` 包该 key,永不读 UI 包。三个控制台 AI 界面(`/ai` 页、chat dock、 Studio copilot)都挂同一个 `ChatPane`,一并生效。 直接读两个包而不用 `t(key, { lng })` 是刻意的:i18next 的答案取决于宿主 app 装了 哪些 bundle 以及 `fallbackLng`,而 zh 查询静默回落到 en 正是上面那个错语言 bug。 取值器内的兜底表按语言分,并被钉成与两个包逐字节一致 —— 万一某个包不再定义该 key, 中文会话兜底到中文,绝不兜到英文。 标签未动:仍随 UI 语言。#3837 那条「`*Label` 漂回会话门就红」的钉子现在同时守住 反向 —— 出站 `*Message` 被重新塞回 `t()` 也会红。 Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 9, 2026 02:55
yinlianghui
deleted the
claude/issue-3896-outbound-conversation-language
branch
August 9, 2026 02:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3896
自
origin/main@2937bcf7db0da9d27cd4f330a7033d2b380d2335切出。缺陷:规则只实现了一半
#772 / #2884 立下的规则写在
AiChatPage的门上 —— 出站文本随会话语言,渲染标签随 UI 语言。三条出站文本的写法是convZh ? '中文字面量' : t('console.ai.…'),而t()读的是 UI 包,于是「非中文」那一支答的是 UI 语言、不是英文;第四条planAnswerMessage连门都没过。两个方向各一个已实测后果:zh.ts:1649-1651、1656),所以那次t()是命中、不是落到英文 defaultValue:点 Build it,进英文线程的是确认,开始搭建。。cloud 确认门(service-ai-studioconfirm-gate.tsAPPROVAL_RE)两种语言都认,构建照走,agent 随后把整条线程转成中文 —— 即 ChatbotEnhanced 约 20 处无条件中文,英文用户直接看到中文;其中一处还作为消息发给 agent #2884 的症状、触发方向相反。For "…", go with: …(chore(deps-dev): bump storybook from 8.6.15 to 8.6.17 #772 开头那句抱怨的字面重演);zh 控制台下的英文会话里则发出中文句子。修法:一个会话语言取值器,四个站点
新增
packages/app-shell/src/console/ai/outboundAgentText.ts:中文会话取zh包该 key,其余会话取en包该 key,永不读 UI 包;planAnswerMessage纳入同门({{question}}/{{option}}占位符照填)。AiChatPage里convZh现在只有一个消费者 —— 这个取值器的桥。三个控制台 AI 界面(/ai页、ChatDock、StudioAiCopilot)都挂同一个ChatPane,一并生效。为什么直接读两个包而不是
t(key, { lng }):i18next 的答案取决于宿主 app 装了哪些 bundle 以及fallbackLng—— 一次 zh 查询在缺 zh bundle 时会静默回落到 en,那正是本单要修的「错语言」bug 换个触发条件重生。取值器里按语言分的兜底表被钉成与两个包逐字节一致,所以万一某个包不再定义该 key,中文会话兜底到中文,绝不兜到英文。顺带的活性收益:今天 zh 包这四个值对中文会话是读不到的(中文会话走硬编码字面量),唯一读到它们的路径就是那个 bug;修完之后它们成了中文会话的正规来源。
钉子
AiChatPage.planCardLocale.test.tsx新增#3896describe:四站点 × 会话{zh,en} × UI{zh,en,de} 全矩阵(真I18nProvider、真语言包、真isConversationZh,ChatbotEnhanced换成 prop 记录器)。de作为第三个 UI 语言同跑,证明取值器没有偷偷靠一次「碰巧一致」的 UI 包查询。outboundAgentText.test.ts:取值器单测,文件里故意没有I18nProvider—— UI 语言在这里连表达都表达不出来,这是单测层面能给出的最强陈述。console-namespace-3546.test.tsx的源码钉按新形状重写(AiChatPage 的 planBuildingLabel 按「对话语言」而非 UI 语言取值 —— 英文界面 + 中文会话时,方案卡上唯一一个中文标签,且 zh 包该 key 永远读不到 #3837 那条的另一半):convZh只许被取值器桥读到;取值器只许被四条*Message调用;并新增一条 —— 任何出站*Message被重新塞回t()就红。outbound-agent-messages.test.ts的自述按 AiChatPage 发给 agent 的四条确认文本仍按 UI 语言取值:zh 控制台 + 英文会话把「确认,开始搭建。」发进英文线程,planAnswerMessage 更是完全没有会话语言门控 #3896 正文的建议改写:它保证的是「八个非门控包都不定义这四个 key」,不是「任何非中文包的t()都会 MISS」—— 后者对 zh 恰恰不成立,而这正是 bug 藏身的前提。同时说清修完之后该守卫的理由变了:第九个包加译文现在只是死值(取值器根本不读那个包),而在 AiChatPage 发给 agent 的四条确认文本仍按 UI 语言取值:zh 控制台 + 英文会话把「确认,开始搭建。」发进英文线程,planAnswerMessage 更是完全没有会话语言门控 #3896 之前它是会被真的发出去、把确认门打哑的(fix(i18n): unconditional Chinese in the chatbot confirm card and field inspector (#2884, #2885) #2900 就是这么发生的)。all-locales-key-parity.test.ts里那段引用同一机制的豁免说明一并更正。反向验证(预判先写,再跑)
把四个站点还原成修前写法(取值器与全部测试保持已提交状态):
*Message)planAnswerMessage)planAnswerMessage)console-namespace-3546源码钉convZh代码行 3 → 6outboundAgentText.test.ts最后两行是刻意预判成绿的,也是本单为什么必须单独立钉:取值器单测钉的是取值器的契约、不是它的采用;#3837 那条旧钉只测了 en UI + 中文会话和 de UI + 英文会话两格,对本缺陷天生盲。合计 4 红 / 66。
判别性最强的那格:
测试证据
pnpm --filter '@object-ui/app-shell^...' build→ EXIT=0packages/app-shell/src/console/ai+packages/i18n,含四个被改的钉子文件):48 files / 682 tests passedturbo run type-check --concurrency=2:78 successful, 78 totalnode scripts/check-control-bytes.mjs:OK(3797 tracked text files);改动文件另跑控制字节自扫,零命中未动的东西
标签仍随 UI 语言,
zh/en语言包的值一字未改(所以check:i18n-en-drift不涉及),de.ts未碰(#3876 在飞),content/docs/releases/未碰。changeset:@object-ui/app-shellpatch。Generated by Claude Code