@migor/cli 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,67 @@
5
5
  (0.x 阶段:minor 可含破坏性变更,每个破坏性变更都在对应版本的「迁移」小节里写明)。
6
6
  决策的完整证据链在 `docs/spec.md` §10(带时间线的决策日志)。
7
7
 
8
+ ## [0.7.2] - 2026-09-20
9
+
10
+ ### 变更
11
+
12
+ > 本版主题(窗口 `0.7.1 → 0.7.2`,含 #77–#81):**第九轮评审收口** —— 一条高优先级的
13
+ > **HITL × `sessionStore` 组合破口**(挂起任务恢复后历史翻倍、成功后又把坏会话写回去),
14
+ > 外加六条中/低优先级的静默失效修复;其余是纯结构重构、回归测试补课与依赖升级。
15
+ > **无破坏性变更,不需要改代码**:所有修复都是「旧行为本来就不该那样」。
16
+ > **两处错误归类收紧(记账口径,不是行为变更)**:Anthropic 流内 4xx 不再落成可重试的
17
+ > `server`,异步宿主的 `runTimeoutMs` 超时不再落 `unknown`。宿主若按 `error.type` /
18
+ > `errorKind` / `retryable` 分支(重试、告警、看板),取值会更准 —— 见下方两条。
19
+ > 本条目的多数内容**是在本次发版时回填的**:窗口内 5 个 PR 都没写 CHANGELOG,
20
+ > 条目按各提交正文重建。
21
+
22
+ ### 修复(第九轮评审收口)
23
+
24
+ - **HITL × `sessionStore`:挂起任务恢复后会话历史翻倍 + 成功后毒化会话**(本版最高优先级):
25
+ 恢复段曾把 session 再注入 `app.run`,而挂起段落库的 `suspendedMessages` 已含完整历史 ⇒
26
+ run 层 `loadSession` 又 prepend 一遍(历史翻倍、token 复利);且成功后 `appendSession`
27
+ 会把含未决 `tool_use` 的整段扩展历史写回会话 —— 该会话**下一轮直接撞 API 400**
28
+ (孤立 `tool_use` + 连续 assistant)。现在恢复段不再注入 session,会话回写改由
29
+ `AsyncRunner` 按「本轮用户输入 + 最终回复」补,口径与 `run.ts` 的三条不变量一致。
30
+ - **惰性审批超时 `#expireAndResume` 补重入闸 + 进闸后重读 store**:异步 store 下两个并发
31
+ `poll` 各拿到一份 `awaiting` 副本 ⇒ 双双填超时拒绝、**双双派发**(同一任务跑两遍)。
32
+ 现在与 `approve` 共用同一把 per-taskId 在飞闸。
33
+ - **MCP StreamableHTTP 连接器不再丢弃 `abandoned`**:`tools/call` 把引擎的「放弃等待」
34
+ 信号透传到在飞 `fetch`(含会话 404 自愈那次重试)—— 裁判放弃后真能掐掉请求,
35
+ 而不是继续在后台烧。stdio 侧 #75 的 `pending` 出簿修复这次补上了回归用例。
36
+ - **Anthropic 流内 `error` 事件的 status 反推补 4xx 档**:`invalid_request_error` /
37
+ `authentication_error` / `permission_error` / `not_found_error` → 400(归 `api`、
38
+ **不可重试**),与 `openai.ts` 同口径。此前这些确定性病因落 500 + `retryable:true`,
39
+ 引擎会白重试 3 次(3 次网络请求 + 3 倍等待)。
40
+ - **异步宿主 `runTimeoutMs` 的超时错误不再落 `unknown`**:改用 `core/timeout.ts` 的
41
+ `TimeoutError`(`code='timeout'`),与引擎工具超时 / MCP 桥兜底同口径。归类由
42
+ `unknown`(`retryable:false`)变为 `timeout`(`retryable:true`)—— 这只是**记账口径**:
43
+ 超时按定义属可重试故障,框架**不会**因此自动重跑整个 run,要不要重试仍由宿主决定。
44
+ - **`FileTaskStore.save` 改为先落盘、成功后再更新内存**:落盘失败时内存不再推进,
45
+ 避免内存与磁盘两本账、重启后静默回退(`get` / `byIdempotency` 查不到未落盘的记录)。
46
+ - **Anthropic SSE 组装拦畸形 `content_block_start.index`**:超大 index(如 `1e9`)会造出
47
+ 稀疏数组、后续 `for...of` / `reduce` 按 `length` 空转;现在畸形 index(负数 / 非整数 /
48
+ 超上限)响亮抛 `AnthropicApiError(500)`。
49
+
50
+ ### 重构(纯结构,零行为变化)
51
+
52
+ - `integrations/metrics.ts`(1050 行)→ `metrics-state.ts` / `metrics-render.ts` /
53
+ `metrics-otlp.ts` / `metrics.ts`(只留选项校验、定时器与组装);
54
+ `integrations/mcp.ts`(897 行)→ `mcp-stdio.ts` / `mcp-http.ts` / `mcp.ts`
55
+ (桥 + 共享 helper + re-export 两个连接器工厂)。**公共面与运行时行为不变**。
56
+
57
+ ### 测试
58
+
59
+ - 补上 #75 遗留的回归用例:stdio MCP 连接器「裁判放弃等待 ⇒ `pending` 记账出簿」的防泄漏
60
+ 修复此前**没有任何用例守着**(夹具新增 `silentcall` 模式:握手 / `tools/list` 正常、
61
+ `tools/call` 永不回包)。
62
+
63
+ ### 依赖
64
+
65
+ - 开发依赖:`@anthropic-ai/sdk` → 0.126.0、`@biomejs/biome` → 2.5.14、
66
+ `@types/node` → 26.6.1、`zod` → 4.6.5(均不影响运行时面)。
67
+ - 官网(不随包发布):`astro` → 7.3.3。
68
+
8
69
  ## [0.7.1] - 2026-09-19
9
70
 
10
71
  ### 变更
@@ -615,7 +676,8 @@
615
676
  首个公开发布:`@migor/agentia` + `@migor/cli`(scope `@migor/*`),两包版本同步。
616
677
  框架本体单包;CLI 独立成包(workspaces)。
617
678
 
618
- [Unreleased]: https://github.com/retrychx/agentia/compare/v0.7.1...HEAD
679
+ [Unreleased]: https://github.com/retrychx/agentia/compare/v0.7.2...HEAD
680
+ [0.7.2]: https://github.com/retrychx/agentia/releases/tag/v0.7.2
619
681
  [0.7.1]: https://github.com/retrychx/agentia/releases/tag/v0.7.1
620
682
  [0.7.0]: https://github.com/retrychx/agentia/releases/tag/v0.7.0
621
683
  [0.6.3]: https://github.com/retrychx/agentia/releases/tag/v0.6.3
package/dist/AGENTS.md CHANGED
@@ -1237,6 +1237,7 @@ const callable = {
1237
1237
  | 挂起段与恢复段是两棵 trace | 每段执行一棵独立的树(`traceId == runId`),恢复段经根 span 的 `links` 挂到上一段;指标按段计(挂起段算一次 ok 的 run —— 「等人」不算失败,区分看 `stop_reason` attribute) |
1238
1238
  | 审批是 at-least-once | 崩溃发生在「批准后、恢复执行中」时,副作用工具会重执行(与 `resumePending` 续跑同口径)—— 副作用工具自己保证幂等 |
1239
1239
  | 挂起/恢复间预算重新起算 | `maxTotalTokens` / `maxCostUsd` 在恢复段从 0 重新计(新树新账,与 `resumePending` 续跑同口径) |
1240
+ | 恢复段的会话回写是进程内快照 | 带 `sessionId` 的任务挂起时,「本轮用户输入」快照只存进程内存(恢复段由 AsyncRunner 自己补写「用户输入 + 最终回复」,不再经 run 层重复拼历史)—— 进程崩在「挂起 → 重启 → approve」之间会**丢这一次会话回写**(会话少一轮,但绝不写进坏历史;审批决定本身已落库) |
1240
1241
  | 嵌套能力内的审批不支持挂起 | @SubAgent / @Skill 子循环里的 `approval: 'required'` 工具无法把整个 run 挂起 —— 子循环挂起会以 `is_error` 交回主 agent(要审批的能力请放主菜单) |
1241
1242
  | 同步 `/run` 撞上审批没人可批 | 同步 RPC 会带着 `stopReason: 'awaiting_approval'` 收尾返回 —— 但响应体(`toHttpBody`)**不含** `suspendedMessages`,也没有任务记录可审批(待决清单只能去 trace 的 `approval.requested` 事件里看)。**要审批请走 `POST /tasks` 异步宿主** |
1242
1243
  | Scheduler 调度表不落库 | `every` / `at` 的调度本身只在内存:已 submit 的任务记录能经 `resumePending` 续跑,但「未来某刻再触发」的调度在重启后不存在(远期单发由宿主自己的 cron 驱动)。另:`drain()` 不停 Scheduler —— 停机窗口内到点的 tick 会打一条触发失败日志(无害但吵),介意就 `scheduler.stop()` 先行 |
package/dist/templates.js CHANGED
@@ -62,7 +62,7 @@ export function projectPackageJson(name) {
62
62
  start: 'node dist/main.js',
63
63
  typecheck: 'tsc --noEmit -p tsconfig.json',
64
64
  },
65
- dependencies: { '@migor/agentia': '^0.7.1' },
65
+ dependencies: { '@migor/agentia': '^0.7.2' },
66
66
  devDependencies: {
67
67
  tsx: '^4.19.0',
68
68
  typescript: '^7.0.2',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@migor/cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Agentia 框架命令行工具:create 脚手架 + g 能力生成 + dev 本地可观测面板(trace inspector)",
5
5
  "type": "module",
6
6
  "bin": {