pi-harness-runtime 0.9.22 → 0.10.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/CHANGELOG.md +49 -7
- package/README.md +51 -51
- package/footer-status.ts +84 -44
- package/harness/auto-compact.ts +1 -1
- package/harness/auto-quota-resume.ts +15 -12
- package/harness/autonomous-review.ts +88 -0
- package/harness/context-compact-orchestrator.ts +23 -23
- package/harness/context-window-manager.ts +5 -5
- package/harness/continue-prompt.ts +3 -3
- package/harness/e2e/minimax-quota-scraper.ts +10 -10
- package/harness/e2e/openai-quota-scraper.ts +442 -0
- package/harness/forked-summarizer.ts +4 -4
- package/harness/herdr-agents.ts +91 -0
- package/harness/index.ts +5 -5
- package/harness/loop-code-agent.ts +284 -0
- package/harness/loop-controller.ts +201 -0
- package/harness/loop-review-agent.ts +295 -0
- package/harness/loop-runtime.ts +21 -17
- package/harness/loop-types.ts +118 -0
- package/harness/notification-events.ts +3 -3
- package/harness/output-limit-handler.ts +1 -1
- package/harness/partial-recovery.ts +3 -3
- package/harness/session-memory.ts +5 -5
- package/index.ts +211 -80
- package/package.json +2 -2
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/a2a-adapter/src/types.ts +5 -5
- package/packages/auth/dist/minimax-browser-auth.d.ts +89 -0
- package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -0
- package/packages/auth/dist/minimax-browser-auth.js +890 -0
- package/packages/auth/dist/minimax-browser-auth.js.map +1 -0
- package/packages/auth/dist/run-minimax-auth.d.ts +19 -0
- package/packages/auth/dist/run-minimax-auth.d.ts.map +1 -0
- package/packages/auth/dist/run-minimax-auth.js +112 -0
- package/packages/auth/dist/run-minimax-auth.js.map +1 -0
- package/packages/auth/package.json +1 -1
- package/packages/auth/tsconfig.json +9 -0
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/dist/inbox.d.ts +3 -3
- package/packages/autonomous-runtime/dist/inbox.js +12 -12
- package/packages/autonomous-runtime/dist/lease.js +14 -14
- package/packages/autonomous-runtime/dist/types.js +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/autonomous-runtime/src/inbox.ts +12 -12
- package/packages/autonomous-runtime/src/lease.ts +15 -15
- package/packages/autonomous-runtime/src/types.ts +13 -13
- package/packages/autonomous-runtime/tsconfig.tsbuildinfo +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/dist/types.js +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/capability-registry/src/types.ts +5 -5
- package/packages/checkpoint/README.md +6 -6
- package/packages/checkpoint/dist/differ.js +2 -2
- package/packages/checkpoint/dist/engine.js +3 -3
- package/packages/checkpoint/dist/index.js +5 -5
- package/packages/checkpoint/dist/storage.js +3 -3
- package/packages/checkpoint/dist/types.js +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/checkpoint/src/differ.ts +2 -2
- package/packages/checkpoint/src/engine.ts +3 -3
- package/packages/checkpoint/src/index.ts +5 -5
- package/packages/checkpoint/src/storage.ts +3 -3
- package/packages/checkpoint/src/types.ts +10 -10
- package/packages/checkpoint/tsconfig.tsbuildinfo +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/dist/src/clipboard.d.ts.map +1 -1
- package/packages/clipboard/dist/src/clipboard.js +15 -7
- package/packages/clipboard/dist/src/clipboard.js.map +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard/src/clipboard.ts +16 -9
- package/packages/code-generation/README.md +13 -13
- package/packages/code-generation/dist/faker.js +4 -4
- package/packages/code-generation/dist/generator.js +3 -3
- package/packages/code-generation/dist/index.js +3 -3
- package/packages/code-generation/dist/templates/registry.js +1 -1
- package/packages/code-generation/dist/types.js +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-generation/src/faker.ts +5 -5
- package/packages/code-generation/src/generator.ts +4 -4
- package/packages/code-generation/src/index.ts +3 -3
- package/packages/code-generation/src/templates/registry.ts +1 -1
- package/packages/code-generation/src/types.ts +10 -10
- package/packages/code-generation/tsconfig.tsbuildinfo +1 -1
- package/packages/code-review/README.md +13 -13
- package/packages/code-review/dist/engine.js +3 -3
- package/packages/code-review/dist/index.js +3 -3
- package/packages/code-review/dist/types.js +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/code-review/src/engine.ts +3 -3
- package/packages/code-review/src/index.ts +3 -3
- package/packages/code-review/src/types.ts +10 -10
- package/packages/code-review/tsconfig.tsbuildinfo +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/context-compiler/dist/compiler.js +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-compiler/src/compiler.ts +1 -1
- package/packages/context-compiler/src/types.ts +11 -11
- package/packages/context-compiler/test/context-compiler.test.ts +11 -11
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/README.md +27 -27
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/cost-optimizer/src/types.ts +5 -5
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/dist/analyzer.js +7 -7
- package/packages/django-plugin/package.json +1 -1
- package/packages/django-plugin/src/analyzer.ts +7 -7
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/dist/engine.js +9 -9
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-engine/src/engine.ts +9 -9
- package/packages/evaluation-engine/src/types.ts +3 -3
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/dist/src/herdr-bus.d.ts +121 -0
- package/packages/event-bus/dist/src/herdr-bus.d.ts.map +1 -0
- package/packages/event-bus/dist/src/herdr-bus.js +322 -0
- package/packages/event-bus/dist/src/herdr-bus.js.map +1 -0
- package/packages/event-bus/dist/src/index.d.ts +2 -0
- package/packages/event-bus/dist/src/index.d.ts.map +1 -1
- package/packages/event-bus/dist/src/index.js +1 -0
- package/packages/event-bus/dist/src/index.js.map +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-bus/src/herdr-bus.ts +525 -0
- package/packages/event-bus/src/index.ts +29 -0
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/dist/replay.js +7 -7
- package/packages/experience-replay/package.json +1 -1
- package/packages/experience-replay/src/replay.ts +7 -7
- package/packages/experience-replay/src/types.ts +5 -5
- package/packages/feedback-collector/package.json +1 -1
- package/packages/framework-detector/README.md +18 -18
- package/packages/framework-detector/dist/detector.js +3 -3
- package/packages/framework-detector/dist/index.js +3 -3
- package/packages/framework-detector/dist/signatures/registry.js +24 -24
- package/packages/framework-detector/dist/types.js +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-detector/src/detector.ts +3 -3
- package/packages/framework-detector/src/index.ts +3 -3
- package/packages/framework-detector/src/signatures/registry.ts +24 -24
- package/packages/framework-detector/src/types.ts +7 -7
- package/packages/framework-detector/tsconfig.tsbuildinfo +1 -1
- package/packages/framework-plugin-sdk/README.md +23 -23
- package/packages/framework-plugin-sdk/dist/index.js +2 -2
- package/packages/framework-plugin-sdk/dist/manager.js +3 -3
- package/packages/framework-plugin-sdk/dist/types.js +2 -2
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/framework-plugin-sdk/src/index.ts +2 -2
- package/packages/framework-plugin-sdk/src/manager.ts +3 -3
- package/packages/framework-plugin-sdk/src/types.ts +10 -10
- package/packages/framework-plugin-sdk/tsconfig.tsbuildinfo +1 -1
- package/packages/frappe-plugin/dist/analyzer.js +8 -8
- package/packages/frappe-plugin/dist/types.js +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/frappe-plugin/src/analyzer.ts +8 -8
- package/packages/frappe-plugin/src/types.ts +10 -10
- package/packages/generic-web-plugin/dist/analyzer.js +5 -5
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/generic-web-plugin/src/analyzer.ts +5 -5
- package/packages/health-monitor/package.json +1 -1
- package/packages/health-monitor/src/monitor.ts +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/laravel-plugin/dist/analyzer.js +11 -11
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/laravel-plugin/src/analyzer.ts +11 -11
- package/packages/learning-engine/dist/engine.js +5 -5
- package/packages/learning-engine/dist/types.js +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/learning-engine/src/engine.ts +5 -5
- package/packages/learning-engine/src/types.ts +6 -6
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/dist/engine.js +8 -8
- package/packages/memory-engine/dist/types.js +2 -2
- package/packages/memory-engine/package.json +1 -1
- package/packages/memory-engine/src/engine.ts +8 -8
- package/packages/memory-engine/src/types.ts +9 -9
- package/packages/model-registry/package.json +1 -1
- package/packages/model-registry/src/types.ts +4 -4
- package/packages/nextjs-plugin/dist/analyzer.js +9 -9
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/nextjs-plugin/src/analyzer.ts +9 -9
- package/packages/notification/dist/notification-center.js +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/notification/src/notification-center.ts +1 -1
- package/packages/observability/dist/alerts.js +2 -2
- package/packages/observability/dist/health.js +4 -4
- package/packages/observability/dist/index.js +6 -6
- package/packages/observability/dist/logger.js +7 -7
- package/packages/observability/dist/metrics.js +11 -11
- package/packages/observability/dist/tracer.js +3 -3
- package/packages/observability/dist/types.js +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/observability/src/alerts.ts +2 -2
- package/packages/observability/src/health.ts +4 -4
- package/packages/observability/src/index.ts +6 -6
- package/packages/observability/src/logger.ts +7 -7
- package/packages/observability/src/metrics.ts +11 -11
- package/packages/observability/src/tracer.ts +3 -3
- package/packages/observability/src/types.ts +7 -7
- package/packages/observability/test/observability.test.ts +4 -4
- package/packages/observability/tsconfig.tsbuildinfo +1 -1
- package/packages/performance-optimizer/dist/optimizer.js +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/performance-optimizer/src/optimizer.ts +1 -1
- package/packages/performance-optimizer/src/types.ts +4 -4
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/dist/analyzer.js +4 -4
- package/packages/project-analyzer/dist/index.js +8 -8
- package/packages/project-analyzer/dist/signals.js +3 -3
- package/packages/project-analyzer/dist/types.js +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-analyzer/src/analyzer.ts +4 -4
- package/packages/project-analyzer/src/index.ts +9 -9
- package/packages/project-analyzer/src/signals.ts +4 -4
- package/packages/project-analyzer/src/types.ts +15 -15
- package/packages/project-analyzer/test/index.test.ts +17 -17
- package/packages/project-analyzer/tsconfig.tsbuildinfo +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/dist/section-builder.js +1 -1
- package/packages/prompt-compiler/dist/types.js +3 -3
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-compiler/src/section-builder.ts +1 -1
- package/packages/prompt-compiler/src/types.ts +12 -12
- package/packages/prompt-compiler/test/prompt-compiler.test.ts +12 -12
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/dist/builder.js +1 -1
- package/packages/provider-adapter-sdk/dist/index.js +5 -5
- package/packages/provider-adapter-sdk/dist/registry.js +1 -1
- package/packages/provider-adapter-sdk/dist/tester.js +1 -1
- package/packages/provider-adapter-sdk/dist/types.js +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-adapter-sdk/src/builder.ts +1 -1
- package/packages/provider-adapter-sdk/src/index.ts +6 -6
- package/packages/provider-adapter-sdk/src/registry.ts +1 -1
- package/packages/provider-adapter-sdk/src/tester.ts +1 -1
- package/packages/provider-adapter-sdk/src/types.ts +5 -5
- package/packages/provider-adapter-sdk/tsconfig.tsbuildinfo +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-router/src/types.ts +4 -4
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/dist/deepagents-adapter.js +1 -1
- package/packages/providers/dist/provider-id.d.ts +5 -0
- package/packages/providers/dist/provider-id.d.ts.map +1 -1
- package/packages/providers/dist/provider-id.js +6 -1
- package/packages/providers/dist/provider-id.js.map +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/providers/src/deepagents-adapter.ts +1 -1
- package/packages/providers/src/provider-id.ts +6 -1
- package/packages/quota-manager/dist/tui-usage-monitor.d.ts.map +1 -1
- package/packages/quota-manager/dist/tui-usage-monitor.js +0 -6
- package/packages/quota-manager/dist/tui-usage-monitor.js.map +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/quota-manager/src/tui-usage-monitor.ts +0 -21
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/dist/analyzer.js +7 -7
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/react-vite-plugin/src/analyzer.ts +7 -7
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/dist/compiler.js +17 -17
- package/packages/requirement-compiler/dist/types.js +2 -2
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/requirement-compiler/src/compiler.ts +17 -17
- package/packages/requirement-compiler/src/types.ts +21 -21
- package/packages/requirement-compiler/test/requirement-compiler.test.ts +17 -17
- package/packages/runtime/dist/command-executor.js +1 -1
- package/packages/runtime/dist/local-runtime-agent.js +1 -1
- package/packages/runtime/dist/policy-engine.js +1 -1
- package/packages/runtime/dist/runtime-api.js +1 -1
- package/packages/runtime/dist/workspace-manager.js +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/runtime/src/command-executor.ts +1 -1
- package/packages/runtime/src/local-runtime-agent.ts +1 -1
- package/packages/runtime/src/policy-engine.ts +1 -1
- package/packages/runtime/src/runtime-api.ts +1 -1
- package/packages/runtime/src/workspace-manager.ts +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/README.md +18 -18
- package/packages/session/dist/history.js +3 -3
- package/packages/session/dist/index.js +5 -5
- package/packages/session/dist/manager.js +3 -3
- package/packages/session/dist/policy.js +2 -2
- package/packages/session/dist/store.js +2 -2
- package/packages/session/dist/types.js +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session/src/history.ts +3 -3
- package/packages/session/src/index.ts +5 -5
- package/packages/session/src/manager.ts +3 -3
- package/packages/session/src/policy.ts +4 -4
- package/packages/session/src/store.ts +3 -3
- package/packages/session/src/types.ts +10 -10
- package/packages/session/tsconfig.tsbuildinfo +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-registry/package.json +1 -1
- package/packages/skill-registry/src/types.ts +4 -4
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/dist/compiler.js +7 -7
- package/packages/task-compiler/dist/decompose.js +11 -11
- package/packages/task-compiler/dist/file-scope.js +6 -6
- package/packages/task-compiler/dist/graph.js +6 -6
- package/packages/task-compiler/dist/index.js +2 -2
- package/packages/task-compiler/dist/types.js +5 -5
- package/packages/task-compiler/dist/validate.js +2 -2
- package/packages/task-compiler/dist/verification.js +2 -2
- package/packages/task-compiler/package.json +1 -1
- package/packages/task-compiler/src/command-policy.ts +1 -1
- package/packages/task-compiler/src/compiler.ts +7 -7
- package/packages/task-compiler/src/decompose.ts +11 -11
- package/packages/task-compiler/src/file-scope.ts +6 -6
- package/packages/task-compiler/src/graph.ts +6 -6
- package/packages/task-compiler/src/index.ts +3 -3
- package/packages/task-compiler/src/types.ts +14 -14
- package/packages/task-compiler/src/validate.ts +2 -2
- package/packages/task-compiler/src/verification.ts +2 -2
- package/packages/task-compiler/test/task-compiler.test.ts +10 -10
- package/packages/test-data-generator/README.md +13 -13
- package/packages/test-data-generator/dist/faker-adapter.js +4 -4
- package/packages/test-data-generator/dist/generator.js +3 -3
- package/packages/test-data-generator/dist/index.js +3 -3
- package/packages/test-data-generator/dist/types.js +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-data-generator/src/faker-adapter.ts +4 -4
- package/packages/test-data-generator/src/generator.ts +3 -3
- package/packages/test-data-generator/src/index.ts +3 -3
- package/packages/test-data-generator/src/types.ts +9 -9
- package/packages/test-data-generator/tsconfig.tsbuildinfo +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/types/src/agent-worker-types.ts +5 -5
- package/packages/types/src/runtime-types.ts +12 -12
- package/packages/types/tsconfig.tsbuildinfo +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/renderer.ts +7 -7
- package/skills/harness-runtime/SKILL.md +15 -15
- package/packages/dependency-analyzer/dist/analyzer.d.ts +0 -17
- package/packages/dependency-analyzer/dist/analyzer.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/analyzer.js +0 -106
- package/packages/dependency-analyzer/dist/analyzer.js.map +0 -1
- package/packages/dependency-analyzer/dist/imports.d.ts +0 -12
- package/packages/dependency-analyzer/dist/imports.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/imports.js +0 -73
- package/packages/dependency-analyzer/dist/imports.js.map +0 -1
- package/packages/dependency-analyzer/dist/index.d.ts +0 -4
- package/packages/dependency-analyzer/dist/index.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/index.js +0 -3
- package/packages/dependency-analyzer/dist/index.js.map +0 -1
- package/packages/dependency-analyzer/dist/test/analyzer.test.js +0 -37
- package/packages/dependency-analyzer/dist/types.d.ts +0 -28
- package/packages/dependency-analyzer/dist/types.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/types.js +0 -5
- package/packages/dependency-analyzer/dist/types.js.map +0 -1
- package/packages/intent-analyzer/dist/analyzer.d.ts +0 -13
- package/packages/intent-analyzer/dist/analyzer.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/analyzer.js +0 -72
- package/packages/intent-analyzer/dist/analyzer.js.map +0 -1
- package/packages/intent-analyzer/dist/index.d.ts +0 -3
- package/packages/intent-analyzer/dist/index.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/index.js +0 -2
- package/packages/intent-analyzer/dist/index.js.map +0 -1
- package/packages/intent-analyzer/dist/test/analyzer.test.js +0 -56
- package/packages/intent-analyzer/dist/types.d.ts +0 -26
- package/packages/intent-analyzer/dist/types.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/types.js +0 -7
- package/packages/intent-analyzer/dist/types.js.map +0 -1
- package/packages/workspace-scanner/dist/detect.d.ts +0 -3
- package/packages/workspace-scanner/dist/detect.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/detect.js +0 -58
- package/packages/workspace-scanner/dist/detect.js.map +0 -1
- package/packages/workspace-scanner/dist/git.d.ts +0 -7
- package/packages/workspace-scanner/dist/git.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/git.js +0 -75
- package/packages/workspace-scanner/dist/git.js.map +0 -1
- package/packages/workspace-scanner/dist/index.d.ts +0 -5
- package/packages/workspace-scanner/dist/index.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/index.js +0 -4
- package/packages/workspace-scanner/dist/index.js.map +0 -1
- package/packages/workspace-scanner/dist/scanner.d.ts +0 -11
- package/packages/workspace-scanner/dist/scanner.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/scanner.js +0 -46
- package/packages/workspace-scanner/dist/scanner.js.map +0 -1
- package/packages/workspace-scanner/dist/test/scanner.test.js +0 -34
- package/packages/workspace-scanner/dist/types.d.ts +0 -35
- package/packages/workspace-scanner/dist/types.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/types.js +0 -5
- package/packages/workspace-scanner/dist/types.js.map +0 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop Review Agent (GPT) — coordinates via blackboard.
|
|
3
|
+
*
|
|
4
|
+
* Polls blackboard for nextAction where agentType="review".
|
|
5
|
+
* Reviews code, writes verdict, updates node status.
|
|
6
|
+
*
|
|
7
|
+
* Usage: bun harness/loop-review-agent.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
import {
|
|
13
|
+
ensureHerdrWorkspace,
|
|
14
|
+
parseVerdict,
|
|
15
|
+
} from "../packages/event-bus/src/herdr-bus.js";
|
|
16
|
+
import { SharedBlackboard } from "./blackboard.js";
|
|
17
|
+
import type {
|
|
18
|
+
LoopNextAction,
|
|
19
|
+
LoopAgentReport,
|
|
20
|
+
LoopVerdict,
|
|
21
|
+
} from "./loop-types.js";
|
|
22
|
+
|
|
23
|
+
const AGENT_ID = "review-agent";
|
|
24
|
+
const AGENT_TYPE = "review";
|
|
25
|
+
const POLL_MS = 1000;
|
|
26
|
+
const REVIEW_TIMEOUT_MS = 5 * 60 * 1000;
|
|
27
|
+
|
|
28
|
+
async function main(): Promise<void> {
|
|
29
|
+
console.log(`[${AGENT_ID}] Starting...`);
|
|
30
|
+
const paths = ensureHerdrWorkspace();
|
|
31
|
+
|
|
32
|
+
// Find active loop config
|
|
33
|
+
const loopId = await findActiveLoop(paths.root);
|
|
34
|
+
if (!loopId) console.log(`[${AGENT_ID}] No active loop found. Waiting...`);
|
|
35
|
+
|
|
36
|
+
const blackboard = new SharedBlackboard(loopId ?? "no-loop", paths.root);
|
|
37
|
+
blackboard.load();
|
|
38
|
+
blackboard.registerAgent(AGENT_ID, "Review Agent", "openai", "gpt-4o");
|
|
39
|
+
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
40
|
+
console.log(`[${AGENT_ID}] Registered. Blackboard: ${blackboard.getPath()}`);
|
|
41
|
+
|
|
42
|
+
while (true) {
|
|
43
|
+
await sleep(POLL_MS);
|
|
44
|
+
|
|
45
|
+
blackboard.load();
|
|
46
|
+
const record = blackboard.getRecord();
|
|
47
|
+
if (!record) continue;
|
|
48
|
+
if (record.jobId !== loopId) continue;
|
|
49
|
+
|
|
50
|
+
// Check for early exit
|
|
51
|
+
const earlyExit = checkEarlyExit(record);
|
|
52
|
+
if (earlyExit) {
|
|
53
|
+
console.log(`[${AGENT_ID}] Loop ended: ${earlyExit}`);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Check nextAction for review agent
|
|
58
|
+
const action = parseNextAction(record.nextAction);
|
|
59
|
+
if (!action || action.agentType !== AGENT_TYPE) continue;
|
|
60
|
+
|
|
61
|
+
// Claim the task
|
|
62
|
+
const locked = blackboard.acquireLock(action.taskId, AGENT_ID);
|
|
63
|
+
if (!locked) continue;
|
|
64
|
+
|
|
65
|
+
blackboard.updateAgentStatus(AGENT_ID, "working", action.taskId);
|
|
66
|
+
console.log(`[${AGENT_ID}] Claimed: ${action.taskId}`);
|
|
67
|
+
|
|
68
|
+
// Handle report task
|
|
69
|
+
if (action.taskId === "report") {
|
|
70
|
+
await finishReport(blackboard, record);
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Do the review
|
|
75
|
+
const verdict = await doReview(action, paths, record.jobId);
|
|
76
|
+
|
|
77
|
+
// Update task status
|
|
78
|
+
updateTaskStatus(blackboard, record, action.taskId, verdict);
|
|
79
|
+
|
|
80
|
+
// Release and report
|
|
81
|
+
blackboard.releaseLock(action.taskId, AGENT_ID);
|
|
82
|
+
blackboard.writeReport({
|
|
83
|
+
agentId: AGENT_ID,
|
|
84
|
+
taskId: action.taskId,
|
|
85
|
+
status: "success",
|
|
86
|
+
message: verdict,
|
|
87
|
+
} as unknown as Parameters<typeof blackboard.writeReport>[0]);
|
|
88
|
+
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
89
|
+
|
|
90
|
+
// Decide next action based on verdict
|
|
91
|
+
if (verdict === "approved" || verdict === "blocked") {
|
|
92
|
+
// Early exit — go to report
|
|
93
|
+
blackboard.setNextAction(
|
|
94
|
+
encodeNextAction({
|
|
95
|
+
taskId: "report",
|
|
96
|
+
agentType: "review",
|
|
97
|
+
iteration: 0,
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
console.log(
|
|
101
|
+
`[${AGENT_ID}] ${verdict.toUpperCase()} — nextAction: report`,
|
|
102
|
+
);
|
|
103
|
+
} else {
|
|
104
|
+
// Changes requested — continue to next write
|
|
105
|
+
const nextWrite = getNextWriteTask(record, action.iteration);
|
|
106
|
+
if (nextWrite) {
|
|
107
|
+
blackboard.setNextAction(
|
|
108
|
+
encodeNextAction({
|
|
109
|
+
taskId: nextWrite,
|
|
110
|
+
agentType: "code",
|
|
111
|
+
iteration: getWriteIteration(nextWrite),
|
|
112
|
+
prompt: action.prompt,
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
115
|
+
console.log(`[${AGENT_ID}] CHANGES — nextAction: code ${nextWrite}`);
|
|
116
|
+
} else {
|
|
117
|
+
blackboard.setNextAction({
|
|
118
|
+
taskId: "report",
|
|
119
|
+
agentType: "review",
|
|
120
|
+
iteration: 0,
|
|
121
|
+
} as unknown as ReturnType<typeof encodeNextAction>);
|
|
122
|
+
console.log(`[${AGENT_ID}] CHANGES — nextAction: report`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ─── Review Logic ────────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
async function doReview(
|
|
131
|
+
action: LoopNextAction,
|
|
132
|
+
paths: { reviews: string },
|
|
133
|
+
loopId: string,
|
|
134
|
+
): Promise<LoopVerdict> {
|
|
135
|
+
const reviewDir = join(paths.reviews, loopId);
|
|
136
|
+
mkdirSync(reviewDir, { recursive: true });
|
|
137
|
+
|
|
138
|
+
const reviewFile = join(reviewDir, `review-${action.iteration}.md`);
|
|
139
|
+
|
|
140
|
+
// Read code files
|
|
141
|
+
const codeBlocks = await Promise.all(
|
|
142
|
+
(action.codeFiles ?? []).map(async (file) => {
|
|
143
|
+
const content = existsSync(file)
|
|
144
|
+
? readFileSync(file, "utf-8").slice(0, 3000)
|
|
145
|
+
: `[Not found: ${file}]`;
|
|
146
|
+
return `## ${file}\n\n\`\`\`\n${content}\n\`\`\`\n`;
|
|
147
|
+
}),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Write review stub
|
|
151
|
+
const review = `# Review — Iteration ${action.iteration}
|
|
152
|
+
|
|
153
|
+
> GPT tab: Edit this file and add your verdict at the bottom.
|
|
154
|
+
> Use: \`## Verdict: APPROVED\`, \`## Verdict: CHANGES_REQUESTED\`, or \`## Verdict: BLOCKED\`
|
|
155
|
+
> GPT tab has ${REVIEW_TIMEOUT_MS / 1000 / 60} minutes to complete.
|
|
156
|
+
|
|
157
|
+
${codeBlocks.join("\n")}
|
|
158
|
+
`;
|
|
159
|
+
writeFileSync(reviewFile, review);
|
|
160
|
+
console.log(`[${AGENT_ID}] Review stub: ${reviewFile}`);
|
|
161
|
+
console.log(`[${AGENT_ID}] Waiting for GPT verdict...`);
|
|
162
|
+
|
|
163
|
+
// Poll for verdict
|
|
164
|
+
return await pollVerdict(reviewFile);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function pollVerdict(reviewFile: string): Promise<LoopVerdict> {
|
|
168
|
+
const deadline = Date.now() + REVIEW_TIMEOUT_MS;
|
|
169
|
+
while (Date.now() < deadline) {
|
|
170
|
+
if (existsSync(reviewFile)) {
|
|
171
|
+
const content = readFileSync(reviewFile, "utf-8");
|
|
172
|
+
const verdict = parseVerdict(content);
|
|
173
|
+
if (verdict) return verdict;
|
|
174
|
+
}
|
|
175
|
+
await sleep(3000);
|
|
176
|
+
}
|
|
177
|
+
console.log(
|
|
178
|
+
`[${AGENT_ID}] Verdict timeout — defaulting to CHANGES_REQUESTED`,
|
|
179
|
+
);
|
|
180
|
+
return "changes_requested";
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function finishReport(
|
|
184
|
+
blackboard: SharedBlackboard,
|
|
185
|
+
record: { tasks: { nodes: Record<string, { status: string }> } },
|
|
186
|
+
): Promise<void> {
|
|
187
|
+
const reportNode = record.tasks.nodes["report"] as { status: string };
|
|
188
|
+
reportNode.status = "done";
|
|
189
|
+
blackboard.save();
|
|
190
|
+
console.log(`[${AGENT_ID}] Report complete. Loop finished.`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
194
|
+
|
|
195
|
+
async function findActiveLoop(rootDir: string): Promise<string | null> {
|
|
196
|
+
const { readdirSync } = await import("fs");
|
|
197
|
+
try {
|
|
198
|
+
const files = readdirSync(rootDir).filter(
|
|
199
|
+
(f) => f.startsWith("loop-") && f.endsWith(".config.json"),
|
|
200
|
+
);
|
|
201
|
+
if (files.length > 0) {
|
|
202
|
+
const config = JSON.parse(readFileSync(join(rootDir, files[0]), "utf-8"));
|
|
203
|
+
return config.loopId;
|
|
204
|
+
}
|
|
205
|
+
} catch {
|
|
206
|
+
// no loop yet
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function checkEarlyExit(record: {
|
|
212
|
+
tasks: { nodes: Record<string, { status: string }> };
|
|
213
|
+
jobId: string;
|
|
214
|
+
}): string | null {
|
|
215
|
+
const reportNode = record.tasks.nodes["report"];
|
|
216
|
+
if (
|
|
217
|
+
reportNode &&
|
|
218
|
+
(reportNode.status === "done" || reportNode.status === "blocked")
|
|
219
|
+
) {
|
|
220
|
+
return reportNode.status === "done" ? "finished" : "blocked";
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function updateTaskStatus(
|
|
226
|
+
blackboard: SharedBlackboard,
|
|
227
|
+
record: {
|
|
228
|
+
tasks: { nodes: Record<string, { status: string; result?: string }> };
|
|
229
|
+
},
|
|
230
|
+
taskId: string,
|
|
231
|
+
verdict: LoopVerdict,
|
|
232
|
+
): void {
|
|
233
|
+
const node = record.tasks.nodes[taskId] as
|
|
234
|
+
| { status: string; result?: string }
|
|
235
|
+
| undefined;
|
|
236
|
+
if (node) {
|
|
237
|
+
node.status = verdict === "blocked" ? "blocked" : "done";
|
|
238
|
+
node.result = verdict;
|
|
239
|
+
node.updatedAt = new Date().toISOString();
|
|
240
|
+
blackboard.save();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function encodeNextAction(action: Partial<LoopNextAction>) {
|
|
245
|
+
return {
|
|
246
|
+
taskId: action.taskId,
|
|
247
|
+
instruction: "LOOP:" + JSON.stringify(action),
|
|
248
|
+
priority: "high" as const,
|
|
249
|
+
createdAt: new Date().toISOString(),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function parseNextAction(nextAction: unknown): LoopNextAction | null {
|
|
254
|
+
if (!nextAction) return null;
|
|
255
|
+
const a = nextAction as Record<string, unknown>;
|
|
256
|
+
if (!a.taskId) return null;
|
|
257
|
+
if (typeof a.instruction === "string" && a.instruction.startsWith("LOOP:")) {
|
|
258
|
+
try {
|
|
259
|
+
return JSON.parse(a.instruction.slice(5)) as LoopNextAction;
|
|
260
|
+
} catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function getNextWriteTask(
|
|
268
|
+
record: { tasks: { nodes: Record<string, { status: string }> } },
|
|
269
|
+
currentReviewIteration: number,
|
|
270
|
+
): string | null {
|
|
271
|
+
const writeCount = Object.keys(record.tasks.nodes).filter((id) =>
|
|
272
|
+
id.startsWith("write-"),
|
|
273
|
+
).length;
|
|
274
|
+
// After review N, next write is N+1
|
|
275
|
+
const nextWrite = currentReviewIteration + 1;
|
|
276
|
+
const taskId = `write-${nextWrite}`;
|
|
277
|
+
if (
|
|
278
|
+
record.tasks.nodes[taskId] &&
|
|
279
|
+
record.tasks.nodes[taskId].status === "pending"
|
|
280
|
+
) {
|
|
281
|
+
return taskId;
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function getWriteIteration(taskId: string): number {
|
|
287
|
+
const m = taskId.match(/^write-(\d+)$/);
|
|
288
|
+
return m ? parseInt(m[1], 10) : 0;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function sleep(ms: number): Promise<void> {
|
|
292
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
main().catch(console.error);
|
package/harness/loop-runtime.ts
CHANGED
|
@@ -46,12 +46,12 @@ import {
|
|
|
46
46
|
createForkedSummarizer,
|
|
47
47
|
} from "./forked-summarizer.js";
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// --- Constants ----------------------------------------------------------------
|
|
50
50
|
|
|
51
51
|
const DEFAULT_MAX_COMPACT_RETRIES = 3;
|
|
52
52
|
const DEFAULT_MAX_OUTPUT_TOKENS = 4096;
|
|
53
53
|
|
|
54
|
-
//
|
|
54
|
+
// --- Lifecycle Callbacks ----------------------------------------------------
|
|
55
55
|
|
|
56
56
|
export interface LoopCallbacks {
|
|
57
57
|
/** Fetch next task from queue */
|
|
@@ -97,7 +97,7 @@ export interface LoopCallbacks {
|
|
|
97
97
|
onCompaction?: (result: CompactResult) => void;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
//
|
|
100
|
+
// --- Loop Result -----------------------------------------------------------
|
|
101
101
|
|
|
102
102
|
export interface LoopResult {
|
|
103
103
|
success: boolean;
|
|
@@ -109,7 +109,7 @@ export interface LoopResult {
|
|
|
109
109
|
totalCompactions?: number;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
//
|
|
112
|
+
// --- Loop Runtime -----------------------------------------------------------
|
|
113
113
|
|
|
114
114
|
export class LoopRuntime {
|
|
115
115
|
private readonly config: Required<LoopConfig>;
|
|
@@ -221,12 +221,12 @@ export class LoopRuntime {
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
//
|
|
224
|
+
// --- Public API ---------------------------------------------------------
|
|
225
225
|
|
|
226
226
|
async run(): Promise<LoopResult> {
|
|
227
227
|
this.running = true;
|
|
228
228
|
|
|
229
|
-
//
|
|
229
|
+
// --- Auto-resume from quota pause ----------------------------------
|
|
230
230
|
const checkpoint = await this.callbacks.onGetCheckpoint?.();
|
|
231
231
|
if (checkpoint?.status === "paused_quota" && checkpoint.resumeAt) {
|
|
232
232
|
const resumeMs = new Date(checkpoint.resumeAt).getTime();
|
|
@@ -244,7 +244,11 @@ export class LoopRuntime {
|
|
|
244
244
|
await new Promise((r) => setTimeout(r, 5 * 60_000)); // 5 min
|
|
245
245
|
// Re-check mirror — quota may have reset early
|
|
246
246
|
const fresh = await this.callbacks.onCheckMirror?.("minimax");
|
|
247
|
-
if (
|
|
247
|
+
if (
|
|
248
|
+
fresh &&
|
|
249
|
+
fresh.h5_used_pct !== undefined &&
|
|
250
|
+
fresh.h5_used_pct < 100
|
|
251
|
+
) {
|
|
248
252
|
break; // quota reset early, resume now
|
|
249
253
|
}
|
|
250
254
|
}
|
|
@@ -344,7 +348,7 @@ export class LoopRuntime {
|
|
|
344
348
|
return this.sessionMemory;
|
|
345
349
|
}
|
|
346
350
|
|
|
347
|
-
//
|
|
351
|
+
// --- Task Execution with Compact ---------------------------------------
|
|
348
352
|
|
|
349
353
|
private async executeTaskWithCompact(task: RuntimeTask): Promise<void> {
|
|
350
354
|
// 1. Pick model
|
|
@@ -686,7 +690,7 @@ export class LoopRuntime {
|
|
|
686
690
|
return parts.join("\n");
|
|
687
691
|
}
|
|
688
692
|
|
|
689
|
-
//
|
|
693
|
+
// --- Quota Handling ----------------------------------------------------
|
|
690
694
|
|
|
691
695
|
private async handleQuotaPause(): Promise<void> {
|
|
692
696
|
this.paused = true;
|
|
@@ -700,20 +704,20 @@ export class LoopRuntime {
|
|
|
700
704
|
if (epoch) {
|
|
701
705
|
const resumeAt = new Date(epoch).toISOString();
|
|
702
706
|
await this.jobState.setResumeTime(resumeAt);
|
|
703
|
-
console.log(
|
|
704
|
-
|
|
705
|
-
);
|
|
707
|
+
// console.log(
|
|
708
|
+
// `[LoopRuntime] Paused for 5h quota. Auto-resume at ${resumeAt}`,
|
|
709
|
+
// );
|
|
706
710
|
} else {
|
|
707
|
-
console.log(
|
|
708
|
-
|
|
709
|
-
);
|
|
711
|
+
// console.log(
|
|
712
|
+
// "[LoopRuntime] Paused for quota but no reset time known yet.",
|
|
713
|
+
// );
|
|
710
714
|
}
|
|
711
715
|
|
|
712
716
|
await this.callbacks.onQuotaEvent?.("paused");
|
|
713
717
|
await this.saveCheckpoint();
|
|
714
718
|
}
|
|
715
719
|
|
|
716
|
-
//
|
|
720
|
+
// --- Persistence --------------------------------------------------------
|
|
717
721
|
|
|
718
722
|
private async saveCheckpoint(): Promise<void> {
|
|
719
723
|
const now = new Date().toISOString();
|
|
@@ -732,7 +736,7 @@ export class LoopRuntime {
|
|
|
732
736
|
await this.callbacks.onCheckpoint?.(checkpoint);
|
|
733
737
|
}
|
|
734
738
|
|
|
735
|
-
//
|
|
739
|
+
// --- Resume from Checkpoint --------------------------------------------
|
|
736
740
|
|
|
737
741
|
async resumeFromCheckpoint(
|
|
738
742
|
checkpoint: RuntimeCheckpoint,
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for loop coordination via blackboard.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
TaskGraph,
|
|
7
|
+
TaskNode,
|
|
8
|
+
} from "../packages/types/src/runtime-types.ts";
|
|
9
|
+
|
|
10
|
+
export type LoopVerdict = "approved" | "changes_requested" | "blocked";
|
|
11
|
+
export type LoopNodeType = "write" | "review" | "decide" | "report";
|
|
12
|
+
export type LoopNodeStatus = "pending" | "running" | "done" | "blocked";
|
|
13
|
+
|
|
14
|
+
export interface LoopNextAction {
|
|
15
|
+
taskId: string;
|
|
16
|
+
agentType: "code" | "review";
|
|
17
|
+
iteration: number;
|
|
18
|
+
prompt?: string;
|
|
19
|
+
codeFiles?: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface LoopAgentReport {
|
|
23
|
+
agentId: string;
|
|
24
|
+
taskId: string;
|
|
25
|
+
status: "running" | "done" | "failed";
|
|
26
|
+
message?: string;
|
|
27
|
+
files?: string[];
|
|
28
|
+
verdict?: LoopVerdict;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface LoopTaskGraph {
|
|
32
|
+
nodes: Record<string, TaskNode>;
|
|
33
|
+
topologicalOrder: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function buildLoopTaskGraph(
|
|
37
|
+
writeCount: number,
|
|
38
|
+
reviewCount: number,
|
|
39
|
+
loopId: string,
|
|
40
|
+
): TaskGraph {
|
|
41
|
+
const now = new Date().toISOString();
|
|
42
|
+
const nodes: Record<string, TaskNode> = {};
|
|
43
|
+
const order: string[] = [];
|
|
44
|
+
|
|
45
|
+
// Write tasks
|
|
46
|
+
for (let i = 1; i <= writeCount; i++) {
|
|
47
|
+
const id = `write-${i}`;
|
|
48
|
+
nodes[id] = {
|
|
49
|
+
id,
|
|
50
|
+
title: `Code Write ${i}`,
|
|
51
|
+
description: `Write iteration ${i}`,
|
|
52
|
+
status: "pending",
|
|
53
|
+
dependencies: [],
|
|
54
|
+
dependents: [],
|
|
55
|
+
createdAt: now,
|
|
56
|
+
updatedAt: now,
|
|
57
|
+
};
|
|
58
|
+
order.push(id);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Review tasks
|
|
62
|
+
const step = Math.max(1, Math.floor(writeCount / (reviewCount || 1)));
|
|
63
|
+
for (let i = 1; i <= reviewCount; i++) {
|
|
64
|
+
const id = `review-${i}`;
|
|
65
|
+
const writeIdx = i * step;
|
|
66
|
+
nodes[id] = {
|
|
67
|
+
id,
|
|
68
|
+
title: `Code Review ${i}`,
|
|
69
|
+
description: `Review iteration ${i}`,
|
|
70
|
+
status: "pending",
|
|
71
|
+
dependencies: writeIdx <= writeCount ? [`write-${writeIdx}`] : [],
|
|
72
|
+
dependents: [],
|
|
73
|
+
createdAt: now,
|
|
74
|
+
updatedAt: now,
|
|
75
|
+
};
|
|
76
|
+
// Wire dependencies
|
|
77
|
+
if (writeIdx <= writeCount) {
|
|
78
|
+
nodes[`write-${writeIdx}`].dependents.push(id);
|
|
79
|
+
}
|
|
80
|
+
order.push(id);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Report task
|
|
84
|
+
const reportId = "report";
|
|
85
|
+
nodes[reportId] = {
|
|
86
|
+
id: reportId,
|
|
87
|
+
title: "Loop Report",
|
|
88
|
+
description: "Final summary",
|
|
89
|
+
status: "pending",
|
|
90
|
+
dependencies: [],
|
|
91
|
+
dependents: [],
|
|
92
|
+
createdAt: now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
};
|
|
95
|
+
order.push(reportId);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
jobId: loopId,
|
|
99
|
+
nodes,
|
|
100
|
+
topologicalOrder: order,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function getNodeStatus(
|
|
105
|
+
graph: TaskGraph,
|
|
106
|
+
nodeId: string,
|
|
107
|
+
): LoopNodeStatus | undefined {
|
|
108
|
+
return graph.nodes[nodeId]?.status as LoopNodeStatus | undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function getReviewVerdict(
|
|
112
|
+
graph: TaskGraph,
|
|
113
|
+
reviewId: string,
|
|
114
|
+
): LoopVerdict | undefined {
|
|
115
|
+
const node = graph.nodes[reviewId];
|
|
116
|
+
if (!node) return undefined;
|
|
117
|
+
return (node as unknown as { result?: LoopVerdict }).result;
|
|
118
|
+
}
|
|
@@ -73,7 +73,7 @@ export class HarnessNotificationEvents {
|
|
|
73
73
|
return this.center.listChannels();
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
//
|
|
76
|
+
// --- Event Emitters ------------------------------------------------
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* Emit JobStarted event
|
|
@@ -173,7 +173,7 @@ export class HarnessNotificationEvents {
|
|
|
173
173
|
await this.emit("Error", { error });
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
//
|
|
176
|
+
// --- State Machine Event Listeners ---------------------------------
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Wire up with JobStateMachine to emit events on transitions
|
|
@@ -207,7 +207,7 @@ export class HarnessNotificationEvents {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
//
|
|
210
|
+
// --- Private Methods -----------------------------------------------
|
|
211
211
|
|
|
212
212
|
private async emit(
|
|
213
213
|
event: NotificationEvent,
|
|
@@ -277,7 +277,7 @@ export class OutputLimitHandler {
|
|
|
277
277
|
return this.attempts >= this.maxAttempts;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
//
|
|
280
|
+
// --- Private Methods ------------------------------------------------
|
|
281
281
|
|
|
282
282
|
private ensureDir(): void {
|
|
283
283
|
if (!existsSync(this.rootDir)) {
|
|
@@ -70,7 +70,7 @@ export class PartialRecovery {
|
|
|
70
70
|
this.loadExistingPartials();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
//
|
|
73
|
+
// --- Public API -----------------------------------------------------------
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* Save a partial response
|
|
@@ -285,7 +285,7 @@ export class PartialRecovery {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
//
|
|
288
|
+
// --- Private Methods ------------------------------------------------
|
|
289
289
|
|
|
290
290
|
private ensureDir(): void {
|
|
291
291
|
if (!existsSync(this.rootDir)) {
|
|
@@ -517,7 +517,7 @@ export class PartialRecovery {
|
|
|
517
517
|
}
|
|
518
518
|
}
|
|
519
519
|
|
|
520
|
-
//
|
|
520
|
+
// --- Factory ----------------------------------------------------------------
|
|
521
521
|
|
|
522
522
|
/**
|
|
523
523
|
* Create a PartialRecovery manager for a task
|
|
@@ -11,7 +11,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import type { CompactableMessage } from "../packages/types/src/runtime-types.js";
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// --- Types ------------------------------------------------------------------
|
|
15
15
|
|
|
16
16
|
export interface SessionMemory {
|
|
17
17
|
jobId: string;
|
|
@@ -41,7 +41,7 @@ export interface TestResult {
|
|
|
41
41
|
timestamp: string;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
//
|
|
44
|
+
// --- Session Memory Manager -------------------------------------------------
|
|
45
45
|
|
|
46
46
|
export class SessionMemoryManager {
|
|
47
47
|
private memory: SessionMemory;
|
|
@@ -66,7 +66,7 @@ export class SessionMemoryManager {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// --- Public API -----------------------------------------------------------
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Extract key facts from recent messages
|
|
@@ -362,7 +362,7 @@ export class SessionMemoryManager {
|
|
|
362
362
|
this.save();
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
//
|
|
365
|
+
// --- Private Methods --------------------------------------------------
|
|
366
366
|
|
|
367
367
|
private load(): SessionMemory | null {
|
|
368
368
|
if (!existsSync(this.memoryPath)) {
|
|
@@ -388,7 +388,7 @@ export class SessionMemoryManager {
|
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
//
|
|
391
|
+
// --- Factory ----------------------------------------------------------------
|
|
392
392
|
|
|
393
393
|
/**
|
|
394
394
|
* Create a SessionMemoryManager for a job
|