pi-harness-runtime 0.9.25 → 1.1.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 +173 -51
- package/harness/auto-compact.ts +1 -1
- 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 +5 -5
- package/harness/e2e/openai-quota-scraper.ts +13 -8
- 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 +10 -10
- 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 +139 -34
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/a2a-adapter/src/types.ts +5 -5
- package/packages/auth/package.json +1 -1
- 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/dist/src/copy-sync.d.ts +27 -0
- package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -0
- package/packages/clipboard/dist/src/copy-sync.js +170 -0
- package/packages/clipboard/dist/src/copy-sync.js.map +1 -0
- package/packages/clipboard/dist/src/gist-relay.d.ts +48 -0
- package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -0
- package/packages/clipboard/dist/src/gist-relay.js +186 -0
- package/packages/clipboard/dist/src/gist-relay.js.map +1 -0
- package/packages/clipboard/dist/src/github-login.d.ts +16 -0
- package/packages/clipboard/dist/src/github-login.d.ts.map +1 -0
- package/packages/clipboard/dist/src/github-login.js +69 -0
- package/packages/clipboard/dist/src/github-login.js.map +1 -0
- package/packages/clipboard/dist/src/index.d.ts +2 -0
- package/packages/clipboard/dist/src/index.d.ts.map +1 -1
- package/packages/clipboard/dist/src/index.js +2 -1
- package/packages/clipboard/dist/src/index.js.map +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard/src/clipboard.ts +16 -9
- package/packages/clipboard/src/copy-sync.ts +201 -0
- package/packages/clipboard/src/gist-relay.ts +240 -0
- package/packages/clipboard/src/github-login.ts +107 -0
- package/packages/clipboard/src/index.ts +2 -0
- package/packages/clipboard/test/mojibake.test.mjs +143 -0
- 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/package.json +1 -1
- package/packages/providers/src/deepagents-adapter.ts +1 -1
- package/packages/quota-manager/package.json +1 -1
- 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/todo-bd-sync/package.json +22 -0
- package/packages/todo-bd-sync/src/detector.ts +150 -0
- package/packages/todo-bd-sync/src/extension.ts +101 -0
- package/packages/todo-bd-sync/src/index.ts +401 -0
- package/packages/todo-bd-sync/src/sync.ts +322 -0
- package/packages/todo-bd-sync/src/todo-reminder.ts +418 -0
- package/packages/todo-bd-sync/src/types.ts +137 -0
- 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
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
roughMessagesTokens,
|
|
23
23
|
} from "../packages/token-estimation/src/index.ts";
|
|
24
24
|
|
|
25
|
-
//
|
|
25
|
+
// --- Constants ----------------------------------------------------------------
|
|
26
26
|
|
|
27
27
|
/** Proactive compact triggers at this many tokens before limit */
|
|
28
28
|
export const AUTOCOMPACT_BUFFER_TOKENS = 13_000;
|
|
@@ -36,7 +36,7 @@ export const BLOCKING_THRESHOLD_BUFFER_TOKENS = 20_000;
|
|
|
36
36
|
/** Maximum consecutive compact failures before circuit breaker */
|
|
37
37
|
export const MAX_CONSECUTIVE_COMPACT_FAILURES = 3;
|
|
38
38
|
|
|
39
|
-
//
|
|
39
|
+
// --- Types ------------------------------------------------------------------
|
|
40
40
|
|
|
41
41
|
export interface CompactThresholds {
|
|
42
42
|
/** Trigger proactive compact at this utilization (0.85) */
|
|
@@ -60,7 +60,7 @@ export interface TokenEstimate {
|
|
|
60
60
|
shouldBlock: boolean;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// --- Context Window Manager -------------------------------------------------
|
|
64
64
|
|
|
65
65
|
export class ContextWindowManager {
|
|
66
66
|
private stats: Map<string, ContextWindowStats> = new Map();
|
|
@@ -95,7 +95,7 @@ export class ContextWindowManager {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
//
|
|
98
|
+
// --- Public API -----------------------------------------------------------
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* Update context window stats after a request
|
|
@@ -399,7 +399,7 @@ export class ContextWindowManager {
|
|
|
399
399
|
}
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
//
|
|
402
|
+
// --- Microcompact Helpers ---------------------------------------------------
|
|
403
403
|
|
|
404
404
|
/**
|
|
405
405
|
* Microcompact: prune old tool results based on time gap.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { CompactableMessage } from "../packages/types/src/runtime-types.js";
|
|
9
9
|
|
|
10
|
-
//
|
|
10
|
+
// --- Types ------------------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
export interface ContinueContext {
|
|
13
13
|
/** Task identifier */
|
|
@@ -35,7 +35,7 @@ export interface MinimalContinueContext {
|
|
|
35
35
|
recentMessages: CompactableMessage[];
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// --- Continue Prompt Generator -----------------------------------------------
|
|
39
39
|
|
|
40
40
|
export class ContinuePromptGenerator {
|
|
41
41
|
/**
|
|
@@ -237,6 +237,6 @@ export class ContinuePromptGenerator {
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
//
|
|
240
|
+
// --- Singleton Instance ------------------------------------------------------
|
|
241
241
|
|
|
242
242
|
export const continuePromptGenerator = new ContinuePromptGenerator();
|
|
@@ -387,7 +387,8 @@ export class MiniMaxQuotaScraper {
|
|
|
387
387
|
} catch {
|
|
388
388
|
const msg =
|
|
389
389
|
"Playwright not installed. Install with: bun add playwright\nThen install browsers: bunx playwright install chromium";
|
|
390
|
-
if (!this.config.quiet)
|
|
390
|
+
if (!this.config.quiet)
|
|
391
|
+
console.error("[DEBUG MiniMaxQuotaScraper] " + msg);
|
|
391
392
|
throw new Error(msg);
|
|
392
393
|
}
|
|
393
394
|
|
|
@@ -399,8 +400,7 @@ export class MiniMaxQuotaScraper {
|
|
|
399
400
|
|
|
400
401
|
if (cookies.length === 0) {
|
|
401
402
|
const dropHint = join(homedir(), ".pi-harness-runtime", "cookies");
|
|
402
|
-
const msg =
|
|
403
|
-
`No cookies found.
|
|
403
|
+
const msg = `No cookies found.
|
|
404
404
|
Drop your platform.minimax.io cookies (Netscape or EditThisCookie JSON) into:
|
|
405
405
|
${dropHint}
|
|
406
406
|
…or run: bun packages/auth/src/run-minimax-auth.ts auth`;
|
|
@@ -550,12 +550,12 @@ MiniMax Quota Scraper Setup Instructions
|
|
|
550
550
|
3. Use the scraper:
|
|
551
551
|
const scraper = new MiniMaxQuotaScraper();
|
|
552
552
|
const quota = await scraper.scrape();
|
|
553
|
-
console.log("5h usage:", quota.h5UsedPct, "%");
|
|
553
|
+
console.log("[DEBUG MiniMaxQuotaScraper] 5h usage:", quota.h5UsedPct, "%");
|
|
554
554
|
`;
|
|
555
555
|
}
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
-
//
|
|
558
|
+
// --- Quota Manager Integration -----------------------------------------------
|
|
559
559
|
|
|
560
560
|
/**
|
|
561
561
|
* Quota Manager that periodically fetches MiniMax quota data
|
|
@@ -205,13 +205,14 @@ export class OpenAIQuotaScraper {
|
|
|
205
205
|
Drop your chatgpt.com cookies (Netscape or EditThisCookie JSON) into:
|
|
206
206
|
${dropHint}
|
|
207
207
|
Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
208
|
-
if (!this.config.quiet)
|
|
208
|
+
if (!this.config.quiet)
|
|
209
|
+
console.error(`[DEBUG OpenAIQuotaScraper] ${msg}`);
|
|
209
210
|
throw new Error(msg);
|
|
210
211
|
}
|
|
211
212
|
|
|
212
213
|
// Launch browser
|
|
213
214
|
if (!this.config.quiet) {
|
|
214
|
-
console.log("[OpenAIQuotaScraper] Launching browser...");
|
|
215
|
+
console.log("[DEBUG OpenAIQuotaScraper] Launching browser...");
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
const browser = await chromium.launch({
|
|
@@ -259,7 +260,9 @@ Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
|
259
260
|
try {
|
|
260
261
|
// Navigate to analytics page
|
|
261
262
|
if (!this.config.quiet) {
|
|
262
|
-
console.log(
|
|
263
|
+
console.log(
|
|
264
|
+
"[DEBUG OpenAIQuotaScraper] Navigating to analytics page...",
|
|
265
|
+
);
|
|
263
266
|
}
|
|
264
267
|
|
|
265
268
|
await page.goto(ANALYTICS_URL, {
|
|
@@ -282,14 +285,16 @@ Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
|
282
285
|
if (currentUrl.includes("login") || currentUrl.includes("auth")) {
|
|
283
286
|
const msg =
|
|
284
287
|
"OpenAI cookies are expired or insufficient. Please re-export cookies from chatgpt.com.";
|
|
285
|
-
if (!this.config.quiet)
|
|
288
|
+
if (!this.config.quiet)
|
|
289
|
+
console.error("[DEBUG OpenAIQuotaScraper] " + msg);
|
|
286
290
|
throw new Error(msg);
|
|
287
291
|
}
|
|
288
292
|
|
|
289
293
|
// Parse the usage data from the captured API response
|
|
290
294
|
if (!usageData) {
|
|
291
295
|
const msg = "Failed to capture usage data from API";
|
|
292
|
-
if (!this.config.quiet)
|
|
296
|
+
if (!this.config.quiet)
|
|
297
|
+
console.error("[DEBUG OpenAIQuotaScraper] " + msg);
|
|
293
298
|
throw new Error(msg);
|
|
294
299
|
}
|
|
295
300
|
|
|
@@ -306,7 +311,7 @@ Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
|
306
311
|
|
|
307
312
|
if (!this.config.quiet) {
|
|
308
313
|
console.log(
|
|
309
|
-
`[OpenAIQuotaScraper] Weekly usage: ${weeklyUsedPct}%, resets in ${weeklyResetsAt}`,
|
|
314
|
+
`[DEBUG OpenAIQuotaScraper] Weekly usage: ${weeklyUsedPct}%, resets in ${weeklyResetsAt}`,
|
|
310
315
|
);
|
|
311
316
|
}
|
|
312
317
|
|
|
@@ -349,7 +354,7 @@ Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
|
349
354
|
if (!response.ok) {
|
|
350
355
|
if (!this.config.quiet) {
|
|
351
356
|
console.log(
|
|
352
|
-
`[OpenAIQuotaScraper] Direct API failed: ${response.status}`,
|
|
357
|
+
`[DEBUG OpenAIQuotaScraper] Direct API failed: ${response.status}`,
|
|
353
358
|
);
|
|
354
359
|
}
|
|
355
360
|
return null;
|
|
@@ -374,7 +379,7 @@ Then run: bun run packages/cookie-sanitizer/src/sync.ts`;
|
|
|
374
379
|
} catch (error) {
|
|
375
380
|
if (!this.config.quiet) {
|
|
376
381
|
console.warn(
|
|
377
|
-
"[OpenAIQuotaScraper] Direct API error:",
|
|
382
|
+
"[DEBUG OpenAIQuotaScraper] Direct API error:",
|
|
378
383
|
error instanceof Error ? error.message : String(error),
|
|
379
384
|
);
|
|
380
385
|
}
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
InvokeResult,
|
|
13
13
|
} from "../packages/types/src/runtime-types.js";
|
|
14
14
|
|
|
15
|
-
//
|
|
15
|
+
// --- Types ------------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
export interface SummarizerConfig {
|
|
18
18
|
/** Model to use for summarization */
|
|
@@ -43,7 +43,7 @@ export interface InvokeOptions {
|
|
|
43
43
|
systemPrompt?: string;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// --- Default System Prompt ---------------------------------------------------
|
|
47
47
|
|
|
48
48
|
const DEFAULT_SUMMARY_SYSTEM = `You are a conversation summarizer. Your task is to create concise, accurate summaries that preserve essential context for continuing a conversation.
|
|
49
49
|
|
|
@@ -70,7 +70,7 @@ const DECISIONS_FOCUS = `Focus specifically on:
|
|
|
70
70
|
4. What constraints or requirements influenced the decisions?
|
|
71
71
|
5. Any lessons learned or trade-offs considered?`;
|
|
72
72
|
|
|
73
|
-
//
|
|
73
|
+
// --- Forked Summarizer ------------------------------------------------------
|
|
74
74
|
|
|
75
75
|
export class ForkedSummarizer {
|
|
76
76
|
private readonly config: SummarizerConfig;
|
|
@@ -283,7 +283,7 @@ Do not include verbatim tool results — summarize their outcomes instead.`;
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
//
|
|
286
|
+
// --- Convenience Factory ----------------------------------------------------
|
|
287
287
|
|
|
288
288
|
/**
|
|
289
289
|
* Create a ForkedSummarizer with default config
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Herdr Agent Commands
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import {
|
|
7
|
+
createHerdrBus,
|
|
8
|
+
getHerdrWorkspacePaths,
|
|
9
|
+
ensureHerdrWorkspace,
|
|
10
|
+
} from "../packages/event-bus/src/herdr-bus.js";
|
|
11
|
+
|
|
12
|
+
async function startReviewAgent(): Promise<void> {
|
|
13
|
+
console.log("[herdr:review] Starting review agent...");
|
|
14
|
+
const bus = createHerdrBus("review-agent");
|
|
15
|
+
ensureHerdrWorkspace();
|
|
16
|
+
bus.subscribe("code.written");
|
|
17
|
+
bus.startPolling(async (payload) => {
|
|
18
|
+
if (payload.topic === "code.written") {
|
|
19
|
+
const data = payload.data as { taskId: string; files: string[] };
|
|
20
|
+
console.log(
|
|
21
|
+
`[herdr:review] code.written: task=${data.taskId} files=${data.files.length}`,
|
|
22
|
+
);
|
|
23
|
+
for (const file of data.files ?? []) {
|
|
24
|
+
console.log(`[herdr:review] Reviewing: ${file}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
console.log(`[herdr:review] Workspace: ${bus.getWorkspace()}`);
|
|
29
|
+
await new Promise(() => {});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function startCodeAgent(): Promise<void> {
|
|
33
|
+
console.log("[herdr:code] Starting code agent...");
|
|
34
|
+
const bus = createHerdrBus("code-agent");
|
|
35
|
+
ensureHerdrWorkspace();
|
|
36
|
+
bus.subscribe("review.completed");
|
|
37
|
+
bus.startPolling(async (payload) => {
|
|
38
|
+
if (payload.topic === "review.completed") {
|
|
39
|
+
const data = payload.data as {
|
|
40
|
+
taskId: string;
|
|
41
|
+
reportFile: string;
|
|
42
|
+
status: string;
|
|
43
|
+
};
|
|
44
|
+
console.log(
|
|
45
|
+
`[herdr:code] Review done: task=${data.taskId} status=${data.status} report=${data.reportFile}`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
console.log(`[herdr:code] Workspace: ${bus.getWorkspace()}`);
|
|
50
|
+
await new Promise(() => {});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function showStatus(): void {
|
|
54
|
+
const paths = getHerdrWorkspacePaths();
|
|
55
|
+
console.log(`Workspace: ${paths.root}`);
|
|
56
|
+
const evPath = join(paths.root, "events.jsonl");
|
|
57
|
+
if (existsSync(evPath)) {
|
|
58
|
+
const lines = readFileSync(evPath, "utf-8")
|
|
59
|
+
.split("\n")
|
|
60
|
+
.filter(Boolean)
|
|
61
|
+
.slice(-10);
|
|
62
|
+
console.log("Recent events:");
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
try {
|
|
65
|
+
const { topic, ts } = JSON.parse(line);
|
|
66
|
+
console.log(` ${ts} ${topic}`);
|
|
67
|
+
} catch {
|
|
68
|
+
/* skip */
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (existsSync(paths.subscriptions)) {
|
|
73
|
+
const agents = readdirSync(paths.subscriptions);
|
|
74
|
+
console.log(`Active agents: ${agents.join(", ") || "none"}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const [command] = process.argv.slice(2);
|
|
79
|
+
switch (command) {
|
|
80
|
+
case "review":
|
|
81
|
+
startReviewAgent().catch(console.error);
|
|
82
|
+
break;
|
|
83
|
+
case "code":
|
|
84
|
+
startCodeAgent().catch(console.error);
|
|
85
|
+
break;
|
|
86
|
+
case "status":
|
|
87
|
+
showStatus();
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
console.log("Usage: bun harness/herdr-agents.ts <review|code|status>");
|
|
91
|
+
}
|
package/harness/index.ts
CHANGED
|
@@ -178,7 +178,7 @@ export type { QuotaStatus, QuotaDisplayConfig } from "./e2e/quota-status.js";
|
|
|
178
178
|
// Project Detector
|
|
179
179
|
export { ProjectDetector } from "./project-detector/detector.js";
|
|
180
180
|
|
|
181
|
-
//
|
|
181
|
+
// --- RFC-0056: Performance Optimizer ----------------------------------------
|
|
182
182
|
export {
|
|
183
183
|
PerformanceOptimizer,
|
|
184
184
|
createPerformanceOptimizer,
|
|
@@ -189,7 +189,7 @@ export type {
|
|
|
189
189
|
PerformanceRecommendation,
|
|
190
190
|
} from "../packages/performance-optimizer/src/types.js";
|
|
191
191
|
|
|
192
|
-
//
|
|
192
|
+
// --- RFC-0057: Evaluation Engine -------------------------------------------
|
|
193
193
|
export {
|
|
194
194
|
EvaluationEngine,
|
|
195
195
|
createEvaluationEngine,
|
|
@@ -200,7 +200,7 @@ export type {
|
|
|
200
200
|
EvaluationFinding,
|
|
201
201
|
} from "../packages/evaluation-engine/src/types.js";
|
|
202
202
|
|
|
203
|
-
//
|
|
203
|
+
// --- RFC-0058: Learning Engine ---------------------------------------------
|
|
204
204
|
export {
|
|
205
205
|
LearningEngine,
|
|
206
206
|
createLearningEngine,
|
|
@@ -210,7 +210,7 @@ export type {
|
|
|
210
210
|
LearnedExperience,
|
|
211
211
|
} from "../packages/learning-engine/src/types.js";
|
|
212
212
|
|
|
213
|
-
//
|
|
213
|
+
// --- RFC-0059: Experience Replay ------------------------------------------
|
|
214
214
|
export {
|
|
215
215
|
ExperienceReplay,
|
|
216
216
|
createExperienceReplay,
|
|
@@ -220,7 +220,7 @@ export type {
|
|
|
220
220
|
ReplayResult,
|
|
221
221
|
} from "../packages/experience-replay/src/types.js";
|
|
222
222
|
|
|
223
|
-
//
|
|
223
|
+
// --- RFC-0060: Memory Engine -----------------------------------------------
|
|
224
224
|
export {
|
|
225
225
|
MemoryEngine,
|
|
226
226
|
createMemoryEngine,
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop Code Agent (Minimax) — coordinates via blackboard.
|
|
3
|
+
*
|
|
4
|
+
* Polls blackboard for nextAction where agentType="code".
|
|
5
|
+
* Writes code, updates node status, sets nextAction for review-agent.
|
|
6
|
+
*
|
|
7
|
+
* Usage: bun harness/loop-code-agent.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
import {
|
|
13
|
+
createHerdrBus,
|
|
14
|
+
ensureHerdrWorkspace,
|
|
15
|
+
} from "../packages/event-bus/src/herdr-bus.js";
|
|
16
|
+
import { SharedBlackboard } from "./blackboard.js";
|
|
17
|
+
import type { LoopNextAction, LoopAgentReport } from "./loop-types.js";
|
|
18
|
+
import type { BlackboardRecord } from "../packages/types/src/runtime-types.js";
|
|
19
|
+
|
|
20
|
+
const AGENT_ID = "code-agent";
|
|
21
|
+
const AGENT_TYPE = "code";
|
|
22
|
+
const POLL_MS = 1000;
|
|
23
|
+
|
|
24
|
+
async function main(): Promise<void> {
|
|
25
|
+
console.log(`[${AGENT_ID}] Starting...`);
|
|
26
|
+
const paths = ensureHerdrWorkspace();
|
|
27
|
+
|
|
28
|
+
// Find active loop config
|
|
29
|
+
const loopId = await findActiveLoop(paths.root);
|
|
30
|
+
if (!loopId) {
|
|
31
|
+
console.log(`[${AGENT_ID}] No active loop found. Waiting...`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const rootDir = paths.root;
|
|
35
|
+
const blackboard = new SharedBlackboard(loopId ?? "no-loop", rootDir);
|
|
36
|
+
blackboard.load();
|
|
37
|
+
blackboard.registerAgent(AGENT_ID, "Code Agent", "minimax", "minimax");
|
|
38
|
+
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
39
|
+
console.log(`[${AGENT_ID}] Registered. Blackboard: ${blackboard.getPath()}`);
|
|
40
|
+
|
|
41
|
+
while (true) {
|
|
42
|
+
await sleep(POLL_MS);
|
|
43
|
+
|
|
44
|
+
blackboard.load();
|
|
45
|
+
const record = blackboard.getRecord();
|
|
46
|
+
if (!record) continue;
|
|
47
|
+
|
|
48
|
+
// Check for early exit
|
|
49
|
+
const earlyExit = checkEarlyExit(record);
|
|
50
|
+
if (earlyExit) {
|
|
51
|
+
console.log(`[${AGENT_ID}] Early exit: ${earlyExit}`);
|
|
52
|
+
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check if this loop is ours (loopId matches)
|
|
57
|
+
if (record.jobId !== loopId) continue;
|
|
58
|
+
|
|
59
|
+
// Check nextAction for code agent
|
|
60
|
+
const action = parseNextAction(record.nextAction);
|
|
61
|
+
if (!action || action.agentType !== AGENT_TYPE) continue;
|
|
62
|
+
|
|
63
|
+
// Claim the task
|
|
64
|
+
const locked = blackboard.acquireLock(action.taskId, AGENT_ID);
|
|
65
|
+
if (!locked) continue;
|
|
66
|
+
|
|
67
|
+
blackboard.updateAgentStatus(AGENT_ID, "working", action.taskId);
|
|
68
|
+
console.log(`[${AGENT_ID}] Claimed: ${action.taskId}`);
|
|
69
|
+
|
|
70
|
+
// Do the work
|
|
71
|
+
const result = await writeCode(action, paths, record.jobId);
|
|
72
|
+
|
|
73
|
+
// Update task status
|
|
74
|
+
updateTaskStatus(blackboard, record, action.taskId, "done", result.files);
|
|
75
|
+
|
|
76
|
+
// Set nextAction for review agent
|
|
77
|
+
const nextTaskId = getNextReviewTask(record, action.iteration);
|
|
78
|
+
if (nextTaskId) {
|
|
79
|
+
blackboard.setNextAction(
|
|
80
|
+
encodeNextAction({
|
|
81
|
+
taskId: nextTaskId,
|
|
82
|
+
agentType: "review",
|
|
83
|
+
iteration: getReviewIteration(nextTaskId),
|
|
84
|
+
prompt: action.prompt,
|
|
85
|
+
codeFiles: result.files,
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
console.log(`[${AGENT_ID}] -> nextAction: review ${nextTaskId}`);
|
|
89
|
+
} else {
|
|
90
|
+
// No review needed — go to report
|
|
91
|
+
const writeDone = getNextWriteTask(record, action.iteration);
|
|
92
|
+
if (writeDone) {
|
|
93
|
+
blackboard.setNextAction(
|
|
94
|
+
encodeNextAction({
|
|
95
|
+
taskId: writeDone,
|
|
96
|
+
agentType: "code",
|
|
97
|
+
iteration: getWriteIteration(writeDone),
|
|
98
|
+
prompt: action.prompt,
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
101
|
+
console.log(`[${AGENT_ID}] -> nextAction: code ${writeDone}`);
|
|
102
|
+
} else {
|
|
103
|
+
// All done — go to report
|
|
104
|
+
blackboard.setNextAction(
|
|
105
|
+
encodeNextAction({
|
|
106
|
+
taskId: "report",
|
|
107
|
+
agentType: "review",
|
|
108
|
+
iteration: 0,
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
console.log(`[${AGENT_ID}] -> nextAction: report`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Release lock and report
|
|
116
|
+
blackboard.releaseLock(action.taskId, AGENT_ID);
|
|
117
|
+
blackboard.writeReport({
|
|
118
|
+
agentId: AGENT_ID,
|
|
119
|
+
taskId: action.taskId,
|
|
120
|
+
status: "success",
|
|
121
|
+
files: result.files,
|
|
122
|
+
} satisfies LoopAgentReport);
|
|
123
|
+
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function writeCode(
|
|
128
|
+
action: LoopNextAction,
|
|
129
|
+
paths: { code: string },
|
|
130
|
+
loopId: string,
|
|
131
|
+
): Promise<{ files: string[] }> {
|
|
132
|
+
const iteration = action.iteration;
|
|
133
|
+
const outputDir = join(paths.code, loopId, `iteration-${iteration}`);
|
|
134
|
+
mkdirSync(outputDir, { recursive: true });
|
|
135
|
+
|
|
136
|
+
const codeFile = join(outputDir, `index.ts`);
|
|
137
|
+
// TODO: Replace with actual Minimax call
|
|
138
|
+
const code = `// Iteration ${iteration} — ${action.prompt}
|
|
139
|
+
// TODO: Replace with actual Minimax code generation
|
|
140
|
+
export const iteration = ${iteration};
|
|
141
|
+
export const prompt = ${JSON.stringify(action.prompt)};
|
|
142
|
+
`;
|
|
143
|
+
writeFileSync(codeFile, code);
|
|
144
|
+
console.log(`[${AGENT_ID}] Wrote: ${codeFile}`);
|
|
145
|
+
return { files: [codeFile] };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
149
|
+
|
|
150
|
+
async function findActiveLoop(rootDir: string): Promise<string | null> {
|
|
151
|
+
const { readdirSync, existsSync } = await import("fs");
|
|
152
|
+
try {
|
|
153
|
+
const files = readdirSync(rootDir).filter(
|
|
154
|
+
(f) => f.startsWith("loop-") && f.endsWith(".config.json"),
|
|
155
|
+
);
|
|
156
|
+
// Find most recent config that has an active blackboard
|
|
157
|
+
for (const configFile of files.slice(-1)) {
|
|
158
|
+
const config = JSON.parse(
|
|
159
|
+
readFileSync(join(rootDir, configFile), "utf-8"),
|
|
160
|
+
);
|
|
161
|
+
const bbPath = join(rootDir, "jobs", config.loopId, "blackboard");
|
|
162
|
+
if (existsSync(bbPath)) return config.loopId;
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
// no loop yet
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function encodeNextAction(action: Partial<LoopNextAction>) {
|
|
171
|
+
return {
|
|
172
|
+
taskId: action.taskId,
|
|
173
|
+
instruction: "LOOP:" + JSON.stringify(action),
|
|
174
|
+
priority: "high" as const,
|
|
175
|
+
createdAt: new Date().toISOString(),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function parseNextAction(nextAction: unknown): LoopNextAction | null {
|
|
180
|
+
if (!nextAction) return null;
|
|
181
|
+
const a = nextAction as Record<string, unknown>;
|
|
182
|
+
if (!a.taskId) return null;
|
|
183
|
+
if (typeof a.instruction === "string" && a.instruction.startsWith("LOOP:")) {
|
|
184
|
+
try {
|
|
185
|
+
return JSON.parse(a.instruction.slice(5)) as LoopNextAction;
|
|
186
|
+
} catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function checkEarlyExit(record: BlackboardRecord): string | null {
|
|
194
|
+
const blocked = Object.values(record.tasks.nodes).find(
|
|
195
|
+
(n) => n.status === "blocked",
|
|
196
|
+
);
|
|
197
|
+
if (blocked) return `blocked at ${blocked.id}`;
|
|
198
|
+
const approved = Object.values(record.tasks.nodes).find(
|
|
199
|
+
(n) =>
|
|
200
|
+
n.status === "done" && (n as { result?: string }).result === "approved",
|
|
201
|
+
);
|
|
202
|
+
if (approved) return "approved";
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function updateTaskStatus(
|
|
207
|
+
blackboard: SharedBlackboard,
|
|
208
|
+
record: BlackboardRecord,
|
|
209
|
+
taskId: string,
|
|
210
|
+
status: "done" | "running" | "blocked",
|
|
211
|
+
files?: string[],
|
|
212
|
+
): void {
|
|
213
|
+
if (record.tasks.nodes[taskId]) {
|
|
214
|
+
(
|
|
215
|
+
record.tasks.nodes[taskId] as unknown as {
|
|
216
|
+
status: string;
|
|
217
|
+
result?: string;
|
|
218
|
+
}
|
|
219
|
+
).status = status;
|
|
220
|
+
if (files)
|
|
221
|
+
(record.tasks.nodes[taskId] as unknown as { result?: string }).result =
|
|
222
|
+
files.join(", ");
|
|
223
|
+
(
|
|
224
|
+
record.tasks.nodes[taskId] as unknown as { updatedAt?: string }
|
|
225
|
+
).updatedAt = new Date().toISOString();
|
|
226
|
+
blackboard.save();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function getNextReviewTask(
|
|
231
|
+
record: BlackboardRecord,
|
|
232
|
+
writeIteration: number,
|
|
233
|
+
): string | null {
|
|
234
|
+
const reviewCount = Object.keys(record.tasks.nodes).filter((id) =>
|
|
235
|
+
id.startsWith("review-"),
|
|
236
|
+
).length;
|
|
237
|
+
const step = Math.max(
|
|
238
|
+
1,
|
|
239
|
+
Math.floor(
|
|
240
|
+
Object.keys(record.tasks.nodes).filter((id) => id.startsWith("write-"))
|
|
241
|
+
.length / (reviewCount || 1),
|
|
242
|
+
),
|
|
243
|
+
);
|
|
244
|
+
const targetReview = Math.ceil(writeIteration / step);
|
|
245
|
+
const taskId = `review-${targetReview}`;
|
|
246
|
+
if (
|
|
247
|
+
record.tasks.nodes[taskId] &&
|
|
248
|
+
record.tasks.nodes[taskId].status === "pending"
|
|
249
|
+
) {
|
|
250
|
+
return taskId;
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function getNextWriteTask(
|
|
256
|
+
record: BlackboardRecord,
|
|
257
|
+
currentIteration: number,
|
|
258
|
+
): string | null {
|
|
259
|
+
const nextWrite = currentIteration + 1;
|
|
260
|
+
const taskId = `write-${nextWrite}`;
|
|
261
|
+
if (
|
|
262
|
+
record.tasks.nodes[taskId] &&
|
|
263
|
+
record.tasks.nodes[taskId].status === "pending"
|
|
264
|
+
) {
|
|
265
|
+
return taskId;
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function getReviewIteration(taskId: string): number {
|
|
271
|
+
const m = taskId.match(/^review-(\d+)$/);
|
|
272
|
+
return m ? parseInt(m[1], 10) : 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function getWriteIteration(taskId: string): number {
|
|
276
|
+
const m = taskId.match(/^write-(\d+)$/);
|
|
277
|
+
return m ? parseInt(m[1], 10) : 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function sleep(ms: number): Promise<void> {
|
|
281
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
main().catch(console.error);
|