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.
Files changed (203) hide show
  1. package/CHANGELOG.md +30 -9
  2. package/README.md +119 -0
  3. package/harness/langchain/agents.d.ts +143 -0
  4. package/harness/langchain/agents.test.d.ts +2 -0
  5. package/harness/langchain/agents.test.ts +0 -1
  6. package/harness/langchain/agents.ts +196 -13
  7. package/harness/langchain/checkpointer.d.ts +48 -0
  8. package/harness/langchain/checkpointer.test.d.ts +8 -0
  9. package/harness/langchain/cron-cli.d.ts +12 -0
  10. package/harness/langchain/cron-cli.ts +169 -0
  11. package/harness/langchain/daemon.d.ts +161 -0
  12. package/harness/langchain/daemon.test.d.ts +11 -0
  13. package/harness/langchain/daemon.test.ts +62 -5
  14. package/harness/langchain/daemon.ts +231 -12
  15. package/harness/langchain/file-tools.d.ts +97 -0
  16. package/harness/langchain/file-tools.ts +29 -11
  17. package/harness/langchain/graph.d.ts +706 -0
  18. package/harness/langchain/graph.ts +184 -26
  19. package/harness/langchain/model-router.d.ts +63 -0
  20. package/harness/langchain/model-router.test.d.ts +2 -0
  21. package/harness/langchain/model-router.test.ts +191 -0
  22. package/harness/langchain/model-router.ts +188 -0
  23. package/harness/langchain/models.d.ts +72 -0
  24. package/harness/langchain/models.ts +111 -49
  25. package/harness/langchain/ping-pong-middleware.d.ts +28 -0
  26. package/harness/langchain/ping-pong-middleware.test.d.ts +2 -0
  27. package/harness/langchain/ping-pong-middleware.test.ts +69 -0
  28. package/harness/langchain/ping-pong-middleware.ts +204 -0
  29. package/harness/langchain/run.d.ts +15 -0
  30. package/harness/langchain/run.ts +15 -3
  31. package/harness/langchain/scoreboard.test.d.ts +13 -0
  32. package/harness/langchain/scoreboard.test.ts +28 -5
  33. package/harness/langchain/status-line.d.ts +91 -0
  34. package/harness/langchain/status-line.test.d.ts +8 -0
  35. package/harness/langchain/surge.d.ts +103 -0
  36. package/harness/langchain/surge.test.d.ts +10 -0
  37. package/harness/langchain/surge.test.ts +179 -0
  38. package/harness/langchain/surge.ts +188 -19
  39. package/harness/langchain/widget.d.ts +105 -0
  40. package/harness/langchain/widget.test.d.ts +8 -0
  41. package/harness/ssh-detach-interceptor.test.ts +263 -0
  42. package/harness/ssh-detach-interceptor.ts +438 -0
  43. package/index.ts +212 -47
  44. package/package.json +4 -2
  45. package/packages/a2a-adapter/package.json +1 -1
  46. package/packages/architecture-generator/package.json +1 -1
  47. package/packages/auth/package.json +1 -1
  48. package/packages/autonomous-refactor/package.json +1 -1
  49. package/packages/autonomous-runtime/package.json +1 -1
  50. package/packages/cache-strategy/package.json +1 -1
  51. package/packages/capability-registry/package.json +1 -1
  52. package/packages/checkpoint/package.json +1 -1
  53. package/packages/cli-plugin-sdk/package.json +1 -1
  54. package/packages/clipboard/package.json +1 -1
  55. package/packages/clipboard-plugin/package.json +1 -1
  56. package/packages/code-generation/package.json +1 -1
  57. package/packages/code-review/package.json +1 -1
  58. package/packages/codex-adapter/package.json +1 -1
  59. package/packages/config-capture/package.json +1 -1
  60. package/packages/context-compiler/package.json +1 -1
  61. package/packages/context-discovery/package.json +1 -1
  62. package/packages/context-manager/package.json +1 -1
  63. package/packages/cookie-sanitizer/package.json +1 -1
  64. package/packages/cost-optimizer/package.json +1 -1
  65. package/packages/dependency-analyzer/package.json +1 -1
  66. package/packages/django-plugin/package.json +1 -1
  67. package/packages/doc-generator/package.json +1 -1
  68. package/packages/evaluation-engine/package.json +1 -1
  69. package/packages/evaluation-runner/package.json +1 -1
  70. package/packages/event-bus/package.json +1 -1
  71. package/packages/event-store/package.json +1 -1
  72. package/packages/experience-replay/package.json +1 -1
  73. package/packages/feedback-collector/package.json +1 -1
  74. package/packages/file-copy-helper/package.json +1 -1
  75. package/packages/framework-detector/package.json +1 -1
  76. package/packages/framework-plugin-sdk/package.json +1 -1
  77. package/packages/frappe-plugin/package.json +1 -1
  78. package/packages/generic-web-plugin/package.json +1 -1
  79. package/packages/health-monitor/package.json +1 -1
  80. package/packages/intent-analyzer/dist/src/index.d.ts +2 -0
  81. package/packages/intent-analyzer/dist/src/index.d.ts.map +1 -1
  82. package/packages/intent-analyzer/dist/src/index.js +1 -0
  83. package/packages/intent-analyzer/dist/src/index.js.map +1 -1
  84. package/packages/intent-analyzer/dist/src/ping-pong.d.ts +56 -0
  85. package/packages/intent-analyzer/dist/src/ping-pong.d.ts.map +1 -0
  86. package/packages/intent-analyzer/dist/src/ping-pong.js +286 -0
  87. package/packages/intent-analyzer/dist/src/ping-pong.js.map +1 -0
  88. package/packages/intent-analyzer/package.json +1 -1
  89. package/packages/intent-analyzer/src/index.ts +13 -0
  90. package/packages/intent-analyzer/src/ping-pong.ts +387 -0
  91. package/packages/intent-analyzer/test/ping-pong.test.ts +96 -0
  92. package/packages/jev-judge/README.md +234 -0
  93. package/packages/jev-judge/dist/decision-engine.d.ts +100 -0
  94. package/packages/jev-judge/dist/decision-engine.d.ts.map +1 -0
  95. package/packages/jev-judge/dist/decision-engine.js +151 -0
  96. package/packages/jev-judge/dist/decision-engine.js.map +1 -0
  97. package/packages/jev-judge/dist/e2e-judge.d.ts +61 -0
  98. package/packages/jev-judge/dist/e2e-judge.d.ts.map +1 -0
  99. package/packages/jev-judge/dist/e2e-judge.js +268 -0
  100. package/packages/jev-judge/dist/e2e-judge.js.map +1 -0
  101. package/packages/jev-judge/dist/flaky-detector.d.ts +34 -0
  102. package/packages/jev-judge/dist/flaky-detector.d.ts.map +1 -0
  103. package/packages/jev-judge/dist/flaky-detector.js +154 -0
  104. package/packages/jev-judge/dist/flaky-detector.js.map +1 -0
  105. package/packages/jev-judge/dist/index.d.ts +77 -0
  106. package/packages/jev-judge/dist/index.d.ts.map +1 -0
  107. package/packages/jev-judge/dist/index.js +271 -0
  108. package/packages/jev-judge/dist/index.js.map +1 -0
  109. package/packages/jev-judge/dist/types.d.ts +97 -0
  110. package/packages/jev-judge/dist/types.d.ts.map +1 -0
  111. package/packages/jev-judge/dist/types.js +8 -0
  112. package/packages/jev-judge/dist/types.js.map +1 -0
  113. package/packages/jev-judge/package.json +46 -0
  114. package/packages/jev-judge/src/decision-engine.ts +231 -0
  115. package/packages/jev-judge/src/e2e-judge.ts +364 -0
  116. package/packages/jev-judge/src/flaky-detector.ts +190 -0
  117. package/packages/jev-judge/src/index.ts +345 -0
  118. package/packages/jev-judge/src/types.ts +131 -0
  119. package/packages/knowledge-graph/package.json +1 -1
  120. package/packages/knowledge-retrieval/package.json +1 -1
  121. package/packages/laravel-plugin/package.json +1 -1
  122. package/packages/learning-engine/package.json +1 -1
  123. package/packages/mcp-adapter/package.json +1 -1
  124. package/packages/memory-engine/package.json +1 -1
  125. package/packages/milestone-manager/package.json +1 -1
  126. package/packages/model-registry/package.json +1 -1
  127. package/packages/nextjs-plugin/package.json +1 -1
  128. package/packages/notification/package.json +1 -1
  129. package/packages/observability/package.json +1 -1
  130. package/packages/okf-indexer/package.json +1 -1
  131. package/packages/performance-optimizer/package.json +1 -1
  132. package/packages/privilege-broker/package.json +1 -1
  133. package/packages/project-analyzer/package.json +1 -1
  134. package/packages/project-bootstrap/package.json +1 -1
  135. package/packages/projection-engine/package.json +1 -1
  136. package/packages/prompt-compiler/package.json +1 -1
  137. package/packages/prompt-versioning/package.json +1 -1
  138. package/packages/provider-adapter-sdk/package.json +1 -1
  139. package/packages/provider-router/package.json +1 -1
  140. package/packages/provider-selector/package.json +1 -1
  141. package/packages/providers/package.json +1 -1
  142. package/packages/quota-manager/package.json +1 -1
  143. package/packages/rate-limiter/package.json +1 -1
  144. package/packages/react-vite-plugin/package.json +1 -1
  145. package/packages/release-manager/package.json +1 -1
  146. package/packages/requirement-compiler/package.json +1 -1
  147. package/packages/runtime/package.json +1 -1
  148. package/packages/scheduler/package.json +1 -1
  149. package/packages/scheduler-adapter/package.json +1 -1
  150. package/packages/session/package.json +1 -1
  151. package/packages/session-api/package.json +1 -1
  152. package/packages/session-export/package.json +1 -1
  153. package/packages/shared-context/package.json +1 -1
  154. package/packages/skill-mcp-client/package.json +1 -1
  155. package/packages/skill-registry/package.json +1 -1
  156. package/packages/sprint-planner/package.json +1 -1
  157. package/packages/subscription-engine/package.json +1 -1
  158. package/packages/task-compiler/package.json +1 -1
  159. package/packages/tencentdb-memory/package.json +1 -1
  160. package/packages/tencentdb-sync/package.json +1 -1
  161. package/packages/test-data-generator/package.json +1 -1
  162. package/packages/test-generator/package.json +1 -1
  163. package/packages/todo-bd-sync/README.md +71 -0
  164. package/packages/todo-bd-sync/package.json +1 -1
  165. package/packages/todo-bd-sync/src/extension.ts +16 -1
  166. package/packages/token-estimation/package.json +1 -1
  167. package/packages/token-optimizer/package.json +1 -1
  168. package/packages/trajectory/dist/src/approved-patterns.d.ts +51 -0
  169. package/packages/trajectory/dist/src/approved-patterns.d.ts.map +1 -0
  170. package/packages/trajectory/dist/src/approved-patterns.js +134 -0
  171. package/packages/trajectory/dist/src/approved-patterns.js.map +1 -0
  172. package/packages/trajectory/dist/src/index.d.ts +13 -0
  173. package/packages/trajectory/dist/src/index.d.ts.map +1 -0
  174. package/packages/trajectory/dist/src/index.js +12 -0
  175. package/packages/trajectory/dist/src/index.js.map +1 -0
  176. package/packages/trajectory/dist/src/store.d.ts +69 -0
  177. package/packages/trajectory/dist/src/store.d.ts.map +1 -0
  178. package/packages/trajectory/dist/src/store.js +253 -0
  179. package/packages/trajectory/dist/src/store.js.map +1 -0
  180. package/packages/trajectory/dist/src/types.d.ts +73 -0
  181. package/packages/trajectory/dist/src/types.d.ts.map +1 -0
  182. package/packages/trajectory/dist/src/types.js +9 -0
  183. package/packages/trajectory/dist/src/types.js.map +1 -0
  184. package/packages/trajectory/dist/test/store.test.d.ts +2 -0
  185. package/packages/trajectory/dist/test/store.test.d.ts.map +1 -0
  186. package/packages/trajectory/dist/test/store.test.js +228 -0
  187. package/packages/trajectory/dist/test/store.test.js.map +1 -0
  188. package/packages/trajectory/package.json +29 -0
  189. package/packages/trajectory/src/approved-patterns.ts +180 -0
  190. package/packages/trajectory/src/index.ts +26 -0
  191. package/packages/trajectory/src/store.ts +285 -0
  192. package/packages/trajectory/src/types.ts +84 -0
  193. package/packages/trajectory/test/store.test.d.ts +2 -0
  194. package/packages/trajectory/test/store.test.ts +250 -0
  195. package/packages/tui/package.json +1 -1
  196. package/packages/types/package.json +1 -1
  197. package/packages/workflow-events/package.json +1 -1
  198. package/packages/workspace-scanner/package.json +1 -1
  199. package/packages/worktree/package.json +1 -1
  200. package/packages/write-review/package.json +1 -1
  201. package/packages/write-review/src/blackboard.ts +38 -5
  202. package/packages/write-review/src/types.ts +13 -0
  203. 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.18](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.13...v1.1.18) (2026-08-24)
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
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agents.test.d.ts.map
@@ -1,4 +1,3 @@
1
-
2
1
  import { describe, it } from "node:test";
