@tea-agent/loop-agent 0.36.4-beta.0 → 0.37.1-beta.0
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/AGENTS.md +2 -6
- package/CHANGELOG.md +72 -163
- package/README.md +1 -1
- package/bin/loop-agent.js +1 -37
- package/dist/application/task-lifecycle/advance.js +0 -1
- package/dist/application/task-lifecycle/observe.js +0 -15
- package/dist/application/task-lifecycle/plan-transitions.js +0 -15
- package/dist/cli/command-definitions.js +0 -7
- package/dist/cli/program.js +3 -8
- package/dist/commands/init-upgrade.js +19 -351
- package/dist/commands/init.js +67 -14
- package/dist/commands/run-dag-progress.js +0 -14
- package/dist/commands/task-advance.js +3 -33
- package/dist/executors/dag-pi-executor.js +30 -47
- package/dist/executors/pi-sdk-executor.js +0 -34
- package/dist/executors/shell-executor.js +95 -6
- package/dist/infrastructure/harness/atomic-write.js +1 -2
- package/dist/shared/operator/capabilities.js +13 -200
- package/dist/shared/package-metadata.js +0 -42
- package/dist/task/frontend-project-capability.js +12 -162
- package/dist/task/source-prepare/completeness.js +0 -17
- package/dist/task/source-prepare/parse-intent.js +1 -15
- package/dist/task/source-prepare/semantic-intake.js +23 -144
- package/dist/worker/console/chat/artifact-card.js +1 -8
- package/dist/worker/console/chat/chat-event-store.js +0 -61
- package/dist/worker/console/chat/human-gate-card.js +1 -9
- package/dist/worker/console/chat/operation-card.js +2 -71
- package/dist/worker/console/chat/pi-runtime.js +62 -86
- package/dist/worker/console/chat/routes.js +8 -36
- package/dist/worker/console/chat/session-store.js +0 -3
- package/dist/worker/console/chat/shortcuts.js +7 -9
- package/dist/worker/console/chat/turn-process.js +23 -97
- package/dist/worker/console/chat/workspace-landing.js +1 -2
- package/dist/worker/console/operation-runner.js +6 -155
- package/dist/worker/console/operator-actions.js +13 -373
- package/dist/worker/console/operator-user-error.js +0 -4
- package/dist/worker/console/recovery-cta.js +3 -50
- package/dist/worker/console/static/assets/index-HX1pbOyl.css +1 -0
- package/dist/worker/console/static/assets/index-M0BLEBfh.js +56 -0
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +9 -13
- package/dist/worker/console/static-src/app/useOperatorActions.js +2 -4
- package/dist/worker/console/static-src/app/useRecoveryActions.js +56 -65
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +1 -73
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +30 -89
- package/dist/worker/console/static-src/operator-chat/refs.js +0 -3
- package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +1 -2
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +11 -30
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +6 -12
- package/dist/worker/console/static-src/operator-chat/useComposer.js +8 -45
- package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +3 -7
- package/dist/worker/loop-agent/loop-agent-client.js +3 -17
- package/dist/worker/observability/read-model.js +0 -20
- package/dist/worker/observe/spec-evidence.js +8 -3
- package/dist/worker/observe/static/operator-chrome.d.ts +0 -1
- package/dist/worker/observe/static/operator-chrome.js +1 -6
- package/dist/worker/observe/static/views/dag-inspector.js +71 -6
- package/dist/worker/observe/static/views/dag.js +0 -12
- package/dist/worker/preflight.js +1 -2
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +707 -37
- package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +109 -7
- package/dist/workflows/dag/backend-test-module-stem.js +5 -0
- package/dist/workflows/dag/backend-test-pytest-collection.js +345 -24
- package/dist/workflows/dag/backend-test-scenario-param.js +890 -164
- package/dist/workflows/dag/backend-test-writer-completeness.js +47 -16
- package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
- package/dist/workflows/dag/dynamic-runtime/shared.js +1 -9
- package/dist/workflows/dag/failure-routing.js +4 -9
- package/dist/workflows/dag/frontend-implementation-contract.js +39 -233
- package/dist/workflows/dag/frontend-prewrite-gate.js +62 -394
- package/dist/workflows/dag/frontend-repair.js +18 -219
- package/dist/workflows/dag/frontend-verification-trace.js +32 -47
- package/dist/workflows/dag/init-hybrid.js +86 -238
- package/dist/workflows/dag/lifecycle.js +0 -4
- package/dist/workflows/dag/node-execution.js +6 -105
- package/dist/workflows/dag/recovery-recommendation.js +0 -58
- package/dist/workflows/dag/report.js +0 -6
- package/dist/workflows/dag/retry-policy.js +0 -11
- package/dist/workflows/dag/runner.js +12 -314
- package/dist/workflows/dag/scheduler.js +3 -257
- package/dist/workflows/dag/types.js +9 -132
- package/dist/workflows/dag/validate.js +2 -7
- package/docs/README.md +3 -3
- package/docs/architecture/evolution.md +67 -102
- package/docs/templates/backend-test-dag.json +50 -32
- package/docs/templates/frontend-design-contract.md +14 -34
- package/docs/templates/frontend-task-constraints.md +13 -33
- package/docs/templates/frontend-task-requirement.md +20 -54
- package/docs/templates/init-managed-agents.md +2 -5
- package/harness.json +2 -2
- package/package.json +3 -4
- package/skills/loop-agent/SKILL.md +0 -1
- package/skills/loop-agent/references/command-reference.md +0 -3
- package/dist/build-stamp.json +0 -6
- package/dist/commands/dag-request-interrupt.js +0 -20
- package/dist/worker/console/chat/assistant-content.js +0 -121
- package/dist/worker/console/chat/semantic-activity.js +0 -471
- package/dist/worker/console/operation-run-facts.js +0 -190
- package/dist/worker/console/operation-wait.js +0 -355
- package/dist/worker/console/recovery-error-copy.js +0 -198
- package/dist/worker/console/static/assets/index-D83DYAFG.css +0 -1
- package/dist/worker/console/static/assets/index-IXm7oYjL.js +0 -59
- package/dist/worker/console/static-src/operator-chat/activity-journey.js +0 -125
- package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +0 -73
- package/dist/worker/console/static-src/operator-chat/activity-references.js +0 -20
- package/dist/worker/console/static-src/operator-chat/slash-palette-layout.js +0 -24
- package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +0 -141
- package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +0 -59
- package/dist/worker/observability/interrupt-eligibility.js +0 -264
- package/dist/workflows/dag/contract-output-registry.js +0 -14
- package/dist/workflows/dag/contract-validator-registrations.js +0 -8
- package/dist/workflows/dag/frontend-recovery-plan.js +0 -73
- package/dist/workflows/dag/frontend-recovery-root-manifest.js +0 -123
- package/dist/workflows/dag/frontend-recovery-run.js +0 -539
- package/dist/workflows/dag/frontend-writer-recovery.js +0 -106
- package/dist/workflows/dag/frontend-writer-rollback.js +0 -821
- package/dist/workflows/dag/interrupt-request.js +0 -559
|
@@ -1,104 +1,70 @@
|
|
|
1
1
|
# 前端任务需求模板
|
|
2
2
|
|
|
3
|
-
本模板只承载**通用编写协议 + 三要素 + fail-closed 规则**,不包含任何具体业务组件名、项目专属路径或项目专属命令。填写时每一节都要给出「**要写什么** / **DAG 如何消费** / **缺失/冲突时 fail-closed**」三要素;缺节、空占位或与验收标准冲突时必须阻塞,不得由模型猜测补写。
|
|
4
|
-
|
|
5
3
|
## 用户目标
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
- **DAG 如何消费**:`frontend-contract-pi` 把它映射为 Scope 与 `requirements[].expectedOutcome`,`frontend-plan-pi` 据它安排实现步骤并映射验收标准。
|
|
9
|
-
- **缺失/冲突时 fail-closed**:缺失用户目标,或用户目标与验收标准互相矛盾时阻塞(`request-revision`/blocked),不得猜测补写或改写为技术实现描述。
|
|
5
|
+
TODO
|
|
10
6
|
|
|
11
7
|
## 目标页面/组件/路由
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
- **DAG 如何消费**:对齐 `docs/runtime/frontend-implementation-workflow.md` §「需求.md 应包含」的「目标路由/页面/组件」,`frontend-contract-pi` 据它确定 `targets.files` / `targets.routes`,`frontend-plan-pi` 据它划定 writeSet 与实现步骤。
|
|
15
|
-
- **缺失/冲突时 fail-closed**:无法确定目标路由/页面/组件,或范围与验收标准不一致时阻塞;只写泛化名词(如「页面」「组件」)而不给具体范围视为缺失。
|
|
9
|
+
TODO
|
|
16
10
|
|
|
17
11
|
## 用户流程
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
- **DAG 如何消费**:`frontend-contract-pi` 据它抽取 `interactions[]`(每条带 `trigger` 与 `expectedBehavior`),`frontend-plan-pi` 据它安排组件/状态/交互实现步骤。
|
|
21
|
-
- **缺失/冲突时 fail-closed**:缺少可执行的端到端路径、流程与验收标准冲突或关键分支未写时阻塞,不得只写「用户进入页面即可」。
|
|
13
|
+
TODO
|
|
22
14
|
|
|
23
15
|
## 必须状态
|
|
24
16
|
|
|
25
|
-
每个适用状态必须写清该状态的触发条件与预期界面表现;不适用状态必须写 `N/A` 并给出非空理由(对齐 runtime 的 `uiStates` / N/A state 规则)。
|
|
26
|
-
|
|
27
17
|
### loading
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
- **DAG 如何消费**:进入 implementation contract 的 `uiStates[]`(`name: "loading"`),`frontend-implement-pi` 按它实现,verify 用它的 `verificationTargetIds` 断言。
|
|
31
|
-
- **缺失/冲突时 fail-closed**:适用但缺失预期行为时阻塞;不适用必须写 `N/A` 并给非空理由,只写 `N/A` 不带理由同样阻塞。
|
|
19
|
+
TODO
|
|
32
20
|
|
|
33
21
|
### empty
|
|
34
22
|
|
|
35
|
-
|
|
36
|
-
- **DAG 如何消费**:进入 `uiStates[]`(`name: "empty"`),verify 断言空态展示与引导。
|
|
37
|
-
- **缺失/冲突时 fail-closed**:适用但缺失预期行为、或与 success/error 展示冲突时阻塞;不适用写 `N/A` + 非空理由。
|
|
23
|
+
TODO
|
|
38
24
|
|
|
39
25
|
### error
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
- **DAG 如何消费**:进入 `uiStates[]`(`name: "error"`),verify 断言错误展示与重试/回退行为。
|
|
43
|
-
- **缺失/冲突时 fail-closed**:适用但缺失错误预期、或错误态会覆盖用户数据时阻塞;不适用写 `N/A` + 非空理由。
|
|
27
|
+
TODO
|
|
44
28
|
|
|
45
29
|
### success
|
|
46
30
|
|
|
47
|
-
|
|
48
|
-
- **DAG 如何消费**:进入 `uiStates[]`(`name: "success"`),verify 断言成功展示与验收标准对应。
|
|
49
|
-
- **缺失/冲突时 fail-closed**:成功态与验收标准不一致、或缺失成功结果时阻塞;不适用写 `N/A` + 非空理由。
|
|
31
|
+
TODO
|
|
50
32
|
|
|
51
33
|
### disabled
|
|
52
34
|
|
|
53
|
-
|
|
54
|
-
- **DAG 如何消费**:进入 `uiStates[]`(`name: "disabled"`),verify 断言禁用态不会被误触。
|
|
55
|
-
- **缺失/冲突时 fail-closed**:适用但缺失禁用条件、或禁用态与交互要求冲突时阻塞;不适用写 `N/A` + 非空理由。
|
|
35
|
+
TODO
|
|
56
36
|
|
|
57
37
|
## 目标运行环境
|
|
58
38
|
|
|
59
|
-
每个环境必须声明适用性;不适用环境写 `N/A` 并给非空理由。
|
|
60
|
-
|
|
61
39
|
### desktop
|
|
62
40
|
|
|
63
|
-
|
|
64
|
-
- **DAG 如何消费**:进入 contract 的 target runtime environment,`frontend-plan-pi` 据它决定响应式范围与样式策略。
|
|
65
|
-
- **缺失/冲突时 fail-closed**:适用但缺失断点/布局说明,或与响应式要求冲突时阻塞;不适用写 `N/A` + 非空理由。
|
|
41
|
+
TODO
|
|
66
42
|
|
|
67
43
|
### mobile
|
|
68
44
|
|
|
69
|
-
|
|
70
|
-
- **DAG 如何消费**:进入 target runtime environment,`frontend-plan-pi` 据它决定响应式范围与组件策略。
|
|
71
|
-
- **缺失/冲突时 fail-closed**:适用但缺失移动端表现,或与交互要求冲突时阻塞;不适用写 `N/A` + 非空理由。
|
|
45
|
+
TODO
|
|
72
46
|
|
|
73
47
|
### tablet
|
|
74
48
|
|
|
75
|
-
|
|
76
|
-
- **DAG 如何消费**:进入 target runtime environment,`frontend-plan-pi` 据它决定响应式策略。
|
|
77
|
-
- **缺失/冲突时 fail-closed**:适用但缺失 tablet 表现时阻塞;不适用写 `N/A` + 非空理由。
|
|
49
|
+
TODO
|
|
78
50
|
|
|
79
51
|
## 交互要求
|
|
80
52
|
|
|
81
|
-
|
|
82
|
-
- **DAG 如何消费**:对齐 §「需求.md 应包含」的「交互要求」,`frontend-contract-pi` 抽取 `interactions[]`(`trigger` + `expectedBehavior`),verify 用行为命令断言。
|
|
83
|
-
- **缺失/冲突时 fail-closed**:交互触发或预期行为缺失、与 UI 状态冲突、或不可自动化断言时阻塞,不得用「用户可正常操作」这类空话。
|
|
53
|
+
TODO
|
|
84
54
|
|
|
85
55
|
## 接口与 Mock 输入
|
|
86
56
|
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
57
|
+
- 接口文档/schema:TODO
|
|
58
|
+
- endpoint、method、关键请求/响应字段:TODO
|
|
59
|
+
- 是否允许依赖真实后端:TODO
|
|
60
|
+
- 是否要求离线或独立行为验证:TODO
|
|
61
|
+
- success/empty/error/permission 状态:TODO
|
|
62
|
+
- 后端当前就绪状态与 Real Integration Gap:TODO
|
|
93
63
|
|
|
94
64
|
## 验收标准
|
|
95
65
|
|
|
96
|
-
|
|
97
|
-
- **DAG 如何消费**:`frontend-contract-pi` 生成 `requirements[].verificationTargetIds` 映射,`frontend-plan-pi` 把每条 AC 落到有序步骤与验证命令,verify 逐条断言。
|
|
98
|
-
- **缺失/冲突时 fail-closed**:无验收标准、AC 无法映射到需求/验证目标、或 AC 与其它节冲突时阻塞,不得把「看起来能用」当验收。
|
|
66
|
+
TODO
|
|
99
67
|
|
|
100
68
|
## 非目标
|
|
101
69
|
|
|
102
|
-
|
|
103
|
-
- **DAG 如何消费**:`frontend-contract-pi` 记录为 Non-goals,`frontend-review-pi` 据它拒绝范围扩散。
|
|
104
|
-
- **缺失/冲突时 fail-closed**:非目标与目标/验收标准冲突、或范围被悄悄扩大时阻塞;明确不做前端时也必须写入非目标。
|
|
70
|
+
TODO
|
|
@@ -33,8 +33,7 @@
|
|
|
33
33
|
| **允许** | 已发布 `loop-agent` / `agent-worker` CLI;只读 status/doctor/report/inspect/observe;准备 `source/*` 与 `task.json` 边界;human gate;shell 验证与 handoff。 |
|
|
34
34
|
| **禁止** | 绕过 CLI 用宿主 Edit/Write/ApplyPatch 直接改业务实现;CLI/DAG 失败后「救火改文件」;用聊天自述代替 shell 验证。 |
|
|
35
35
|
| **失败时** | 先 `dag report` / `dag doctor`;优先 `dag rerun --from-node` 安全子图续跑;仅契约/源真变或 plan 不合格时同 task 重 advance / `dag rerun-task`;paused 用 approve→`dag resume`。 |
|
|
36
|
-
| **实现写入** | 业务代码 **只** 经受治理 DAG writer(`implement-pi` / `repair-pi`)经 `task advance`(批准 writeSet gate
|
|
37
|
-
| **契约漂移** | 直接编辑 `source/需求.md` / `执行约束.md` 后契约会进入 `externally-modified`,此时 advance/dagRunTask 拒用新内容(DIRTY_SOURCE / hash 不一致)。合法收编路径:`task contract adopt --task <id> --expected-revision <n> --expected-observed-hash <hash> --request-id <id> --request-payload-sha256 <sha>`(hash 从 `task status --json` 的 `contract.observedCanonicalHash` 取);或改 PRD 后重新 importPrd 走完整重投影。禁止手工改 `lifecycle.json` / `.transactions/` 绕过。 |
|
|
36
|
+
| **实现写入** | 业务代码 **只** 经受治理 DAG writer(`implement-pi` / `repair-pi`)经 `task advance`(批准 writeSet gate 后长跑)。 |
|
|
38
37
|
|
|
39
38
|
**永远不要**:`loop-agent` / `agent-worker` 失败 ⇒ 主会话直接改仓库实现;也勿因 provider 抖动或只读节点失败**新建无关 task-id**。
|
|
40
39
|
|
|
@@ -110,8 +109,6 @@ loop-agent task status <task-id> --json
|
|
|
110
109
|
# 有 plan 时收尾:loop-agent plan complete <plan-id> --summary "..."
|
|
111
110
|
```
|
|
112
111
|
|
|
113
|
-
长跑 DAG 采用 `prepareDagExecution → runDag → operationId` 异步 operation 路径(`--approve-gate` 不在前台 Bash 中同步等待);监督退避 60 → 90 → 120 → 180 秒,状态变化后重置为 60 秒,疑似 stall 用 30–60 秒复查。
|
|
114
|
-
|
|
115
112
|
`--verify` 命令应取项目 `AGENTS.md` / `__LOOP_AGENT_GOVERNANCE_ROOT__/verification-matrix.md` 登记的验证命令(不要假定 `npm run typecheck` 存在);`--verify` 可选,省略时自动从 package.json scripts 或既有 managed `task.json.verifyCommands` 推导建议。
|
|
116
113
|
|
|
117
114
|
`source/需求.md` 与 `source/执行约束.md` 仍必需(M8/M9),但默认由 `task advance --prd` 投影生成,而不是主会话手写。`plan create` 不是 `task advance` 的硬依赖。写入前同步 `task.json.allowedPaths` / `task.json.forbiddenPaths` 并审查 writer `writeSet`。高级任意 DagSpec 才用 `dag validate|execute|report`,不进入标准 happy path。
|
|
@@ -142,7 +139,7 @@ live run 先用 `loop-agent dag status --run-id <run-id>` 看 lifecycle 与 live
|
|
|
142
139
|
|
|
143
140
|
**失败默认恢复序**:`dag report`/`dag doctor` → 优先 `dag rerun --from-node <node> --plan` 再带 `--plan-hash`(provider 抖动、plan/review/verify 安全下游;writer/decision/fingerprint 不合格勿硬跑)→ paused:approve→`dag resume` → 契约/源真变或 R1 不合格:同 task `task advance` / `dag rerun-task`(禁无理由新建 task-id)→ Worker-owned:`agent-worker task retry`。
|
|
144
141
|
|
|
145
|
-
Operator 须监控 live run 至终态(FINISHED / FAILED / partial_failed)或 Decision Gate 需要 approve
|
|
142
|
+
Operator 须监控 live run 至终态(FINISHED / FAILED / partial_failed)或 Decision Gate 需要 approve;可在节点/rank 变化、verify/closeout、stall 或需 approve 时简短汇报(告知非请求确认)。判活须组合 runner heartbeat、session events 与 `dag doctor` liveness/provider meaningful progress(heartbeat alone ≠ progress)。bounded writer 运行期间不得并发修改工作区(write guard / write-guard 会把越界 diff 错误归因到 writer);只读 status/doctor/report 与 approve/reject/resume 仍允许。恢复:report/doctor → **优先** `dag rerun --from-node` → 必要时 rerun-task/同 task advance → shell verify。**禁止**把主会话直接 Edit 业务代码当作恢复手段。
|
|
146
143
|
|
|
147
144
|
### 运行态与验证
|
|
148
145
|
|
package/harness.json
CHANGED
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
},
|
|
80
80
|
"executors": {
|
|
81
81
|
"pi": {
|
|
82
|
-
"description": "Pi 负责规划、评审、诊断;当 DAG toolProfile=write
|
|
82
|
+
"description": "Pi 负责规划、评审、诊断;当 DAG toolProfile=write 时也可做有界写入。模型按复杂度三档配置,格式为 provider/model 字符串(例:wizard-local/grok-4.5);斜杠前为 Pi provider,后为 modelId,勿只写裸 modelId。",
|
|
83
83
|
"LOW": "wizard-local/minimax-m3",
|
|
84
|
-
"MED": "wizard-local/grok-4.
|
|
84
|
+
"MED": "wizard-local/grok-4.5",
|
|
85
85
|
"HIGH": "wizard-local/gpt-5.6-sol"
|
|
86
86
|
}
|
|
87
87
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tea-agent/loop-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.1-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"loop-agent": "bin/loop-agent.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"pi-prompt": "node --import tsx/esm src/cli.ts pi-prompt",
|
|
46
46
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
47
47
|
"brand:sync": "node scripts/sync-brand-assets.mjs",
|
|
48
|
-
"build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build
|
|
48
|
+
"build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build",
|
|
49
49
|
"console:typecheck": "tsc -p src/worker/console/tsconfig.json",
|
|
50
50
|
"console:build": "npm run console:typecheck && vite build --config src/worker/console/vite.config.ts",
|
|
51
51
|
"prepack": "npm run build",
|
|
@@ -88,6 +88,5 @@
|
|
|
88
88
|
"typescript": "^5.9.3",
|
|
89
89
|
"vite": "^7.0.0",
|
|
90
90
|
"vitest": "^3.2.4"
|
|
91
|
-
}
|
|
92
|
-
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
|
|
91
|
+
}
|
|
93
92
|
}
|
|
@@ -24,7 +24,6 @@ references:
|
|
|
24
24
|
## 初始化升级路由
|
|
25
25
|
|
|
26
26
|
- 写入型「**loop-agent初始化更新**」「loop-agent 初始化更新」「更新 loop-agent 初始化内容」「升级后对齐」统一运行 `loop-agent init upgrade --repo-root . --json`;处理 controller 返回的单文件 `allowedPaths`,以同一 run `--continue` 推进至终态,不停在中间状态。
|
|
27
|
-
- 升级可能因 gitignore 迁移评估暂停:若 `.agents/` 存在已跟踪内容,需先审查是否有应团队共享的自定义内容;存在 staged 变更或 git 查询失败时需先解决 blocker,再重跑评估。建议的 `git rm -r --cached --ignore-unmatch` 只修改 index、保留工作区文件,且由用户执行而非 controller。
|
|
28
27
|
- 「检查初始化更新」「初始化更新校验」「只检查,不要修改」仅运行 `loop-agent init check-update --repo-root . --markdown`,不得创建 run 或写入。
|
|
29
28
|
- facts 位于 `.harness/init-upgrades/<run-id>/`;禁止业务源码和宽泛 glob。默认管理项目 `.opencode/plugins/`、`.pi/extensions/`、`.pi/settings.json`;Pi trust 后加载,默认不读写 `~/.pi/agent/settings.json`。
|
|
30
29
|
|
|
@@ -152,8 +152,6 @@ fresh init 将精确引用写到 `executors.pi.LOW/MED/HIGH`。fresh `loop-agent
|
|
|
152
152
|
|
|
153
153
|
`init upgrade` 是写入型升级入口:首次运行冻结 controller identity、检查 npm latest、扫描 surface、自动执行安全动作,并把 run facts 持久化到 `.harness/init-upgrades/<run-id>/`。`--status` 与 `--report` 严格只读;`--continue` 会重新核验 identity、当前 hash 与不变量。版本选择、无法判定冲突、凭据、破坏性删除或 active writer 才进入 human decision。普通语义冲突返回具体单文件 `allowedPaths` merge task,主会话必须合并后继续,不能把 `needs-model-merge` 作为完成。默认管理项目级 OpenCode/Pi recovery 与 `.pi/settings.json` nested merge,保留显式 disabled,Pi trust 后才加载;默认不读写 `~/.pi/agent/settings.json`。旧 `init reconcile` 保留为兼容低层诊断。
|
|
154
154
|
|
|
155
|
-
升级在 managed block 收敛后生成只读 gitignore 迁移评估(`.harness/init-upgrades/<run-id>/gitignore-migration.json`):inventory 已跟踪的 `.harness/**` 与 `.agents/**`,建议 index-only 命令 `git rm -r --cached --ignore-unmatch .harness` / `.agents`(只改 index、保留工作区文件;`scripts/**` 与 `ai_workspace/loop-agent/**` 永不出现)。`.agents` 已跟踪内容会触发 human-decision 暂停等待审查;非 Git 仓库、git 查询失败或存在 staged 条目时 `status: blocked` 且无命令建议。controller 不自动修改 Git index。
|
|
156
|
-
|
|
157
155
|
### 查看或复制内置示例
|
|
158
156
|
|
|
159
157
|
```bash
|
|
@@ -321,7 +319,6 @@ loop-agent dag report [--run-id <run-id>] [--lifecycle active|paused|completed|a
|
|
|
321
319
|
loop-agent dag reconcile-run --run-id <run-id> # 只读检查 effectiveStatus 与恢复/收口资格
|
|
322
320
|
loop-agent dag reconcile-run --run-id <run-id> --action supersede --reason "..." # 显式保留证据并标记为任务已另行完成
|
|
323
321
|
loop-agent dag reconcile-run --run-id <run-id> --action abandon --reason "..." # 显式保留证据并收口为已放弃
|
|
324
|
-
loop-agent dag request-interrupt --run-id <run-id> --request-id <id> --target-operation-id <id> --reason-code <code> --reason <detail> [--json] # 协作中止:写入 interrupt.json(identity CAS);需配 --expected-runner-pid/--expected-runner-hostname 校验 runner 身份
|
|
325
322
|
loop-agent dag rerun --run-id <run-id> --from-node <node-id> --plan [--json] # 从节点重跑资格预检(不执行)
|
|
326
323
|
loop-agent dag rerun --run-id <run-id> --from-node <node-id> --plan-hash <sha256> --request-id <key> --reason "..." [--json] # 安全子图 continuation
|
|
327
324
|
loop-agent dag rerun-task --run-id <run-id> --reason "..." --request-id <key> [--profile auto] [--task-id <id>] [--json] # standalone 完整任务重跑
|
package/dist/build-stamp.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { DagInterruptError, executeDagRequestInterrupt, parseDagRequestInterruptArgs, } from "../workflows/dag/interrupt-request.js";
|
|
2
|
-
export { parseDagRequestInterruptArgs, executeDagRequestInterrupt };
|
|
3
|
-
export async function runDagRequestInterrupt(repoRoot, rawArgs) {
|
|
4
|
-
try {
|
|
5
|
-
const result = await executeDagRequestInterrupt(repoRoot, rawArgs);
|
|
6
|
-
console.log(JSON.stringify(result, null, 2));
|
|
7
|
-
}
|
|
8
|
-
catch (error) {
|
|
9
|
-
if (error instanceof DagInterruptError) {
|
|
10
|
-
console.log(JSON.stringify({
|
|
11
|
-
ok: false,
|
|
12
|
-
code: error.code,
|
|
13
|
-
message: error.message,
|
|
14
|
-
}, null, 2));
|
|
15
|
-
process.exitCode = 1;
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
throw error;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Assistant content-block helpers shared by Pi event mapping and Operator Chat UI.
|
|
3
|
-
* Mirrors pi-web `lib/message-display.ts` (process vs answer split) without deferred fetch.
|
|
4
|
-
*/
|
|
5
|
-
function asRecord(value) {
|
|
6
|
-
if (!value || typeof value !== "object")
|
|
7
|
-
return undefined;
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
function readString(value) {
|
|
11
|
-
return typeof value === "string" ? value : undefined;
|
|
12
|
-
}
|
|
13
|
-
/** Parse a persisted/SSE content array; unknown shapes are dropped. */
|
|
14
|
-
export function parseAssistantContent(value) {
|
|
15
|
-
if (!Array.isArray(value))
|
|
16
|
-
return undefined;
|
|
17
|
-
const blocks = [];
|
|
18
|
-
for (const item of value) {
|
|
19
|
-
const rec = asRecord(item);
|
|
20
|
-
if (!rec)
|
|
21
|
-
continue;
|
|
22
|
-
const type = readString(rec.type) ?? "";
|
|
23
|
-
if (type === "thinking" || type === "reasoning") {
|
|
24
|
-
const thinking = readString(rec.thinking) ?? readString(rec.text) ?? "";
|
|
25
|
-
blocks.push({ type: "thinking", thinking });
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
if (type === "toolCall" ||
|
|
29
|
-
type === "tool_call" ||
|
|
30
|
-
type === "toolUse" ||
|
|
31
|
-
type === "tool_use") {
|
|
32
|
-
const toolCallId = readString(rec.toolCallId) ?? readString(rec.id) ?? "";
|
|
33
|
-
if (!toolCallId)
|
|
34
|
-
continue;
|
|
35
|
-
const toolName = readString(rec.toolName) ?? readString(rec.name);
|
|
36
|
-
blocks.push({
|
|
37
|
-
type: "toolCall",
|
|
38
|
-
toolCallId,
|
|
39
|
-
...(toolName ? { toolName } : {}),
|
|
40
|
-
});
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (type === "text" || type === "output_text" || type === "") {
|
|
44
|
-
const text = readString(rec.text);
|
|
45
|
-
if (text !== undefined)
|
|
46
|
-
blocks.push({ type: "text", text });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return blocks;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Extract ordered assistant content blocks from a Pi SDK message object.
|
|
53
|
-
* Thinking/reasoning blocks keep their own type so they never leak into answer text.
|
|
54
|
-
*/
|
|
55
|
-
export function extractAssistantContentBlocks(message) {
|
|
56
|
-
const rec = asRecord(message);
|
|
57
|
-
if (!rec)
|
|
58
|
-
return [];
|
|
59
|
-
const contents = Array.isArray(rec.content) ? rec.content : [];
|
|
60
|
-
const parts = Array.isArray(rec.parts) ? rec.parts : [];
|
|
61
|
-
const fromArrays = parseAssistantContent([...contents, ...parts]) ?? [];
|
|
62
|
-
if (fromArrays.length > 0)
|
|
63
|
-
return fromArrays;
|
|
64
|
-
const top = readString(rec.text);
|
|
65
|
-
return top ? [{ type: "text", text: top }] : [];
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Pi emits message_end for user / toolResult / custom too. Only assistant
|
|
69
|
-
* payloads belong in the Operator Chat assistant bubble (pi-web same split).
|
|
70
|
-
*/
|
|
71
|
-
export function isAssistantSdkMessage(message) {
|
|
72
|
-
const rec = asRecord(message);
|
|
73
|
-
if (!rec)
|
|
74
|
-
return false;
|
|
75
|
-
const role = readString(rec.role);
|
|
76
|
-
return role === undefined || role === "assistant";
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Latest assistant answer text (text blocks only). Thinking is excluded.
|
|
80
|
-
* Preserves the historical `{ text }` / `{ parts: [{ text }] }` fallbacks.
|
|
81
|
-
*/
|
|
82
|
-
export function extractAssistantText(message) {
|
|
83
|
-
return extractAssistantContentBlocks(message)
|
|
84
|
-
.filter((block) => block.type === "text")
|
|
85
|
-
.map((block) => block.text)
|
|
86
|
-
.join("");
|
|
87
|
-
}
|
|
88
|
-
export function isEmptyThinkingBlock(block, options = {}) {
|
|
89
|
-
return (block.type === "thinking" &&
|
|
90
|
-
!options.isStreaming &&
|
|
91
|
-
block.thinking.trim() === "");
|
|
92
|
-
}
|
|
93
|
-
export function getDisplayableAssistantBlocks(blocks, options = {}) {
|
|
94
|
-
return blocks.filter((block) => !isEmptyThinkingBlock(block, options));
|
|
95
|
-
}
|
|
96
|
-
function isFinalAnswerBlock(block) {
|
|
97
|
-
return block.type === "text";
|
|
98
|
-
}
|
|
99
|
-
export function splitFinalAssistantBlocks(blocks, options = {}) {
|
|
100
|
-
const displayable = getDisplayableAssistantBlocks(blocks, options);
|
|
101
|
-
let lastProcessIndex = -1;
|
|
102
|
-
for (let i = displayable.length - 1; i >= 0; i--) {
|
|
103
|
-
if (!isFinalAnswerBlock(displayable[i])) {
|
|
104
|
-
lastProcessIndex = i;
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (lastProcessIndex === -1) {
|
|
109
|
-
return { answerBlocks: displayable, processBlocks: [] };
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
answerBlocks: displayable.slice(lastProcessIndex + 1),
|
|
113
|
-
processBlocks: displayable.slice(0, lastProcessIndex + 1),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
export function joinAssistantText(blocks) {
|
|
117
|
-
return blocks
|
|
118
|
-
.filter((block) => block.type === "text")
|
|
119
|
-
.map((block) => block.text)
|
|
120
|
-
.join("");
|
|
121
|
-
}
|