agentic-orchestrator 0.1.2 → 0.1.4
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/.claude/settings.local.json +15 -0
- package/CLAUDE.md +126 -0
- package/README.md +166 -25
- package/agentic/orchestrator/adapters.yaml +3 -0
- package/agentic/orchestrator/gates.yaml +47 -0
- package/agentic/orchestrator/policy.yaml +89 -0
- package/agentic/orchestrator/schemas/adapters.schema.json +12 -0
- package/agentic/orchestrator/schemas/gates.schema.json +6 -1
- package/agentic/orchestrator/schemas/index.schema.json +14 -0
- package/agentic/orchestrator/schemas/multi-project.schema.json +41 -0
- package/agentic/orchestrator/schemas/policy.schema.json +449 -52
- package/agentic/orchestrator/schemas/state.schema.json +16 -0
- package/agentic/orchestrator/tools/catalog.json +68 -0
- package/agentic/orchestrator/tools/schemas/input/cost.get.input.schema.json +10 -0
- package/agentic/orchestrator/tools/schemas/input/cost.record.input.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +11 -0
- package/agentic/orchestrator/tools/schemas/input/performance.get_analytics.input.schema.json +10 -0
- package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +18 -0
- package/agentic/orchestrator/tools/schemas/output/cost.get.output.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/output/cost.record.output.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +23 -0
- package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +46 -0
- package/agentic/orchestrator/tools/schemas/output/performance.record_outcome.output.schema.json +10 -0
- package/agentic/orchestrator/tools.md +5 -0
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +28 -2
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +12 -0
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +92 -0
- package/apps/control-plane/src/application/adapters/adapter-registry.ts +169 -0
- package/apps/control-plane/src/application/multi-project-loader.ts +119 -0
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +199 -0
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +82 -0
- package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +86 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +8 -7
- package/apps/control-plane/src/application/services/gate-interpolation-service.ts +15 -0
- package/apps/control-plane/src/application/services/gate-service.ts +38 -2
- package/apps/control-plane/src/application/services/instance-isolation-service.ts +18 -0
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +469 -0
- package/apps/control-plane/src/application/services/merge-service.ts +67 -3
- package/apps/control-plane/src/application/services/notifier-service.ts +295 -0
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +122 -0
- package/apps/control-plane/src/application/services/plan-service.ts +51 -0
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +262 -0
- package/apps/control-plane/src/application/services/reactions-service.ts +175 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +17 -2
- package/apps/control-plane/src/application/services/run-lease-service.ts +16 -38
- package/apps/control-plane/src/application/tools/tool-metadata.ts +4 -1
- package/apps/control-plane/src/cli/aop.ts +1 -1
- package/apps/control-plane/src/cli/attach-command-handler.ts +120 -0
- package/apps/control-plane/src/cli/cleanup-command-handler.ts +190 -0
- package/apps/control-plane/src/cli/cli-argument-parser.ts +69 -3
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +57 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +163 -0
- package/apps/control-plane/src/cli/init-command-handler.ts +609 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +1 -0
- package/apps/control-plane/src/cli/retry-command-handler.ts +138 -0
- package/apps/control-plane/src/cli/run-command-handler.ts +115 -3
- package/apps/control-plane/src/cli/send-command-handler.ts +65 -0
- package/apps/control-plane/src/cli/status-command-handler.ts +102 -2
- package/apps/control-plane/src/cli/types.ts +26 -1
- package/apps/control-plane/src/core/constants.ts +8 -2
- package/apps/control-plane/src/core/error-codes.ts +3 -1
- package/apps/control-plane/src/core/gates.ts +170 -50
- package/apps/control-plane/src/core/kernel.ts +280 -5
- package/apps/control-plane/src/core/path-layout.ts +12 -0
- package/apps/control-plane/src/core/tool-caller.ts +36 -0
- package/apps/control-plane/src/core/workspace-hooks.ts +87 -0
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +258 -9
- package/apps/control-plane/src/providers/providers.ts +235 -14
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +129 -8
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +123 -5
- package/apps/control-plane/src/supervisor/run-coordinator.ts +143 -6
- package/apps/control-plane/src/supervisor/runtime.ts +135 -6
- package/apps/control-plane/src/supervisor/types.ts +12 -21
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +8 -0
- package/apps/control-plane/test/activity-monitor.spec.ts +294 -0
- package/apps/control-plane/test/adapter-registry.spec.ts +132 -0
- package/apps/control-plane/test/batch-operations.spec.ts +112 -0
- package/apps/control-plane/test/bootstrap-attach.spec.ts +102 -0
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +252 -0
- package/apps/control-plane/test/bootstrap.spec.ts +560 -0
- package/apps/control-plane/test/cleanup-command.spec.ts +301 -0
- package/apps/control-plane/test/cli-helpers.spec.ts +404 -1
- package/apps/control-plane/test/cli.unit.spec.ts +182 -1
- package/apps/control-plane/test/collision-queue.spec.ts +104 -1
- package/apps/control-plane/test/core-utils.spec.ts +175 -2
- package/apps/control-plane/test/cost-tracking.spec.ts +143 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +247 -0
- package/apps/control-plane/test/dashboard-client.spec.ts +116 -0
- package/apps/control-plane/test/dashboard-command.spec.ts +103 -0
- package/apps/control-plane/test/dependency-scheduler.spec.ts +189 -0
- package/apps/control-plane/test/epoch-tracking.spec.ts +4 -4
- package/apps/control-plane/test/feature-deletion-service.spec.ts +422 -0
- package/apps/control-plane/test/feature-lifecycle.spec.ts +202 -0
- package/apps/control-plane/test/git-spawn-error.spec.ts +24 -0
- package/apps/control-plane/test/incremental-gates.spec.ts +137 -0
- package/apps/control-plane/test/init-wizard.spec.ts +506 -0
- package/apps/control-plane/test/instance-isolation.spec.ts +83 -0
- package/apps/control-plane/test/issue-tracker.spec.ts +890 -0
- package/apps/control-plane/test/kernel.coverage.spec.ts +3 -5
- package/apps/control-plane/test/kernel.coverage2.spec.ts +871 -0
- package/apps/control-plane/test/kernel.spec.ts +13 -11
- package/apps/control-plane/test/lock-service.spec.ts +508 -0
- package/apps/control-plane/test/mcp-helpers.spec.ts +176 -0
- package/apps/control-plane/test/mcp.spec.ts +50 -15
- package/apps/control-plane/test/merge-service.spec.ts +67 -4
- package/apps/control-plane/test/multi-project.spec.ts +372 -0
- package/apps/control-plane/test/notifier-service.spec.ts +388 -0
- package/apps/control-plane/test/parallel-gates.spec.ts +312 -0
- package/apps/control-plane/test/patch-service.spec.ts +253 -0
- package/apps/control-plane/test/performance-analytics.spec.ts +338 -0
- package/apps/control-plane/test/planning-wave-executor.spec.ts +168 -0
- package/apps/control-plane/test/pr-monitor.spec.ts +385 -0
- package/apps/control-plane/test/providers.spec.ts +344 -1
- package/apps/control-plane/test/reactions.spec.ts +392 -0
- package/apps/control-plane/test/resume-command.spec.ts +390 -0
- package/apps/control-plane/test/run-coordinator.spec.ts +481 -2
- package/apps/control-plane/test/schema-date-time.spec.ts +46 -0
- package/apps/control-plane/test/service-retry-paths.spec.ts +30 -0
- package/apps/control-plane/test/services.spec.ts +95 -2
- package/apps/control-plane/test/session-management.spec.ts +450 -0
- package/apps/control-plane/test/spec-ingestion.spec.ts +190 -0
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +699 -2
- package/apps/control-plane/test/supervisor.spec.ts +36 -30
- package/apps/control-plane/test/supervisor.unit.spec.ts +405 -0
- package/apps/control-plane/test/worker-decision-loop.spec.ts +57 -0
- package/apps/control-plane/test/workspace-hooks.spec.ts +177 -0
- package/apps/control-plane/vitest.config.ts +21 -5
- package/dist/apps/control-plane/application/adapters/adapter-registry.d.ts +44 -0
- package/dist/apps/control-plane/application/adapters/adapter-registry.js +76 -0
- package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -0
- package/dist/apps/control-plane/application/multi-project-loader.d.ts +31 -0
- package/dist/apps/control-plane/application/multi-project-loader.js +82 -0
- package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +43 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +132 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +28 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +48 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.d.ts +26 -0
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.js +75 -0
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +2 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +6 -7
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.d.ts +7 -0
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js +7 -0
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/gate-service.js +32 -2
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.d.ts +11 -0
- package/dist/apps/control-plane/application/services/instance-isolation-service.js +17 -0
- package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +65 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +358 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/merge-service.d.ts +4 -0
- package/dist/apps/control-plane/application/services/merge-service.js +44 -2
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.d.ts +74 -0
- package/dist/apps/control-plane/application/services/notifier-service.js +212 -0
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +39 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +75 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/plan-service.d.ts +1 -0
- package/dist/apps/control-plane/application/services/plan-service.js +53 -0
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +44 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +192 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reactions-service.d.ts +67 -0
- package/dist/apps/control-plane/application/services/reactions-service.js +114 -0
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +1 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +13 -2
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +2 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +14 -38
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +3 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
- package/dist/apps/control-plane/cli/aop.d.ts +1 -1
- package/dist/apps/control-plane/cli/aop.js +1 -1
- package/dist/apps/control-plane/cli/attach-command-handler.d.ts +12 -0
- package/dist/apps/control-plane/cli/attach-command-handler.js +98 -0
- package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/cleanup-command-handler.d.ts +12 -0
- package/dist/apps/control-plane/cli/cleanup-command-handler.js +162 -0
- package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js +73 -3
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +7 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +45 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/help-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/help-command-handler.js +146 -0
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/init-command-handler.d.ts +26 -0
- package/dist/apps/control-plane/cli/init-command-handler.js +517 -0
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/retry-command-handler.js +111 -0
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/run-command-handler.d.ts +5 -0
- package/dist/apps/control-plane/cli/run-command-handler.js +82 -3
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/send-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/send-command-handler.js +55 -0
- package/dist/apps/control-plane/cli/send-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/status-command-handler.d.ts +12 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +55 -2
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +26 -1
- package/dist/apps/control-plane/cli/types.js +15 -1
- package/dist/apps/control-plane/cli/types.js.map +1 -1
- package/dist/apps/control-plane/core/constants.d.ts +6 -0
- package/dist/apps/control-plane/core/constants.js +8 -2
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.d.ts +2 -0
- package/dist/apps/control-plane/core/error-codes.js +3 -1
- package/dist/apps/control-plane/core/error-codes.js.map +1 -1
- package/dist/apps/control-plane/core/gates.d.ts +4 -0
- package/dist/apps/control-plane/core/gates.js +140 -43
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.d.ts +50 -1
- package/dist/apps/control-plane/core/kernel.js +220 -7
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/path-layout.d.ts +3 -0
- package/dist/apps/control-plane/core/path-layout.js +9 -0
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/tool-caller.d.ts +32 -0
- package/dist/apps/control-plane/core/tool-caller.js +2 -0
- package/dist/apps/control-plane/core/tool-caller.js.map +1 -0
- package/dist/apps/control-plane/core/workspace-hooks.d.ts +20 -0
- package/dist/apps/control-plane/core/workspace-hooks.js +69 -0
- package/dist/apps/control-plane/core/workspace-hooks.js.map +1 -0
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +245 -9
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +42 -3
- package/dist/apps/control-plane/providers/providers.js +216 -5
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +115 -6
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +109 -5
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +15 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js +132 -6
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/runtime.js +110 -6
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +9 -16
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +5 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/eslint.config.mjs +2 -1
- package/package.json +12 -2
- package/packages/web-dashboard/next-env.d.ts +5 -0
- package/packages/web-dashboard/next.config.js +7 -0
- package/packages/web-dashboard/package.json +26 -0
- package/packages/web-dashboard/src/app/api/actions/route.ts +64 -0
- package/packages/web-dashboard/src/app/api/events/route.ts +51 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +256 -0
- package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +10 -0
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +25 -0
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +63 -0
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +16 -0
- package/packages/web-dashboard/src/app/api/projects/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/status/route.ts +15 -0
- package/packages/web-dashboard/src/app/globals.css +2 -0
- package/packages/web-dashboard/src/app/layout.tsx +15 -0
- package/packages/web-dashboard/src/app/page.tsx +393 -0
- package/packages/web-dashboard/src/lib/aop-client.ts +244 -0
- package/packages/web-dashboard/src/lib/multi-project-config.ts +116 -0
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +284 -0
- package/packages/web-dashboard/src/lib/types.ts +58 -0
- package/packages/web-dashboard/tsconfig.json +40 -0
- package/packages/web-dashboard/vitest.config.ts +6 -0
- package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +1764 -0
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +348 -0
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +344 -0
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +374 -0
- package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +1059 -0
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +466 -0
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +198 -0
- package/spec-files/outstanding/agentic_orchestrator_validator_hardening_spec.md +365 -0
- package/spec-files/progress.md +481 -52
- /package/spec-files/{agentic_orchestrator_cli_delete_command_spec.md → completed/agentic_orchestrator_cli_delete_command_spec.md} +0 -0
- /package/spec-files/{agentic_orchestrator_dot_aop_generated_artifacts_spec.md → completed/agentic_orchestrator_dot_aop_generated_artifacts_spec.md} +0 -0
- /package/spec-files/{agentic_orchestrator_mcp_formalization_spec.md → completed/agentic_orchestrator_mcp_formalization_spec.md} +0 -0
- /package/spec-files/{agentic_orchestrator_oop_refactor_spec.md → completed/agentic_orchestrator_oop_refactor_spec.md} +0 -0
- /package/spec-files/{agentic_orchestrator_single_global_orchestrator_spec.md → completed/agentic_orchestrator_single_global_orchestrator_spec.md} +0 -0
- /package/spec-files/{agentic_orchestrator_spec.md → completed/agentic_orchestrator_spec.md} +0 -0
|
@@ -14,6 +14,9 @@ import { type BuildWaveExecutor } from './build-wave-executor.js';
|
|
|
14
14
|
import { type QaWaveExecutor } from './qa-wave-executor.js';
|
|
15
15
|
import { type LeaseHeartbeatService } from './lease-heartbeat-service.js';
|
|
16
16
|
import { NOOP_WORKER_DECISION_RUNNER, type WorkerDecisionRunner } from './worker-decision-loop.js';
|
|
17
|
+
import type { NotifierService } from '../application/services/notifier-service.js';
|
|
18
|
+
import type { PrMonitorService } from '../application/services/pr-monitor-service.js';
|
|
19
|
+
import type { IssueTracker } from '../application/services/issue-tracker-service.js';
|
|
17
20
|
|
|
18
21
|
interface RunCoordinatorDependencies {
|
|
19
22
|
kernel: FeatureOrchestrationPort & RuntimeStateReader;
|
|
@@ -31,6 +34,9 @@ interface RunCoordinatorDependencies {
|
|
|
31
34
|
takeoverStaleRun: boolean;
|
|
32
35
|
providerConfigRefHash: () => string;
|
|
33
36
|
workerDecisionRunner?: WorkerDecisionRunner;
|
|
37
|
+
notifier?: NotifierService;
|
|
38
|
+
prMonitor?: PrMonitorService;
|
|
39
|
+
issueTracker?: IssueTracker;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export class RunCoordinator {
|
|
@@ -49,7 +55,11 @@ export class RunCoordinator {
|
|
|
49
55
|
private readonly takeoverStaleRun: boolean;
|
|
50
56
|
private readonly providerConfigRefHash: () => string;
|
|
51
57
|
private readonly workerDecisionRunner: WorkerDecisionRunner;
|
|
52
|
-
private
|
|
58
|
+
private readonly notifier: NotifierService | undefined;
|
|
59
|
+
private readonly prMonitor: PrMonitorService | undefined;
|
|
60
|
+
private readonly issueTracker: IssueTracker | undefined;
|
|
61
|
+
private readonly statusCache: Map<string, string>;
|
|
62
|
+
private static readonly TERMINAL_STATUSES = new Set<string>([STATUS.MERGED, STATUS.FAILED, STATUS.PAUSED_BUDGET]);
|
|
53
63
|
|
|
54
64
|
constructor(dependencies: RunCoordinatorDependencies) {
|
|
55
65
|
this.kernel = dependencies.kernel;
|
|
@@ -67,6 +77,10 @@ export class RunCoordinator {
|
|
|
67
77
|
this.takeoverStaleRun = dependencies.takeoverStaleRun;
|
|
68
78
|
this.providerConfigRefHash = dependencies.providerConfigRefHash;
|
|
69
79
|
this.workerDecisionRunner = dependencies.workerDecisionRunner ?? NOOP_WORKER_DECISION_RUNNER;
|
|
80
|
+
this.notifier = dependencies.notifier;
|
|
81
|
+
this.prMonitor = dependencies.prMonitor;
|
|
82
|
+
this.issueTracker = dependencies.issueTracker;
|
|
83
|
+
this.statusCache = new Map();
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
async start(features: FeatureInput[]): Promise<Record<string, unknown>> {
|
|
@@ -106,10 +120,13 @@ export class RunCoordinator {
|
|
|
106
120
|
}
|
|
107
121
|
await this.leaseHeartbeatService.renew();
|
|
108
122
|
activeFeatureIds = await this.applyOrchestratorPrioritization(activeFeatureIds, iteration + 1);
|
|
123
|
+
// N3: Check budget before waves; pause over-budget features
|
|
124
|
+
activeFeatureIds = await this.pauseOverBudgetFeatures(activeFeatureIds);
|
|
109
125
|
await this.planningWaveExecutor.run(activeFeatureIds);
|
|
110
126
|
await this.buildWaveExecutor.run(activeFeatureIds, this.maxParallelGateRuns);
|
|
111
127
|
await this.qaWaveExecutor.run(activeFeatureIds, this.maxParallelGateRuns);
|
|
112
128
|
await this.planningWaveExecutor.runPostQaReconciliation(activeFeatureIds, iteration + 1);
|
|
129
|
+
await this.notifyStatusTransitions(activeFeatureIds);
|
|
113
130
|
activeFeatureIds = await this.rebalanceActiveFeatures(activeFeatureIds);
|
|
114
131
|
}
|
|
115
132
|
|
|
@@ -127,6 +144,39 @@ export class RunCoordinator {
|
|
|
127
144
|
};
|
|
128
145
|
}
|
|
129
146
|
|
|
147
|
+
private async pauseOverBudgetFeatures(activeFeatureIds: string[]): Promise<string[]> {
|
|
148
|
+
const remaining: string[] = [];
|
|
149
|
+
for (const featureId of activeFeatureIds) {
|
|
150
|
+
const budgetCheck = await this.kernel.checkBudget(featureId);
|
|
151
|
+
if (budgetCheck.over_budget) {
|
|
152
|
+
await this.kernel.updateState(featureId, null, (_fm) => Promise.resolve({
|
|
153
|
+
frontMatter: {
|
|
154
|
+
status: STATUS.PAUSED_BUDGET,
|
|
155
|
+
status_reason: `Feature paused: estimated cost $${budgetCheck.current_cost_usd.toFixed(4)} exceeds budget limit $${budgetCheck.limit_usd.toFixed(2)}`
|
|
156
|
+
}
|
|
157
|
+
}));
|
|
158
|
+
if (this.notifier) {
|
|
159
|
+
await this.notifier.notify('budget_exceeded', {
|
|
160
|
+
feature_id: featureId,
|
|
161
|
+
message: `Budget exceeded for ${featureId}: $${budgetCheck.current_cost_usd.toFixed(4)} >= $${budgetCheck.limit_usd.toFixed(2)}`,
|
|
162
|
+
details: { current_cost_usd: budgetCheck.current_cost_usd, limit_usd: budgetCheck.limit_usd }
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
await this.sessionOrchestrator.closeFeatureCluster(featureId);
|
|
166
|
+
} else {
|
|
167
|
+
remaining.push(featureId);
|
|
168
|
+
if (budgetCheck.alert_threshold_reached && this.notifier) {
|
|
169
|
+
await this.notifier.notify('budget_alert', {
|
|
170
|
+
feature_id: featureId,
|
|
171
|
+
message: `Budget alert for ${featureId}: $${budgetCheck.current_cost_usd.toFixed(4)} (${Math.round(budgetCheck.alert_threshold * 100)}% of $${budgetCheck.limit_usd.toFixed(2)})`,
|
|
172
|
+
details: { current_cost_usd: budgetCheck.current_cost_usd, limit_usd: budgetCheck.limit_usd, alert_threshold: budgetCheck.alert_threshold }
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return remaining;
|
|
178
|
+
}
|
|
179
|
+
|
|
130
180
|
private async rebalanceActiveFeatures(currentActiveFeatureIds: string[]): Promise<string[]> {
|
|
131
181
|
const survivingActiveFeatureIds: string[] = [];
|
|
132
182
|
const sortedCurrent = [...currentActiveFeatureIds].sort((a, b) => a.localeCompare(b));
|
|
@@ -172,16 +222,103 @@ export class RunCoordinator {
|
|
|
172
222
|
return activeFeatureIds;
|
|
173
223
|
}
|
|
174
224
|
|
|
175
|
-
private
|
|
225
|
+
private static asRecord(value: unknown): Record<string, unknown> {
|
|
226
|
+
return value && typeof value === 'object' ? (value as Record<string, unknown>) : {};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private async readFeatureStateSnapshot(
|
|
230
|
+
featureId: string
|
|
231
|
+
): Promise<{ status: string | null; branch: string; hasPr: boolean }> {
|
|
176
232
|
try {
|
|
177
233
|
const state = await this.toolCaller.callTool<FeatureStatePayload>('orchestrator', TOOLS.FEATURE_STATE_GET, {
|
|
178
234
|
feature_id: featureId
|
|
179
235
|
});
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
236
|
+
const frontMatter = RunCoordinator.asRecord(state.data.front_matter);
|
|
237
|
+
const status = typeof frontMatter.status === 'string' ? frontMatter.status : null;
|
|
238
|
+
const prValue = frontMatter.pr;
|
|
239
|
+
const hasPr = prValue !== null && typeof prValue === 'object';
|
|
240
|
+
const branch =
|
|
241
|
+
typeof frontMatter.worktree_branch === 'string'
|
|
242
|
+
? frontMatter.worktree_branch
|
|
243
|
+
: typeof frontMatter.branch === 'string'
|
|
244
|
+
? frontMatter.branch
|
|
245
|
+
: featureId;
|
|
246
|
+
return { status, branch, hasPr };
|
|
247
|
+
} catch {
|
|
248
|
+
return { status: null, branch: featureId, hasPr: false };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private async readFeatureStatus(featureId: string): Promise<string | null> {
|
|
253
|
+
const snapshot = await this.readFeatureStateSnapshot(featureId);
|
|
254
|
+
return snapshot.status;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private async notifyStatusTransitions(featureIds: string[]): Promise<void> {
|
|
258
|
+
for (const featureId of featureIds) {
|
|
259
|
+
const snapshot = await this.readFeatureStateSnapshot(featureId);
|
|
260
|
+
const newStatus = snapshot.status;
|
|
261
|
+
if (newStatus === null) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const prevStatus = this.statusCache.get(featureId);
|
|
265
|
+
const shouldPollPr = this.prMonitor && (newStatus === STATUS.READY_TO_MERGE || snapshot.hasPr);
|
|
266
|
+
if (prevStatus === newStatus && shouldPollPr) {
|
|
267
|
+
await this.prMonitor.checkAndUpdate(featureId, snapshot.branch);
|
|
268
|
+
}
|
|
269
|
+
if (prevStatus === newStatus) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
this.statusCache.set(featureId, newStatus);
|
|
273
|
+
if (this.notifier) {
|
|
274
|
+
if (newStatus === STATUS.BLOCKED) {
|
|
275
|
+
const event = prevStatus === STATUS.PLANNING ? 'collision_detected' : 'gate_failed';
|
|
276
|
+
await this.notifier.notify(event, {
|
|
277
|
+
feature_id: featureId,
|
|
278
|
+
message: `Feature ${featureId} blocked (event: ${event})`
|
|
279
|
+
});
|
|
280
|
+
} else if (newStatus === STATUS.READY_TO_MERGE) {
|
|
281
|
+
await this.notifier.notify('ready_to_merge', {
|
|
282
|
+
feature_id: featureId,
|
|
283
|
+
message: `Feature ${featureId} is ready to merge`
|
|
284
|
+
});
|
|
285
|
+
if (shouldPollPr) {
|
|
286
|
+
await this.prMonitor.checkAndUpdate(featureId, snapshot.branch);
|
|
287
|
+
}
|
|
288
|
+
} else if (newStatus === STATUS.MERGED) {
|
|
289
|
+
await this.notifier.notify('feature_merged', {
|
|
290
|
+
feature_id: featureId,
|
|
291
|
+
message: `Feature ${featureId} was merged`
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (this.issueTracker) {
|
|
296
|
+
await this.syncIssueTrackerStatus(featureId, newStatus, prevStatus);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private async syncIssueTrackerStatus(featureId: string, status: string, prevStatus: string | undefined): Promise<void> {
|
|
302
|
+
if (!this.issueTracker) {return;}
|
|
303
|
+
const issueId = featureId.replace(/^feature[/_]/, '');
|
|
304
|
+
if (status === STATUS.PLANNING && prevStatus === undefined) {
|
|
305
|
+
// Spec enrichment: fetch issue context when planning starts, store in frontmatter
|
|
306
|
+
const issue = await this.issueTracker.getIssue(issueId).catch(() => null);
|
|
307
|
+
if (issue && issue.title) {
|
|
308
|
+
const issueCtx = {
|
|
309
|
+
id: issue.id,
|
|
310
|
+
title: issue.title,
|
|
311
|
+
body: issue.body,
|
|
312
|
+
status: issue.status,
|
|
313
|
+
url: issue.url
|
|
314
|
+
};
|
|
315
|
+
await this.kernel.updateState(featureId, null, (fm) =>
|
|
316
|
+
Promise.resolve({ frontMatter: { ...fm, issue_context: issueCtx } })
|
|
317
|
+
);
|
|
318
|
+
}
|
|
184
319
|
}
|
|
320
|
+
await this.issueTracker.addComment(issueId, `AOP: feature status changed to \`${status}\``).catch(() => undefined);
|
|
321
|
+
await this.issueTracker.updateIssueStatus(issueId, status).catch(() => undefined);
|
|
185
322
|
}
|
|
186
323
|
|
|
187
324
|
private async applyOrchestratorPrioritization(
|
|
@@ -11,6 +11,19 @@ import { QaWaveExecutor } from './qa-wave-executor.js';
|
|
|
11
11
|
import { LeaseHeartbeatService } from './lease-heartbeat-service.js';
|
|
12
12
|
import { RunCoordinator } from './run-coordinator.js';
|
|
13
13
|
import { WorkerDecisionLoop } from './worker-decision-loop.js';
|
|
14
|
+
import { createNotifierService } from '../application/services/notifier-service.js';
|
|
15
|
+
import { ReactionsService } from '../application/services/reactions-service.js';
|
|
16
|
+
import { ActivityMonitorService } from '../application/services/activity-monitor-service.js';
|
|
17
|
+
import { PrMonitorService, createGhRunner } from '../application/services/pr-monitor-service.js';
|
|
18
|
+
import { createIssueTracker } from '../application/services/issue-tracker-service.js';
|
|
19
|
+
import {
|
|
20
|
+
globalAdapterRegistry,
|
|
21
|
+
NOTIFICATION_CHANNEL_SLOT,
|
|
22
|
+
ACTIVITY_DETECTOR_SLOT,
|
|
23
|
+
SCM_PROVIDER_SLOT,
|
|
24
|
+
type AdapterSlot
|
|
25
|
+
} from '../application/adapters/adapter-registry.js';
|
|
26
|
+
import type { ReactionsPolicy } from '../application/services/reactions-service.js';
|
|
14
27
|
import type {
|
|
15
28
|
AgentPromptProvider,
|
|
16
29
|
AppError,
|
|
@@ -26,6 +39,32 @@ import type {
|
|
|
26
39
|
WorkerSessions
|
|
27
40
|
} from './types.js';
|
|
28
41
|
|
|
42
|
+
type NamedContract = { name: string };
|
|
43
|
+
|
|
44
|
+
function resolveAdapterName(
|
|
45
|
+
slot: AdapterSlot<NamedContract>,
|
|
46
|
+
configuredValue: unknown,
|
|
47
|
+
fallback: string | null
|
|
48
|
+
): string | null {
|
|
49
|
+
const configured = typeof configuredValue === 'string' && configuredValue.length > 0 ? configuredValue : null;
|
|
50
|
+
const candidate = configured ?? fallback;
|
|
51
|
+
if (!candidate) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return globalAdapterRegistry.resolve(slot, candidate, {}).name;
|
|
56
|
+
} catch {
|
|
57
|
+
if (!fallback || candidate === fallback) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
return globalAdapterRegistry.resolve(slot, fallback, {}).name;
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
29
68
|
export class SupervisorRuntime
|
|
30
69
|
implements SupervisorToolCaller, AgentPromptProvider, InitialPlanGenerator, FeatureClusterPatcher
|
|
31
70
|
{
|
|
@@ -58,11 +97,18 @@ export class SupervisorRuntime
|
|
|
58
97
|
this.provider = provider;
|
|
59
98
|
this.toolClient = toolClient;
|
|
60
99
|
this.maxActiveFeatures = options.max_active_features ?? 5;
|
|
61
|
-
this.maxParallelGateRuns = options.max_parallel_gate_runs
|
|
100
|
+
this.maxParallelGateRuns = this.resolveMaxParallelGateRuns(options.max_parallel_gate_runs);
|
|
62
101
|
this.maxIterationsPerPhase = this.resolveMaxIterationsPerPhase(options.max_iterations_per_phase);
|
|
63
102
|
this.takeoverStaleRun = Boolean(options.takeover_stale_run);
|
|
64
103
|
const runId = options.run_id ?? `run:${Date.now()}`;
|
|
65
104
|
const ownerInstanceId = options.owner_instance_id ?? `supervisor:${process.pid}:${crypto.randomUUID()}`;
|
|
105
|
+
const adaptersConfig =
|
|
106
|
+
typeof (this.kernel as { getAdaptersConfig?: () => Record<string, unknown> }).getAdaptersConfig === 'function'
|
|
107
|
+
? this.kernel.getAdaptersConfig()
|
|
108
|
+
: {};
|
|
109
|
+
const notificationChannel = resolveAdapterName(NOTIFICATION_CHANNEL_SLOT, adaptersConfig['notification-channel'], null);
|
|
110
|
+
const activityDetector = resolveAdapterName(ACTIVITY_DETECTOR_SLOT, adaptersConfig['activity-detector'], 'claude-jsonl');
|
|
111
|
+
const scmProvider = resolveAdapterName(SCM_PROVIDER_SLOT, adaptersConfig['scm-provider'], 'github');
|
|
66
112
|
|
|
67
113
|
this.state = {
|
|
68
114
|
runId,
|
|
@@ -74,7 +120,12 @@ export class SupervisorRuntime
|
|
|
74
120
|
started_at: new Date().toISOString(),
|
|
75
121
|
owner_instance_id: ownerInstanceId,
|
|
76
122
|
takeover_stale_run: this.takeoverStaleRun,
|
|
77
|
-
resolved_provider: provider.selection
|
|
123
|
+
resolved_provider: provider.selection,
|
|
124
|
+
adapters: {
|
|
125
|
+
notification_channel: notificationChannel,
|
|
126
|
+
activity_detector: activityDetector,
|
|
127
|
+
scm_provider: scmProvider
|
|
128
|
+
}
|
|
78
129
|
}
|
|
79
130
|
};
|
|
80
131
|
|
|
@@ -88,9 +139,43 @@ export class SupervisorRuntime
|
|
|
88
139
|
state: this.state
|
|
89
140
|
});
|
|
90
141
|
|
|
142
|
+
const notifier = createNotifierService(this.kernel.getPolicySnapshot(), notificationChannel);
|
|
143
|
+
const reactionsPolicy = this.resolveReactionsPolicy();
|
|
144
|
+
const reactionsService = new ReactionsService({
|
|
145
|
+
toolCaller: this,
|
|
146
|
+
notifier,
|
|
147
|
+
policy: reactionsPolicy
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const activityMonitor = new ActivityMonitorService({
|
|
151
|
+
toolCaller: this,
|
|
152
|
+
notifier,
|
|
153
|
+
reactionsPolicy,
|
|
154
|
+
idleThresholdMs: this.resolveActivityIdleThresholdMs(),
|
|
155
|
+
detectorName: activityDetector ?? 'claude-jsonl'
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const prMonitor =
|
|
159
|
+
scmProvider === 'github'
|
|
160
|
+
? new PrMonitorService({
|
|
161
|
+
toolCaller: this,
|
|
162
|
+
notifier,
|
|
163
|
+
reactionsPolicy,
|
|
164
|
+
ghRunner: createGhRunner()
|
|
165
|
+
})
|
|
166
|
+
: undefined;
|
|
167
|
+
|
|
168
|
+
const policy = this.kernel.getPolicySnapshot();
|
|
169
|
+
const rawIssueTrackerConfig = policy['issue_tracker'];
|
|
170
|
+
const issueTrackerConfig = typeof rawIssueTrackerConfig === 'object' && rawIssueTrackerConfig !== null
|
|
171
|
+
? (rawIssueTrackerConfig as { type: string; config?: Record<string, string> })
|
|
172
|
+
: undefined;
|
|
173
|
+
const issueTracker = createIssueTracker(issueTrackerConfig);
|
|
174
|
+
|
|
91
175
|
this.workerDecisionLoop = new WorkerDecisionLoop({
|
|
92
176
|
provider: this.provider,
|
|
93
|
-
toolCaller: this
|
|
177
|
+
toolCaller: this,
|
|
178
|
+
activityMonitor
|
|
94
179
|
});
|
|
95
180
|
|
|
96
181
|
this.planningWaveExecutor = new PlanningWaveExecutor({
|
|
@@ -101,7 +186,8 @@ export class SupervisorRuntime
|
|
|
101
186
|
|
|
102
187
|
this.buildWaveExecutor = new BuildWaveExecutor({
|
|
103
188
|
toolCaller: this,
|
|
104
|
-
workerDecisionRunner: this.workerDecisionLoop
|
|
189
|
+
workerDecisionRunner: this.workerDecisionLoop,
|
|
190
|
+
reactionsService
|
|
105
191
|
});
|
|
106
192
|
|
|
107
193
|
this.qaWaveExecutor = new QaWaveExecutor({
|
|
@@ -111,7 +197,8 @@ export class SupervisorRuntime
|
|
|
111
197
|
promptProvider: this,
|
|
112
198
|
featureClusterPatcher: this,
|
|
113
199
|
state: this.state,
|
|
114
|
-
workerDecisionRunner: this.workerDecisionLoop
|
|
200
|
+
workerDecisionRunner: this.workerDecisionLoop,
|
|
201
|
+
reactionsService
|
|
115
202
|
});
|
|
116
203
|
|
|
117
204
|
this.leaseHeartbeatService = new LeaseHeartbeatService({
|
|
@@ -134,7 +221,10 @@ export class SupervisorRuntime
|
|
|
134
221
|
maxIterationsPerPhase: this.maxIterationsPerPhase,
|
|
135
222
|
takeoverStaleRun: this.takeoverStaleRun,
|
|
136
223
|
providerConfigRefHash: () => this.providerConfigRefHash(),
|
|
137
|
-
workerDecisionRunner: this.workerDecisionLoop
|
|
224
|
+
workerDecisionRunner: this.workerDecisionLoop,
|
|
225
|
+
notifier,
|
|
226
|
+
prMonitor,
|
|
227
|
+
issueTracker
|
|
138
228
|
});
|
|
139
229
|
}
|
|
140
230
|
|
|
@@ -220,6 +310,45 @@ export class SupervisorRuntime
|
|
|
220
310
|
return SupervisorRuntime.DEFAULT_MAX_ITERATIONS_PER_PHASE;
|
|
221
311
|
}
|
|
222
312
|
|
|
313
|
+
private resolveMaxParallelGateRuns(cliOverride: number | undefined): number {
|
|
314
|
+
if (typeof cliOverride === 'number' && Number.isFinite(cliOverride) && cliOverride >= 1) {
|
|
315
|
+
return Math.floor(cliOverride);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const policy = this.kernel.getPolicySnapshot();
|
|
319
|
+
const supervisor =
|
|
320
|
+
policy.supervisor && typeof policy.supervisor === 'object'
|
|
321
|
+
? (policy.supervisor as Record<string, unknown>)
|
|
322
|
+
: null;
|
|
323
|
+
const configured = supervisor?.max_parallel_gate_runs;
|
|
324
|
+
if (typeof configured === 'number' && Number.isFinite(configured) && configured >= 1) {
|
|
325
|
+
return Math.floor(configured);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return 2;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
private resolveReactionsPolicy(): ReactionsPolicy | undefined {
|
|
332
|
+
const policy = this.kernel.getPolicySnapshot();
|
|
333
|
+
if (policy.reactions && typeof policy.reactions === 'object') {
|
|
334
|
+
return policy.reactions as ReactionsPolicy;
|
|
335
|
+
}
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private resolveActivityIdleThresholdMs(): number {
|
|
340
|
+
const policy = this.kernel.getPolicySnapshot();
|
|
341
|
+
const supervisor =
|
|
342
|
+
policy.supervisor && typeof policy.supervisor === 'object'
|
|
343
|
+
? (policy.supervisor as Record<string, unknown>)
|
|
344
|
+
: null;
|
|
345
|
+
const configured = supervisor?.agent_idle_threshold_ms;
|
|
346
|
+
if (typeof configured === 'number' && Number.isFinite(configured) && configured > 0) {
|
|
347
|
+
return Math.floor(configured);
|
|
348
|
+
}
|
|
349
|
+
return 300_000;
|
|
350
|
+
}
|
|
351
|
+
|
|
223
352
|
async ensureGlobalOrchestratorSession(): Promise<void> {
|
|
224
353
|
await this.sessionOrchestrator.ensureGlobalOrchestratorSession();
|
|
225
354
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { AgentsConfigSnapshot } from '../core/kernel.js';
|
|
2
|
+
import type { FeatureStatePayload } from '../core/tool-caller.js';
|
|
3
|
+
import type { BudgetCheckResult } from '../application/services/cost-tracking-service.js';
|
|
4
|
+
export type {
|
|
5
|
+
FeatureStateFrontMatter,
|
|
6
|
+
FeatureStatePayload,
|
|
7
|
+
RuntimeRole,
|
|
8
|
+
ToolCaller as SupervisorToolCaller
|
|
9
|
+
} from '../core/tool-caller.js';
|
|
2
10
|
|
|
3
11
|
export interface AppError extends Error {
|
|
4
12
|
code?: string;
|
|
@@ -24,19 +32,6 @@ export interface WorkerSessions {
|
|
|
24
32
|
qa: string;
|
|
25
33
|
}
|
|
26
34
|
|
|
27
|
-
export type RuntimeRole = 'orchestrator' | 'planner' | 'builder' | 'qa';
|
|
28
|
-
|
|
29
|
-
export interface FeatureStateFrontMatter {
|
|
30
|
-
version: number;
|
|
31
|
-
status: string;
|
|
32
|
-
cluster?: Record<string, string>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface FeatureStatePayload {
|
|
36
|
-
front_matter: FeatureStateFrontMatter;
|
|
37
|
-
body?: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
35
|
export interface FeatureContextPayload {
|
|
41
36
|
state: FeatureStatePayload;
|
|
42
37
|
spec?: string;
|
|
@@ -101,6 +96,7 @@ export interface RuntimeStateReader {
|
|
|
101
96
|
getRepoRoot(): string;
|
|
102
97
|
getAgentsConfig(): AgentsConfigSnapshot;
|
|
103
98
|
getPolicySnapshot(): Record<string, unknown>;
|
|
99
|
+
getAdaptersConfig(): Record<string, unknown>;
|
|
104
100
|
}
|
|
105
101
|
|
|
106
102
|
export interface FeatureOrchestrationPort {
|
|
@@ -113,18 +109,13 @@ export interface FeatureOrchestrationPort {
|
|
|
113
109
|
renewLeases(featureIds: string[]): Promise<void>;
|
|
114
110
|
renewRunLease(runId: string, ownerInstanceId: string): Promise<{ data: { lease_expires_at: string } }>;
|
|
115
111
|
repoDiff(featureId: string, options?: string[]): Promise<{ data: Record<string, unknown> }>;
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
+
updateState(featureId: string, expectedVersion: number | null, updater: (fm: Record<string, any>, body: string) => Promise<{ frontMatter?: Record<string, any>; body?: string }>): Promise<Record<string, unknown>>;
|
|
114
|
+
checkBudget(featureId: string): Promise<BudgetCheckResult>;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
117
|
export type SupervisorKernelPort = RuntimeStateReader & FeatureOrchestrationPort;
|
|
119
118
|
|
|
120
|
-
export interface SupervisorToolCaller {
|
|
121
|
-
callTool<TData = Record<string, unknown>>(
|
|
122
|
-
role: RuntimeRole,
|
|
123
|
-
toolName: string,
|
|
124
|
-
args: Record<string, unknown>
|
|
125
|
-
): Promise<{ ok: true; data: TData }>;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
119
|
export interface AgentPromptProvider {
|
|
129
120
|
loadRolePrompts(): Promise<PromptBundle>;
|
|
130
121
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TOOLS } from '../core/constants.js';
|
|
2
2
|
import type { WorkerProvider } from '../providers/providers.js';
|
|
3
3
|
import type { RuntimeRole, SupervisorToolCaller } from './types.js';
|
|
4
|
+
import type { ActivityMonitorService } from '../application/services/activity-monitor-service.js';
|
|
4
5
|
|
|
5
6
|
type AnyRecord = Record<string, unknown>;
|
|
6
7
|
|
|
@@ -86,15 +87,18 @@ export const NOOP_WORKER_DECISION_RUNNER: WorkerDecisionRunner = {
|
|
|
86
87
|
interface WorkerDecisionLoopDependencies {
|
|
87
88
|
provider: WorkerProvider;
|
|
88
89
|
toolCaller: SupervisorToolCaller;
|
|
90
|
+
activityMonitor?: ActivityMonitorService;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
92
94
|
private readonly provider: WorkerProvider;
|
|
93
95
|
private readonly toolCaller: SupervisorToolCaller;
|
|
96
|
+
private readonly activityMonitor: ActivityMonitorService | undefined;
|
|
94
97
|
|
|
95
98
|
constructor(dependencies: WorkerDecisionLoopDependencies) {
|
|
96
99
|
this.provider = dependencies.provider;
|
|
97
100
|
this.toolCaller = dependencies.toolCaller;
|
|
101
|
+
this.activityMonitor = dependencies.activityMonitor;
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
async execute(input: WorkerDecisionInput): Promise<WorkerDecisionResult> {
|
|
@@ -140,6 +144,10 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
140
144
|
}
|
|
141
145
|
}
|
|
142
146
|
|
|
147
|
+
if (this.activityMonitor) {
|
|
148
|
+
await this.activityMonitor.checkAndNotifyStuck(input.featureId);
|
|
149
|
+
}
|
|
150
|
+
|
|
143
151
|
return result;
|
|
144
152
|
}
|
|
145
153
|
|