3
2
  import assert from "node:assert";
4
3
  import { isAutonomyRequest } from "./agents.js";
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Multi-Agent definitions — GPT (planner/reviewer/supervisor) + MiniMax (coder).
2
+ * Multi-Agent definitions — GPT (planner) + GLM (master reviewer) + MiniMax (coder).
3
3
  *
4
- * This is a TypeScript port of the "supervisor + agents-as-tools" pattern from
5
- * Mohamad-Hachem/MultiAgent_Wedding_Planner_With_Langchain (agents.py):
4
+ * Ping-pong loop:
5
+ * Planner (GPT) → plan
6
+ * Coder (MiniMax) → code
7
+ * Reviewer (GLM) → verdict: approved | changes_requested | blocked
6
8
  *
7
- * Python (agents.py) TypeScript (this file)
8
- * ------------------------------------------------------------------
9
- * subagent1 = create_agent(...) → coderAgent = createAgent({ model: minimax ... })
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 can
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 (GPT) in an autonomous daemon loop.
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. Be strict: request changes only
130
- for real problems. Output a structured verdict — the loop reads it automatically.
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,8 @@
1
+ /**
2
+ * FileCheckpointSaver tests — T9–T11 (wiki/auto-trigger-multi-agent.md §M5)
3
+ *
4
+ * Run:
5
+ * bun test harness/langchain/checkpointer.test.ts
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=checkpointer.test.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