fix(app-iced): M119 r1 —— 常驻「模拟」标识 + 确认条的键盘通路
复审 r1 的两条 p2,都是「说成真的、其实是假的」与「能走进死路」这个级别的问题。
## P2-1:界面必须自己说清「这是模拟」
原判:生产默认后端是**脚本化 rig**(`ULL_AGENT_SCRIPT` 的 6 种剧情),而「后端未接 / 模型还没
接上」两句诚实文案被我改成了中性话,理由写着「由端点标签说」——**那条端点标签在壳里根本不存在**。
于是默认配置下用户敲一句话得到一段像是模型编的回答。判据:没读过代码的用户,打开右栏、敲一句话,
必须能自己看出来这不是真模型(不接受 tooltip、不接受藏在设置里)。
修法(①恢复诚实文案 + ②常驻可见标记,并用):
| 位置 | 文案 / 形态 | 谁给的 |
|---|---|---|
| 标题右侧**常驻胶囊**(`SurfaceVariant` tonal)| `Key::AgentSimulated`(Simulated / 模拟)| `AgentHost::is_simulated()` → `Session.simulated` → 视图 |
| 标题下副标题 | 「模拟助手 · 还没接真实模型」 | `Key::AgentSubtitle`(原本是「未接」被改成中性的「会话」,现在写回来且更明确)|
| 空会话正文 | 「…当前是模拟助手,没有接真实模型。」 | `Key::AgentEmptyBody` |
| 输入框占位符 | 「给模拟助手发消息…」 | `Key::AgentPlaceholder` |
**标记不是硬编码在视图里**:`AgentHost.simulated` 是事实字段(今天 transport 只有 rig ⇒ 恒 true)。
接真 `AgentTransport` 那天把它传 `false`,四个位置的「模拟」措辞会一起消失——这是为什么用字段而不是
写死一句话。
## P2-2:确认条必须有键盘通路
原判:Allow/Deny 只有鼠标路径 ⇒ 键盘用户在写操作确认处**永久卡死**(`busy` 锁发送、
`Stop` 走主后端、清不掉 presenter 的 pending confirm)。
- 焦点环多两格:`Focus::ConfirmAllow` / `Focus::ConfirmDeny`,**只在有待确认时**存在
(鼠标用户不会 Tab 到不存在的按钮);
- 待确认出现 ⇒ `sync_confirm_focus()` 把焦点直接落到「允许」并**打开键盘巡航**(阻塞态主动亮环),
消失 ⇒ 焦点收回输入框、巡航关闭;
- `Enter` 与 `Space` 都映射到 `Activate`(`Space` 不抢输入框:`keyboard_mode` 那道闸在
鼠标点进输入框时是关的);
- 焦点环不是 10% 状态层——在**实心主色**按钮上那层几乎看不见(出图实测过一版就是没有)。
改成 2dp `Primary` 描边 + 3px 留白,两个按钮恒定加这层 padding,所以焦点变化不移动布局。
测试(`crates/app-iced/src/app/update/agent/tests.rs`):
`a_blocking_confirm_can_be_decided_with_the_keyboard_alone` —— 全程只有键盘消息:
确认到达后断言 `focus == ConfirmAllow && keyboard_mode`,发一条 `KeyPressed(Enter)` 完成允许;
第二轮 `Tab`(走到 Deny)+ `KeyPressed(Space)` 完成拒绝;两轮各记一条审计、焦点都收回 Composer。
另有 `the_default_backend_reports_itself_as_simulated` 钉住 P2-1 的事实来源。
## 视图入参顺带收成结构体
`docked`/`page` 本来是 6 个形参(`ui, agent, rail, failure, catalog, width`),这一轮还要加
`simulated` ⇒ 7 个。按塔台登记的可维护性口径改成 `Session { agent, rail, failure, simulated }`:
两个宿主各 3 个形参,以后再加展示事实只改 `Session`。
## 出图(18 张,浅深各一)
`DevDocs/artifacts/m119/`:新增 `08-agent-simulated-*`(空会话 + 四处「模拟」措辞)与
`09-agent-confirm-focus-*`(确认条 + 焦点环落在「允许」);其余 7 组全部重出(文案与焦点环都变了)。
## 门禁(真实退出码)
| 命令 | 退出码 |
|---|---|
| `cargo fmt --all --check` | 0 |
| `cargo clippy -p unlucky-app-iced -p unlucky-presenter -p unlucky-agent -p unlucky-i18n --all-targets -- -D warnings` | 0(0 warning)|
| `cargo test -p unlucky-app-iced --lib` | 0(601 passed / 0 failed / 2 ignored)|
| `cargo test --workspace --exclude unlucky-app` | 0(58 套 2277 passed / 0 failed / 11 ignored)|
`golden.rs` 400 行(+1 条 `AgentSimulated` 正好顶线);全树受检文件无 >400。
This commit is contained in:
1 parent
b5e96c61ac
commit
a22baebe70
13 files changed
+383
-122
No files matched your search
@@ -14,9 +14,10 @@ macro_rules! agent_entries {
|
||||
$($acc)*
|
||||
// ── AI 助手(右栗 + 独立页共用)
|
||||
AgentTitle => ("Assistant", "助手"),
|
||||
// M119:接线之前这条写的是「后端未接」。真接进 presenter 之后那句话成了假话,
|
||||
// 改成中性的「会话」;「跑的是什么后端」由端点标签与错误横幅说,不在标题下重复。
|
||||
AgentSubtitle => ("Conversation", "会话"),
|
||||
// M119 r1 复审 P2-1:这条一度被改成中性的「会话」,理由是「跑什么后端由端点标签说」——
|
||||
// 但端点标签在壳里根本不存在,于是默认配置下用户看到的是一个像是接上了模型的助手。
|
||||
// 现在把诚实的话写回来,而且它是**常驻**的(标题下就一行,不点也能看到)。
|
||||
AgentSubtitle => ("Simulated assistant · no real model is connected", "模拟助手 · 还没接真实模型"),
|
||||
AgentCollapse => ("Collapse", "收起"),
|
||||
AgentDetach => ("Pop out", "拆出"),
|
||||
AgentDock => ("Dock back", "收回"),
|
||||
@@ -24,10 +25,11 @@ macro_rules! agent_entries {
|
||||
AgentStripLabel => ("AI", "助手"),
|
||||
AgentSend => ("Send", "发送"),
|
||||
AgentStop => ("Stop", "中断"),
|
||||
AgentPlaceholder => ("Message the assistant…", "给助手发消息…"),
|
||||
// 输入框上再说一次:用户真要动手的位置就在这儿
|
||||
AgentPlaceholder => ("Message the simulated assistant…", "给模拟助手发消息…"),
|
||||
AgentEmptyTitle => ("Nothing in this session yet", "这个会话还没有内容"),
|
||||
// M119:同上——「模型还没接上」这句在接线后是假话。真接的是什么由端点标签说。
|
||||
AgentEmptyBody => ("Ask about instances, downloads or logs.", "可以问实例、下载或日志。"),
|
||||
// 空会话是最容易被误读的一屏(没有人说过话,很容易以为是「连上了但还没问」)
|
||||
AgentEmptyBody => ("Ask about instances, downloads or logs. This assistant is simulated: no real model is connected.", "可以问实例、下载或日志。当前是模拟助手,没有接真实模型。"),
|
||||
AgentNotePending => ("Placeholder shell: your message is kept here, nothing was sent to a model.", "占位外壳:消息留在这里,没有发给任何模型。"),
|
||||
AgentNoteStopped => ("Stopped by you.", "你中断了这次回复。"),
|
||||
AgentUnread => ("{count} unread", "{count} 条未读"),
|
||||
@@ -46,6 +48,8 @@ macro_rules! agent_entries {
|
||||
AgentConfirmRequest => ("The assistant wants to change something: {summary}", "助手想改一项设置:{summary}"),
|
||||
AgentConfirmAllow => ("Allow", "允许"),
|
||||
AgentConfirmDeny => ("Deny", "拒绝"),
|
||||
// 头部常驻小标记(P2-1):与副标题/占位符互为冗余,三个位置都能看到「这是模拟」
|
||||
AgentSimulated => ("Simulated", "模拟"),
|
||||
} }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ pub(super) const GOLDEN: &[(&str, &str, &str)] = &[
|
||||
("LogsEmptyBody", "Logs stream here while the launcher or the game is running. Pick an instance and start it to see the first lines.", "启动器或游戏运行时,日志会实时出现在这里。选择一个实例并启动,就能看到第一批日志。"),
|
||||
("LogsEmptyAction", "Choose an instance", "选择实例"),
|
||||
("AgentTitle", "Assistant", "助手"),
|
||||
("AgentSubtitle", "Conversation", "会话"),
|
||||
("AgentSubtitle", "Simulated assistant · no real model is connected", "模拟助手 · 还没接真实模型"),
|
||||
("AgentCollapse", "Collapse", "收起"),
|
||||
("AgentDetach", "Pop out", "拆出"),
|
||||
("AgentDock", "Dock back", "收回"),
|
||||
@@ -132,9 +132,9 @@ pub(super) const GOLDEN: &[(&str, &str, &str)] = &[
|
||||
("AgentStripLabel", "AI", "助手"),
|
||||
("AgentSend", "Send", "发送"),
|
||||
("AgentStop", "Stop", "中断"),
|
||||
("AgentPlaceholder", "Message the assistant…", "给助手发消息…"),
|
||||
("AgentPlaceholder", "Message the simulated assistant…", "给模拟助手发消息…"),
|
||||
("AgentEmptyTitle", "Nothing in this session yet", "这个会话还没有内容"),
|
||||
("AgentEmptyBody", "Ask about instances, downloads or logs.", "可以问实例、下载或日志。"),
|
||||
("AgentEmptyBody", "Ask about instances, downloads or logs. This assistant is simulated: no real model is connected.", "可以问实例、下载或日志。当前是模拟助手,没有接真实模型。"),
|
||||
("AgentNotePending", "Placeholder shell: your message is kept here, nothing was sent to a model.", "占位外壳:消息留在这里,没有发给任何模型。"),
|
||||
("AgentNoteStopped", "Stopped by you.", "你中断了这次回复。"),
|
||||
("AgentUnread", "{count} unread", "{count} 条未读"),
|
||||
@@ -149,6 +149,7 @@ pub(super) const GOLDEN: &[(&str, &str, &str)] = &[
|
||||
("AgentConfirmRequest", "The assistant wants to change something: {summary}", "助手想改一项设置:{summary}"),
|
||||
("AgentConfirmAllow", "Allow", "允许"),
|
||||
("AgentConfirmDeny", "Deny", "拒绝"),
|
||||
("AgentSimulated", "Simulated", "模拟"),
|
||||
// ── M106 `I18NFOLLOW`:General 分组真控件(语言选择器 + 其余三行)。**只追加在链尾**,
|
||||
// 上一行到 `LogsEmptyAction` 的既有顺序一字未动(金表要证明的正是这件事)。
|
||||
("SettingsLanguageFollowSystem", "Follow system", "跟随系统"),
|
||||
|
||||
Reference in new issue
Block a user