AiChatPage 发给 agent 的四条确认文本仍按 UI 语言取值:zh 控制台 + 英文会话把「确认,开始搭建。」发进英文线程,planAnswerMessage 更是完全没有会话语言门控 #3896
Description
在 #3837(标签半边)的 PR 里写行为钉子时实测量到,不在该单范围内(#3837 只把 planBuildingLabel 从 convZh 摘出;这是同一个门的发送内容半边),单独立项。
规则
AiChatPage.tsx:1581-1586 的注释:发给 agent 的文本随会话语言(cloud 确认门 service-ai-studio confirm-gate.ts APPROVAL_RE 只认中英),标签随 UI 语言。#772 / #2884 就是为前者建立的。
后果 A —— zh 控制台 + 英文会话,发出的是中文
三条出站文本的三元(AiChatPage.tsx:1591 / 1594 / 1602)的 false 分支是 t(key) —— 读的是 UI 包,不是会话:
const planApproveMessage = convZh
? '确认,开始搭建。'
: t('console.ai.planApproveMessage', { defaultValue: 'Looks good — build it as proposed.' });
packages/i18n/src/__tests__/outbound-agent-messages.test.ts:19-21 把该设计的前提写得很清楚:
> That t() call is expected to MISS in every non-Chinese pack and fall through to its English defaultValue.
这对八个非门控包成立(该测试正是这么守的),对 zh 包不成立 —— 同一个测试的第二个用例恰恰要求 zh 定义全部四个 key(packages/i18n/src/locales/zh.ts:1649-1651、1656)。于是 zh 控制台 + 英文会话点 Build it,发进英文线程的是 确认,开始搭建。:门认中文、构建照走,但 agent 之后整条线程转中文 —— 正是 #2884 记录的症状(英文用户点确认把 agent 翻成中文),只是触发方向相反。
实测(#3837 的 PR 中,真渲染 ChatPane + 真 I18nProvider,defaultLanguage: 'zh' + 一条英文 user turn):
renderPane('zh', EN_THREAD).planApproveMessage === '确认,开始搭建。'
因为属于发送半边,#3837 的钉子没有把它钉成现状(不钉缺陷),改用 de 控制台断言英文默认值,并在测试注释里指了本单。
后果 B —— planAnswerMessage 完全没有门控
AiChatPage.tsx:2210-2216 的一键回答芯片:
planAnswerMessage={(question, option) =>
t('console.ai.planAnswerMessage', { question, option, defaultValue: 'For "{{question}}", go with: {{option}}.' })
}
它是出站文本(outbound-agent-messages.test.ts:35 把它列进 OUTBOUND_KEYS,zh 包也定义了它:zh.ts:1651),却完全不过 convZh。所以中文会话 + 英文控制台点芯片,发进自己线程的是 For "…", go with: … —— 这就是 #772 开头那句抱怨的字面重演(a Chinese thread under an English UI was sending English into its own chat);zh 控制台 + 英文会话则相反,发出中文句子。
根因与建议的修法(未裁决)
一句话:出站文本的语言必须由会话解析,t()(UI 包)不能当兜底。四个站点、一个修法 —— 收进一个按会话语言解析出站文本的函数(会话为中文 → 中文值;否则 → en 值,而不是 UI 包的值),四条一起走;同时把 outbound-agent-messages.test.ts 的自述前提改成它实际能保证的东西(它保证的是「八个非门控包不定义」,不是「任何非中文包都会 MISS」)。
关联:#772 / #2884(建立该规则)、#3837(标签半边,已修)、#3546 切片四(把这些 key 补进十包)、#2458 第 4 条(渲染层中英混杂,另一件事)。
Activity
os-zhuang commentedon Aug 9, 2026
Triage:
pm:queue— execution card of an already-made ruling, not a new decision.t()as the non-zh fallback on three gated sites;planAnswerMessagenot gated at all). Sending it back to the decision box would be the docs(layout): app-shell.mdx 的 AppShellProps 声明块补齐到 7 个 props,并钉到 interface (#4808) #4829 failure shape.origin/main@50fa376(note the real path — the filing's bareAiChatPage.tsx:1581ispackages/app-shell/src/console/ai/AiChatPage.tsx; lines shifted slightly):convZhmemo at:1594, the three gated outbound sites from:1598(each falling back tot()), and the ungatedplanAnswerMessageat:2215-2216. The zh pack defining all four keys — the premise that breaks the "MISS in every non-Chinese pack" design — is exactly as the card states.planAnswerMessagesearch returns only this card; AiChatPage 的 planBuildingLabel 按「对话语言」而非 UI 语言取值 —— 英文界面 + 中文会话时,方案卡上唯一一个中文标签,且 zh 包该 key 永远读不到 #3837 (label half) is merged and explicitly excluded this half; 258 个 t() 调用点引用的 key 在任何语言包里都不存在(#3530 守卫首跑实测),其中 8 处直接把 raw key 渲染给用户 #3546 slice 4 is the key-coverage sweep, different concern.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 9, 2026
🔒 分诊 + 认领(objectui shard PM 亲跑分诊轮,session
session_01GTRjn8xBqp75dk7kFupVRt)定级:concrete —— #3837 dev 立卡时带实测(zh 控制台 + 英文会话把「确认,开始搭建。」发进英文线程;
planAnswerMessage属 OUTBOUND_KEYS 却完全不过 convZh)。不变量已由 #772/#2884/#3837 钉死:出站文本随会话语言、双向成立。四站点一个修法。claude/issue-3896-outbound-conversation-languageplanAnswerMessage纳入同门。注意 AiChatPage 的 planBuildingLabel 按「对话语言」而非 UI 语言取值 —— 英文界面 + 中文会话时,方案卡上唯一一个中文标签,且 zh 包该 key 永远读不到 #3837/PR3897 刚立的钉(convZh 只许门控出站 *Message)与 outbound-agent-messages.test.ts 的 OUTBOUND_KEYS 都要保持绿并按需扩展。packages/app-shell/src/console/ai/AiChatPage.tsx+ 钉子;与在飞 metadata-admin 的record:details.sections块设计器没有name输入位 —— Studio 搭出来的 section 结构上无法翻译,且必然挂着上游translation-section-name-missing#3819(metadata-admin 设计器)同包不同目录,零文件相交。Generated by Claude Code
test(types): drop 37 spec-retired DROPPED_SCHEMA_EXPORTS rows, add li…
fix(app-shell): 方案卡的 Building… 徽标随 UI 语言取值,不再被会话语言门控 (objectstack-ai#…
fix(app-shell): AI 卡片的出站文本随会话语言取值,不再读 UI 包 (objectstack-ai#3896) (obj…
feat(plugin-dashboard): publish the honoured dashboard inputs, pin th…
feat(plugin-dashboard): publish the honoured dashboard inputs, pin th…
fix(types): retire DashboardComponentSchema.aria — spec-tombstoned, r…