pi-harness-runtime 1.1.49 → 1.1.71-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 +30 -9
- package/README.md +119 -0
- package/harness/langchain/agents.d.ts +143 -0
- package/harness/langchain/agents.test.d.ts +2 -0
- package/harness/langchain/agents.test.ts +0 -1
- package/harness/langchain/agents.ts +196 -13
- package/harness/langchain/checkpointer.d.ts +48 -0
- package/harness/langchain/checkpointer.test.d.ts +8 -0
- package/harness/langchain/cron-cli.d.ts +12 -0
- package/harness/langchain/cron-cli.ts +169 -0
- package/harness/langchain/daemon.d.ts +161 -0
- package/harness/langchain/daemon.test.d.ts +11 -0
- package/harness/langchain/daemon.test.ts +62 -5
- package/harness/langchain/daemon.ts +231 -12
- package/harness/langchain/file-tools.d.ts +97 -0
- package/harness/langchain/file-tools.ts +29 -11
- package/harness/langchain/graph.d.ts +706 -0
- package/harness/langchain/graph.ts +184 -26
- package/harness/langchain/model-router.d.ts +63 -0
- package/harness/langchain/model-router.test.d.ts +2 -0
- package/harness/langchain/model-router.test.ts +191 -0
- package/harness/langchain/model-router.ts +188 -0
- package/harness/langchain/models.d.ts +72 -0
- package/harness/langchain/models.ts +111 -49
- package/harness/langchain/ping-pong-middleware.d.ts +28 -0
- package/harness/langchain/ping-pong-middleware.test.d.ts +2 -0
- package/harness/langchain/ping-pong-middleware.test.ts +69 -0
- package/harness/langchain/ping-pong-middleware.ts +204 -0
- package/harness/langchain/run.d.ts +15 -0
- package/harness/langchain/run.ts +15 -3
- package/harness/langchain/scoreboard.test.d.ts +13 -0
- package/harness/langchain/scoreboard.test.ts +28 -5
- package/harness/langchain/status-line.d.ts +91 -0
- package/harness/langchain/status-line.test.d.ts +8 -0
- package/harness/langchain/surge.d.ts +103 -0
- package/harness/langchain/surge.test.d.ts +10 -0
- package/harness/langchain/surge.test.ts +179 -0
- package/harness/langchain/surge.ts +188 -19
- package/harness/langchain/widget.d.ts +105 -0
- package/harness/langchain/widget.test.d.ts +8 -0
- package/harness/ssh-detach-interceptor.test.ts +263 -0
- package/harness/ssh-detach-interceptor.ts +438 -0
- package/index.ts +212 -47
- package/package.json +4 -2
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/dist/src/index.d.ts +2 -0
- package/packages/intent-analyzer/dist/src/index.d.ts.map +1 -1
- package/packages/intent-analyzer/dist/src/index.js +1 -0
- package/packages/intent-analyzer/dist/src/index.js.map +1 -1
- package/packages/intent-analyzer/dist/src/ping-pong.d.ts +56 -0
- package/packages/intent-analyzer/dist/src/ping-pong.d.ts.map +1 -0
- package/packages/intent-analyzer/dist/src/ping-pong.js +286 -0
- package/packages/intent-analyzer/dist/src/ping-pong.js.map +1 -0
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/intent-analyzer/src/index.ts +13 -0
- package/packages/intent-analyzer/src/ping-pong.ts +387 -0
- package/packages/intent-analyzer/test/ping-pong.test.ts +96 -0
- package/packages/jev-judge/README.md +234 -0
- package/packages/jev-judge/dist/decision-engine.d.ts +100 -0
- package/packages/jev-judge/dist/decision-engine.d.ts.map +1 -0
- package/packages/jev-judge/dist/decision-engine.js +151 -0
- package/packages/jev-judge/dist/decision-engine.js.map +1 -0
- package/packages/jev-judge/dist/e2e-judge.d.ts +61 -0
- package/packages/jev-judge/dist/e2e-judge.d.ts.map +1 -0
- package/packages/jev-judge/dist/e2e-judge.js +268 -0
- package/packages/jev-judge/dist/e2e-judge.js.map +1 -0
- package/packages/jev-judge/dist/flaky-detector.d.ts +34 -0
- package/packages/jev-judge/dist/flaky-detector.d.ts.map +1 -0
- package/packages/jev-judge/dist/flaky-detector.js +154 -0
- package/packages/jev-judge/dist/flaky-detector.js.map +1 -0
- package/packages/jev-judge/dist/index.d.ts +77 -0
- package/packages/jev-judge/dist/index.d.ts.map +1 -0
- package/packages/jev-judge/dist/index.js +271 -0
- package/packages/jev-judge/dist/index.js.map +1 -0
- package/packages/jev-judge/dist/types.d.ts +97 -0
- package/packages/jev-judge/dist/types.d.ts.map +1 -0
- package/packages/jev-judge/dist/types.js +8 -0
- package/packages/jev-judge/dist/types.js.map +1 -0
- package/packages/jev-judge/package.json +46 -0
- package/packages/jev-judge/src/decision-engine.ts +231 -0
- package/packages/jev-judge/src/e2e-judge.ts +364 -0
- package/packages/jev-judge/src/flaky-detector.ts +190 -0
- package/packages/jev-judge/src/index.ts +345 -0
- package/packages/jev-judge/src/types.ts +131 -0
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/README.md +71 -0
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/todo-bd-sync/src/extension.ts +16 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/dist/src/approved-patterns.d.ts +51 -0
- package/packages/trajectory/dist/src/approved-patterns.d.ts.map +1 -0
- package/packages/trajectory/dist/src/approved-patterns.js +134 -0
- package/packages/trajectory/dist/src/approved-patterns.js.map +1 -0
- package/packages/trajectory/dist/src/index.d.ts +13 -0
- package/packages/trajectory/dist/src/index.d.ts.map +1 -0
- package/packages/trajectory/dist/src/index.js +12 -0
- package/packages/trajectory/dist/src/index.js.map +1 -0
- package/packages/trajectory/dist/src/store.d.ts +69 -0
- package/packages/trajectory/dist/src/store.d.ts.map +1 -0
- package/packages/trajectory/dist/src/store.js +253 -0
- package/packages/trajectory/dist/src/store.js.map +1 -0
- package/packages/trajectory/dist/src/types.d.ts +73 -0
- package/packages/trajectory/dist/src/types.d.ts.map +1 -0
- package/packages/trajectory/dist/src/types.js +9 -0
- package/packages/trajectory/dist/src/types.js.map +1 -0
- package/packages/trajectory/dist/test/store.test.d.ts +2 -0
- package/packages/trajectory/dist/test/store.test.d.ts.map +1 -0
- package/packages/trajectory/dist/test/store.test.js +228 -0
- package/packages/trajectory/dist/test/store.test.js.map +1 -0
- package/packages/trajectory/package.json +29 -0
- package/packages/trajectory/src/approved-patterns.ts +180 -0
- package/packages/trajectory/src/index.ts +26 -0
- package/packages/trajectory/src/store.ts +285 -0
- package/packages/trajectory/src/types.ts +84 -0
- package/packages/trajectory/test/store.test.d.ts +2 -0
- package/packages/trajectory/test/store.test.ts +250 -0
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/packages/write-review/src/blackboard.ts +38 -5
- package/packages/write-review/src/types.ts +13 -0
- package/skills/harness-runtime/SKILL.md +67 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,60 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
### [1.1.
|
|
5
|
+
### [1.1.71-1](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.69...v1.1.71-1) (2026-09-19)
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* add jev-judge package for structured decision making ([810a6d8](https://github.com/ManotLuijiu/pi-harness-runtime/commit/810a6d81ae5803d28a471a3cd059197e953c9707))
|
|
11
|
+
|
|
12
|
+
### [1.1.71-0](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.69...v1.1.71-0) (2026-09-19)
|
|
13
|
+
|
|
14
|
+
### [1.1.70](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.69...v1.1.70) (2026-09-19)
|
|
15
|
+
|
|
16
|
+
### [1.1.69](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.68...v1.1.69) (2026-09-14)
|
|
17
|
+
|
|
18
|
+
### [1.1.68](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.76...v1.1.68) (2026-09-14)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **interceptor:** guard foreground daemon-over-SSH hangs with timeout ([57770b5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/57770b5f477d9885836cc1b0dddee612a5c55d18))
|
|
24
|
+
|
|
25
|
+
### [1.1.19](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.61...v1.1.19) (2026-09-10)
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
* add ping-pong intent middleware ([c2b4f4b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/c2b4f4b86fdd22c151dd1dee1cab5fa3dbcfdcd5))
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* improve langchain daemon and surge test ([42245b4](https://github.com/ManotLuijiu/pi-harness-runtime/commit/42245b4364c3516c70df82fedbfe63e1b0cadd8e))
|
|
34
|
+
|
|
35
|
+
### [1.1.18](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.18) (2026-08-24)
|
|
36
|
+
|
|
8
37
|
### Features
|
|
9
38
|
|
|
10
39
|
* **glm-quota:** add robust GLM quota countdown with auto-resume ([cb78a2b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/cb78a2bdf5ecf79fc028030d43e3ce40767253cb))
|
|
11
40
|
* **glm:** add structured logging for GLM quota events ([09e692e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/09e692ec17b9c21a448c72f081d18fb35b8636ae))
|
|
12
41
|
|
|
13
|
-
|
|
14
42
|
### Bug Fixes
|
|
15
43
|
|
|
16
44
|
* **glm:** improve footer status display with specific 5h quota and reset time ([ab991c3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ab991c329bdb4097e77503d3d7f574edc6cdc1c4))
|
|
17
45
|
|
|
18
46
|
### [1.1.17](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.17) (2026-08-24)
|
|
19
47
|
|
|
20
|
-
|
|
21
48
|
### Features
|
|
22
49
|
|
|
23
50
|
* **glm-quota:** add robust GLM quota countdown with auto-resume ([cb78a2b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/cb78a2bdf5ecf79fc028030d43e3ce40767253cb))
|
|
24
51
|
* **glm:** add structured logging for GLM quota events ([09e692e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/09e692ec17b9c21a448c72f081d18fb35b8636ae))
|
|
25
52
|
|
|
26
|
-
|
|
27
53
|
### Bug Fixes
|
|
28
54
|
|
|
29
55
|
* **glm:** improve footer status display with specific 5h quota and reset time ([ab991c3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ab991c329bdb4097e77503d3d7f574edc6cdc1c4))
|
|
30
56
|
|
|
31
57
|
### [1.1.16](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.16) (2026-08-24)
|
|
32
58
|
|
|
33
|
-
|
|
34
59
|
### Features
|
|
35
60
|
|
|
36
61
|
* **glm-quota:** add robust GLM quota countdown with auto-resume ([cb78a2b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/cb78a2bdf5ecf79fc028030d43e3ce40767253cb))
|
|
37
62
|
* **glm:** add structured logging for GLM quota events ([09e692e](https://github.com/ManotLuijiu/pi-harness-runtime/commit/09e692ec17b9c21a448c72f081d18fb35b8636ae))
|
|
38
63
|
|
|
39
|
-
|
|
40
64
|
### Bug Fixes
|
|
41
65
|
|
|
42
66
|
* **glm:** improve footer status display with specific 5h quota and reset time ([ab991c3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ab991c329bdb4097e77503d3d7f574edc6cdc1c4))
|
|
43
67
|
|
|
44
68
|
### [1.1.15](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.15) (2026-08-24)
|
|
45
69
|
|
|
46
|
-
|
|
47
70
|
### Features
|
|
48
71
|
|
|
49
72
|
* **glm-quota:** add robust GLM quota countdown with auto-resume ([cb78a2b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/cb78a2bdf5ecf79fc028030d43e3ce40767253cb))
|
|
50
73
|
|
|
51
|
-
|
|
52
74
|
### Bug Fixes
|
|
53
75
|
|
|
54
76
|
* **glm:** improve footer status display with specific 5h quota and reset time ([ab991c3](https://github.com/ManotLuijiu/pi-harness-runtime/commit/ab991c329bdb4097e77503d3d7f574edc6cdc1c4))
|
|
55
77
|
|
|
56
78
|
### [1.1.14](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.14) (2026-08-24)
|
|
57
79
|
|
|
58
|
-
|
|
59
80
|
### Features
|
|
60
81
|
|
|
61
82
|
* **glm-quota:** add robust GLM quota countdown with auto-resume ([cb78a2b](https://github.com/ManotLuijiu/pi-harness-runtime/commit/cb78a2bdf5ecf79fc028030d43e3ce40767253cb))
|
package/README.md
CHANGED
|
@@ -155,6 +155,125 @@ bd --version
|
|
|
155
155
|
# Tasks: 4/4 done [x]
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
## LangChain Multi-Agent Loop (Autonomous Write-Review)
|
|
159
|
+
|
|
160
|
+
A **human-on-the-loop** autonomous system where multiple AI agents collaborate on code:
|
|
161
|
+
|
|
162
|
+
- **GPT** → writes the plan
|
|
163
|
+
- **MiniMax** → writes the code
|
|
164
|
+
- **GPT/GLM** → reviews the code
|
|
165
|
+
- Loop repeats until approved or max iterations hit
|
|
166
|
+
|
|
167
|
+
### Quick Start
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# One-shot (human triggers once)
|
|
171
|
+
bun harness/langchain/run.ts --mode graph --request "implement feature X"
|
|
172
|
+
|
|
173
|
+
# Dry-run (no API keys, uses stubs)
|
|
174
|
+
bun harness/langchain/run.ts --mode graph --request "fix bug Y" --dry-run
|
|
175
|
+
|
|
176
|
+
# Daemon mode (auto-triggers on new tasks — stays running)
|
|
177
|
+
bun harness/langchain/run.ts --daemon
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Daemon Mode (Auto-Trigger)
|
|
181
|
+
|
|
182
|
+
The daemon runs as a **standalone long-running process** and watches for new tasks:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
186
|
+
│ Terminal 1: pi-coding-agent (GPT/MiniMax/GLM — your coding agent) │
|
|
187
|
+
│ Terminal 2: bun harness/langchain/run.ts --daemon │
|
|
188
|
+
│ Terminal 3: (optional) second agent │
|
|
189
|
+
│ Terminal N: (optional) more agents │
|
|
190
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**How it works:**
|
|
194
|
+
|
|
195
|
+
1. You interact with coding agents in their terminals
|
|
196
|
+
2. Agents create tasks via `bd create ...` or inbox files
|
|
197
|
+
3. Daemon detects new pending tasks automatically
|
|
198
|
+
4. Loop runs: plan → write → review → fix (autonomous, no human relay)
|
|
199
|
+
5. Human is notified only at approval gates or when blocked
|
|
200
|
+
|
|
201
|
+
**Stop the daemon:** `Ctrl+C` or `kill $(pid)`
|
|
202
|
+
|
|
203
|
+
### Multi-Agent Roles
|
|
204
|
+
|
|
205
|
+
Request format in task or inbox file:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
[planner: gpt] [reviewer: GLM] [coder: MiniMax] implement feature X
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Default (from env vars):
|
|
212
|
+
|
|
213
|
+
| Role | Default | Env Var |
|
|
214
|
+
| ------ | --------- | --------- |
|
|
215
|
+
| Planner | GPT | `PLANNER_*` |
|
|
216
|
+
| Coder | MiniMax | `MINIMAX_*` |
|
|
217
|
+
| Reviewer | GPT | `GLM_*` |
|
|
218
|
+
|
|
219
|
+
### Architecture
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Triggers:
|
|
223
|
+
bd tasks ─┐
|
|
224
|
+
inbox ────┼──► Daemon ──► LeaseManager ──► LangGraph Loop
|
|
225
|
+
bus event ─┤ (watchers) │
|
|
226
|
+
cron ──────┘ │
|
|
227
|
+
│
|
|
228
|
+
Loop (LangGraph): publish
|
|
229
|
+
START → plan(GPT) → write(MiniMax) → review(GPT) ──► HerdrEventBus
|
|
230
|
+
↓ │
|
|
231
|
+
changes_requested? │
|
|
232
|
+
↓ yes no │
|
|
233
|
+
fix(MiniMax) approved ──► Notification
|
|
234
|
+
↓ │
|
|
235
|
+
review(GPT) ─────────────────────────►
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Key Design Invariants
|
|
239
|
+
|
|
240
|
+
| # | Invariant |
|
|
241
|
+
| --- | --- |
|
|
242
|
+
| I1 | No step waits for a human unless an approval gate fires |
|
|
243
|
+
| I2 | Agents talk directly via graph state + events (no human relay) |
|
|
244
|
+
| I3 | Exactly one daemon processes a task at a time (lease-based) |
|
|
245
|
+
| I4 | Every transition is observable via HerdrEventBus |
|
|
246
|
+
| I5 | Loop always terminates: maxIterations, blocked verdict, or error |
|
|
247
|
+
| I6 | Crash-safe: loop state survives daemon restarts (checkpointer) |
|
|
248
|
+
| I7 | Human gates are config-driven, default to "notify don't block" |
|
|
249
|
+
|
|
250
|
+
### Files
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
harness/langchain/
|
|
254
|
+
├── run.ts # CLI entry point (modes: graph, supervisor, daemon)
|
|
255
|
+
├── daemon.ts # Core daemon: watchers + lease + loop orchestration
|
|
256
|
+
├── graph.ts # LangGraph state machine (plan→write→review→fix)
|
|
257
|
+
├── agents.ts # Agent factory (planner, reviewer, coder)
|
|
258
|
+
├── model-router.ts # Smart model routing per request tags
|
|
259
|
+
├── ping-pong-middleware.ts # Decision engine: complex? → loop. simple? → one-shot
|
|
260
|
+
├── checkpointer.ts # Crash-safe state persistence
|
|
261
|
+
├── inbox-watcher.ts # Watches inbox dir for new task files
|
|
262
|
+
├── bus-watcher.ts # Watches HerdrEventBus for task.proposed events
|
|
263
|
+
├── cron-watcher.ts # Stub for scheduled task triggers
|
|
264
|
+
├── status-line.ts # Real-time loop status display
|
|
265
|
+
├── surge.ts # Peak-hour surge detection
|
|
266
|
+
└── widget.ts # TUI widget for loop progress
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Wiki Docs
|
|
270
|
+
|
|
271
|
+
| Doc | Description |
|
|
272
|
+
| ----- | ------------- |
|
|
273
|
+
| `wiki/auto-trigger-multi-agent.md` | Full daemon spec, event contracts, acceptance tests |
|
|
274
|
+
| `wiki/multi-agent-langchain.md` | LangChain/LangGraph design notes |
|
|
275
|
+
| `wiki/ping-pong-shared-state.md` | Shared state between agents |
|
|
276
|
+
|
|
158
277
|
## Architecture
|
|
159
278
|
|
|
160
279
|
```
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent definitions — GPT (planner) + GLM (master reviewer) + MiniMax (coder).
|
|
3
|
+
*
|
|
4
|
+
* Ping-pong loop:
|
|
5
|
+
* Planner (GPT) → plan
|
|
6
|
+
* Coder (MiniMax) → code
|
|
7
|
+
* Reviewer (GLM) → verdict: approved | changes_requested | blocked
|
|
8
|
+
*
|
|
9
|
+
* The GLM reviewer is the master. If GLM approves → loop ends. If GLM requests
|
|
10
|
+
* changes → MiniMax addresses them → GLM reviews again. After maxIterations or
|
|
11
|
+
* smart-stop, the loop terminates.
|
|
12
|
+
*
|
|
13
|
+
* Verdict values intentionally match the existing harness LoopVerdict type
|
|
14
|
+
* ("approved" | "changes_requested" | "blocked") so this module can feed the
|
|
15
|
+
* existing blackboard / HerdrEventBus infrastructure.
|
|
16
|
+
*
|
|
17
|
+
* Wiki: wiki/multi-agent-langchain.md
|
|
18
|
+
*/
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import { type ModelOptions } from "./models.js";
|
|
21
|
+
export declare const ReviewVerdictSchema: z.ZodObject<{
|
|
22
|
+
verdict: z.ZodEnum<{
|
|
23
|
+
approved: "approved";
|
|
24
|
+
blocked: "blocked";
|
|
25
|
+
changes_requested: "changes_requested";
|
|
26
|
+
}>;
|
|
27
|
+
summary: z.ZodString;
|
|
28
|
+
comments: z.ZodArray<z.ZodObject<{
|
|
29
|
+
file: z.ZodOptional<z.ZodString>;
|
|
30
|
+
comment: z.ZodString;
|
|
31
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
critical: "critical";
|
|
33
|
+
major: "major";
|
|
34
|
+
minor: "minor";
|
|
35
|
+
}>>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export type ReviewVerdict = z.infer<typeof ReviewVerdictSchema>;
|
|
39
|
+
export declare function isAutonomyRequest(request: string): boolean;
|
|
40
|
+
/** Directive injected into every system prompt when autonomy signal is detected. */
|
|
41
|
+
export declare function autonomyDirective(): string;
|
|
42
|
+
export declare function createPlannerAgent(opts?: ModelOptions): import("langchain").ReactAgent<import("langchain").AgentTypeConfig<import("langchain").ResponseFormatUndefined, undefined, import("langchain").AnyAnnotationRoot, readonly import("langchain").AnyAgentMiddleware[], readonly [], readonly []>>;
|
|
43
|
+
export declare function createCoderAgent(opts?: ModelOptions): import("langchain").ReactAgent<import("langchain").AgentTypeConfig<import("langchain").ResponseFormatUndefined, undefined, import("langchain").AnyAnnotationRoot, readonly import("langchain").AnyAgentMiddleware[], readonly (import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
44
|
+
path: z.ZodString;
|
|
45
|
+
encoding: z.ZodOptional<z.ZodEnum<{
|
|
46
|
+
ascii: "ascii";
|
|
47
|
+
base64: "base64";
|
|
48
|
+
"utf-16": "utf-16";
|
|
49
|
+
"utf-8": "utf-8";
|
|
50
|
+
}>>;
|
|
51
|
+
}, z.core.$strip>, {
|
|
52
|
+
path: string;
|
|
53
|
+
encoding?: "ascii" | "base64" | "utf-16" | "utf-8" | undefined;
|
|
54
|
+
}, {
|
|
55
|
+
path: string;
|
|
56
|
+
encoding?: "ascii" | "base64" | "utf-16" | "utf-8" | undefined;
|
|
57
|
+
}, string, unknown, "read_file"> | import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
58
|
+
path: z.ZodString;
|
|
59
|
+
content: z.ZodString;
|
|
60
|
+
append: z.ZodOptional<z.ZodBoolean>;
|
|
61
|
+
}, z.core.$strip>, {
|
|
62
|
+
path: string;
|
|
63
|
+
content: string;
|
|
64
|
+
append?: boolean | undefined;
|
|
65
|
+
}, {
|
|
66
|
+
path: string;
|
|
67
|
+
content: string;
|
|
68
|
+
append?: boolean | undefined;
|
|
69
|
+
}, string, unknown, "write_file"> | import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
70
|
+
path: z.ZodString;
|
|
71
|
+
}, z.core.$strip>, {
|
|
72
|
+
path: string;
|
|
73
|
+
}, {
|
|
74
|
+
path: string;
|
|
75
|
+
}, string, unknown, "list_directory">)[], readonly []>>;
|
|
76
|
+
export declare function createReviewerAgent(opts?: ModelOptions): import("langchain").ReactAgent<import("langchain").AgentTypeConfig<{
|
|
77
|
+
verdict: "approved" | "blocked" | "changes_requested";
|
|
78
|
+
summary: string;
|
|
79
|
+
comments: {
|
|
80
|
+
file?: string | undefined;
|
|
81
|
+
comment: string;
|
|
82
|
+
severity?: "critical" | "major" | "minor" | undefined;
|
|
83
|
+
}[];
|
|
84
|
+
}, undefined, import("langchain").AnyAnnotationRoot, readonly import("langchain").AnyAgentMiddleware[], readonly [], readonly []>>;
|
|
85
|
+
export type PlannerAgent = ReturnType<typeof createPlannerAgent>;
|
|
86
|
+
export type CoderAgent = ReturnType<typeof createCoderAgent>;
|
|
87
|
+
export type ReviewerAgent = ReturnType<typeof createReviewerAgent>;
|
|
88
|
+
export type SupervisorAgent = ReturnType<typeof createSupervisor>;
|
|
89
|
+
/** Extract the last assistant message text from an agent result. */
|
|
90
|
+
export declare function lastMessage(agentResult: {
|
|
91
|
+
messages: Array<{
|
|
92
|
+
content: unknown;
|
|
93
|
+
}>;
|
|
94
|
+
}): string;
|
|
95
|
+
export declare function buildDelegationTools(opts?: {
|
|
96
|
+
coder?: CoderAgent;
|
|
97
|
+
reviewer?: ReviewerAgent;
|
|
98
|
+
}): {
|
|
99
|
+
delegateToCoder: import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
100
|
+
instruction: z.ZodString;
|
|
101
|
+
reviewComments: z.ZodOptional<z.ZodString>;
|
|
102
|
+
}, z.core.$strip>, {
|
|
103
|
+
instruction: string;
|
|
104
|
+
reviewComments?: string | undefined;
|
|
105
|
+
}, {
|
|
106
|
+
instruction: string;
|
|
107
|
+
reviewComments?: string | undefined;
|
|
108
|
+
}, string, unknown, "delegate_to_coder">;
|
|
109
|
+
delegateToReviewer: import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
110
|
+
plan: z.ZodString;
|
|
111
|
+
code: z.ZodString;
|
|
112
|
+
}, z.core.$strip>, {
|
|
113
|
+
plan: string;
|
|
114
|
+
code: string;
|
|
115
|
+
}, {
|
|
116
|
+
plan: string;
|
|
117
|
+
code: string;
|
|
118
|
+
}, string, unknown, "delegate_to_reviewer">;
|
|
119
|
+
};
|
|
120
|
+
export declare function createSupervisor(opts?: {
|
|
121
|
+
plannerModel?: ModelOptions;
|
|
122
|
+
coder?: CoderAgent;
|
|
123
|
+
reviewer?: ReviewerAgent;
|
|
124
|
+
}): import("langchain").ReactAgent<import("langchain").AgentTypeConfig<import("langchain").ResponseFormatUndefined, undefined, import("langchain").AnyAnnotationRoot, readonly import("langchain").AnyAgentMiddleware[], readonly [import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
125
|
+
instruction: z.ZodString;
|
|
126
|
+
reviewComments: z.ZodOptional<z.ZodString>;
|
|
127
|
+
}, z.core.$strip>, {
|
|
128
|
+
instruction: string;
|
|
129
|
+
reviewComments?: string | undefined;
|
|
130
|
+
}, {
|
|
131
|
+
instruction: string;
|
|
132
|
+
reviewComments?: string | undefined;
|
|
133
|
+
}, string, unknown, "delegate_to_coder">, import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
134
|
+
plan: z.ZodString;
|
|
135
|
+
code: z.ZodString;
|
|
136
|
+
}, z.core.$strip>, {
|
|
137
|
+
plan: string;
|
|
138
|
+
code: string;
|
|
139
|
+
}, {
|
|
140
|
+
plan: string;
|
|
141
|
+
code: string;
|
|
142
|
+
}, string, unknown, "delegate_to_reviewer">], readonly []>>;
|
|
143
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Multi-Agent definitions — GPT (planner
|
|
2
|
+
* Multi-Agent definitions — GPT (planner) + GLM (master reviewer) + MiniMax (coder).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Ping-pong loop:
|
|
5
|
+
* Planner (GPT) → plan
|
|
6
|
+
* Coder (MiniMax) → code
|
|
7
|
+
* Reviewer (GLM) → verdict: approved | changes_requested | blocked
|
|
6
8
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @tool delegate_to_subagent1 → delegateToCoder = tool(... { name: "delegate_to_coder" })
|
|
11
|
-
* main_agent(tools=[delegates]) → supervisor = createAgent({ tools: [delegateToCoder, ...] })
|
|
9
|
+
* The GLM reviewer is the master. If GLM approves → loop ends. If GLM requests
|
|
10
|
+
* changes → MiniMax addresses them → GLM reviews again. After maxIterations or
|
|
11
|
+
* smart-stop, the loop terminates.
|
|
12
12
|
*
|
|
13
13
|
* Verdict values intentionally match the existing harness LoopVerdict type
|
|
14
14
|
* ("approved" | "changes_requested" | "blocked") so this module can feed the
|
|
@@ -95,8 +95,8 @@ permission to write code until finish without waiting for confirmation.
|
|
|
95
95
|
const PLANNER_PROMPT = `You are the Planning Agent (GPT) in an autonomous daemon loop.
|
|
96
96
|
|
|
97
97
|
Given a feature request, produce a concise implementation plan: goals, non-goals,
|
|
98
|
-
ordered steps, files to touch, risks, and a definition-of-done the reviewer
|
|
99
|
-
check against.
|
|
98
|
+
ordered steps, files to touch, risks, and a definition-of-done the GLM reviewer
|
|
99
|
+
can check against.
|
|
100
100
|
|
|
101
101
|
Output markdown only. Do NOT ask for confirmation. Do NOT output "Next Steps".
|
|
102
102
|
The loop will route automatically.`;
|
|
@@ -124,10 +124,11 @@ IMPORTANT:
|
|
|
124
124
|
- If you cannot proceed, fail with a clear error message
|
|
125
125
|
- Your output is consumed by the loop, not read by a human for guidance`;
|
|
126
126
|
|
|
127
|
-
const REVIEWER_PROMPT = `You are the Code Review Agent (
|
|
127
|
+
const REVIEWER_PROMPT = `You are the Master Code Review Agent (GLM) in an autonomous daemon loop.
|
|
128
128
|
|
|
129
|
-
You review the coder's output against the plan.
|
|
130
|
-
for real problems.
|
|
129
|
+
You are the master reviewer. You review the MiniMax coder's output against the plan.
|
|
130
|
+
Be strict: request changes only for real problems. Output a structured verdict —
|
|
131
|
+
the loop reads it automatically and routes MiniMax back to fix or approves.
|
|
131
132
|
|
|
132
133
|
IMPORTANT:
|
|
133
134
|
- Do NOT output "Next Steps" or "Looks good, waiting for approval"
|
|
@@ -146,6 +147,188 @@ IMPORTANT:
|
|
|
146
147
|
- Do NOT output a summary for a human — the loop reads the verdict
|
|
147
148
|
- Keep iterating until approved or truly blocked, then output a verdict`;
|
|
148
149
|
|
|
150
|
+
// ─── ADK ParallelAgent Pattern: Specialist Reviewers ─────────────────────────
|
|
151
|
+
// ADK equivalent: ParallelAgent([SecurityAuditor, StyleEnforcer, PerfAnalyst])
|
|
152
|
+
// This runs 3 specialist reviews in parallel via Promise.all.
|
|
153
|
+
// Each specialist focuses on one dimension — faster and more thorough than
|
|
154
|
+
// one monolithic reviewer.
|
|
155
|
+
|
|
156
|
+
export type SpecialistType = "security" | "style" | "performance";
|
|
157
|
+
|
|
158
|
+
const SPECIALIST_PROMPTS: Record<SpecialistType, string> = {
|
|
159
|
+
security: `You are a Security Auditor in an autonomous code review loop.
|
|
160
|
+
|
|
161
|
+
FOCUS: Find real security vulnerabilities only. Do NOT flag style, formatting, or performance issues.
|
|
162
|
+
|
|
163
|
+
Check for:
|
|
164
|
+
- SQL injection, command injection, path traversal
|
|
165
|
+
- Hardcoded secrets, API keys, passwords in code
|
|
166
|
+
- Insecure deserialization, XXE, SSRF
|
|
167
|
+
- Authentication/authorization bypass patterns
|
|
168
|
+
- Unsafe eval/Function/exec with user input
|
|
169
|
+
- Missing input validation on security-sensitive operations
|
|
170
|
+
- Insecure file operations, TOCTOU
|
|
171
|
+
- Weak crypto, improper SSL/TLS usage
|
|
172
|
+
|
|
173
|
+
Output a structured verdict. Do NOT say "looks good overall" — give a precise security assessment.`,
|
|
174
|
+
|
|
175
|
+
style: `You are a Code Style and Maintainability Auditor in an autonomous code review loop.
|
|
176
|
+
|
|
177
|
+
FOCUS: Check style, readability, and maintainability only. Do NOT flag security vulnerabilities or performance issues.
|
|
178
|
+
|
|
179
|
+
Check for:
|
|
180
|
+
- Consistent naming conventions (camelCase vs snake_case)
|
|
181
|
+
- Missing or inconsistent JSDoc/type annotations
|
|
182
|
+
- Overly complex functions (cyclomatic complexity)
|
|
183
|
+
- Magic numbers without named constants
|
|
184
|
+
- Deeply nested callbacks / callback hell
|
|
185
|
+
- Missing error handling or empty catch blocks
|
|
186
|
+
- Unused imports or variables
|
|
187
|
+
- Inconsistent error handling patterns
|
|
188
|
+
|
|
189
|
+
Output a structured verdict. Focus on real maintainability problems, not personal preferences.`,
|
|
190
|
+
|
|
191
|
+
performance: `You are a Performance Analyst in an autonomous code review loop.
|
|
192
|
+
|
|
193
|
+
FOCUS: Find real performance and scalability problems only. Do NOT flag style or security (unless it causes a performance issue).
|
|
194
|
+
|
|
195
|
+
Check for:
|
|
196
|
+
- N+1 query patterns (DB, HTTP, file I/O)
|
|
197
|
+
- Synchronous blocking operations in async code
|
|
198
|
+
- Memory leaks (unbounded arrays, missing cleanup)
|
|
199
|
+
- Expensive operations in hot paths (loops, regex in loops)
|
|
200
|
+
- Missing pagination or cursor-based iteration
|
|
201
|
+
- Unbounded recursion without memoization
|
|
202
|
+
- Inefficient data structures (array search vs Map/Set)
|
|
203
|
+
- Missing caching where repeated computation occurs
|
|
204
|
+
|
|
205
|
+
Output a structured verdict. Flag only real performance problems, not premature optimizations.`,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/** Create a specialist reviewer agent for parallel review. */
|
|
209
|
+
export function createSpecialistReviewer(
|
|
210
|
+
type: SpecialistType,
|
|
211
|
+
opts: ModelOptions = {},
|
|
212
|
+
) {
|
|
213
|
+
return createAgent({
|
|
214
|
+
model: createReviewerModel(opts),
|
|
215
|
+
tools: [],
|
|
216
|
+
systemPrompt: SPECIALIST_PROMPTS[type],
|
|
217
|
+
responseFormat: ReviewVerdictSchema,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* ADK ParallelAgent equivalent: run multiple specialist reviews in parallel.
|
|
223
|
+
* Returns aggregated verdict — approved only if ALL specialists pass.
|
|
224
|
+
*/
|
|
225
|
+
export async function parallelReview(
|
|
226
|
+
specialists: {
|
|
227
|
+
security: ReturnType<typeof createSpecialistReviewer>;
|
|
228
|
+
style: ReturnType<typeof createSpecialistReviewer>;
|
|
229
|
+
performance: ReturnType<typeof createSpecialistReviewer>;
|
|
230
|
+
},
|
|
231
|
+
plan: string,
|
|
232
|
+
code: string,
|
|
233
|
+
writtenFiles: Record<string, string>,
|
|
234
|
+
): Promise<ReviewVerdict> {
|
|
235
|
+
const codeSection =
|
|
236
|
+
Object.keys(writtenFiles).length > 0
|
|
237
|
+
? Object.entries(writtenFiles)
|
|
238
|
+
.map(([path, content]) => `## ${path}\n\n\`\`\`\n${content}\n\`\`\`\n`)
|
|
239
|
+
.join("\n\n")
|
|
240
|
+
: `## Code\n\n\`\`\`\n${code}\n\`\`\`\n`;
|
|
241
|
+
|
|
242
|
+
const prompt = `## Plan\n${plan}\n\n${codeSection}`;
|
|
243
|
+
|
|
244
|
+
// ── ADK ParallelAgent: fan-out 3 specialists simultaneously ──
|
|
245
|
+
const [secResult, styleResult, perfResult] = await Promise.all([
|
|
246
|
+
specialists.security.invoke({
|
|
247
|
+
messages: [{ role: "user", content: prompt }],
|
|
248
|
+
}),
|
|
249
|
+
specialists.style.invoke({
|
|
250
|
+
messages: [{ role: "user", content: prompt }],
|
|
251
|
+
}),
|
|
252
|
+
specialists.performance.invoke({
|
|
253
|
+
messages: [{ role: "user", content: prompt }],
|
|
254
|
+
}),
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
// Parse each specialist result
|
|
258
|
+
const parseResult = (
|
|
259
|
+
r: unknown,
|
|
260
|
+
_specialist: SpecialistType,
|
|
261
|
+
): { verdict: string; summary: string; comments: unknown[] } => {
|
|
262
|
+
if (typeof r === "object" && r !== null && "structuredResponse" in r) {
|
|
263
|
+
const sr = (
|
|
264
|
+
r as {
|
|
265
|
+
structuredResponse: {
|
|
266
|
+
verdict: string;
|
|
267
|
+
summary: string;
|
|
268
|
+
comments: unknown[];
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
).structuredResponse;
|
|
272
|
+
return { verdict: sr.verdict, summary: sr.summary, comments: sr.comments };
|
|
273
|
+
}
|
|
274
|
+
return { verdict: "approved", summary: "", comments: [] };
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const sec = parseResult(secResult, "security");
|
|
278
|
+
const style = parseResult(styleResult, "style");
|
|
279
|
+
const perf = parseResult(perfResult, "performance");
|
|
280
|
+
|
|
281
|
+
// ── ADK ParallelAgent: gather results and synthesize ──
|
|
282
|
+
const buildLabeledComments = (
|
|
283
|
+
comments: unknown[],
|
|
284
|
+
type: SpecialistType,
|
|
285
|
+
): {
|
|
286
|
+
file?: string;
|
|
287
|
+
comment: string;
|
|
288
|
+
severity: "critical" | "major" | "minor";
|
|
289
|
+
}[] =>
|
|
290
|
+
(comments ?? []).map((c) => {
|
|
291
|
+
const comment = c as {
|
|
292
|
+
file?: string;
|
|
293
|
+
comment: string;
|
|
294
|
+
severity?: "critical" | "major" | "minor";
|
|
295
|
+
};
|
|
296
|
+
return {
|
|
297
|
+
file: comment.file,
|
|
298
|
+
comment: `[${type}] ${comment.comment}`,
|
|
299
|
+
severity: comment.severity ?? "minor",
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const labeledComments = [
|
|
304
|
+
...buildLabeledComments(sec.comments, "security"),
|
|
305
|
+
...buildLabeledComments(style.comments, "style"),
|
|
306
|
+
...buildLabeledComments(perf.comments, "performance"),
|
|
307
|
+
];
|
|
308
|
+
|
|
309
|
+
// Only approve if ALL specialists approve
|
|
310
|
+
let finalVerdict: ReviewVerdict["verdict"] = "approved";
|
|
311
|
+
if (
|
|
312
|
+
sec.verdict === "blocked" ||
|
|
313
|
+
style.verdict === "blocked" ||
|
|
314
|
+
perf.verdict === "blocked"
|
|
315
|
+
) {
|
|
316
|
+
finalVerdict = "blocked";
|
|
317
|
+
} else if (
|
|
318
|
+
sec.verdict === "changes_requested" ||
|
|
319
|
+
style.verdict === "changes_requested" ||
|
|
320
|
+
perf.verdict === "changes_requested"
|
|
321
|
+
) {
|
|
322
|
+
finalVerdict = "changes_requested";
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
verdict: finalVerdict,
|
|
327
|
+
summary: `[security] ${sec.summary} | [style] ${style.summary} | [perf] ${perf.summary}`,
|
|
328
|
+
comments: labeledComments,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
149
332
|
// ─── Agents ─────────────────────────────────────────────────────────────────
|
|
150
333
|
|
|
151
334
|
export function createPlannerAgent(opts: ModelOptions = {}) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based checkpointer — persists LangGraph StateGraph checkpoints to disk.
|
|
3
|
+
*
|
|
4
|
+
* Enables crash-safe loop resume: if the daemon dies mid-task, a new instance
|
|
5
|
+
* resumes from the last checkpoint instead of restarting from scratch.
|
|
6
|
+
*
|
|
7
|
+
* Storage layout:
|
|
8
|
+
* <root>/
|
|
9
|
+
* ├── <threadId>/
|
|
10
|
+
* │ ├── index.jsonl # one line per checkpoint (id, ts, parentId, step)
|
|
11
|
+
* │ └── <checkpointId>.json # full checkpoint + metadata + parentConfig
|
|
12
|
+
*
|
|
13
|
+
* Wiki: wiki/auto-trigger-multi-agent.md §M5
|
|
14
|
+
*/
|
|
15
|
+
import { BaseCheckpointSaver, Checkpoint, CheckpointListOptions, CheckpointMetadata, CheckpointTuple } from "@langchain/langgraph-checkpoint";
|
|
16
|
+
import type { ChannelVersions } from "@langchain/langgraph-checkpoint";
|
|
17
|
+
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
18
|
+
/**
|
|
19
|
+
* File-based LangGraph checkpointer. Implements BaseCheckpointSaver so it can be
|
|
20
|
+
* passed directly to `buildWriteReviewLoop()` as the `checkpointer` option.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* const saver = new FileCheckpointSaver({ root: "/tmp/checkpoints" });
|
|
24
|
+
* const loop = buildWriteReviewLoop(deps, { checkpointer: saver });
|
|
25
|
+
*
|
|
26
|
+
* On daemon restart, pass the same root — checkpoints persist across restarts.
|
|
27
|
+
*/
|
|
28
|
+
export declare class FileCheckpointSaver extends BaseCheckpointSaver {
|
|
29
|
+
private readonly root;
|
|
30
|
+
constructor(opts: {
|
|
31
|
+
root: string;
|
|
32
|
+
});
|
|
33
|
+
get(config: RunnableConfig): Promise<Checkpoint | undefined>;
|
|
34
|
+
getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
|
|
35
|
+
private _loadCheckpoint;
|
|
36
|
+
list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
|
|
37
|
+
put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;
|
|
38
|
+
putWrites(_config: RunnableConfig, _writes: [], _taskId: string): Promise<void>;
|
|
39
|
+
deleteThread(threadId: string): Promise<void>;
|
|
40
|
+
toJSON(): string;
|
|
41
|
+
/** List all known thread IDs with saved checkpoints. */
|
|
42
|
+
listThreads(): string[];
|
|
43
|
+
/** Delete all checkpoints for all threads (cleanup). */
|
|
44
|
+
clearAll(): void;
|
|
45
|
+
}
|
|
46
|
+
/** Build a FileCheckpointSaver wired to the daemon's workspace. */
|
|
47
|
+
export declare function createLoopCheckpointer(workspace: string): FileCheckpointSaver;
|
|
48
|
+
//# sourceMappingURL=checkpointer.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cron task management CLI.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* bun harness/langchain/run.ts cron add <schedule> <request>
|
|
6
|
+
* bun harness/langchain/run.ts cron list
|
|
7
|
+
* bun harness/langchain/run.ts cron rm <task-id>
|
|
8
|
+
*
|
|
9
|
+
* Schedules: every-5m, every-10m, every-30m, hourly, daily, weekly
|
|
10
|
+
*/
|
|
11
|
+
export declare function runCron(argv: string[]): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=cron-cli.d.ts.map
|