chore: checkpoint pi lab rust integration work
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# 3-28 dev:hot seed smoke 启动契约缺失
|
||||
|
||||
## 状态
|
||||
|
||||
- 已修复
|
||||
- 日期:2026-07-11
|
||||
- Owner:`03-rust-web`
|
||||
|
||||
## 症状
|
||||
|
||||
依赖 `scripts/lib/control-plane-dev-seed.js` 的 browser smoke 在当前 `dev:hot` 服务上调用 `/api/dev/seed` 时返回:
|
||||
|
||||
```text
|
||||
403 dev_seed_disabled
|
||||
```
|
||||
|
||||
脚本在创建测试 workspace / AI policy 前终止,导致真实 UI 交互未执行。由于 cargo-watch 只重启 Rust 子进程,临时修改启动环境但不重启 Node `dev:hot` 主进程也不会生效。
|
||||
|
||||
## 根因
|
||||
|
||||
- `dev:hot` 没有建立“默认可运行 seed 依赖 smoke”的启动契约。
|
||||
- `MNOTE_WEB_ALLOW_DEV_FIXTURES` 只能由操作者临时记忆和手工补充。
|
||||
- seed helper 只返回通用 403,未明确指出应重启哪个启动链。
|
||||
|
||||
## 修复
|
||||
|
||||
- `npm run dev:hot` 默认设置 `MNOTE_WEB_ALLOW_DEV_FIXTURES=1`。
|
||||
- 显式 `MNOTE_WEB_ALLOW_DEV_FIXTURES=0 npm run dev:hot` 仍可关闭。
|
||||
- `desktop:hot` 与生产启动保持默认关闭,不扩大正式运行边界。
|
||||
- dev seed helper 对 `dev_seed_disabled` 输出明确的启动与重启指令。
|
||||
- Pi RPC API smoke 不再把 `dev_seed_disabled` 静默标记为 skipped,而是明确失败并要求恢复正确启动契约。
|
||||
- 完整 RPC smoke 暴露了 abort 后迟到 `agent_end` 将 `aborted` 覆盖为 `runtime_running` 的竞态;runtime 现在保持 `aborted/error` 终态,迟到空回复事件也不会覆盖已中止状态。
|
||||
- RPC smoke 按当前 status 合同验收:已中止会话退出 auto-resume `status.session`,并通过 `/api/page-ai/pi/sessions/{sessionId}` 验证持久化状态为 `aborted`。
|
||||
- `scripts/TESTING_REFERENCE.md` 增加 seed 依赖 smoke 的统一启动契约。
|
||||
- `task-dev-hot-plan-test.js` 固化默认开启和显式关闭行为。
|
||||
|
||||
## 验证
|
||||
|
||||
- `node scripts/task-dev-hot-plan-test.js`
|
||||
- 重启 `npm run dev:hot`
|
||||
- `node scripts/task-pi-lab-input-controls-smoke.js`
|
||||
- `node scripts/task-pi-lab-model-thinking-controls-smoke.js`
|
||||
- `node scripts/task-pi-lab-rpc-api-smoke.js`
|
||||
@@ -0,0 +1,52 @@
|
||||
# 7-59 Page AI Pi OmniRoute 兼容修复过度降级
|
||||
|
||||
## 状态
|
||||
|
||||
- 已修复
|
||||
- 日期:2026-07-11
|
||||
- Owner:`07-ai`
|
||||
|
||||
## 症状
|
||||
|
||||
为处理 Pi Rust 经 OmniRoute 偶发空回复,MNote 曾在 session `models.json` 中设置:
|
||||
|
||||
- `supportsTools=false`
|
||||
- `supportsUsageInStreaming=false`
|
||||
- 将请求改经 MNote 内置代理并删除 `stream_options`
|
||||
|
||||
普通文本回复恢复后,Pi 的原生 function calling 实际被关闭,MNote bridge、LightRAG、MCP 和扩展工具无法由模型调用。
|
||||
|
||||
## 根因
|
||||
|
||||
`pi_agent_rust 0.1.18` 在 `supportsTools=false` 时会完全省略 OpenAI 请求的 `tools` 字段,不存在文本工具调用 fallback。
|
||||
|
||||
进一步实测表明:
|
||||
|
||||
- Pi Rust 直连当前 OmniRoute 时,`stream_options.include_usage=false` 和 `true` 均能完成真实工具调用。
|
||||
- OmniRoute `freefirst` 的少量空流是上游路由偶发现象,未与 `stream_options` 建立因果关系。
|
||||
- 真实 Pi RPC 在 `supportsTools=true` 下可调用 `mnote_allowed_roots_describe`,收到 `pi-rust-native-context-file` 工具结果并完成第二轮回答。
|
||||
|
||||
本次空回复修复中真正需要保留的是:
|
||||
|
||||
- `apiKey` 使用裸环境变量名 `OPENAI_API_KEY`
|
||||
- 不再把 `MNOTE_PI_CONTEXT_V1` 前缀注入模型可见 prompt
|
||||
|
||||
## 修复
|
||||
|
||||
- OmniRoute provider 恢复 `supportsTools=true`
|
||||
- 恢复 `supportsUsageInStreaming=true`
|
||||
- Pi Rust 恢复直连配置的 OmniRoute base URL
|
||||
- 删除只为移除 `stream_options` 引入的 MNote 中转路由
|
||||
- 增加 models 配置单测和静态 smoke 断言
|
||||
|
||||
## 验证
|
||||
|
||||
- `cargo test -p mnote-web page_ai_pi --lib`:24 passed
|
||||
- `cargo fmt --check`
|
||||
- `node scripts/task-pi-lab-static-smoke.js`:228 checks passed
|
||||
- 真实 Chromium + 3000:
|
||||
- `supportsTools=true`
|
||||
- `supportsUsageInStreaming=true`
|
||||
- 工具调用:`mnote_allowed_roots_describe`
|
||||
- 工具结果:`pi-rust-native-context-file`
|
||||
- 最终回复:`PI_TOOLS_RESTORED_OK_1783711633924`
|
||||
@@ -0,0 +1,39 @@
|
||||
# 7-60 Page AI Pi 模型与思考深度弹层锚定修复
|
||||
|
||||
## 状态
|
||||
|
||||
- 已修复
|
||||
- 日期:2026-07-11
|
||||
- Owner:`07-ai`
|
||||
|
||||
## 症状
|
||||
|
||||
Page AI Pi 底部工具栏中:
|
||||
|
||||
- 先点击 `+` 后再打开模型或思考深度,原生下拉通常出现在按钮附近。
|
||||
- 直接点击模型或思考深度,或先点击页面其它位置再打开时,Chromium 原生下拉可能出现在页面中央。
|
||||
- `+` 与访问控制使用按钮锚定自定义菜单,模型与思考深度仍使用原生 `<select>`,交互与关闭规则不一致。
|
||||
|
||||
## 根因
|
||||
|
||||
模型与思考深度的选项面板由浏览器原生 `<select>` popup 承载,其位置不受 Page AI composer 的定位上下文和菜单互斥状态控制。焦点、滚动容器和点击顺序变化时,浏览器可能使用独立 popup 坐标,导致弹层脱离按钮。
|
||||
|
||||
## 修复
|
||||
|
||||
- 将模型与思考深度改为 `button + position: relative wrapper + absolute menu`。
|
||||
- 菜单统一向对应按钮上方展开,不再依赖 Chromium 原生 select popup。
|
||||
- 模型、思考深度、`+` 和访问控制统一使用互斥菜单状态。
|
||||
- 点击工具栏其它位置、面板外或关闭 Page AI 时统一关闭 composer 菜单。
|
||||
- 模型与思考深度选项继续写入原有 Pi session 配置状态,并沿 `/api/page-ai/pi/configure` 应用到 runtime。
|
||||
- 增加 `aria-expanded`、`menuitemradio` 和选中状态,保留键盘/辅助技术可识别的控制语义。
|
||||
|
||||
## 验证
|
||||
|
||||
- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js`
|
||||
- Chromium 真实页面验证:
|
||||
- 模型菜单位于模型按钮正上方。
|
||||
- 思考深度菜单位于思考按钮正上方。
|
||||
- 模型、思考深度、`+` 菜单互斥。
|
||||
- 点击输入框后关闭,再次打开仍锚定按钮。
|
||||
- 选择“思考 关”后标签与 runtime 状态同步。
|
||||
- 专项静态与浏览器 smoke 见对应测试脚本结果。
|
||||
@@ -0,0 +1,31 @@
|
||||
# 7-61 Page AI Pi 历史回放真源混用
|
||||
|
||||
## 问题
|
||||
|
||||
Pi Lab 实时对话正常,但重新打开历史 session 后,同一条 assistant 结果可能重复显示多次;工具过程没有同步重复。
|
||||
|
||||
## 根因
|
||||
|
||||
历史打开链路同时读取并合并两个来源:
|
||||
|
||||
- `/api/page-ai/pi/sessions/{id}/tree`:Pi Rust JSONL session tree,会话消息真源。
|
||||
- `/api/page-ai/pi/sessions/{id}/events`:control-plane runtime events,用于 SSE backlog、导出和诊断。
|
||||
|
||||
`events` 中同一次回复可能以 `message_update/text_delta`、`message_end`、`agent_end` 等形式记录运行过程;它不是历史消息 UI 的 canonical source。前端把 `tree` 和 `events` 合并回放后,就会把同一 assistant 结果渲染成多条消息。
|
||||
|
||||
## 修复
|
||||
|
||||
- `sidebar-page-ai-pi-lab-runtime.js`
|
||||
- `openHistorySession()` 只从 `/tree` 读取并回放消息。
|
||||
- 移除历史回放消息层面的 `eventsToReplayMessages()` / `mergeReplayMessages()` / `replayMessageKey()`,避免用去重掩盖多真源。
|
||||
- `/events` 继续保留给实时 SSE backlog、导出和诊断,不参与历史消息回放。
|
||||
- `scripts/task-pi-lab-history-tail-smoke.js`
|
||||
- 构造 JSONL 只有 1 条 assistant 回复,但 runtime events 中包含多段同文结果事件。
|
||||
- 打开历史后断言 UI 只显示 JSONL 中的 1 条 assistant 回复。
|
||||
|
||||
## 验证
|
||||
|
||||
- `node --check rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js`
|
||||
- `node --check scripts/task-pi-lab-history-tail-smoke.js`
|
||||
- `node scripts/task-pi-lab-static-smoke.js`
|
||||
- `node scripts/task-pi-lab-history-tail-smoke.js`
|
||||
Reference in New Issue
Block a user