agentic-orchestrator 0.1.6 → 0.1.7
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/.prettierignore +10 -0
- package/.prettierrc.json +24 -0
- package/CLAUDE.md +3 -2
- package/README.md +47 -46
- package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
- package/agentic/orchestrator/prompts/planner.system.md +1 -0
- package/agentic/orchestrator/schemas/agents.schema.json +4 -21
- package/agentic/orchestrator/schemas/gates.schema.json +4 -19
- package/agentic/orchestrator/schemas/index.schema.json +3 -14
- package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
- package/agentic/orchestrator/schemas/plan.schema.json +6 -26
- package/agentic/orchestrator/schemas/policy.schema.json +19 -81
- package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
- package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
- package/agentic/orchestrator/schemas/state.schema.json +11 -61
- package/agentic/orchestrator/tools/catalog.json +33 -164
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
- package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
- package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
- package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
- package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
- package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
- package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
- package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
- package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
- package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
- package/apps/control-plane/src/application/services/gate-service.ts +64 -41
- package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
- package/apps/control-plane/src/application/services/lock-service.ts +75 -49
- package/apps/control-plane/src/application/services/merge-service.ts +91 -50
- package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
- package/apps/control-plane/src/application/services/patch-service.ts +73 -44
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
- package/apps/control-plane/src/application/services/plan-service.ts +148 -89
- package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
- package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
- package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
- package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
- package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
- package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
- package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
- package/apps/control-plane/src/cli/aop.ts +2 -2
- package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
- package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
- package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
- package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
- package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
- package/apps/control-plane/src/cli/init-command-handler.ts +110 -54
- package/apps/control-plane/src/cli/io.ts +7 -3
- package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
- package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
- package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
- package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
- package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
- package/apps/control-plane/src/cli/spec-utils.ts +2 -2
- package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
- package/apps/control-plane/src/cli/tooling.ts +3 -3
- package/apps/control-plane/src/cli/types.ts +1 -1
- package/apps/control-plane/src/core/collisions.ts +27 -10
- package/apps/control-plane/src/core/constants.ts +13 -7
- package/apps/control-plane/src/core/error-codes.ts +1 -1
- package/apps/control-plane/src/core/fs.ts +11 -5
- package/apps/control-plane/src/core/gates.ts +53 -27
- package/apps/control-plane/src/core/git.ts +18 -6
- package/apps/control-plane/src/core/kernel.ts +515 -227
- package/apps/control-plane/src/core/patch.ts +7 -3
- package/apps/control-plane/src/core/path-layout.ts +5 -1
- package/apps/control-plane/src/core/path-rules.ts +19 -5
- package/apps/control-plane/src/core/qa-index.ts +26 -12
- package/apps/control-plane/src/core/response.ts +9 -6
- package/apps/control-plane/src/core/schemas.ts +29 -10
- package/apps/control-plane/src/core/tool-caller.ts +1 -1
- package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
- package/apps/control-plane/src/index.ts +3 -9
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +69 -32
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
- package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
- package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
- package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
- package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
- package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
- package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
- package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
- package/apps/control-plane/src/mcp/tool-client.ts +17 -5
- package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
- package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
- package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
- package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
- package/apps/control-plane/src/providers/providers.ts +72 -48
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
- package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
- package/apps/control-plane/src/supervisor/runtime.ts +59 -35
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
- package/apps/control-plane/src/supervisor/types.ts +22 -7
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
- package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
- package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
- package/apps/control-plane/test/aop.spec.ts +4 -4
- package/apps/control-plane/test/batch-operations.spec.ts +20 -18
- package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
- package/apps/control-plane/test/bootstrap.spec.ts +72 -40
- package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
- package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
- package/apps/control-plane/test/cli.spec.ts +1 -1
- package/apps/control-plane/test/cli.unit.spec.ts +226 -167
- package/apps/control-plane/test/collision-queue.spec.ts +49 -40
- package/apps/control-plane/test/collisions.spec.ts +30 -30
- package/apps/control-plane/test/core-utils.spec.ts +29 -15
- package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
- package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
- package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
- package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
- package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
- package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
- package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
- package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
- package/apps/control-plane/test/gates.spec.ts +101 -81
- package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
- package/apps/control-plane/test/helpers.ts +10 -6
- package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
- package/apps/control-plane/test/init-wizard.spec.ts +162 -67
- package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
- package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
- package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
- package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
- package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
- package/apps/control-plane/test/kernel.spec.ts +134 -51
- package/apps/control-plane/test/lock-service.spec.ts +92 -68
- package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
- package/apps/control-plane/test/mcp.spec.ts +231 -115
- package/apps/control-plane/test/merge-service.spec.ts +142 -94
- package/apps/control-plane/test/multi-project.spec.ts +28 -22
- package/apps/control-plane/test/notifier-service.spec.ts +136 -92
- package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
- package/apps/control-plane/test/patch-service.spec.ts +128 -48
- package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
- package/apps/control-plane/test/plan-service.spec.ts +50 -39
- package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
- package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
- package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
- package/apps/control-plane/test/providers.spec.ts +133 -102
- package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
- package/apps/control-plane/test/qa-index.spec.ts +58 -61
- package/apps/control-plane/test/reactions.spec.ts +88 -45
- package/apps/control-plane/test/response.spec.ts +5 -5
- package/apps/control-plane/test/resume-command.spec.ts +121 -80
- package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
- package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
- package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
- package/apps/control-plane/test/services.spec.ts +147 -129
- package/apps/control-plane/test/session-management.spec.ts +136 -74
- package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
- package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
- package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
- package/apps/control-plane/test/supervisor.spec.ts +67 -43
- package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
- package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
- package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
- package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
- package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
- package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
- package/apps/control-plane/tsconfig.build.json +2 -7
- package/apps/control-plane/tsconfig.json +1 -5
- package/apps/control-plane/vitest.config.ts +7 -7
- package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
- package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
- package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
- package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.js +26 -26
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/lock-service.js +32 -32
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/merge-service.js +41 -27
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/patch-service.js +21 -19
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.js +33 -33
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
- package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
- package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +44 -33
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/io.js +2 -2
- package/dist/apps/control-plane/cli/io.js.map +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/tooling.js +1 -1
- package/dist/apps/control-plane/core/collisions.js +11 -8
- package/dist/apps/control-plane/core/collisions.js.map +1 -1
- package/dist/apps/control-plane/core/constants.js +13 -7
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.js +1 -1
- package/dist/apps/control-plane/core/fs.js.map +1 -1
- package/dist/apps/control-plane/core/gates.d.ts +2 -2
- package/dist/apps/control-plane/core/gates.js +26 -19
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/git.js +3 -3
- package/dist/apps/control-plane/core/git.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.d.ts +1 -0
- package/dist/apps/control-plane/core/kernel.js +134 -81
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/patch.js +7 -3
- package/dist/apps/control-plane/core/patch.js.map +1 -1
- package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
- package/dist/apps/control-plane/core/path-layout.js +4 -1
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/path-rules.js +3 -1
- package/dist/apps/control-plane/core/path-rules.js.map +1 -1
- package/dist/apps/control-plane/core/qa-index.js +5 -5
- package/dist/apps/control-plane/core/qa-index.js.map +1 -1
- package/dist/apps/control-plane/core/response.js +3 -3
- package/dist/apps/control-plane/core/response.js.map +1 -1
- package/dist/apps/control-plane/core/schemas.js +10 -6
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
- package/dist/apps/control-plane/index.d.ts +1 -1
- package/dist/apps/control-plane/index.js +1 -1
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +31 -20
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
- package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
- package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
- package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
- package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
- package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-client.js +2 -2
- package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
- package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +1 -1
- package/dist/apps/control-plane/providers/providers.js +31 -34
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.js +25 -21
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/eslint.config.mjs +20 -20
- package/example-configurations/README.md +1 -1
- package/example-configurations/java/agents.yaml +3 -3
- package/example-configurations/java/policy.yaml +1 -1
- package/example-configurations/node/agents.yaml +3 -3
- package/example-configurations/node/policy.yaml +1 -1
- package/package.json +10 -5
- package/packages/web-dashboard/next.config.js +2 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
- package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
- package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
- package/packages/web-dashboard/src/app/globals.css +10 -2
- package/packages/web-dashboard/src/app/page.tsx +100 -37
- package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
- package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
- package/packages/web-dashboard/tsconfig.json +3 -11
- package/scripts/nx-safe.mjs +10 -10
- package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
- package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +187 -90
- package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
- package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
- package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
- package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
- package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
- package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
- package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
- package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
- package/spec-files/progress.md +186 -175
- package/tsconfig.json +2 -8
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
RuntimeStateReader,
|
|
8
8
|
SupervisorKernelPort,
|
|
9
9
|
SupervisorRuntimeState,
|
|
10
|
-
SupervisorToolCaller
|
|
10
|
+
SupervisorToolCaller,
|
|
11
11
|
} from './types.js';
|
|
12
12
|
import { UNASSIGNED_SESSION_ID } from './types.js';
|
|
13
13
|
|
|
@@ -67,7 +67,7 @@ export class SessionOrchestrator {
|
|
|
67
67
|
run_id: this.state.runId,
|
|
68
68
|
owner_instance_id: this.state.ownerInstanceId,
|
|
69
69
|
orchestrator_session_id: orchestratorSession.session_id,
|
|
70
|
-
increment_epoch: canReuse
|
|
70
|
+
increment_epoch: canReuse,
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
if (canReuse && candidate) {
|
|
@@ -90,8 +90,8 @@ export class SessionOrchestrator {
|
|
|
90
90
|
const reattachResult = await Promise.race([
|
|
91
91
|
this.provider.reattachSession(sessionId),
|
|
92
92
|
new Promise<never>((_, reject) =>
|
|
93
|
-
setTimeout(() => reject(new Error('Reattach timeout')), timeoutMs)
|
|
94
|
-
)
|
|
93
|
+
setTimeout(() => reject(new Error('Reattach timeout')), timeoutMs),
|
|
94
|
+
),
|
|
95
95
|
]);
|
|
96
96
|
return Boolean(reattachResult?.session_id === sessionId);
|
|
97
97
|
} catch (_error) {
|
|
@@ -116,14 +116,16 @@ export class SessionOrchestrator {
|
|
|
116
116
|
metadata: {
|
|
117
117
|
orphan_session_id: sessionId,
|
|
118
118
|
previous_epoch: previousEpoch,
|
|
119
|
-
new_epoch: previousEpoch + 1
|
|
120
|
-
}
|
|
119
|
+
new_epoch: previousEpoch + 1,
|
|
120
|
+
},
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
-
await this.toolCaller
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
await this.toolCaller
|
|
124
|
+
.callTool('orchestrator', TOOLS.FEATURE_LOG_APPEND, {
|
|
125
|
+
feature_id: 'global',
|
|
126
|
+
note: JSON.stringify(orphanEvent),
|
|
127
|
+
})
|
|
128
|
+
.catch(() => ({ ok: true, data: {} }));
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
async cleanupOrphanWorkerSessions(scopedFeatureIds: string[]): Promise<void> {
|
|
@@ -138,7 +140,11 @@ export class SessionOrchestrator {
|
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
const assignment = assignments[featureId];
|
|
141
|
-
for (const sessionId of [
|
|
143
|
+
for (const sessionId of [
|
|
144
|
+
assignment.planner_session_id,
|
|
145
|
+
assignment.builder_session_id,
|
|
146
|
+
assignment.qa_session_id,
|
|
147
|
+
]) {
|
|
142
148
|
if (!sessionId || sessionId === UNASSIGNED_SESSION_ID) {
|
|
143
149
|
continue;
|
|
144
150
|
}
|
|
@@ -159,7 +165,7 @@ export class SessionOrchestrator {
|
|
|
159
165
|
this.state.sessionsByFeature.set(featureId, {
|
|
160
166
|
planner: plannerSession.session_id,
|
|
161
167
|
builder: builderSession.session_id,
|
|
162
|
-
qa: qaSession.session_id
|
|
168
|
+
qa: qaSession.session_id,
|
|
163
169
|
});
|
|
164
170
|
|
|
165
171
|
await this.kernel.updateFeatureSessionAssignment({
|
|
@@ -168,14 +174,14 @@ export class SessionOrchestrator {
|
|
|
168
174
|
feature_id: featureId,
|
|
169
175
|
planner_session_id: plannerSession.session_id,
|
|
170
176
|
builder_session_id: builderSession.session_id,
|
|
171
|
-
qa_session_id: qaSession.session_id
|
|
177
|
+
qa_session_id: qaSession.session_id,
|
|
172
178
|
});
|
|
173
179
|
|
|
174
180
|
await this.patchFeatureCluster(featureId, {
|
|
175
181
|
orchestrator_session_id: this.state.orchestratorSessionId ?? 'unknown',
|
|
176
182
|
planner_session_id: plannerSession.session_id,
|
|
177
183
|
builder_session_id: builderSession.session_id,
|
|
178
|
-
qa_session_id: qaSession.session_id
|
|
184
|
+
qa_session_id: qaSession.session_id,
|
|
179
185
|
});
|
|
180
186
|
}
|
|
181
187
|
|
|
@@ -204,14 +210,14 @@ export class SessionOrchestrator {
|
|
|
204
210
|
feature_id: feature.feature_id,
|
|
205
211
|
planner_session_id: UNASSIGNED_SESSION_ID,
|
|
206
212
|
builder_session_id: UNASSIGNED_SESSION_ID,
|
|
207
|
-
qa_session_id: UNASSIGNED_SESSION_ID
|
|
213
|
+
qa_session_id: UNASSIGNED_SESSION_ID,
|
|
208
214
|
});
|
|
209
215
|
|
|
210
216
|
await this.patchFeatureCluster(feature.feature_id, {
|
|
211
217
|
orchestrator_session_id: this.state.orchestratorSessionId ?? 'unknown',
|
|
212
218
|
planner_session_id: UNASSIGNED_SESSION_ID,
|
|
213
219
|
builder_session_id: UNASSIGNED_SESSION_ID,
|
|
214
|
-
qa_session_id: UNASSIGNED_SESSION_ID
|
|
220
|
+
qa_session_id: UNASSIGNED_SESSION_ID,
|
|
215
221
|
});
|
|
216
222
|
}
|
|
217
223
|
}
|
|
@@ -223,9 +229,13 @@ export class SessionOrchestrator {
|
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
for (const featureId of [...activeFeatureIds].sort((a, b) => a.localeCompare(b))) {
|
|
226
|
-
const state = await this.toolCaller.callTool<FeatureStatePayload>(
|
|
227
|
-
|
|
228
|
-
|
|
232
|
+
const state = await this.toolCaller.callTool<FeatureStatePayload>(
|
|
233
|
+
'orchestrator',
|
|
234
|
+
TOOLS.FEATURE_STATE_GET,
|
|
235
|
+
{
|
|
236
|
+
feature_id: featureId,
|
|
237
|
+
},
|
|
238
|
+
);
|
|
229
239
|
|
|
230
240
|
const cluster = state.data.front_matter.cluster ?? {};
|
|
231
241
|
if (cluster.orchestrator_session_id === orchestratorSessionId) {
|
|
@@ -239,18 +249,25 @@ export class SessionOrchestrator {
|
|
|
239
249
|
front_matter: {
|
|
240
250
|
cluster: {
|
|
241
251
|
...cluster,
|
|
242
|
-
orchestrator_session_id: orchestratorSessionId
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
252
|
+
orchestrator_session_id: orchestratorSessionId,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
246
256
|
});
|
|
247
257
|
}
|
|
248
258
|
}
|
|
249
259
|
|
|
250
|
-
async patchFeatureCluster(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
260
|
+
async patchFeatureCluster(
|
|
261
|
+
featureId: string,
|
|
262
|
+
clusterPatch: Record<string, string>,
|
|
263
|
+
): Promise<void> {
|
|
264
|
+
const state = await this.toolCaller.callTool<FeatureStatePayload>(
|
|
265
|
+
'orchestrator',
|
|
266
|
+
TOOLS.FEATURE_STATE_GET,
|
|
267
|
+
{
|
|
268
|
+
feature_id: featureId,
|
|
269
|
+
},
|
|
270
|
+
);
|
|
254
271
|
|
|
255
272
|
await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_PATCH, {
|
|
256
273
|
feature_id: featureId,
|
|
@@ -259,10 +276,10 @@ export class SessionOrchestrator {
|
|
|
259
276
|
front_matter: {
|
|
260
277
|
cluster: {
|
|
261
278
|
...(state.data.front_matter.cluster ?? {}),
|
|
262
|
-
...clusterPatch
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
279
|
+
...clusterPatch,
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
266
283
|
});
|
|
267
284
|
}
|
|
268
285
|
}
|
|
@@ -5,7 +5,7 @@ export type {
|
|
|
5
5
|
FeatureStateFrontMatter,
|
|
6
6
|
FeatureStatePayload,
|
|
7
7
|
RuntimeRole,
|
|
8
|
-
ToolCaller as SupervisorToolCaller
|
|
8
|
+
ToolCaller as SupervisorToolCaller,
|
|
9
9
|
} from '../core/tool-caller.js';
|
|
10
10
|
|
|
11
11
|
export interface AppError extends Error {
|
|
@@ -103,14 +103,29 @@ export interface FeatureOrchestrationPort {
|
|
|
103
103
|
ensureLoaded(): Promise<void>;
|
|
104
104
|
recoverFromState(): Promise<{ data: Record<string, unknown> }>;
|
|
105
105
|
acquireRunLease(input: AcquireRunLeaseInput): Promise<{ data: { took_over_stale: boolean } }>;
|
|
106
|
-
updateOrchestratorSession(
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
updateOrchestratorSession(
|
|
107
|
+
params: UpdateOrchestratorSessionInput,
|
|
108
|
+
): Promise<{ data: { runtime_sessions: RuntimeSessionsSnapshot } }>;
|
|
109
|
+
updateFeatureSessionAssignment(
|
|
110
|
+
params: UpdateFeatureSessionAssignmentInput,
|
|
111
|
+
): Promise<{ data: { updated: boolean } }>;
|
|
112
|
+
pruneFeatureSessionAssignments(
|
|
113
|
+
params: PruneFeatureSessionAssignmentsInput,
|
|
114
|
+
): Promise<{ data: { removed: string[] } }>;
|
|
109
115
|
renewLeases(featureIds: string[]): Promise<void>;
|
|
110
|
-
renewRunLease(
|
|
116
|
+
renewRunLease(
|
|
117
|
+
runId: string,
|
|
118
|
+
ownerInstanceId: string,
|
|
119
|
+
): Promise<{ data: { lease_expires_at: string } }>;
|
|
111
120
|
repoDiff(featureId: string, options?: string[]): Promise<{ data: Record<string, unknown> }>;
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
updateState(
|
|
122
|
+
featureId: string,
|
|
123
|
+
expectedVersion: number | null,
|
|
124
|
+
updater: (
|
|
125
|
+
fm: Record<string, unknown>,
|
|
126
|
+
body: string,
|
|
127
|
+
) => Promise<{ frontMatter?: Record<string, unknown>; body?: string }>,
|
|
128
|
+
): Promise<Record<string, unknown>>;
|
|
114
129
|
checkBudget(featureId: string): Promise<BudgetCheckResult>;
|
|
115
130
|
}
|
|
116
131
|
|
|
@@ -62,9 +62,7 @@ function readPlanVersion(value: unknown): number | null {
|
|
|
62
62
|
function asOutputs(result: Record<string, unknown>): AnyRecord[] {
|
|
63
63
|
const outputs = result.outputs;
|
|
64
64
|
if (Array.isArray(outputs)) {
|
|
65
|
-
return outputs
|
|
66
|
-
.map((item) => asRecord(item))
|
|
67
|
-
.filter((item) => Object.keys(item).length > 0);
|
|
65
|
+
return outputs.map((item) => asRecord(item)).filter((item) => Object.keys(item).length > 0);
|
|
68
66
|
}
|
|
69
67
|
return [asRecord(result)];
|
|
70
68
|
}
|
|
@@ -76,12 +74,12 @@ function makeEmptyResult(): WorkerDecisionResult {
|
|
|
76
74
|
noteLogged: false,
|
|
77
75
|
requestHandled: false,
|
|
78
76
|
priorityOrder: [],
|
|
79
|
-
toolResults: []
|
|
77
|
+
toolResults: [],
|
|
80
78
|
};
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
export const NOOP_WORKER_DECISION_RUNNER: WorkerDecisionRunner = {
|
|
84
|
-
execute: () => Promise.resolve(makeEmptyResult())
|
|
82
|
+
execute: () => Promise.resolve(makeEmptyResult()),
|
|
85
83
|
};
|
|
86
84
|
|
|
87
85
|
interface WorkerDecisionLoopDependencies {
|
|
@@ -116,8 +114,8 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
116
114
|
runtime_selection: {
|
|
117
115
|
provider: this.provider.selection.provider,
|
|
118
116
|
model: this.provider.selection.model,
|
|
119
|
-
provider_config_ref: this.provider.selection.provider_config_ref
|
|
120
|
-
}
|
|
117
|
+
provider_config_ref: this.provider.selection.provider_config_ref,
|
|
118
|
+
},
|
|
121
119
|
});
|
|
122
120
|
|
|
123
121
|
const outputs = asOutputs(workerOutput);
|
|
@@ -154,7 +152,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
154
152
|
private async routePlanSubmission(
|
|
155
153
|
input: WorkerDecisionInput,
|
|
156
154
|
output: AnyRecord,
|
|
157
|
-
result: WorkerDecisionResult
|
|
155
|
+
result: WorkerDecisionResult,
|
|
158
156
|
): Promise<void> {
|
|
159
157
|
if (input.role !== 'planner') {
|
|
160
158
|
return;
|
|
@@ -172,7 +170,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
172
170
|
if (existingVersion == null) {
|
|
173
171
|
const response = await this.toolCaller.callTool('planner', TOOLS.PLAN_SUBMIT, {
|
|
174
172
|
feature_id: input.featureId,
|
|
175
|
-
plan_json: planJson
|
|
173
|
+
plan_json: planJson,
|
|
176
174
|
});
|
|
177
175
|
result.toolResults.push(asRecord(response.data));
|
|
178
176
|
result.planSubmission = true;
|
|
@@ -183,13 +181,17 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
183
181
|
const response = await this.toolCaller.callTool('planner', TOOLS.PLAN_UPDATE, {
|
|
184
182
|
feature_id: input.featureId,
|
|
185
183
|
expected_plan_version: expectedPlanVersion,
|
|
186
|
-
plan_json: planJson
|
|
184
|
+
plan_json: planJson,
|
|
187
185
|
});
|
|
188
186
|
result.toolResults.push(asRecord(response.data));
|
|
189
187
|
result.planSubmission = true;
|
|
190
188
|
}
|
|
191
189
|
|
|
192
|
-
private async routePatch(
|
|
190
|
+
private async routePatch(
|
|
191
|
+
input: WorkerDecisionInput,
|
|
192
|
+
output: AnyRecord,
|
|
193
|
+
result: WorkerDecisionResult,
|
|
194
|
+
): Promise<void> {
|
|
193
195
|
if (input.role !== 'builder' && input.role !== 'qa') {
|
|
194
196
|
return;
|
|
195
197
|
}
|
|
@@ -201,18 +203,22 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
201
203
|
|
|
202
204
|
const response = await this.toolCaller.callTool(input.role, TOOLS.REPO_APPLY_PATCH, {
|
|
203
205
|
feature_id: input.featureId,
|
|
204
|
-
unified_diff: unifiedDiff
|
|
206
|
+
unified_diff: unifiedDiff,
|
|
205
207
|
});
|
|
206
208
|
result.toolResults.push(asRecord(response.data));
|
|
207
209
|
result.patchApplied = true;
|
|
208
210
|
}
|
|
209
211
|
|
|
210
|
-
private async routeNote(
|
|
212
|
+
private async routeNote(
|
|
213
|
+
featureId: string,
|
|
214
|
+
output: AnyRecord,
|
|
215
|
+
result: WorkerDecisionResult,
|
|
216
|
+
): Promise<void> {
|
|
211
217
|
const content = asNonEmptyString(output.content) ?? JSON.stringify(output);
|
|
212
218
|
try {
|
|
213
219
|
const response = await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_LOG_APPEND, {
|
|
214
220
|
feature_id: featureId,
|
|
215
|
-
note: content
|
|
221
|
+
note: content,
|
|
216
222
|
});
|
|
217
223
|
result.toolResults.push(asRecord(response.data));
|
|
218
224
|
result.noteLogged = true;
|
|
@@ -221,7 +227,11 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
221
227
|
}
|
|
222
228
|
}
|
|
223
229
|
|
|
224
|
-
private async routeRequest(
|
|
230
|
+
private async routeRequest(
|
|
231
|
+
input: WorkerDecisionInput,
|
|
232
|
+
output: AnyRecord,
|
|
233
|
+
result: WorkerDecisionResult,
|
|
234
|
+
): Promise<void> {
|
|
225
235
|
const request = asRecord(output.request ?? output);
|
|
226
236
|
const action = asNonEmptyString(request.action ?? request.request_type)?.toLowerCase();
|
|
227
237
|
if (!action) {
|
|
@@ -244,7 +254,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
244
254
|
}
|
|
245
255
|
const response = await this.toolCaller.callTool('orchestrator', TOOLS.LOCKS_ACQUIRE, {
|
|
246
256
|
feature_id: input.featureId,
|
|
247
|
-
resources
|
|
257
|
+
resources,
|
|
248
258
|
});
|
|
249
259
|
result.toolResults.push(asRecord(response.data));
|
|
250
260
|
result.requestHandled = true;
|
|
@@ -258,7 +268,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
258
268
|
}
|
|
259
269
|
const response = await this.toolCaller.callTool('orchestrator', TOOLS.LOCKS_RELEASE, {
|
|
260
270
|
feature_id: input.featureId,
|
|
261
|
-
resources
|
|
271
|
+
resources,
|
|
262
272
|
});
|
|
263
273
|
result.toolResults.push(asRecord(response.data));
|
|
264
274
|
result.requestHandled = true;
|
|
@@ -267,7 +277,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
267
277
|
|
|
268
278
|
if (action === 'more_context' || action === 'context_refresh') {
|
|
269
279
|
const response = await this.toolCaller.callTool(input.role, TOOLS.FEATURE_GET_CONTEXT, {
|
|
270
|
-
feature_id: input.featureId
|
|
280
|
+
feature_id: input.featureId,
|
|
271
281
|
});
|
|
272
282
|
result.toolResults.push(asRecord(response.data));
|
|
273
283
|
result.requestHandled = true;
|
|
@@ -286,7 +296,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
286
296
|
if (existingVersion == null) {
|
|
287
297
|
const response = await this.toolCaller.callTool('planner', TOOLS.PLAN_SUBMIT, {
|
|
288
298
|
feature_id: input.featureId,
|
|
289
|
-
plan_json: planJson
|
|
299
|
+
plan_json: planJson,
|
|
290
300
|
});
|
|
291
301
|
result.toolResults.push(asRecord(response.data));
|
|
292
302
|
result.requestHandled = true;
|
|
@@ -297,7 +307,7 @@ export class WorkerDecisionLoop implements WorkerDecisionRunner {
|
|
|
297
307
|
const response = await this.toolCaller.callTool('planner', TOOLS.PLAN_UPDATE, {
|
|
298
308
|
feature_id: input.featureId,
|
|
299
309
|
expected_plan_version: requestedExpectedVersion ?? existingVersion,
|
|
300
|
-
plan_json: planJson
|
|
310
|
+
plan_json: planJson,
|
|
301
311
|
});
|
|
302
312
|
result.toolResults.push(asRecord(response.data));
|
|
303
313
|
result.requestHandled = true;
|
|
@@ -14,7 +14,7 @@ function makeToolCaller(frontMatter: Record<string, unknown>) {
|
|
|
14
14
|
return { ok: true, data: { front_matter: { version: 1, ...frontMatter } } };
|
|
15
15
|
}
|
|
16
16
|
return { ok: true, data: {} };
|
|
17
|
-
})
|
|
17
|
+
}),
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -27,7 +27,7 @@ describe('ActivityMonitorService', () => {
|
|
|
27
27
|
const toolCaller = makeToolCaller({ status: 'building', last_heartbeat_at: RECENT_TIMESTAMP });
|
|
28
28
|
const service = new ActivityMonitorService({
|
|
29
29
|
toolCaller: toolCaller as never,
|
|
30
|
-
idleThresholdMs: DEFAULT_THRESHOLD
|
|
30
|
+
idleThresholdMs: DEFAULT_THRESHOLD,
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
const snapshot = await service.getActivityState('feature_a');
|
|
@@ -42,7 +42,7 @@ describe('ActivityMonitorService', () => {
|
|
|
42
42
|
const toolCaller = makeToolCaller({ status: 'building', last_heartbeat_at: STALE_TIMESTAMP });
|
|
43
43
|
const service = new ActivityMonitorService({
|
|
44
44
|
toolCaller: toolCaller as never,
|
|
45
|
-
idleThresholdMs: DEFAULT_THRESHOLD
|
|
45
|
+
idleThresholdMs: DEFAULT_THRESHOLD,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
const snapshot = await service.getActivityState('feature_b');
|
|
@@ -89,8 +89,13 @@ describe('ActivityMonitorService', () => {
|
|
|
89
89
|
notifier: notifier as never,
|
|
90
90
|
idleThresholdMs: DEFAULT_THRESHOLD,
|
|
91
91
|
reactionsPolicy: {
|
|
92
|
-
agent_stuck: {
|
|
93
|
-
|
|
92
|
+
agent_stuck: {
|
|
93
|
+
enabled: true,
|
|
94
|
+
action: 'notify_only',
|
|
95
|
+
idle_threshold_ms: DEFAULT_THRESHOLD,
|
|
96
|
+
escalate_after: 2,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
94
99
|
});
|
|
95
100
|
|
|
96
101
|
const stuck = await service.checkAndNotifyStuck('feature_f');
|
|
@@ -98,7 +103,7 @@ describe('ActivityMonitorService', () => {
|
|
|
98
103
|
expect(stuck).toBe(true);
|
|
99
104
|
expect(notifier.notify).toHaveBeenCalledWith(
|
|
100
105
|
'agent_stuck',
|
|
101
|
-
expect.objectContaining({ feature_id: 'feature_f' })
|
|
106
|
+
expect.objectContaining({ feature_id: 'feature_f' }),
|
|
102
107
|
);
|
|
103
108
|
});
|
|
104
109
|
|
|
@@ -110,8 +115,13 @@ describe('ActivityMonitorService', () => {
|
|
|
110
115
|
notifier: notifier as never,
|
|
111
116
|
idleThresholdMs: DEFAULT_THRESHOLD,
|
|
112
117
|
reactionsPolicy: {
|
|
113
|
-
agent_stuck: {
|
|
114
|
-
|
|
118
|
+
agent_stuck: {
|
|
119
|
+
enabled: false,
|
|
120
|
+
action: 'notify_only',
|
|
121
|
+
idle_threshold_ms: DEFAULT_THRESHOLD,
|
|
122
|
+
escalate_after: 2,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
115
125
|
});
|
|
116
126
|
|
|
117
127
|
const stuck = await service.checkAndNotifyStuck('feature_g');
|
|
@@ -122,13 +132,13 @@ describe('ActivityMonitorService', () => {
|
|
|
122
132
|
|
|
123
133
|
it('GIVEN formatForStatus called WHEN state is idle THEN string includes idle', () => {
|
|
124
134
|
const service = new ActivityMonitorService({
|
|
125
|
-
toolCaller: { callTool: vi.fn() } as never
|
|
135
|
+
toolCaller: { callTool: vi.fn() } as never,
|
|
126
136
|
});
|
|
127
137
|
const snapshot: ActivitySnapshot = {
|
|
128
138
|
featureId: 'feature_h',
|
|
129
139
|
state: 'idle',
|
|
130
140
|
lastEventAt: new Date(Date.now() - 10 * 60_000).toISOString(),
|
|
131
|
-
detectedVia: 'jsonl'
|
|
141
|
+
detectedVia: 'jsonl',
|
|
132
142
|
};
|
|
133
143
|
|
|
134
144
|
const str = service.formatForStatus(snapshot);
|
|
@@ -138,13 +148,13 @@ describe('ActivityMonitorService', () => {
|
|
|
138
148
|
|
|
139
149
|
it('GIVEN formatForStatus called WHEN state has no timestamp THEN returns state name', () => {
|
|
140
150
|
const service = new ActivityMonitorService({
|
|
141
|
-
toolCaller: { callTool: vi.fn() } as never
|
|
151
|
+
toolCaller: { callTool: vi.fn() } as never,
|
|
142
152
|
});
|
|
143
153
|
const snapshot: ActivitySnapshot = {
|
|
144
154
|
featureId: 'feature_i',
|
|
145
155
|
state: 'unknown',
|
|
146
156
|
lastEventAt: null,
|
|
147
|
-
detectedVia: 'unknown'
|
|
157
|
+
detectedVia: 'unknown',
|
|
148
158
|
};
|
|
149
159
|
|
|
150
160
|
const str = service.formatForStatus(snapshot);
|
|
@@ -160,8 +170,13 @@ describe('ActivityMonitorService', () => {
|
|
|
160
170
|
notifier: notifier as never,
|
|
161
171
|
idleThresholdMs: DEFAULT_THRESHOLD,
|
|
162
172
|
reactionsPolicy: {
|
|
163
|
-
agent_stuck: {
|
|
164
|
-
|
|
173
|
+
agent_stuck: {
|
|
174
|
+
enabled: true,
|
|
175
|
+
action: 'notify_only',
|
|
176
|
+
idle_threshold_ms: DEFAULT_THRESHOLD,
|
|
177
|
+
escalate_after: 2,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
165
180
|
});
|
|
166
181
|
|
|
167
182
|
const stuck = await service.checkAndNotifyStuck('feature_j');
|
|
@@ -174,7 +189,7 @@ describe('ActivityMonitorService', () => {
|
|
|
174
189
|
const toolCaller = makeToolCaller({ status: 'building', last_run_at: RECENT_TIMESTAMP });
|
|
175
190
|
const service = new ActivityMonitorService({
|
|
176
191
|
toolCaller: toolCaller as never,
|
|
177
|
-
detectorName: 'codex-rpc'
|
|
192
|
+
detectorName: 'codex-rpc',
|
|
178
193
|
});
|
|
179
194
|
|
|
180
195
|
const snapshot = await service.getActivityState('feature_codex');
|
|
@@ -188,10 +203,10 @@ describe('ActivityMonitorService', () => {
|
|
|
188
203
|
const toolCaller = makeToolCaller({
|
|
189
204
|
status: 'building',
|
|
190
205
|
status_reason: 'waiting_input:user_confirmation',
|
|
191
|
-
last_heartbeat_at: RECENT_TIMESTAMP
|
|
206
|
+
last_heartbeat_at: RECENT_TIMESTAMP,
|
|
192
207
|
});
|
|
193
208
|
const service = new ActivityMonitorService({
|
|
194
|
-
toolCaller: toolCaller as never
|
|
209
|
+
toolCaller: toolCaller as never,
|
|
195
210
|
});
|
|
196
211
|
|
|
197
212
|
const snapshot = await service.getActivityState('feature_wait');
|
|
@@ -202,7 +217,7 @@ describe('ActivityMonitorService', () => {
|
|
|
202
217
|
it('GIVEN_checkAndNotifyStuck_WHEN_snapshot_changes_THEN_activity_snapshot_persisted_to_state', async () => {
|
|
203
218
|
const toolCaller = makeToolCaller({ status: 'building', last_heartbeat_at: STALE_TIMESTAMP });
|
|
204
219
|
const service = new ActivityMonitorService({
|
|
205
|
-
toolCaller: toolCaller as never
|
|
220
|
+
toolCaller: toolCaller as never,
|
|
206
221
|
});
|
|
207
222
|
|
|
208
223
|
await service.checkAndNotifyStuck('feature_patch');
|
|
@@ -215,10 +230,10 @@ describe('ActivityMonitorService', () => {
|
|
|
215
230
|
patch: expect.objectContaining({
|
|
216
231
|
front_matter: expect.objectContaining({
|
|
217
232
|
activity_state: 'idle',
|
|
218
|
-
activity_detected_via: 'jsonl'
|
|
219
|
-
})
|
|
220
|
-
})
|
|
221
|
-
})
|
|
233
|
+
activity_detected_via: 'jsonl',
|
|
234
|
+
}),
|
|
235
|
+
}),
|
|
236
|
+
}),
|
|
222
237
|
);
|
|
223
238
|
});
|
|
224
239
|
});
|
|
@@ -230,7 +245,7 @@ describe('ActivityMonitorService detectedVia and resolveLastEvent branches', ()
|
|
|
230
245
|
const service = new ActivityMonitorService({
|
|
231
246
|
toolCaller: toolCaller as never,
|
|
232
247
|
detectorName: 'codex-rpc',
|
|
233
|
-
operationLedger
|
|
248
|
+
operationLedger,
|
|
234
249
|
});
|
|
235
250
|
const snapshot = await service.getActivityState('feature_ledger');
|
|
236
251
|
expect(snapshot.detectedVia).toBe('ledger');
|
|
@@ -240,7 +255,7 @@ describe('ActivityMonitorService detectedVia and resolveLastEvent branches', ()
|
|
|
240
255
|
const toolCaller = makeToolCaller({ status: 'building', last_heartbeat_at: RECENT_TIMESTAMP });
|
|
241
256
|
const service = new ActivityMonitorService({
|
|
242
257
|
toolCaller: toolCaller as never,
|
|
243
|
-
detectorName: 'process-heuristic'
|
|
258
|
+
detectorName: 'process-heuristic',
|
|
244
259
|
});
|
|
245
260
|
const snapshot = await service.getActivityState('feature_proc');
|
|
246
261
|
expect(snapshot.detectedVia).toBe('process');
|
|
@@ -252,17 +267,21 @@ describe('ActivityMonitorService detectedVia and resolveLastEvent branches', ()
|
|
|
252
267
|
const service = new ActivityMonitorService({
|
|
253
268
|
toolCaller: toolCaller as never,
|
|
254
269
|
detectorName: 'codex-rpc',
|
|
255
|
-
operationLedger
|
|
270
|
+
operationLedger,
|
|
256
271
|
});
|
|
257
272
|
const snapshot = await service.getActivityState('feature_norpc');
|
|
258
273
|
expect(snapshot.detectedVia).toBe('process');
|
|
259
274
|
});
|
|
260
275
|
|
|
261
276
|
it('GIVEN_process_heuristic_with_last_run_at_WHEN_getActivityState_THEN_uses_last_run_at', async () => {
|
|
262
|
-
const toolCaller = makeToolCaller({
|
|
277
|
+
const toolCaller = makeToolCaller({
|
|
278
|
+
status: 'building',
|
|
279
|
+
last_run_at: RECENT_TIMESTAMP,
|
|
280
|
+
last_heartbeat_at: undefined,
|
|
281
|
+
});
|
|
263
282
|
const service = new ActivityMonitorService({
|
|
264
283
|
toolCaller: toolCaller as never,
|
|
265
|
-
detectorName: 'process-heuristic'
|
|
284
|
+
detectorName: 'process-heuristic',
|
|
266
285
|
});
|
|
267
286
|
const snapshot = await service.getActivityState('feature_run_at');
|
|
268
287
|
expect(snapshot.lastEventAt).toBe(RECENT_TIMESTAMP);
|
|
@@ -272,7 +291,7 @@ describe('ActivityMonitorService detectedVia and resolveLastEvent branches', ()
|
|
|
272
291
|
const toolCaller = makeToolCaller({ status: 'building', last_heartbeat_at: RECENT_TIMESTAMP });
|
|
273
292
|
const service = new ActivityMonitorService({
|
|
274
293
|
toolCaller: toolCaller as never,
|
|
275
|
-
detectorName: 'some-unknown-detector'
|
|
294
|
+
detectorName: 'some-unknown-detector',
|
|
276
295
|
});
|
|
277
296
|
const snapshot = await service.getActivityState('feature_unknown_detector');
|
|
278
297
|
expect(snapshot.detectedVia).toBe('unknown');
|
|
@@ -282,10 +301,15 @@ describe('ActivityMonitorService detectedVia and resolveLastEvent branches', ()
|
|
|
282
301
|
const toolCaller = {
|
|
283
302
|
callTool: vi.fn(async (_role: string, toolName: string) => {
|
|
284
303
|
if (toolName === TOOLS.FEATURE_STATE_GET) {
|
|
285
|
-
return {
|
|
304
|
+
return {
|
|
305
|
+
ok: true,
|
|
306
|
+
data: {
|
|
307
|
+
front_matter: { version: 1, status: 'building', last_heartbeat_at: STALE_TIMESTAMP },
|
|
308
|
+
},
|
|
309
|
+
};
|
|
286
310
|
}
|
|
287
311
|
throw new Error('patch failed');
|
|
288
|
-
})
|
|
312
|
+
}),
|
|
289
313
|
};
|
|
290
314
|
const service = new ActivityMonitorService({ toolCaller: toolCaller as never });
|
|
291
315
|
// Should not throw even when persistSnapshot fails - still returns stuck status
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
DefaultAdapterRegistry,
|
|
4
4
|
AGENT_PROVIDER_SLOT,
|
|
5
5
|
globalAdapterRegistry,
|
|
6
|
-
REGISTERED_PROVIDER_NAMES
|
|
6
|
+
REGISTERED_PROVIDER_NAMES,
|
|
7
7
|
} from '../src/application/adapters/adapter-registry.js';
|
|
8
8
|
import { SUPPORTED_PROVIDERS } from '../src/providers/providers.js';
|
|
9
9
|
import { ERROR_CODES } from '../src/core/error-codes.js';
|
|
@@ -47,7 +47,7 @@ describe('DefaultAdapterRegistry', () => {
|
|
|
47
47
|
const registry = new DefaultAdapterRegistry();
|
|
48
48
|
const slot = { name: 'compute-slot' };
|
|
49
49
|
registry.register(slot, { slot: 'compute-slot', name: 'fast' }, (config) => ({
|
|
50
|
-
speed: (config as { speed: number }).speed
|
|
50
|
+
speed: (config as { speed: number }).speed,
|
|
51
51
|
}));
|
|
52
52
|
const result = registry.resolve(slot, 'fast', { speed: 100 });
|
|
53
53
|
expect(result).toEqual({ speed: 100 });
|
|
@@ -59,7 +59,7 @@ describe('DefaultAdapterRegistry', () => {
|
|
|
59
59
|
const registry = new DefaultAdapterRegistry();
|
|
60
60
|
const slot = { name: 'missing-slot' };
|
|
61
61
|
expect(() => registry.resolve(slot, 'ghost', {})).toThrowError(
|
|
62
|
-
expect.objectContaining({ code: ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER })
|
|
62
|
+
expect.objectContaining({ code: ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER }),
|
|
63
63
|
);
|
|
64
64
|
});
|
|
65
65
|
|
|
@@ -74,7 +74,7 @@ describe('DefaultAdapterRegistry', () => {
|
|
|
74
74
|
}
|
|
75
75
|
expect((caught as { details: Record<string, unknown> }).details).toMatchObject({
|
|
76
76
|
slot: 'missing-slot',
|
|
77
|
-
name: 'ghost'
|
|
77
|
+
name: 'ghost',
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
80
|
});
|
|
@@ -87,7 +87,7 @@ describe('DefaultAdapterRegistry', () => {
|
|
|
87
87
|
registry.register(slot, { slot: 'multi-slot', name: 'b' }, () => 'b');
|
|
88
88
|
registry.register(slot, { slot: 'multi-slot', name: 'c' }, () => 'c');
|
|
89
89
|
expect(registry.list('multi-slot').map((m) => m.name)).toEqual(
|
|
90
|
-
expect.arrayContaining(['a', 'b', 'c'])
|
|
90
|
+
expect.arrayContaining(['a', 'b', 'c']),
|
|
91
91
|
);
|
|
92
92
|
});
|
|
93
93
|
});
|
|
@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
6
6
|
import { runCli } from '../src/interfaces/cli/bootstrap.js';
|
|
7
7
|
|
|
8
8
|
vi.mock('../src/interfaces/cli/bootstrap.js', () => ({
|
|
9
|
-
runCli: vi.fn()
|
|
9
|
+
runCli: vi.fn(),
|
|
10
10
|
}));
|
|
11
11
|
|
|
12
12
|
const ORIGINAL_ARGV = [...process.argv];
|
|
@@ -33,7 +33,7 @@ describe('aop.ts entrypoint', () => {
|
|
|
33
33
|
|
|
34
34
|
const runtime = {
|
|
35
35
|
cwd: '/tmp/custom-repo',
|
|
36
|
-
env: { NODE_ENV: 'test' } as NodeJS.ProcessEnv
|
|
36
|
+
env: { NODE_ENV: 'test' } as NodeJS.ProcessEnv,
|
|
37
37
|
};
|
|
38
38
|
const exitCode = await main(['status'], runtime);
|
|
39
39
|
|
|
@@ -51,7 +51,7 @@ describe('aop.ts entrypoint', () => {
|
|
|
51
51
|
expect(exitCode).toBe(0);
|
|
52
52
|
expect(runCli).toHaveBeenCalledWith(['resume'], {
|
|
53
53
|
cwd: process.cwd(),
|
|
54
|
-
env: process.env
|
|
54
|
+
env: process.env,
|
|
55
55
|
});
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -132,7 +132,7 @@ describe('aop.ts entrypoint', () => {
|
|
|
132
132
|
expect(process.exitCode).toBe(17);
|
|
133
133
|
expect(runCli).toHaveBeenCalledWith(['status'], {
|
|
134
134
|
cwd: process.cwd(),
|
|
135
|
-
env: process.env
|
|
135
|
+
env: process.env,
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
138
|
});
|