mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-11 19:05:16 +00:00
* 修复 Pi 恢复子任务的状态和对话跟踪
关联 #9200。
改动:
- 仅在 action:resume 确认成功启动新的 single async run 后登记独立子任务条目,按新 run ID 和 asyncDir 跟踪状态,拒绝失败及管理调用产生的假条目。
- 将对话去重从文件级调整为子任务条目与文件组合,支持恢复运行复用 session JSONL,避免旧通知结束新运行。
- 扩展原适配器回归测试,并附脱敏的命令输出、真实工具结果和 macOS Electron 截图,未改 UI、协议或共享生命周期。
实际验证:
- 原适配器下恢复条目回归为 RED;恢复旧文件级去重后共享对话回归为 RED。
- 基线 d46ee6558c 上 npm run build:server、npm run format、npm run typecheck、npm run lint、git diff --check 均成功。
- 在 packages/server 执行 npx vitest run src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts --bail=1,21/21 通过。
- 已在此前 0.15.3 开发版中,通过真实 macOS Electron、Pi 1.5.0、pi-subagents 0.86.0 验证 A→B→C 恢复、运行条目和对话、完成状态、归档保留运行任务、失败恢复不产生假条目;普通启动走 CLI/API,恢复通过真实 composer。截图不是 0.15.4 发布包验收。
- 同步后适配器与测试文件字节和第三方锁定依赖均未变,复用独立代码评审与上述桌面证据。公开材料已做隐私扫描。
- 未执行全量测试(仓库禁止本地全量执行)、CI、其他平台或发布安装包验证;短暂重复 Shell 文案原因未定位,不宣称本次修复。
回滚:
- 本提交仍为 HEAD 时执行 git revert HEAD;否则先用 git log --oneline --grep='修复 Pi 恢复子任务的状态和对话跟踪' 确认本提交哈希,再 git revert <确认的哈希>,不要重置或覆盖其他修改。
- 回滚后重跑该适配器测试并执行 npm run build:server;若需要部署回滚产物,另行安排服务切换,禁止未经授权重启正在使用的 Paseo daemon。
- 本提交仅改源码、测试和 QA 证据,无数据迁移;回滚不应删除已有 Pi 会话或异步目录。独立 QA 服务不由本提交启停。
* 补强 Pi 恢复对话的新消息与实时回放断言
回应 PR #9261 的 Greptile P2 评论 discussion_r4521416122。
改动:
- 只修改 pi-subagents/index.test.ts,按子任务 ID 提取 assistant_message 文本,精确检查 C 的历史与本轮内容。
- 观察 C reader 初始读取后再追加消息,在写入终态前验证新消息实时到达且 C 仍运行,避免只靠完成时刷新通过。
- 回放精确校验三条预期消息、顺序与 resume-c 归属,保留旧通知隔离、完成状态和 bg_wait 断言。
- 不修改生产实现、历史 QA 证据或普通启动行为。
实际验证:
- 临时在测试观察回调中丢弃 C 本轮消息:定向测试 exit 1,只有 Attempt b 的历史不能通过初始断言。
- 临时只丢弃 C 后追加消息:定向测试 exit 1,缺少 Attempt c follow-up 的断言在写入完成状态前失败。
- 两次故障注入已移除;最终在 packages/server 执行 npx vitest run src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts --bail=1,21/21 通过。
- npm run format、npm run typecheck、npm run lint 和 git diff --check 均通过;全仓 lint 为 0 warnings / 0 errors。
- LSP 推断项目模式仅报告未修改旧测试行的两处 results 类型警告;项目正式 typecheck 通过。
- 未运行全量测试、远端 CI 或重复桌面验收。本次只有测试变更,复用原产品评审和真实桌面验证,不将临时故障注入当作生产缺陷。
回滚:
- 本提交仍为 HEAD 时执行 git revert HEAD;否则用 git log --oneline --grep='补强 Pi 恢复对话的新消息与实时回放断言' 确认哈希后 git revert <该哈希>。
- 回滚后重跑上述适配器测试;这只撤销测试增强,不应回滚先前 #9200 产品修复,也无需重启 daemon 或删除任何会话数据。
197 lines
5.7 KiB
Plaintext
197 lines
5.7 KiB
Plaintext
Captured command output. Only private absolute paths are replaced with <REPO_ROOT>/<USER_HOME>.
|
||
RED runs are intentional regression failures, not final failures.
|
||
|
||
=== Before fix: resume arguments rejected (expected RED, exit 1) ===
|
||
$ cd packages/server && npx vitest run src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts --bail=1
|
||
|
||
RUN v4.1.6 <REPO_ROOT>/packages/server
|
||
|
||
stdout | src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts
|
||
[dotenv@17.3.1] injecting env (0) from .env.test -- tip: ⚙️ suppress all logs with { quiet: true }
|
||
[dotenv@17.3.1] injecting env (0) from ../.env -- tip: ⚙️ suppress all logs with { quiet: true }
|
||
|
||
❯ src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts (10 tests | 1 failed) 7ms
|
||
× registers a successful resume as a new async attempt without spawn arguments 6ms
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts > pi-subagents adapter > registers a successful resume as a new async attempt without spawn arguments
|
||
AssertionError: expected undefined to deeply equal [ { type: 'upsert', …(5) } ]
|
||
|
||
- Expected:
|
||
[
|
||
{
|
||
"description": "Continue",
|
||
"id": "resume-b",
|
||
"status": "running",
|
||
"title": "Subagent",
|
||
"toolCallId": "resume-b",
|
||
"type": "upsert",
|
||
},
|
||
]
|
||
|
||
+ Received:
|
||
undefined
|
||
|
||
❯ src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts:66:32
|
||
64| },
|
||
65| });
|
||
66| expect(resumed?.subagents).toEqual([
|
||
| ^
|
||
67| {
|
||
68| type: "upsert",
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
|
||
|
||
|
||
Test Files 1 failed (1)
|
||
Tests 1 failed (10)
|
||
Start at 21:05:21
|
||
Duration 474ms (transform 245ms, setup 31ms, import 328ms, tests 7ms, environment 0ms)
|
||
|
||
|
||
=== Intermediate implementation: old file-only transcript deduplication (expected RED, exit 1) ===
|
||
$ cd packages/server && npx vitest run src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts --bail=1
|
||
|
||
RUN v4.1.6 <REPO_ROOT>/packages/server
|
||
|
||
stdout | src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts
|
||
[dotenv@17.3.1] injecting env (0) from .env.test -- tip: ⚡️ secrets for agents: https://dotenvx.com/as2
|
||
[dotenv@17.3.1] injecting env (0) from ../.env -- tip: ⚙️ override existing env vars with { override: true }
|
||
|
||
❯ src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts (16 tests | 1 failed) 1329ms
|
||
× follows consecutive resumed attempts and keeps stale notices on their own rows 1320ms
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts > pi-subagents adapter > follows consecutive resumed attempts and keeps stale notices on their own rows
|
||
AssertionError: expected false to be true // Object.is equality
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
- true
|
||
+ false
|
||
|
||
❯ src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts:155:78
|
||
153| ]);
|
||
154| replay.mapToolCall(call);
|
||
155| await expect.poll(() => hasChildTimeline(received, `resume-${r…
|
||
| ^
|
||
156| }
|
||
157| const oldNotice = {
|
||
|
||
Caused by: Error: Matcher did not succeed in time.
|
||
❯ src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts:155:9
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
|
||
|
||
|
||
Test Files 1 failed (1)
|
||
Tests 1 failed | 6 passed (16)
|
||
Start at 21:09:04
|
||
Duration 1.85s (transform 247ms, setup 24ms, import 389ms, tests 1.33s, environment 0ms)
|
||
|
||
|
||
=== Final baseline d46ee655: GREEN, exit 0 ===
|
||
$ cd packages/server && npx vitest run src/server/agent/providers/pi/extensions/pi-subagents/index.test.ts --bail=1
|
||
|
||
RUN v4.1.6 <REPO_ROOT>/packages/server
|
||
|
||
|
||
Test Files 1 passed (1)
|
||
Tests 21 passed (21)
|
||
Start at 13:07:04
|
||
Duration 1.97s (transform 256ms, setup 26ms, import 355ms, tests 1.45s, environment 0ms)
|
||
|
||
|
||
=== Final typecheck, exit 0 ===
|
||
$ npm run typecheck
|
||
|
||
> paseo@0.15.4 typecheck
|
||
> npm run typecheck --workspaces --if-present
|
||
|
||
|
||
> @getpaseo/builtin-plugins@0.15.4 typecheck
|
||
> tsgo -p tsconfig.json --noEmit
|
||
|
||
|
||
> @getpaseo/expo-two-way-audio@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/highlight@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/plugin@0.15.4 typecheck
|
||
> tsgo --noEmit && npm run typecheck:examples
|
||
|
||
|
||
> @getpaseo/plugin@0.15.4 typecheck:examples
|
||
> npm --prefix ../../plugin-examples/markdown-panel install --ignore-scripts --no-audit --no-fund && tsgo -p tsconfig.examples.json --noEmit
|
||
|
||
|
||
up to date in 433ms
|
||
|
||
> @getpaseo/protocol@0.15.4 pretypecheck
|
||
> npm run generate:validators
|
||
|
||
|
||
> @getpaseo/protocol@0.15.4 generate:validators
|
||
> node scripts/generate-validation-aot.mjs
|
||
|
||
generated src/generated/validation/ws-outbound.aot.ts: envelope + 250 session message validators
|
||
|
||
> @getpaseo/protocol@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/client@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/server@0.15.4 typecheck
|
||
> tsgo -p tsconfig.server.typecheck.json --noEmit
|
||
|
||
|
||
> @getpaseo/app@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/relay@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/website@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
> @getpaseo/desktop@0.15.4 typecheck
|
||
> tsgo --noEmit -p tsconfig.json
|
||
|
||
|
||
> @getpaseo/cli@0.15.4 typecheck
|
||
> tsgo --noEmit
|
||
|
||
|
||
=== Final lint, exit 0 ===
|
||
$ npm run lint
|
||
|
||
> paseo@0.15.4 lint
|
||
> oxlint
|
||
|
||
Found 0 warnings and 0 errors.
|
||
Finished in 2.3s on 5442 files with 177 rules using 12 threads.
|
||
|
||
=== Final full formatter, exit 0; no unrelated changes ===
|
||
$ npm run format
|
||
|
||
> paseo@0.15.4 format
|
||
> oxfmt .
|
||
|
||
Finished in 2684ms on 5928 files using 12 threads.
|
||
|
||
$ git diff --check
|
||
(exit 0; no output)
|