@tea-agent/loop-agent 0.43.0-next.17 → 0.43.0-next.3
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 +9 -140
- package/dist/application/task-lifecycle/advance.js +4 -17
- package/dist/application/task-lifecycle/observe.js +29 -43
- package/dist/application/task-lifecycle/plan-transitions.js +4 -5
- package/dist/build-stamp.json +3 -3
- package/dist/commands/client-recovery.js +55 -20
- package/dist/commands/new-task.js +5 -0
- package/dist/commands/status.js +57 -0
- package/dist/commands/task-contract.js +269 -0
- package/dist/executors/dag-pi-executor.js +230 -269
- package/dist/executors/pi-executor.js +0 -2
- package/dist/executors/pi-sdk-executor.js +39 -77
- package/dist/executors/shell-executor.js +2 -3
- package/dist/executors/shell-write-guard.js +32 -27
- package/dist/shared/pi-context-pressure/extension.js +16 -26
- package/dist/shared/pi-retry-settings.js +0 -40
- package/dist/shared/prompts.js +26 -0
- package/dist/task/config.js +2 -0
- package/dist/task/contract/validate-draft.js +106 -0
- package/dist/task/goal.js +3 -0
- package/dist/task/index.js +12 -0
- package/dist/task/lifecycle.js +1 -0
- package/dist/task/operator/capabilities.js +6 -0
- package/dist/task/operator/envelope.js +2 -0
- package/dist/task/operator/index.js +5 -0
- package/dist/task/operator/registry.js +2 -0
- package/dist/task/operator/types.js +1 -0
- package/dist/task/paths.js +1 -0
- package/dist/task/source-prepare/source-fidelity-pi.js +2 -2
- package/dist/task/source-references.js +23 -48
- package/dist/task/source-state.js +1 -0
- package/dist/task/subagent-guidance.js +1 -0
- package/dist/worker/console/chat/assistant-content.js +2 -23
- package/dist/worker/console/chat/explore-tools.js +0 -13
- package/dist/worker/console/chat/pi-runtime.js +1182 -221
- package/dist/worker/console/chat/routes.js +71 -213
- package/dist/worker/console/chat/sdd-data-alignment.js +9 -65
- package/dist/worker/console/chat/session-catalog.js +0 -32
- package/dist/worker/console/chat/session-store.js +6 -22
- package/dist/worker/console/chat/shortcuts.js +0 -6
- package/dist/worker/console/chat/sift-bridge.js +1 -0
- package/dist/worker/console/chat/tool-preview.js +0 -11
- package/dist/worker/console/chat/tools.js +0 -6
- package/dist/worker/console/console-update-and-init.js +19 -1
- package/dist/worker/console/console-update-runtime.js +20 -5
- package/dist/worker/console/index.js +20 -0
- package/dist/worker/console/operator-actions.js +1 -13
- package/dist/worker/console/routes.js +0 -8
- package/dist/worker/console/server.js +29 -11
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-hUmM_GRf.js} +1 -1
- package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-Bt-xuieW.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-DTqkL4DJ.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-Cy0MNnzV.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-DDdlT0Pd.js} +1 -1
- package/dist/worker/console/static/assets/channel-BpzRnZmU.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-3JawwNZ6.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-DoTp7Cri.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-CcirhZaS.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-VrG21gnP.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DDOgIS70.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-CBjmgvJ_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-CCQSht8M.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-BpGMkUUV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-DNDT41QL.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-euXnDFbn.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BhlMVqCc.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BhlMVqCc.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-BJ6NAeql.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-F5JKIvIq.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-Cwmkl_Gi.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-BmCZ8815.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-zWA3hUnX.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-BzA-888F.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-tPNheoch.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-Cdi7Fyqp.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-DFK9VBf1.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-xCUr1kpg.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-BANQHY_A.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-VHJYEMkP.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-DiyZQ0C6.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-CZtIeBBa.js} +1 -1
- package/dist/worker/console/static/assets/index-BlN6ytLr.css +1 -0
- package/dist/worker/console/static/assets/index-CA-jfWlE.js +449 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-BuSspC0X.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DRJZyPFy.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-DIfXIVuE.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-CT10_7Lt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-ufemj74H.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-DEQe8-_m.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-BRLUrbrC.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-BgibKtiF.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-D3eyfdV9.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-DXeTk5Px.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-BgXdFEe7.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-CseC2A7R.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-D80PFzfJ.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-BWzHW7LS.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-xWQYTLAn.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-CLxtpZeL.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CiVoq4G-.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-DwugtmWV.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BkdgdpfR.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-DHEOwHIe.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-pmbZKlBK.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-CivHoM5q.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-BfHIE7o6.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +10 -122
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +0 -7
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +15 -35
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +62 -136
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +68 -159
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +56 -75
- package/dist/worker/console/static-src/operator-chat/useComposer.js +78 -206
- package/dist/worker/console/workspace-context.js +1 -21
- package/dist/worker/observe/static/router.js +1 -1
- package/dist/worker/observe/static/styles.css +4 -7
- package/dist/worker/observe/static/views/dag-inspector.js +19 -12
- package/dist/worker/observe/static/views/dag.js +2 -2
- package/dist/worker/scheduler/index.js +25 -0
- package/dist/workflows/dag/facts.js +4 -0
- package/dist/workflows/dag/frontend-closeout.js +1 -1
- package/dist/workflows/dag/frontend-design-policy.js +1 -2
- package/dist/workflows/dag/frontend-implementation-contract.js +4 -8
- package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
- package/dist/workflows/dag/frontend-repair.js +76 -55
- package/dist/workflows/dag/frontend-review-context.js +1 -2
- package/dist/workflows/dag/frontend-review-scopes.js +12 -34
- package/dist/workflows/dag/frontend-shape-facts.js +2 -12
- package/dist/workflows/dag/frontend-verification-trace.js +42 -8
- package/dist/workflows/dag/index.js +6 -0
- package/dist/workflows/dag/init-hybrid.js +160 -97
- package/dist/workflows/dynamic/index.js +7 -0
- package/docs/architecture/runtime-boundaries.md +3 -3
- package/docs/templates/frontend-implementation-dag.json +8 -9
- package/package.json +3 -7
- package/skills/frontend-bounded-implement/SKILL.md +3 -4
- package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
- package/skills/frontend-contract/references/contract-protocol.md +1 -3
- package/skills/frontend-design-review/SKILL.md +7 -12
- package/skills/frontend-design-review/references/review-checklist.md +7 -7
- package/skills/frontend-plan/SKILL.md +0 -19
- package/skills/frontend-plan/references/decision-contract.md +19 -26
- package/skills/frontend-review/SKILL.md +18 -12
- package/skills/frontend-review/references/review-findings.md +43 -24
- package/dist/shared/pi-provider-recovery.js +0 -182
- package/dist/worker/console/chat/browser-automation.js +0 -363
- package/dist/worker/console/chat/browser-policy.js +0 -113
- package/dist/worker/console/chat/browser-routes.js +0 -162
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +0 -44
- package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +0 -89
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +0 -202
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +0 -79
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +0 -86
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +0 -38
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +0 -28
- package/dist/worker/console/chat/pi-runtime/inspection.js +0 -439
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +0 -153
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +0 -5
- package/dist/worker/console/chat/scm-routes.js +0 -217
- package/dist/worker/console/chat/scm-service.js +0 -283
- package/dist/worker/console/chat/scm-tools.js +0 -111
- package/dist/worker/console/chat/session-mode-view.js +0 -49
- package/dist/worker/console/chat/session-mode.js +0 -220
- package/dist/worker/console/chat/terminal-routes.js +0 -216
- package/dist/worker/console/chat/terminal-sessions.js +0 -348
- package/dist/worker/console/chat/terminal-tools.js +0 -211
- package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/index-B9goN3S5.css +0 -1
- package/dist/worker/console/static/assets/index-wXlQohNs.js +0 -469
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
- package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +0 -10
- package/dist/worker/console/static-src/operator-chat/chat-link.js +0 -94
- package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +0 -24
- package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +0 -192
- package/dist/worker/console/static-src/operator-chat/process-label.js +0 -41
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +0 -13
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +0 -10
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +0 -51
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +0 -21
- package/dist/worker/console/workspace-initialization.js +0 -209
- package/dist/workflows/dag/frontend-capacity.js +0 -9
- package/dist/workflows/dag/frontend-plan-completeness.js +0 -186
- package/dist/workflows/dag/frontend-plan-recovery-policy.js +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,79 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
- 修复前端实现因测试名称没有 VT 编号而反复失败:按测试命令与文件关联执行结果,保留已有测试名称及测试失败阻断。
|
|
6
|
-
|
|
7
|
-
- 整理设置弹窗布局:当前工作区优先、待处理文件紧凑分组、详情按需展开,全局程序信息收拢;窄屏导航改为横向排列。
|
|
8
|
-
|
|
9
|
-
- 工作区配置按实际能力提供更新按钮,逐文件说明待处理原因与下一步,并支持复制智能体处理说明;只剩合并或确认项时不再显示无效更新按钮。
|
|
10
|
-
|
|
11
|
-
- 前端实现恢复已有测试维护与执行:优先任务声明,否则复用项目测试入口;没有测试时不强制补框架,避免只构建通过却遗漏旧单测回归。
|
|
12
|
-
|
|
13
|
-
- Operator Chat 新增对话驱动的侧边栏浏览器自动化:模型可在工作流 / Pi 会话调用 `browser_navigate` / `browser_search` / `browser_inspect` / `browser_act`,把百度等页面打开到右侧浏览器面板,执行静态搜索、GET 表单填充提交、链接点击并返回结构化页面元素;命令通道按工作区隔离,自动化不读取或修改仓库文件,也不执行页面脚本。
|
|
14
|
-
|
|
15
|
-
- 修复前端 Plan 无法提交实现步骤的问题:finalize_plan 支持按 AC 绑定实施动作,缺漏在节点内返回修正,避免空计划反复进入设计审查。
|
|
16
|
-
|
|
17
|
-
- 修复前端最终审查反复猜错范围 ID:明确 checkpoint 参数和补交步骤,收尾正确识别 checkpoint 之后的审批结论。
|
|
18
|
-
|
|
19
|
-
- 前端实现流程简化为需求实现覆盖审查与项目验证命令,不强制独立测试方案;已有测试仍需维护并执行,无测试项目不强制补框架,构建结果不冒充行为验证。
|
|
20
|
-
|
|
21
|
-
### 改进
|
|
22
|
-
|
|
23
|
-
- Console 将全局「更新程序」与当前工作区初始化分开:添加或切换工作区后只读检查并提示,设置中展示仓库路径、初始化状态、待处理文件和操作进度;首次初始化显式选择可用模型,安全更新仅作用于当前仓库,冲突保留并提示处理。
|
|
24
|
-
|
|
25
|
-
- Operator Chat 内置内部 provider 瞬态异常恢复:即使目标仓库未执行 `loop-agent init`,也能识别完整或被裁剪的 `UnknownError` / `TypeValidationError` / `LLMRequestError` / 502 / 中文「网络波动、模型处理超时」响应,将其规范化后交给 Pi 原生有界重试;Console 缺省使用 loop-agent 推荐重试参数,项目显式字段优先于用户全局字段,用户配置优先于推荐默认值。共享纯分类器同时生成 OpenCode 插件谓词,overflow、认证、权限、配额、取消和业务错误继续 fail-fast。
|
|
26
|
-
|
|
27
|
-
- Operator Chat 浏览器面板默认以完整权限运行(去掉 iframe 沙箱与「临时解锁」状态条),并放开本机回环地址限制——`localhost` / `127.0.0.1` / `::1` 等本地开发服务器可直接在面板内浏览;地址栏仍仅放行 http/https,`javascript:` / `data:` / `file:` 等危险协议继续拦截,拒绝嵌入站点(X-Frame-Options / frame-ancestors)的解释面板与出口保持不变。
|
|
28
|
-
|
|
29
|
-
- 前端 Plan 普通分片按本批完整需求材料打包,固定提示词、用户消息和工具定义不再挤占 24 KB 分片目标,也不再触发发送前的机械二分,减少小需求逐 AC 会话;实际模型容量检查与超限恢复继续生效。
|
|
30
|
-
|
|
31
|
-
- 前端 Plan 小任务合并规划不再受固定 48 KB 输入门槛限制,避免提示词、用户消息或工具定义变长导致额外分片;完整输入、其余任务规模条件及容量恢复机制保持不变。
|
|
32
|
-
- 节点侧栏修复执行分次下拉菜单被执行记录工具栏遮挡的问题,直接展示所选失败尝试的简要原因,并移除重复的左右切换箭头。
|
|
33
|
-
- Operator Chat 的 Pi Runtime 按职责拆出工具构造、运行态检视和 SDK 适配,并共用创建/恢复/分叉的会话准备流程;对外入口、错误类型和会话行为保持不变。
|
|
34
|
-
|
|
35
|
-
### 修复
|
|
36
|
-
|
|
37
|
-
- 对话页修复用户消息在流式回复中漏显示或重复分组、加载历史后的滚动跳动,以及删除会话后旧请求恢复条目的问题;移除工作区后隐藏非选中的空白会话,并正确恢复删除失败的列表状态。
|
|
38
|
-
- 修复 Operator Chat 的跨会话输入污染与快速重复提交:切换会话时立即撤销旧会话发送权,草稿、附件和 ↑ 输入历史按会话独立保存;发送、排队、撤回、编辑、插话、文件建议和图片读取的迟到结果只回写原会话。提交改用带快照的有界 attempt,相同内容的快速双 Enter/双击只产生一次请求,失败恢复或排队响应不再覆盖后来输入;流式更新和会话切换保持同一个 composer DOM,中文 IME 更稳定。同步修复 durable 用户消息确认后时间重排导致闪烁光标跑到用户消息上方的问题。
|
|
39
|
-
|
|
40
|
-
- 前端设计审查的写入门禁只统计已提交的审批终态,避免审查范围、发现记录导致合法审批被误判为缺失或歧义;要求修改时保留具体审查意见,缺失、重复及冲突终态仍阻断写入。
|
|
41
|
-
|
|
42
|
-
## [0.42.1] - 2026-09-09
|
|
43
|
-
|
|
44
|
-
### 新增
|
|
45
|
-
|
|
46
|
-
- Console Chat 的 `/goal` 持续目标能力对 Pi 模式开放(与工作流模式同语义):斜杠面板两模式均可见 `/goal`;Pi 会话注册 `get_goal` / `create_goal` / `update_goal` 工具并纳入激活集;Goal HTTP 接口(创建/暂停/恢复/清除)在 Pi 会话不再返回模式拒绝;GoalBar 与目标编辑面板在 Pi 会话渲染;压缩恢复、每轮 Goal 上下文与有界自主续跑(仅显式 `/goal` 才 arm,maxRounds 上限,reload/重启/出错/暂停即 disarm)在 Pi 会话可用。
|
|
47
|
-
|
|
48
|
-
- Operator Chat 浏览器面板(DSH 风格):Console 右侧辅助栏新增「浏览器」tab——地址栏(自动补 https、仅 http/https、禁止 javascript/data/file 等危险协议与本机回环地址)、后退/前进/刷新导航栈、系统浏览器跳转;页面运行在无 same-origin、无 top-navigation 的沙箱 iframe 中(访问的页面拿不到 Console 的存储与 API),沙箱状态条支持单页面临时解锁(红色警示 + 一键恢复);对拒绝被嵌入的站点(X-Frame-Options / frame-ancestors)给出明确解释面板与「在系统浏览器打开 / 仍要加载」出口,探测端点仅返回响应头、仅限 http(s) 非回环、8 秒硬超时。
|
|
49
|
-
- Operator Chat 源代码管理(DSH 风格):模型获得 `scm` 工具(status/diff/stage/unstage/discard/commit/log/branch/push/pull,固定参数 git 无 shell、限时限量输出);Console 右侧辅助栏新增「源码」面板(DSH GitView 布局——分支下拉切换、已暂存/更改分组与全部暂存/取消暂存、单行提交框 Ctrl+Enter、内联分页历史带 refs 徽标与相对时间、点击文件看 diff、右键菜单放弃更改/复制路径);模型与面板共用同一工作区级 ScmService。
|
|
50
|
-
- Operator Chat 在具备 Aimax 凭据资格时,向对话进程注入 `$AIMAX_AUTH_TOKEN`(明文或 `sm4:v1:` 解密后的 ticket),供 skills 读取;文件缺失、无法解析或解密失败时不注入该变量。
|
|
51
|
-
- Operator Chat 终端管理(DSH 风格):模型获得 `terminal` 持久 PTY 工具(跨平台 shell 目录——Windows 提供 powershell/bash/cmd,macOS/Linux 提供 bash/zsh,pwsh 7 装了即用;cwd/环境变量/后台任务跨调用保留,完成标记协议 + 超时与截断保护,枚举与默认值按平台动态生成);Console 右侧辅助栏新增「终端」面板(xterm.js 渲染,实时查看/接管模型的 shell,按平台动态展示可创建的 shell,支持发送输入、Ctrl+C、终止并关闭);模型 shell 与用户面板共用同一会话注册表并开在工作区仓库根目录,命名区分来源。
|
|
52
|
-
- Windows 原生 `cmd.exe` 终端体验补全:仅 Windows 平台提供 `cmd` shell,使用经典 `C:\path>` 提示符、cmd 黑底浅灰配色与方块光标,并补回 ConPTY 丢失的 `Microsoft Windows [版本 …]` 启动横幅;bash 与 PowerShell 保持各自原生输出,不注入 Windows 横幅。
|
|
53
|
-
- Operator Chat 详情栏调整:「源码」tab 紧邻「文件」tab,便于在文件预览与源码管理之间快速切换。
|
|
54
|
-
|
|
55
5
|
### 改进
|
|
56
6
|
|
|
57
|
-
- 修复前端设计评审与实施评审遗漏 `complete_review_scope` 工具权限,导致模型无法完成分段确认、最终评审反复被拒绝的问题;补充真实 Pi SDK 工具激活与分段收口回归验证。
|
|
58
|
-
|
|
59
|
-
- 对话正文与 Human Gate、任务活动和产物卡片统一绑定会话所属工作区;修正旧式任务/运行链接,只有操作编号时查询真实记录再定位,工作区冲突或记录缺失时明确提示,避免误入其他工作区或总览。
|
|
60
|
-
|
|
61
|
-
- 节点侧栏在首次原始运行中隐藏「来源与影响」,派生运行保留该入口;打开运行中节点默认定位到「执行记录」,手动选择和明确的链接位置在刷新时保持。
|
|
62
|
-
|
|
63
|
-
- 修复前端契约可选字段未填写时,评审分片索引引用不存在字段、导致设计评审启动前失败的问题。分片生成跳过 undefined;读取端明确拒绝缺失字段、无效引用、重复或非法范围及未索引内容,保留合法空数组和 JSON 空值。
|
|
64
|
-
|
|
65
|
-
- Operator Chat 侧栏「添加工作区」图标改为与 DSH 一致的文件夹加号,不再用纯加号。
|
|
66
|
-
- Operator Chat 侧栏改为单一「新会话」;空白会话在输入框上方用芯片选择工作区和模式(工作流 / Pi),有历史后芯片收起。不再用落地页双卡或「新 Pi」按钮;换模式会复用或新建对应空白会话,不会改已有会话的模式。
|
|
67
|
-
- 修复模型续跑取消后带部分文字仍被标记成功的问题;前端 Plan 的取消、认证、限流及策略失败优先于容量恢复,精确格式错误保留原修复路径。完整性检查按需求建立单次索引,减少大计划重复扫描,同时拆分纯检查与恢复策略模块。
|
|
68
|
-
- 长会话中的输入框不再因历史消息和工具记录增多而逐键重绘整段会话,输入与自动增高在低性能电脑上更流畅。
|
|
69
|
-
- 优化 Operator Chat 长会话的流式渲染:完成回合、消息行、工具卡和用户输入锚点建立稳定的 memo 边界,流式文本更新不再重复渲染整段历史或重装锚点测量监听;缓存会在历史消息或工具实际更新时正确失效;无新增折叠回合时不再提交空状态及重复写入本地存储,工具参数与结果格式化按真实输入变化缓存。
|
|
70
|
-
- 对话页「过程折叠」对齐 DSH 细节:模型回复完成时直接进入折叠态,不再先展开再跳动;折叠摘要、过程内容和最终回答采用与 DSH 一致的间距,折叠内容仍保留在页面中,浏览器 Ctrl+F 可直接命中并自动展开;折叠行展开时不再多出底部空隙;箭头改为 16px、颜色更淡的固定图标(靠旋转而非换图标),并补齐系统「减少动态效果」偏好;汇总文案新增「N 个 subagent」,内置 Explore 子代理不再计入普通工具调用。
|
|
71
|
-
- 恢复前端 Plan 实时事实分页读取、逐需求 UX 遗漏检查与已完成范围复用;超限时补齐剩余验证目标,并接通 DAG 到 SDK 的原会话续跑。局部状态修改保留其他需求的关联,沿用耐久账本、显式替换和冻结分片边界。
|
|
72
|
-
|
|
73
|
-
- DAG 的 Pi SDK 节点遇到 `stopReason=length` 时,先在原会话内最多续跑 3 次,保留已完成写入和事实,成功恢复不消耗额外节点重试次数;共享原超时与上下文预算,已成功提交终态时不重复续跑,耗尽后才进入原有缩片或重试路径。
|
|
74
|
-
- 修复前端 Design Review 成功后可能清空原 Plan 账本的问题,撤回未接通合同校验和物化的修订工具;同时移除误加在实施后 Review 的修订指令。Review 节点内局部修订尚未实现,设计缺陷仍走原有拒绝与恢复流程。
|
|
75
|
-
- 前端 Plan 输出超限后按已提交事实续跑:带部分结果或网关诊断也会保留进度,自动缩小剩余需求;单个过大需求进一步按缺失事实逐项恢复,并在恢复耗尽时输出剩余范围。
|
|
76
|
-
- 大需求前端 Plan 增加可分页的实时事实读取,保留长标识和跨批验收绑定;UX 按有限需求范围执行,重试复用完整批次和全局命名表,逐需求检查遗漏。冻结交付文件超过单 writer 容量时在 Contract 后提前识别拆分需求;自动子任务执行链路尚未接通,此项不代表自动拆分已可用。
|
|
77
|
-
|
|
78
7
|
- 前端 DAG 修正否定约束导致的小任务误升级;Plan 在分片前统一 compact 判定并保留完整执行组。支持冻结 coverage 并发上限(1–4,默认 4),限流后减少后续并发且不增加重试。自动恢复子进程与 DAG 共用长跑超时,避免继承通用 120 秒上限而中途终止。
|
|
79
8
|
- 前端 DAG 保留完整需求并按作用域/执行组分批,工具提交改为先校验和耐久保存再回执;支持按组共享覆盖、逐端点/逐 finding 提交和缺项恢复。小任务走短流程,容量耗尽直接缩小剩余工作;模型窗口不再硬编码为 100K/16K。独立 AC、来源保真与 writer/verify 门禁保持有效。
|
|
80
9
|
- 观测台阅读与口径修补:失败节点的产出页把「错误输出」提到正文之前,未登记文件关系时不再展示空文件卡;检查器 Tab 条放不下时两端渐隐提示并保证选中 Tab 可见,每页顶部说明卡可收起。异常 Task 的分类与建议跟进显示中文业务术语(未知 token 原样透传并可悬停看原始值),资源池「合计」改为口径明确的「已建 Task」并附悬停说明,数据更新文案改为「数据更新于 … · 仅提示」。DAG 详情面包屑使用可读运行标题(缺失回退运行 ID、窄屏截断),「记录保存位置」移入「诊断信息」折叠区,页面刷新按钮与标题同行靠右。
|
|
@@ -87,20 +16,6 @@
|
|
|
87
16
|
|
|
88
17
|
### 修复
|
|
89
18
|
|
|
90
|
-
- 悬停或打开会话「更多」菜单时,Pi / 工作流徽章与相对时间一并让出,避免被三个点按钮盖住。
|
|
91
|
-
- 修复点「新 Pi」后一发消息侧栏就变成「工作流」:全局会话列表和点进会话时漏了 `sessionMode`,缺省被当成工作流。
|
|
92
|
-
- 修复手动压缩上下文后,长会话会清空并重复绘制大量历史内容的问题;压缩结果现在会直接在当前消息流中更新,不再触发整段会话重载。
|
|
93
|
-
- 修复对话页存在运行活动时,收起状态的右侧辅助栏展开按钮覆盖「运行活动 N」及数字徽标的问题;中大尺寸布局现在保留 8px 操作间距,窄屏布局不变。
|
|
94
|
-
- 修复 Operator Chat 消息流的六处实际使用问题:
|
|
95
|
-
- **回复被吞**:断线/重连(含每 25 秒的 SSE 事件窗口轮转)后,保留事件里已经生成的正文会在事件流恢复时重新应用到对应回合,不再被静默丢弃;仅当该回合已有更新内容时才跳过,避免重复气泡。
|
|
96
|
-
- **用户输入消失或重复**:新消息发送后会在每一帧模型输出中持续显示,不再等回复结束才重新出现;服务端确认后,提交回滚(排队抢占、被拒绝、连接失败)不再删掉已确认的消息;确认帧到达时会原地合并临时消息与会话快照,不再重复显示同一条输入。
|
|
97
|
-
- **回复重复**:上下文溢出自动压缩并重新生成后,被打断的旧回复会被取代,不再与重新生成的回复同时显示。
|
|
98
|
-
- **只有思考没有正文**:模型回复以工具调用或思考结尾时,正文会作为回答显示,不再被折叠进「过程」区。
|
|
99
|
-
- **空气泡误删**:只包含思考或工具内容、正文为空的回合不再被清理掉。
|
|
100
|
-
- **停止语义**:被停止中断的工具调用显示「已停止」,不再显示为「出错」并强制展开、计入「N 次出错」。
|
|
101
|
-
|
|
102
|
-
- 任务成功与收尾只认可匹配当前契约版本和哈希的运行;更新需求后重新审查 gate,旧成功记录不再阻止新运行。需求独立审核接受 `revision: null` 表示无修订,保留拒绝结论和身份校验;相同角色、相同内容的 PRD 重复导入复用不可变引用,不再重复增加副本或无故推进契约版本。
|
|
103
|
-
|
|
104
19
|
- 前端 Plan 重试复用首次冻结的分片归属,避免重试提示词变长导致进度绑定不匹配或重复处理已完成需求;布局缺失、损坏或漂移时保留证据并阻断派发。风险路由仅忽略完整的范围排除声明,条件句和嵌套否定中的真实权限风险在生成期与运行期均保持升级。
|
|
105
20
|
- 执行记录搜索直接高亮命中文字,标识当前跳转记录;未搜索或无匹配时禁用上下箭头,清空搜索恢复原文。
|
|
106
21
|
|
|
@@ -120,61 +35,15 @@
|
|
|
120
35
|
|
|
121
36
|
### 改进
|
|
122
37
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
- 修复
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
- 修复前端 Plan 重试梯级遮蔽修复指令的问题:invalid-output / structured-output-truncated 的账本修复指引现在优先于 compact-terminal-first 等梯级话术。此前 length 失败把重试梯级单调升到 compact-terminal-first 后,后续 invalid-output 重试拿到的是「保持已提交账本完整」的档位指令,与「重提交修正后的 record_* facts」这一唯一治愈动作正面冲突,修复指引成为死代码;修复指引同步补上 duplicate/replace 语义(duplicate 收据是修正邀请而非禁令,replace=true 为同 id 全量替换,回填反向引用不属于重推导已提交事实)。`skills/frontend-plan` 新增跨段引用规则与 Bidirectional VT cross-reference invariant 小节:跨切片引用已提交 VT 时当场以同 id + replace=true 回填,双向引用在提交时即闭合,不再拖到 attempt 末尾的双向检查才暴露。
|
|
133
|
-
- 修复 DAG Pi 节点把 provider `stopReason=length` 的输出/上下文截断误判为 `empty-output` 失败的问题:仅 `empty-output` 基础上的长度截断会改判为专门的 `output-limit` 可重试类别(raw 类别保留诊断),已有精确修复指令的类别(output-too-large / invalid-output / protocol-invalid / structured-output-truncated / writer 类)原样保留,避免通用指令遮蔽任务专属修复提示;`output-limit` 通用增量指令(从已提交 typed facts 与现有工作区只补未完成部分、每个生成单元产出后立即校验格式并在当节点修复)作为兜底排在所有精确分支之后,前端规划梯级(compact-terminal-first 正是 length 场景的领域档位)与结构化冻结修复路径优先。只读/结构化/前端规划/后端测试补全策略的默认重试额度从 3 次提升到 5 次;旧 artifact 中的 `writer-thinking-exhausted` / `planner-thinking-exhausted` 终态标签仅作历史保留(Console/报告展示映射同步归入 executor 容量类),新执行不再产生。
|
|
134
|
-
- 前端 Scout 在中高复杂度任务中并行收集 target surface 与 design evidence;大型 Plan 将 requirement coverage 按批次并行映射,再按固定顺序归并到唯一 reducer,保持 Contract → Scout → Plan 依赖与确定性终态,同时缩短最长串行等待。
|
|
135
|
-
- 前端 Verify bundle 会在同一次执行中按工作目录和冻结命令去重:static、behavior、Mock、lint lane 复用相同命令结果,同时为每个 lane 保留独立证据,避免重复启动耗时的 typecheck/test/build 进程。
|
|
136
|
-
- 前端 Micro/Small shape 路由不再把 `test/`、`e2e/`、`docs/` 等验证或文档根目录误计为业务跨域;`src/**` + `test/**` 的局部 UI 改动现在可以正确命中轻量拓扑,真实跨包路径仍保持升级。
|
|
137
|
-
- 修复前端 Plan 漏读独立行为证据、重试丢失已重新录入的 UX 名称的问题;必交付文件改由 Contract 显式声明并绑定原始来源,避免把允许修改或参考路径误判为交付义务。缺失交付物和 UX 名称冲突现在可在 Plan 提交前发现并修正,发布 schema 同步支持组件覆盖与复用证据字段。
|
|
138
|
-
- 修复前端 DAG 的 Plan 按 AC 分片重复发明同一批需求、交互和 UI 状态的问题:Contract 的 canonical requirement 文本与来源片段改由 runtime 从冻结 ledger 写入,Plan 先基于全部需求提交一次全局 UX registry,再在单一全局 UX 会话中建模组件、状态和交互;来源声明的 UI 状态必须完整闭合,复用既有组件必须提供真实存在的文件证据,交付文件完整性与逐状态/交互组件覆盖由确定性 gate 校验。
|
|
139
|
-
- 修复顶部一级「观测」入口被恢复工作区残留的 DAG 或上次观测对象劫持的问题:现在点击该入口始终回到当前 Workspace 的运行总览,具体 DAG 仍通过「全屏观测」等显式入口打开。
|
|
140
|
-
- 修复节点检查器通俗字段旁的问号只有图标、悬浮时看不到具体说明的问题;问号现在支持鼠标悬浮和键盘聚焦,并显示对应字段含义及原技术字段。
|
|
141
|
-
- Next 发布测试升级到 Vitest 4.1.11,采用上游 worker RPC 修复,避免所有断言通过后仍因 `onTaskUpdate` 通讯超时阻断发包;同时隔离会改写构建产物的 package-surface 测试,并恢复两条此前被错误嵌套、实际未执行的 Console 更新回归;发布门禁继续严格检查 unhandled errors。
|
|
142
|
-
- 前端计划契约新增确定性锚定校验(恶劣网关冒烟 4 轮 design 拒绝的主因):behavior 验证目标必须至少引用一个 requirement,且在契约声明了 UI 状态或交互时必须引用至少一个已声明的 UI 状态(纯逻辑契约豁免)。校验位于共享 schema refine,plan 节点的自修阶梯当场拿到精确到字段的报错并修复,不再烧一整轮 design-review 才发现映射缺失;`skills/frontend-plan` 决策契约参考同步补充 canonical 示例(behavior target 形态、状态名逐字引用、stylingStrategy 禁止承诺任务源非目标能力)。
|
|
143
|
-
- 修复前端 design 拒绝后自动恢复子 run 无法启动的问题(恶劣网关前端冒烟三轮复现):staging 物化 child state 时现在按 child spec 写入 `frontendShapeState` 冻结拓扑绑定(此前 execute 前的绑定断言以 `frontend topology binding is missing` 在 398ms 内 fail-closed),并把父 run 中已导入边界节点(contract/scout 等 FINISHED 导入节点)的 committed shape facts 一并继承——否则 child 会在首个 shape 门禁以 `frontend-shape-fact-invalid` 整体 SKIPPED;reset 边界由重跑节点重新提交。同时修复 recovery child runId 派生误传参导致碰撞安全后缀失效、可与已归档 run 同名的问题(默认 `buildDagRunId` 现在正确收到 `{ cwd }` options)。
|
|
144
|
-
- 修复 backend-test N2 把 provider `stopReason=length` 的截断 Markdown 计划误判为 `FINISHED`、继而延迟到 N3 `missing-module-index` 的问题:长度截断现在在 producer 节点归类为 `output-too-large`;正常结束但缺少必需 heading、Module Index 八列表/模块行或使用代码围栏时归类为 `invalid-output`。两类失败均使用有界 artifact-first retry,下一 attempt 只携带控制器生成的限长协议诊断;N3 ownership/path/模块数门禁与业务 pytest 单次执行不放宽。
|
|
145
|
-
- 可选依赖 `@agent-context/sift` 从 `0.0.1-alpha.6` 精确 pin 升级到 `0.0.1-alpha.7`:新增 `retrieveLines` 行级分片取回与省略点内联 stash 路径/起始行号(模型可直接换算 read 行号),纯文本压缩策略更保守(不同编号/状态的内容不因句式相似而合并);桥接层沿用既有 `createSift`/`siftRequest`/`retrieve` API,行为与回退开关不变,仍不投影 init。
|
|
146
|
-
- 修复后端实现 DAG Pi 扩展 resolver 无法解析版本 pin spec 的问题:`packageNameFromSpec` 现在剥除尾部 `@<version>`/`@<dist-tag>`(保留 scoped 包名开头的 `@`),与 Console 插件面语义对齐。此前 settings 中的 `npm:pi-lens@3.8.72`(Console 升级插件写入的形式)会被当作包名 `pi-lens@3.8.72`,永远匹配不上别名表,读侧节点(contract/scout/plan/verify)的 `pi-lens` 全部静默降级为 `not-installed`;`pi-extensions.json` 观测产物可鉴别此场景。
|
|
147
|
-
- 修复前端自动恢复实际重跑整棵 DAG、忽略已冻结 reset plan 的问题:恢复 operation 现在校验 operationId/lease 归属,按 parent recovery plan 导入已完成事实并只执行 reset 子图;设计拒绝缺少 typed findings 时 fail-closed;多轮 continuation 会继续注入共享 recovery controller、递增并校验完整 lineage;崩溃重放会复用 completed child;缺少已绑定 child lineage 的伪成功 operation 不再标记 recovered;rerun-task 的全局 requestId 重放会校验请求类型、父 run 与完整 payload,避免串用其它请求结果。
|
|
148
|
-
- 冒烟再暴露 writeSet 授权缺口:冻结验证命令引用的基建文件(如 `--config` 的 vitest 配置)不在 plan verification targets 内时,writer 被具体 writeSet 拦住无法创建、verify-shell 必然失败。现在 admission 生效边界确定性并入冻结命令引用的文件(机械提取、仍受 allowedPaths/forbiddenPaths 约束),writer 聚焦检查失败后可自行补齐基建文件。
|
|
149
|
-
- 前端 verification contract v2:plan 不再手写五值 `type`,改为引用生成期冻结命令目录的 `commandId`,`mode(static|behavior)` 与 `commandLabel` 由 runtime 在物化时解析——`type: component + npm run build` 这类非法组合在 Plan 工具边界(`verification-target-unknown-command`)与物化校验(`verification-target-phase-mismatch`,behavior 命令必须绑定测试文件)即被拒绝,不再拖到 writer focused-check 才以 `invalid-output` 失败;展示用的 `scope` 不参与控制流。
|
|
150
|
-
- 修复 /inspect/* 静态资源(operator-chrome.js/css、观测文档)缺少 Cache-Control 的问题:现在与 Console SPA 一律 `no-store`。此前浏览器启发式缓存会让 Console 更新/重启后继续挂旧版导航模块,表现为顶部导航「回退」到只有操作/观测、缺少对话入口的旧版布局。
|
|
151
|
-
- 新建、删除和切换对话的反馈更及时;会话列表默认展示 5 条,“展开其余会话”和“收起”也更整齐易用。
|
|
152
|
-
- 发送消息后会立即显示在对话流中,完成回合的过程摘要也更清晰,长时间等待连接时不会让输入内容消失。
|
|
153
|
-
- 文件预览支持页面内交互和独立窗口阅读,大型 HTML 内容也能完整打开。
|
|
154
|
-
- 模型配置更新后,继续使用旧会话时会自动采用最新认证信息,消息流顺序也更加稳定。
|
|
155
|
-
- 执行记录默认跟随最新内容,也可以暂停自动滚动并保留当前阅读位置。
|
|
156
|
-
- 任务执行、恢复和结果查看更加稳定,工作区和滚动区域的使用体验得到改进。
|
|
157
|
-
|
|
158
|
-
<details>
|
|
159
|
-
<summary>实现细节(开发者参考)</summary>
|
|
160
|
-
|
|
161
|
-
- Operator Chat 会话列表默认收敛为最近 5 条;展开与收起控件采用稳定的整行布局,折叠工作区后恢复默认列表;长历史会话改为分页加载,并在加载更早消息后保持原有滚动位置。
|
|
162
|
-
- Operator Chat 长会话增量构建活动 turn、复用已完成过程节点,并支持对已完成且无错误的历史 turn 进行 Compact,降低长消息流的渲染开销。
|
|
163
|
-
- 修复 backend-test Manifest 把模型生成的 Module Stem 展示单元格当成模块身份真源、导致 low-tier 输出(缺 `test_` 前缀或整段 Markdown 链接)在 N3 `module-markdown-path-mismatch` 反复失败的问题:N3 现在先解析唯一合法 Markdown Path 与 `<stem>.md` 相对链接作为 canonical 身份,再校验业务 ownership/split 与路径安全;Stem 单元格只作冗余展示并能确定性重写为 canonical 文件名 stem。strict `backendTest.moduleLayout` 改为先按唯一 required Markdown Path 定位模块,再恢复冻结 Markdown/Pytest path pair,避免错误 stem 提前丢弃整行,同时保留 Plan-only pytest path 修复。Markdown Path 缺失/多候选/越界或与 strict path pair 冲突、以及多行 canonicalize 后同 identity(`duplicate-canonical-module-stem`)继续 fail-closed,不再静默去重。同步加强 N2 prompt(Stem 单元格仅允许纯文件名 stem)。
|
|
164
|
-
- 修复 Next Release 的 io-heavy 测试不稳定:在保留发布单 worker、完整测试集合和严格 unhandled-error 门禁的同时,将 Vitest 升级到包含上游 RPC settlement 修复的 4.1.11,避免全绿测试因 `onTaskUpdate` timeout 退出 1;会重建共享 `dist/**` 的 package-surface 测试改由单 worker integration 池持有,避免与 controller identity 指纹检查竞态;并把误嵌套在 `dagDoctor` stub 中的 `consoleUpdateAndInit` suite 移回顶层、补齐 `workspaceId` 契约,使两条回归重新进入真实执行。
|
|
165
|
-
- 修复 backend-test 唯一 pytest collection repair 已产生受控非空修改、却因模型遗漏 `IMPLEMENTATION_OUTCOME` 而阻断整条执行链的问题:仅 N11 exact repair writer 可把完全缺失的 outcome 确定性恢复为候选 changed,随后仍必须由 N12 重新通过 scenario、correspondence、payload、collection、fixture 和 readiness 门禁;unknown/conflicting/blocked、空 diff、越界写入及 provider/context failure 继续 fail-closed。
|
|
166
|
-
- 新建和删除对话现在会立即在侧栏中反馈:新建时先显示“正在创建”,删除时平滑淡出;网络失败会自动恢复原会话,不再需要等待整张会话列表刷新后才看到变化。
|
|
167
|
-
- 新建对话会优先复用当前工作区中真正的空白会话,避免重复创建;有历史消息、工具调用、待发送内容或正在运行的会话不会被复用。
|
|
168
|
-
- 会话列表刷新现在会复用未变化的行和列表引用,标题、运行状态或队列变化时只更新对应会话,侧栏切换和刷新更平滑。
|
|
169
|
-
- Operator Chat 新增仅对具备 Aimax 凭证的用户可见的 `/sdd-bingo` 数据对齐命令;`wizard-local` 模型请求会自动携带与上报一致的 OpenCode 风格会话身份、当前模型和最新 API key,请求头与资格文件变更均在下一次操作自动生效。
|
|
170
|
-
- DAG 节点检查器的「执行记录」默认自动跟随最新内容;右下角新增纯图标悬浮开关,可显式暂停并保留阅读位置,恢复后立即回到底部,悬停时显示当前可执行动作。
|
|
171
|
-
- 修复前端任务产物派生续跑无法识别当前节点链的问题;从实现节点继续时,设计约束、写入准入、验证和收尾步骤会按现行流程安全重放。
|
|
172
|
-
- 统一工作区、Todo 和其他滚动区域的滚动条样式,默认更轻巧,鼠标悬浮时也更容易辨认。
|
|
173
|
-
- HTML 文件预览现在支持页面内的标签切换等交互;较大的自包含 HTML 可以在新窗口中直接完整加载,不再受源码摘要长度影响。
|
|
174
|
-
- 修复 Operator Chat 长工具链的消息错序:模型过程文字、思考和工具卡片现在按服务端事件顺序稳定交替展示,刷新历史会话后也保持相同顺序。
|
|
175
|
-
- 修复 Operator Chat 旧会话继续使用过期模型认证的问题:模型配置变化后,下一轮发送或手动重新加载会自动刷新模型目录和当前模型认证。
|
|
176
|
-
|
|
177
|
-
</details>
|
|
38
|
+
- 具备 Aimax 凭证的用户可在对话输入框使用 `/sdd-bingo` 完成 SDD 数据对齐;不指定名称时自动选择分析类别,成功提示显示实际使用的类别。
|
|
39
|
+
- 前端 Scout 在中高复杂度任务中并行收集 target surface 与 design evidence;大型 Plan 的 requirement coverage 按批次并行映射后按固定顺序归并。
|
|
40
|
+
- 前端 Micro/Small shape 路由不再把 `test/`、`e2e/`、`docs/` 等目录误计为业务跨域,局部 UI 改动正确命中轻量拓扑。
|
|
41
|
+
- 前端计划契约新增确定性锚定校验:behavior 验证目标必须引用 requirement,声明了 UI 状态/交互时必须引用已声明状态,缺失在 Plan 自修阶梯当场报错,不再烧一整轮 design-review。
|
|
42
|
+
- 可选依赖 `@agent-context/sift` 升级到 `0.0.1-alpha.7`(行级分片取回、更保守的纯文本压缩),回退开关与 init 投影不变。
|
|
43
|
+
- 修复 DAG Pi 扩展 resolver 无法解析版本 pin spec 的问题(`npm:pi-lens@3.8.72` 不再静默降级 `not-installed`)。
|
|
44
|
+
- 修复 `/inspect/*` 静态资源缺 Cache-Control 导致 Console 更新后挂旧版导航的问题(一律 `no-store`)。
|
|
45
|
+
- Next 发布测试升级 Vitest 4.1.11(worker RPC 修复,全绿测试不再因 `onTaskUpdate` 超时阻断发包)。
|
|
46
|
+
- 会话列表默认展示 5 条、展开收起更整齐;新建/删除对话即时反馈;发送消息立即显示;文件预览支持页面内交互与独立窗口阅读;执行记录默认跟随最新内容可暂停;模型配置更新后旧会话自动采用最新认证。
|
|
178
47
|
|
|
179
48
|
## [0.41.3] - 2026-09-04
|
|
180
49
|
|
|
@@ -552,13 +552,11 @@ export async function advanceTaskLifecycle(input) {
|
|
|
552
552
|
// Prefer basename-aligned names for multi-file product suites.
|
|
553
553
|
name: path.basename(prd.filePath).replace(/\.(md|markdown|txt)$/iu, "") || undefined,
|
|
554
554
|
});
|
|
555
|
-
|
|
556
|
-
importedMaterializedPaths.push(imported.materializedRelativePath);
|
|
557
|
-
}
|
|
555
|
+
importedMaterializedPaths.push(imported.materializedRelativePath);
|
|
558
556
|
}
|
|
559
557
|
// Latch even when prdPaths is empty so a mis-planned import cannot loop.
|
|
560
558
|
importedPrdThisCall = true;
|
|
561
|
-
if (
|
|
559
|
+
if ((input.prdPaths?.length ?? 0) > 0) {
|
|
562
560
|
record = {
|
|
563
561
|
...appendTransition(record, "prd-imported"),
|
|
564
562
|
pendingPrdRefresh: true,
|
|
@@ -570,15 +568,12 @@ export async function advanceTaskLifecycle(input) {
|
|
|
570
568
|
completed.push("prd-imported");
|
|
571
569
|
await saveLifecycleRecord(input.repoRoot, record);
|
|
572
570
|
}
|
|
573
|
-
refreshManagedContractThisCall = Boolean(record.pendingPrdRefresh ||
|
|
574
|
-
hasContractChangingInput({ ...effectiveInput, prdPaths: undefined }));
|
|
575
571
|
snapshot = await observeTaskLifecycle(input.repoRoot, input.taskId);
|
|
576
572
|
// Two-phase Console bridge: when this call only had --prd and no
|
|
577
573
|
// engineering boundary, stop after archive. Re-plan would otherwise
|
|
578
574
|
// immediately prepare (hasPrdInput latched false + alreadyImported)
|
|
579
575
|
// and burn one-shot Semantic Intake before multi-file imports finish.
|
|
580
|
-
if (!hasBoundary &&
|
|
581
|
-
(input.prdPaths?.length ?? 0) > 0) {
|
|
576
|
+
if (!hasBoundary && (input.prdPaths?.length ?? 0) > 0) {
|
|
582
577
|
return {
|
|
583
578
|
taskId: input.taskId,
|
|
584
579
|
lifecycleState: "intake-incomplete",
|
|
@@ -1163,7 +1158,7 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1163
1158
|
continue;
|
|
1164
1159
|
}
|
|
1165
1160
|
if (action.type === "promote") {
|
|
1166
|
-
const runId = snapshot.
|
|
1161
|
+
const runId = run?.runId ?? snapshot.latestRun?.runId ?? snapshot.activeRun?.runId;
|
|
1167
1162
|
if (!runId) {
|
|
1168
1163
|
blockers.push({
|
|
1169
1164
|
code: "PROMOTE_RUN_MISSING",
|
|
@@ -1191,13 +1186,6 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1191
1186
|
continue;
|
|
1192
1187
|
}
|
|
1193
1188
|
if (action.type === "closeout") {
|
|
1194
|
-
if (!snapshot.promotion?.ready || !snapshot.currentRun) {
|
|
1195
|
-
blockers.push({
|
|
1196
|
-
code: "CLOSEOUT_EVIDENCE_STALE",
|
|
1197
|
-
message: "closeout requires promoted evidence for the current contract run",
|
|
1198
|
-
});
|
|
1199
|
-
break;
|
|
1200
|
-
}
|
|
1201
1189
|
const closed = await closeoutTask(input.repoRoot, input.taskId);
|
|
1202
1190
|
closeout = { path: closed.progressPath };
|
|
1203
1191
|
record = appendTransition(record, "closeout-completed");
|
|
@@ -1205,7 +1193,6 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1205
1193
|
...record,
|
|
1206
1194
|
closeout: {
|
|
1207
1195
|
path: closed.progressPath,
|
|
1208
|
-
runId: snapshot.currentRun.runId,
|
|
1209
1196
|
completedAt: new Date().toISOString(),
|
|
1210
1197
|
},
|
|
1211
1198
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { access, readFile, readdir } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { getTaskDir, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
|
|
4
|
-
import { getArtifactPath } from "../../shared/artifacts-core.js";
|
|
3
|
+
import { getTaskDir, getTaskPaths, getTaskStatus, loadTaskConfig, } from "../../task/runtime.js";
|
|
5
4
|
import { logicalRevisionForState, observeTaskContractState, } from "../../task/contract/index.js";
|
|
6
5
|
import { assessDagRunLiveness, listAllDagRunEntries, readDagRunSpec, readDagRunState, } from "../../workflows/dag/lifecycle.js";
|
|
7
6
|
import { resolveRunningControllerIdentity } from "../../shared/package-metadata.js";
|
|
@@ -203,7 +202,6 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
203
202
|
let stateStatus;
|
|
204
203
|
let failureCategory;
|
|
205
204
|
let lastMeaningfulProgressAt;
|
|
206
|
-
let contractBinding = null;
|
|
207
205
|
try {
|
|
208
206
|
const state = await readDagRunState(entry.runDir);
|
|
209
207
|
stateStatus = state.status;
|
|
@@ -240,19 +238,20 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
240
238
|
catch {
|
|
241
239
|
// state unreadable; may still match via binding
|
|
242
240
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
241
|
+
if (!source) {
|
|
242
|
+
try {
|
|
243
|
+
const spec = await readDagRunSpec(entry.runDir);
|
|
244
|
+
if (spec.taskContractBinding?.taskId === taskId) {
|
|
245
|
+
source = "task-contract-binding";
|
|
246
|
+
}
|
|
247
|
+
else if (spec.sourceBinding?.taskId === taskId) {
|
|
248
|
+
source = "source-binding";
|
|
249
|
+
}
|
|
248
250
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
catch {
|
|
252
|
+
// ignore
|
|
251
253
|
}
|
|
252
254
|
}
|
|
253
|
-
catch {
|
|
254
|
-
// Association may remain visible, but unreadable identity cannot prove completion.
|
|
255
|
-
}
|
|
256
255
|
if (!source)
|
|
257
256
|
continue;
|
|
258
257
|
related.push({
|
|
@@ -263,7 +262,6 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
263
262
|
failureCategory,
|
|
264
263
|
lastMeaningfulProgressAt,
|
|
265
264
|
source,
|
|
266
|
-
contractBinding,
|
|
267
265
|
});
|
|
268
266
|
}
|
|
269
267
|
return related.sort((a, b) => a.runId.localeCompare(b.runId));
|
|
@@ -279,10 +277,9 @@ function deriveLifecycleState(input) {
|
|
|
279
277
|
return "running";
|
|
280
278
|
if (input.closeoutExists && input.promotionReady)
|
|
281
279
|
return "evidence-closed";
|
|
282
|
-
if (input.
|
|
283
|
-
input.
|
|
284
|
-
|
|
285
|
-
if (input.latestRun?.lifecycle === "completed" && input.latestRun.status !== "finished") {
|
|
280
|
+
if (input.latestRun?.lifecycle === "completed") {
|
|
281
|
+
if (input.latestRun.status === "finished")
|
|
282
|
+
return "run-succeeded";
|
|
286
283
|
// A newly opened current writeSet gate supersedes an older failed run so
|
|
287
284
|
// operators can approve and start the next DAG run. Success stays terminal
|
|
288
285
|
// here so promote/closeout is not hijacked by a residual open gate.
|
|
@@ -384,19 +381,6 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
384
381
|
const runs = await listExplicitlyAssociatedRuns(repoRoot, taskId);
|
|
385
382
|
const activeRun = runs.find((run) => run.lifecycle === "active" || run.lifecycle === "paused") ?? null;
|
|
386
383
|
const latestRun = runs.length > 0 ? runs[runs.length - 1] : null;
|
|
387
|
-
const ref = contractState.ref;
|
|
388
|
-
const currentRun = contractState.effectiveStatus === "managed" && ref
|
|
389
|
-
? runs.filter((run) => {
|
|
390
|
-
const binding = run.contractBinding;
|
|
391
|
-
return (binding?.taskId === taskId &&
|
|
392
|
-
binding.revision === ref.revision &&
|
|
393
|
-
binding.canonicalHash === ref.canonicalHash &&
|
|
394
|
-
binding.taskConfigSha256 === ref.taskConfigSha256 &&
|
|
395
|
-
binding.projectionVersion === ref.projectionVersion &&
|
|
396
|
-
binding.canonicalizerVersion === ref.canonicalizerVersion &&
|
|
397
|
-
binding.taskConfigSchemaVersion === ref.taskConfigSchemaVersion);
|
|
398
|
-
}).at(-1) ?? null
|
|
399
|
-
: null;
|
|
400
384
|
const strictValidated = Boolean(record?.strictValidatedAt) &&
|
|
401
385
|
Boolean(record?.lastDagSpecHash) &&
|
|
402
386
|
record?.lastDagSpecHash === specHash;
|
|
@@ -449,13 +433,17 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
449
433
|
!rejectedCurrent
|
|
450
434
|
? buildWriteSetGate({ taskId, bound: gateBound, delta: gateDelta })
|
|
451
435
|
: null;
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
await
|
|
436
|
+
const gateOpen = Boolean(gate);
|
|
437
|
+
let legacyState;
|
|
438
|
+
try {
|
|
439
|
+
legacyState = await getTaskStatus(repoRoot, taskId);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
legacyState = null;
|
|
443
|
+
}
|
|
444
|
+
const promotionReady = Boolean(legacyState?.artifacts.modifyLog && legacyState?.artifacts.verifyResult);
|
|
456
445
|
const closeout = closeoutPath(repoRoot, taskId);
|
|
457
|
-
const closeoutExists =
|
|
458
|
-
record?.closeout?.path === closeout && await exists(closeout));
|
|
446
|
+
const closeoutExists = await exists(closeout);
|
|
459
447
|
const awaitingDecision = activeRun?.lifecycle === "paused" ||
|
|
460
448
|
activeRun?.status === "paused" ||
|
|
461
449
|
Boolean(activeRun?.status === "waiting-for-human");
|
|
@@ -475,9 +463,8 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
475
463
|
gateOpen: Boolean(gate),
|
|
476
464
|
activeRun,
|
|
477
465
|
latestRun,
|
|
478
|
-
currentRun,
|
|
479
466
|
promotionReady,
|
|
480
|
-
closeoutExists,
|
|
467
|
+
closeoutExists: closeoutExists || Boolean(record?.closeout),
|
|
481
468
|
needsAttention: Boolean(needsAttention),
|
|
482
469
|
awaitingDecision: Boolean(awaitingDecision),
|
|
483
470
|
});
|
|
@@ -523,15 +510,14 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
523
510
|
gate,
|
|
524
511
|
activeRun,
|
|
525
512
|
latestRun,
|
|
526
|
-
currentRun,
|
|
527
513
|
runs,
|
|
528
514
|
promotion: {
|
|
529
|
-
required: Boolean(
|
|
530
|
-
ready: promotionReady,
|
|
515
|
+
required: Boolean(latestRun && latestRun.lifecycle === "completed"),
|
|
516
|
+
ready: promotionReady || Boolean(record?.promotion),
|
|
531
517
|
},
|
|
532
518
|
closeout: {
|
|
533
519
|
path: closeout,
|
|
534
|
-
exists: closeoutExists,
|
|
520
|
+
exists: closeoutExists || Boolean(record?.closeout),
|
|
535
521
|
},
|
|
536
522
|
completedTransitions: record?.completedTransitions ?? [],
|
|
537
523
|
blockers: sourceFidelityReady
|
|
@@ -225,9 +225,9 @@ export function planTransitions(input) {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
if (!input.skipFinalize &&
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
(snapshot.lifecycleState === "run-succeeded" ||
|
|
229
|
+
(snapshot.latestRun?.lifecycle === "completed" &&
|
|
230
|
+
snapshot.latestRun.status === "finished"))) {
|
|
231
231
|
if (!snapshot.promotion?.ready) {
|
|
232
232
|
actions.push({ type: "promote" });
|
|
233
233
|
expectedTransitions.push("promotion-completed");
|
|
@@ -237,8 +237,7 @@ export function planTransitions(input) {
|
|
|
237
237
|
expectedTransitions.push("closeout-completed");
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
|
-
if (snapshot.lifecycleState === "evidence-closed"
|
|
241
|
-
!dagRefreshRequired && !shouldImportPrd) {
|
|
240
|
+
if (snapshot.lifecycleState === "evidence-closed") {
|
|
242
241
|
return {
|
|
243
242
|
actions: [{ type: "stop", reason: "terminal" }],
|
|
244
243
|
gate: null,
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.43.0-next.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.43.0-next.3",
|
|
4
|
+
"gitSha": "58353199a043d50d24063322a173d81b4b8f1d2f",
|
|
5
|
+
"builtAt": "2026-09-08T04:08:10.997Z"
|
|
6
6
|
}
|
|
@@ -18,7 +18,6 @@ export const BACKOFF_MS = [2000, 4000, 8000, 16000, 30000];
|
|
|
18
18
|
export const MAX_SESSION_RETRIES = 5;
|
|
19
19
|
/** Hard cap for OpenCode overflow compact+resume recoveries (≤ 2). */
|
|
20
20
|
export const MAX_OVERFLOW_RECOVERIES = 1;
|
|
21
|
-
import { buildGeneratedTransientProviderClassifierSource, classifyTransientProviderError, } from "../shared/pi-provider-recovery.js";
|
|
22
21
|
import { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY, } from "../shared/pi-retry-settings.js";
|
|
23
22
|
import { CONTEXT_OVERFLOW_PHRASES, buildGeneratedOverflowClassifierSource, isContextOverflow as classifySharedOverflow, } from "../shared/pi-context-pressure/overflow.js";
|
|
24
23
|
export { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY };
|
|
@@ -52,6 +51,17 @@ const PERMANENT_MESSAGE_PATTERNS = [
|
|
|
52
51
|
pattern: /\b(business validation|invalid task|schema validation)\b/i,
|
|
53
52
|
},
|
|
54
53
|
];
|
|
54
|
+
const TRANSIENT_MESSAGE_PATTERNS = [
|
|
55
|
+
/\bcode[:\s]*502\b/i,
|
|
56
|
+
/\b502\b/,
|
|
57
|
+
/\bLLMRequestError\b/i,
|
|
58
|
+
/\bnetwork fluctuation\b/i,
|
|
59
|
+
/\btimeout\b/i,
|
|
60
|
+
/\btransient provider failure\b/i,
|
|
61
|
+
/\bnon-standard (payload|response)\b/i,
|
|
62
|
+
/\bupstream returned\b/i,
|
|
63
|
+
/\bmodel processing timeout\b/i,
|
|
64
|
+
];
|
|
55
65
|
export function isClientRecoveryMode(value) {
|
|
56
66
|
return (typeof value === "string" &&
|
|
57
67
|
CLIENT_RECOVERY_MODES.includes(value));
|
|
@@ -162,16 +172,30 @@ export function isContextOverflow(error) {
|
|
|
162
172
|
return classifySharedOverflow(error);
|
|
163
173
|
}
|
|
164
174
|
function looksTransient(error) {
|
|
165
|
-
|
|
175
|
+
const text = collectErrorText(error);
|
|
176
|
+
if (TRANSIENT_MESSAGE_PATTERNS.some((pattern) => pattern.test(text)))
|
|
177
|
+
return true;
|
|
178
|
+
if (error && typeof error === "object") {
|
|
179
|
+
const record = error;
|
|
180
|
+
if (record.code === 502 || record.status === 502)
|
|
181
|
+
return true;
|
|
182
|
+
if (record.data && typeof record.data === "object") {
|
|
183
|
+
const data = record.data;
|
|
184
|
+
if (data.code === 502 || data.status === 502)
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
166
189
|
}
|
|
167
190
|
/**
|
|
168
191
|
* Decide whether an OpenCode error should be resumed by the project plugin.
|
|
169
|
-
*
|
|
170
|
-
* internal-provider fluctuation messages that built-in APIError retry misses.
|
|
192
|
+
* Only compensates transient UnknownError paths that built-in APIError retry misses.
|
|
171
193
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
194
|
+
* TypeValidation bypass: a bare TypeValidationError (provider/SDK surfaces
|
|
195
|
+
* zod invalid_union directly, without the UnknownError wrapper) is treated as
|
|
196
|
+
* a retryable transient-unknown-error ONLY when it also carries a transient
|
|
197
|
+
* signal (502 / LLMRequestError / timeout / etc.). A pure schema mismatch
|
|
198
|
+
* without a transient signal is still rejected (resumable: false).
|
|
175
199
|
*/
|
|
176
200
|
export function classifyTransientUnknownError(error) {
|
|
177
201
|
const permanent = permanentReason(error);
|
|
@@ -184,9 +208,6 @@ export function classifyTransientUnknownError(error) {
|
|
|
184
208
|
}
|
|
185
209
|
const isUnknownShape = hasUnknownErrorShape(error);
|
|
186
210
|
const isTypeValidationShape = hasTypeValidationShape(error);
|
|
187
|
-
if (looksTransient(error)) {
|
|
188
|
-
return { resumable: true, reason: "transient-unknown-error" };
|
|
189
|
-
}
|
|
190
211
|
if (!isUnknownShape && !isTypeValidationShape) {
|
|
191
212
|
return {
|
|
192
213
|
resumable: false,
|
|
@@ -194,11 +215,14 @@ export function classifyTransientUnknownError(error) {
|
|
|
194
215
|
interaction: PERMANENT_ERROR_INTERACTION,
|
|
195
216
|
};
|
|
196
217
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
218
|
+
if (!looksTransient(error)) {
|
|
219
|
+
return {
|
|
220
|
+
resumable: false,
|
|
221
|
+
reason: "unknown-non-transient",
|
|
222
|
+
interaction: PERMANENT_ERROR_INTERACTION,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return { resumable: true, reason: "transient-unknown-error" };
|
|
202
226
|
}
|
|
203
227
|
export function nextBackoffMs(attempt) {
|
|
204
228
|
if (!Number.isInteger(attempt) ||
|
|
@@ -454,9 +478,8 @@ export function buildOpenCodeTransientRetryPluginSource() {
|
|
|
454
478
|
* loop-agent OpenCode transient recovery plugin
|
|
455
479
|
* Path: ${OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH}
|
|
456
480
|
*
|
|
457
|
-
* Compensates
|
|
458
|
-
*
|
|
459
|
-
* APIError retry does not cover. Never runs concurrently with session.status === "retry".
|
|
481
|
+
* Compensates transient UnknownError cases that OpenCode built-in APIError
|
|
482
|
+
* retry does not cover. Never runs concurrently with session.status === "retry".
|
|
460
483
|
* Permanent failures use interaction "${PERMANENT_ERROR_INTERACTION}".
|
|
461
484
|
* User aborts (MessageAbortedError / cancel words) are silently cleared.
|
|
462
485
|
* Best-effort file log: ${OPENCODE_TRANSIENT_RETRY_LOG_PATH}.
|
|
@@ -479,7 +502,7 @@ const LOG_PATH = (() => {
|
|
|
479
502
|
const PERMANENT_INTERACTION = ${JSON.stringify(PERMANENT_ERROR_INTERACTION)};
|
|
480
503
|
const BACKOFF_MS = ${JSON.stringify([...BACKOFF_MS])};
|
|
481
504
|
const MAX_RETRIES = ${MAX_SESSION_RETRIES};
|
|
482
|
-
${
|
|
505
|
+
${buildGeneratedContextOverflowPatternSource()}
|
|
483
506
|
void logToFile("load ok");
|
|
484
507
|
|
|
485
508
|
const sessionState = new Map();
|
|
@@ -540,7 +563,19 @@ function isPermanent(error) {
|
|
|
540
563
|
|
|
541
564
|
function isTransientUnknown(error) {
|
|
542
565
|
if (isPermanent(error)) return false;
|
|
543
|
-
|
|
566
|
+
const text = textOf(error);
|
|
567
|
+
const hasUnknown = /UnknownError/i.test(text) || (error && /UnknownError/i.test(String(error.name || "")));
|
|
568
|
+
const hasTypeValidation =
|
|
569
|
+
/\\bTypeValidationError\\b/i.test(text) ||
|
|
570
|
+
/Type validation failed/i.test(text) ||
|
|
571
|
+
(error && /TypeValidationError/i.test(String(error.name || "")));
|
|
572
|
+
if (!hasUnknown && !hasTypeValidation) return false;
|
|
573
|
+
return (
|
|
574
|
+
/\\b(code[:\\s]*502|502|LLMRequestError|network fluctuation|timeout|transient provider failure|non-standard)\\b/i.test(
|
|
575
|
+
text,
|
|
576
|
+
) ||
|
|
577
|
+
(error && (error.code === 502 || error.status === 502))
|
|
578
|
+
);
|
|
544
579
|
}
|
|
545
580
|
|
|
546
581
|
function buildResumePrompt(sessionId, error, attempt) {
|