@revisium/orchestrator 0.1.0-alpha.1 → 0.1.0-alpha.11
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/README.md +202 -1
- package/control-plane/bootstrap.config.json +104 -2
- package/control-plane/default-playbook/catalog/pipelines.json +657 -0
- package/control-plane/default-playbook/catalog/roles.json +65 -0
- package/control-plane/default-playbook/package.json +5 -0
- package/control-plane/default-playbook/playbook.json +13 -0
- package/control-plane/default-playbook/prompts/analyst.md +29 -0
- package/control-plane/default-playbook/prompts/developer.md +26 -0
- package/control-plane/default-playbook/prompts/integrator.md +20 -0
- package/control-plane/default-playbook/prompts/orchestrator.md +23 -0
- package/control-plane/default-playbook/prompts/reviewer.md +28 -0
- package/control-plane/default-playbook/prompts/triager.md +51 -0
- package/control-plane/default-playbook/prompts/watcher.md +24 -0
- package/dist/api/graphql-api/filters/agent-observability-exception.filter.js +24 -0
- package/dist/api/graphql-api/filters/agent-observability-exception.filter.js.map +1 -0
- package/dist/api/graphql-api/filters/graphql-validation-exception.filter.js +36 -0
- package/dist/api/graphql-api/filters/graphql-validation-exception.filter.js.map +1 -0
- package/dist/api/graphql-api/graphql-api.module.js +77 -0
- package/dist/api/graphql-api/graphql-api.module.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-bridge.service.js +296 -0
- package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-bridge.service.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-mappers.js +64 -0
- package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-mappers.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/constants.js +11 -0
- package/dist/api/graphql-api/graphql-ws/constants.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/pubsub.module.js +32 -0
- package/dist/api/graphql-api/graphql-ws/pubsub.module.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/run-progress-subscription-poller.service.js +101 -0
- package/dist/api/graphql-api/graphql-ws/run-progress-subscription-poller.service.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/subscription-bridge.service.js +115 -0
- package/dist/api/graphql-api/graphql-ws/subscription-bridge.service.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/subscription-mappers.js +85 -0
- package/dist/api/graphql-api/graphql-ws/subscription-mappers.js.map +1 -0
- package/dist/api/graphql-api/graphql-ws/ws.js +22 -0
- package/dist/api/graphql-api/graphql-ws/ws.js.map +1 -0
- package/dist/api/graphql-api/inbox/inbox-subscription.resolver.js +56 -0
- package/dist/api/graphql-api/inbox/inbox-subscription.resolver.js.map +1 -0
- package/dist/api/graphql-api/inbox/inbox.resolver.js +125 -0
- package/dist/api/graphql-api/inbox/inbox.resolver.js.map +1 -0
- package/dist/api/graphql-api/inbox/inputs/answer-question.input.js +33 -0
- package/dist/api/graphql-api/inbox/inputs/answer-question.input.js.map +1 -0
- package/dist/api/graphql-api/inbox/inputs/gate-decision.input.js +27 -0
- package/dist/api/graphql-api/inbox/inputs/gate-decision.input.js.map +1 -0
- package/dist/api/graphql-api/inbox/inputs/list-inbox.input.js +28 -0
- package/dist/api/graphql-api/inbox/inputs/list-inbox.input.js.map +1 -0
- package/dist/api/graphql-api/inbox/inputs/resolve-inbox-item.input.js +38 -0
- package/dist/api/graphql-api/inbox/inputs/resolve-inbox-item.input.js.map +1 -0
- package/dist/api/graphql-api/inbox/model/gate-risk.model.js +53 -0
- package/dist/api/graphql-api/inbox/model/gate-risk.model.js.map +1 -0
- package/dist/api/graphql-api/inbox/model/inbox-connection.model.js +16 -0
- package/dist/api/graphql-api/inbox/model/inbox-connection.model.js.map +1 -0
- package/dist/api/graphql-api/inbox/model/inbox-item.model.js +88 -0
- package/dist/api/graphql-api/inbox/model/inbox-item.model.js.map +1 -0
- package/dist/api/graphql-api/inbox/model/inbox-resolution.model.js +48 -0
- package/dist/api/graphql-api/inbox/model/inbox-resolution.model.js.map +1 -0
- package/dist/api/graphql-api/method/inputs/list-method.input.js +15 -0
- package/dist/api/graphql-api/method/inputs/list-method.input.js.map +1 -0
- package/dist/api/graphql-api/method/method.resolver.js +90 -0
- package/dist/api/graphql-api/method/method.resolver.js.map +1 -0
- package/dist/api/graphql-api/method/model/alternative-role-group.model.js +32 -0
- package/dist/api/graphql-api/method/model/alternative-role-group.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/pipeline-connection.model.js +16 -0
- package/dist/api/graphql-api/method/model/pipeline-connection.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/pipeline.model.js +69 -0
- package/dist/api/graphql-api/method/model/pipeline.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/playbook-connection.model.js +16 -0
- package/dist/api/graphql-api/method/model/playbook-connection.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/playbook.model.js +47 -0
- package/dist/api/graphql-api/method/model/playbook.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/role-connection.model.js +16 -0
- package/dist/api/graphql-api/method/model/role-connection.model.js.map +1 -0
- package/dist/api/graphql-api/method/model/role.model.js +98 -0
- package/dist/api/graphql-api/method/model/role.model.js.map +1 -0
- package/dist/api/graphql-api/pr/inputs/pr-readiness.input.js +52 -0
- package/dist/api/graphql-api/pr/inputs/pr-readiness.input.js.map +1 -0
- package/dist/api/graphql-api/pr/model/pr-readiness.model.js +403 -0
- package/dist/api/graphql-api/pr/model/pr-readiness.model.js.map +1 -0
- package/dist/api/graphql-api/pr/pr.resolver.js +76 -0
- package/dist/api/graphql-api/pr/pr.resolver.js.map +1 -0
- package/dist/api/graphql-api/registerGraphqlEnums.js +9 -0
- package/dist/api/graphql-api/registerGraphqlEnums.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/create-run.input.js +63 -0
- package/dist/api/graphql-api/runs/inputs/create-run.input.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/get-agent-log.input.js +48 -0
- package/dist/api/graphql-api/runs/inputs/get-agent-log.input.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/get-run-attempts.input.js +32 -0
- package/dist/api/graphql-api/runs/inputs/get-run-attempts.input.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/get-run-events.input.js +28 -0
- package/dist/api/graphql-api/runs/inputs/get-run-events.input.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/list-runs.input.js +23 -0
- package/dist/api/graphql-api/runs/inputs/list-runs.input.js.map +1 -0
- package/dist/api/graphql-api/runs/inputs/simulate-route.input.js +43 -0
- package/dist/api/graphql-api/runs/inputs/simulate-route.input.js.map +1 -0
- package/dist/api/graphql-api/runs/model/agent-activity.model.js +367 -0
- package/dist/api/graphql-api/runs/model/agent-activity.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/create-run-result.model.js +53 -0
- package/dist/api/graphql-api/runs/model/create-run-result.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-attempt.model.js +114 -0
- package/dist/api/graphql-api/runs/model/run-attempt.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-connection.model.js +16 -0
- package/dist/api/graphql-api/runs/model/run-connection.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-cost.model.js +67 -0
- package/dist/api/graphql-api/runs/model/run-cost.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-digest.model.js +41 -0
- package/dist/api/graphql-api/runs/model/run-digest.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-event-connection.model.js +16 -0
- package/dist/api/graphql-api/runs/model/run-event-connection.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-event.model.js +58 -0
- package/dist/api/graphql-api/runs/model/run-event.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-progress.model.js +33 -0
- package/dist/api/graphql-api/runs/model/run-progress.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run-workflow.model.js +287 -0
- package/dist/api/graphql-api/runs/model/run-workflow.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/run.model.js +57 -0
- package/dist/api/graphql-api/runs/model/run.model.js.map +1 -0
- package/dist/api/graphql-api/runs/model/usage.model.js +32 -0
- package/dist/api/graphql-api/runs/model/usage.model.js.map +1 -0
- package/dist/api/graphql-api/runs/run-digest.resolver.js +40 -0
- package/dist/api/graphql-api/runs/run-digest.resolver.js.map +1 -0
- package/dist/api/graphql-api/runs/run-events.resolver.js +45 -0
- package/dist/api/graphql-api/runs/run-events.resolver.js.map +1 -0
- package/dist/api/graphql-api/runs/run-progress.resolver.js +53 -0
- package/dist/api/graphql-api/runs/run-progress.resolver.js.map +1 -0
- package/dist/api/graphql-api/runs/runs-subscription.resolver.js +124 -0
- package/dist/api/graphql-api/runs/runs-subscription.resolver.js.map +1 -0
- package/dist/api/graphql-api/runs/runs.resolver.js +165 -0
- package/dist/api/graphql-api/runs/runs.resolver.js.map +1 -0
- package/dist/api/graphql-api/share/graphql-param-types.js +6 -0
- package/dist/api/graphql-api/share/graphql-param-types.js.map +1 -0
- package/dist/api/graphql-api/share/inputs/connection.input.js +27 -0
- package/dist/api/graphql-api/share/inputs/connection.input.js.map +1 -0
- package/dist/api/graphql-api/share/inputs/run-subscription.input.js +22 -0
- package/dist/api/graphql-api/share/inputs/run-subscription.input.js.map +1 -0
- package/dist/api/graphql-api/share/model/paginated.model.js +75 -0
- package/dist/api/graphql-api/share/model/paginated.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/daemon-status.model.js +47 -0
- package/dist/api/graphql-api/system/model/daemon-status.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/doctor-result.model.js +33 -0
- package/dist/api/graphql-api/system/model/doctor-result.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/project.model.js +37 -0
- package/dist/api/graphql-api/system/model/project.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/repository-context.model.js +70 -0
- package/dist/api/graphql-api/system/model/repository-context.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/repository-validation.model.js +62 -0
- package/dist/api/graphql-api/system/model/repository-validation.model.js.map +1 -0
- package/dist/api/graphql-api/system/model/system-status.model.js +29 -0
- package/dist/api/graphql-api/system/model/system-status.model.js.map +1 -0
- package/dist/api/graphql-api/system/system.resolver.js +83 -0
- package/dist/api/graphql-api/system/system.resolver.js.map +1 -0
- package/dist/cli/commands/doctor-report.js +70 -0
- package/dist/cli/commands/doctor-report.js.map +1 -0
- package/dist/cli/commands/lifecycle.js +463 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/mcp.js +53 -8
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/process-tree.js +87 -0
- package/dist/cli/commands/process-tree.js.map +1 -0
- package/dist/cli/commands/revisium-helpers.js +2 -2
- package/dist/cli/commands/rogue-reaper.js +63 -0
- package/dist/cli/commands/rogue-reaper.js.map +1 -0
- package/dist/cli/index.js +5 -29
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/program.js +7 -23
- package/dist/cli/program.js.map +1 -1
- package/dist/config.js +79 -1
- package/dist/config.js.map +1 -1
- package/dist/control-plane/bootstrap.js +106 -0
- package/dist/control-plane/bootstrap.js.map +1 -0
- package/dist/control-plane/change-notifications.js +35 -0
- package/dist/control-plane/change-notifications.js.map +1 -0
- package/dist/control-plane/client-transport.js +74 -41
- package/dist/control-plane/client-transport.js.map +1 -1
- package/dist/control-plane/data-access.js +13 -5
- package/dist/control-plane/data-access.js.map +1 -1
- package/dist/control-plane/definitions.js +1 -1
- package/dist/control-plane/definitions.js.map +1 -1
- package/dist/control-plane/inbox.js +5 -31
- package/dist/control-plane/inbox.js.map +1 -1
- package/dist/control-plane/index.js +1 -1
- package/dist/control-plane/index.js.map +1 -1
- package/dist/control-plane/json-fields.js +2 -0
- package/dist/control-plane/json-fields.js.map +1 -1
- package/dist/control-plane/resolve-cwd.js +76 -8
- package/dist/control-plane/resolve-cwd.js.map +1 -1
- package/dist/control-plane/schema-migration.js +82 -0
- package/dist/control-plane/schema-migration.js.map +1 -0
- package/dist/control-plane/seed-default-playbook.js +163 -0
- package/dist/control-plane/seed-default-playbook.js.map +1 -0
- package/dist/control-plane/steps.js +15 -349
- package/dist/control-plane/steps.js.map +1 -1
- package/dist/control-plane/tables.js +1 -0
- package/dist/control-plane/tables.js.map +1 -1
- package/dist/e2e/kit/agents.js +142 -0
- package/dist/e2e/kit/agents.js.map +1 -0
- package/dist/e2e/kit/assertions.js +163 -0
- package/dist/e2e/kit/assertions.js.map +1 -0
- package/dist/e2e/kit/crash.js +44 -0
- package/dist/e2e/kit/crash.js.map +1 -0
- package/dist/e2e/kit/drive.js +45 -0
- package/dist/e2e/kit/drive.js.map +1 -0
- package/dist/e2e/kit/env.js +16 -0
- package/dist/e2e/kit/env.js.map +1 -0
- package/dist/e2e/kit/fake-integrator.js +57 -0
- package/dist/e2e/kit/fake-integrator.js.map +1 -0
- package/dist/e2e/kit/gh-emulator.js +213 -0
- package/dist/e2e/kit/gh-emulator.js.map +1 -0
- package/dist/e2e/kit/git-target-repo.js +115 -0
- package/dist/e2e/kit/git-target-repo.js.map +1 -0
- package/dist/e2e/kit/harness.js +72 -0
- package/dist/e2e/kit/harness.js.map +1 -0
- package/dist/e2e/kit/index.js +14 -0
- package/dist/e2e/kit/index.js.map +1 -0
- package/dist/e2e/kit/mcp.js +32 -0
- package/dist/e2e/kit/mcp.js.map +1 -0
- package/dist/e2e/kit/scenarios.js +196 -0
- package/dist/e2e/kit/scenarios.js.map +1 -0
- package/dist/e2e/recovery-crash-child.js +29 -0
- package/dist/e2e/recovery-crash-child.js.map +1 -0
- package/dist/e2e/recovery-dd-crash-child.js +43 -0
- package/dist/e2e/recovery-dd-crash-child.js.map +1 -0
- package/dist/engine/dbos.module.js +2 -1
- package/dist/engine/dbos.module.js.map +1 -1
- package/dist/engine/dbos.service.js +89 -18
- package/dist/engine/dbos.service.js.map +1 -1
- package/dist/engine/ensure-postgres.js +18 -4
- package/dist/engine/ensure-postgres.js.map +1 -1
- package/dist/features/inbox/commands/handlers/inbox-command.handlers.js +80 -0
- package/dist/features/inbox/commands/handlers/inbox-command.handlers.js.map +1 -0
- package/dist/features/inbox/commands/impl/answer-question.command.js +7 -0
- package/dist/features/inbox/commands/impl/answer-question.command.js.map +1 -0
- package/dist/features/inbox/commands/impl/approve-gate.command.js +7 -0
- package/dist/features/inbox/commands/impl/approve-gate.command.js.map +1 -0
- package/dist/features/inbox/commands/impl/reject-gate.command.js +7 -0
- package/dist/features/inbox/commands/impl/reject-gate.command.js.map +1 -0
- package/dist/features/inbox/commands/impl/resolve-inbox-item.command.js +7 -0
- package/dist/features/inbox/commands/impl/resolve-inbox-item.command.js.map +1 -0
- package/dist/features/inbox/commands/index.js +8 -0
- package/dist/features/inbox/commands/index.js.map +1 -0
- package/dist/features/inbox/inbox-api.module.js +23 -0
- package/dist/features/inbox/inbox-api.module.js.map +1 -0
- package/dist/features/inbox/inbox-api.service.js +63 -0
- package/dist/features/inbox/inbox-api.service.js.map +1 -0
- package/dist/features/inbox/queries/handlers/inbox-query.handlers.js +111 -0
- package/dist/features/inbox/queries/handlers/inbox-query.handlers.js.map +1 -0
- package/dist/features/inbox/queries/impl/get-inbox-item.query.js +7 -0
- package/dist/features/inbox/queries/impl/get-inbox-item.query.js.map +1 -0
- package/dist/features/inbox/queries/impl/get-pending-decisions.query.js +7 -0
- package/dist/features/inbox/queries/impl/get-pending-decisions.query.js.map +1 -0
- package/dist/features/inbox/queries/impl/list-inbox.query.js +7 -0
- package/dist/features/inbox/queries/impl/list-inbox.query.js.map +1 -0
- package/dist/features/inbox/queries/impl/summarize-gate-risk.query.js +7 -0
- package/dist/features/inbox/queries/impl/summarize-gate-risk.query.js.map +1 -0
- package/dist/features/inbox/queries/index.js +8 -0
- package/dist/features/inbox/queries/index.js.map +1 -0
- package/dist/features/method/commands/index.js +2 -0
- package/dist/features/method/commands/index.js.map +1 -0
- package/dist/features/method/method-api.module.js +23 -0
- package/dist/features/method/method-api.module.js.map +1 -0
- package/dist/features/method/method-api.service.js +47 -0
- package/dist/features/method/method-api.service.js.map +1 -0
- package/dist/features/method/queries/handlers/method-query.handlers.js +115 -0
- package/dist/features/method/queries/handlers/method-query.handlers.js.map +1 -0
- package/dist/features/method/queries/impl/get-pipeline.query.js +7 -0
- package/dist/features/method/queries/impl/get-pipeline.query.js.map +1 -0
- package/dist/features/method/queries/impl/get-role.query.js +7 -0
- package/dist/features/method/queries/impl/get-role.query.js.map +1 -0
- package/dist/features/method/queries/impl/list-pipelines.query.js +7 -0
- package/dist/features/method/queries/impl/list-pipelines.query.js.map +1 -0
- package/dist/features/method/queries/impl/list-playbooks.query.js +7 -0
- package/dist/features/method/queries/impl/list-playbooks.query.js.map +1 -0
- package/dist/features/method/queries/impl/list-roles.query.js +7 -0
- package/dist/features/method/queries/impl/list-roles.query.js.map +1 -0
- package/dist/features/method/queries/index.js +9 -0
- package/dist/features/method/queries/index.js.map +1 -0
- package/dist/features/pr/commands/index.js +2 -0
- package/dist/features/pr/commands/index.js.map +1 -0
- package/dist/features/pr/pr-api.module.js +23 -0
- package/dist/features/pr/pr-api.module.js.map +1 -0
- package/dist/features/pr/pr-api.service.js +35 -0
- package/dist/features/pr/pr-api.service.js.map +1 -0
- package/dist/features/pr/queries/handlers/pr-query.handlers.js +48 -0
- package/dist/features/pr/queries/handlers/pr-query.handlers.js.map +1 -0
- package/dist/features/pr/queries/impl/get-pr-readiness.query.js +7 -0
- package/dist/features/pr/queries/impl/get-pr-readiness.query.js.map +1 -0
- package/dist/features/pr/queries/impl/list-pr-feedback.query.js +7 -0
- package/dist/features/pr/queries/impl/list-pr-feedback.query.js.map +1 -0
- package/dist/features/pr/queries/index.js +3 -0
- package/dist/features/pr/queries/index.js.map +1 -0
- package/dist/features/runs/commands/handlers/runs-command.handlers.js +32 -0
- package/dist/features/runs/commands/handlers/runs-command.handlers.js.map +1 -0
- package/dist/features/runs/commands/impl/create-run.command.js +7 -0
- package/dist/features/runs/commands/impl/create-run.command.js.map +1 -0
- package/dist/features/runs/commands/index.js +3 -0
- package/dist/features/runs/commands/index.js.map +1 -0
- package/dist/features/runs/queries/handlers/runs-query.handlers.js +359 -0
- package/dist/features/runs/queries/handlers/runs-query.handlers.js.map +1 -0
- package/dist/features/runs/queries/impl/get-agent-activity.query.js +7 -0
- package/dist/features/runs/queries/impl/get-agent-activity.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-agent-attempts.query.js +7 -0
- package/dist/features/runs/queries/impl/get-agent-attempts.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-agent-log.query.js +7 -0
- package/dist/features/runs/queries/impl/get-agent-log.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run-attempts.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run-attempts.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run-digest.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run-digest.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run-events.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run-events.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run-progress.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run-progress.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run-workflow.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run-workflow.query.js.map +1 -0
- package/dist/features/runs/queries/impl/get-run.query.js +7 -0
- package/dist/features/runs/queries/impl/get-run.query.js.map +1 -0
- package/dist/features/runs/queries/impl/list-runs.query.js +7 -0
- package/dist/features/runs/queries/impl/list-runs.query.js.map +1 -0
- package/dist/features/runs/queries/impl/simulate-route.query.js +7 -0
- package/dist/features/runs/queries/impl/simulate-route.query.js.map +1 -0
- package/dist/features/runs/queries/index.js +15 -0
- package/dist/features/runs/queries/index.js.map +1 -0
- package/dist/features/runs/runs-api.module.js +23 -0
- package/dist/features/runs/runs-api.module.js.map +1 -0
- package/dist/features/runs/runs-api.service.js +79 -0
- package/dist/features/runs/runs-api.service.js.map +1 -0
- package/dist/features/shared/connection.js +39 -0
- package/dist/features/shared/connection.js.map +1 -0
- package/dist/features/system/commands/index.js +2 -0
- package/dist/features/system/commands/index.js.map +1 -0
- package/dist/features/system/queries/handlers/system-query.handlers.js +96 -0
- package/dist/features/system/queries/handlers/system-query.handlers.js.map +1 -0
- package/dist/features/system/queries/impl/doctor.query.js +4 -0
- package/dist/features/system/queries/impl/doctor.query.js.map +1 -0
- package/dist/features/system/queries/impl/get-project.query.js +4 -0
- package/dist/features/system/queries/impl/get-project.query.js.map +1 -0
- package/dist/features/system/queries/impl/get-repository-context.query.js +7 -0
- package/dist/features/system/queries/impl/get-repository-context.query.js.map +1 -0
- package/dist/features/system/queries/impl/get-status.query.js +4 -0
- package/dist/features/system/queries/impl/get-status.query.js.map +1 -0
- package/dist/features/system/queries/impl/validate-repository.query.js +7 -0
- package/dist/features/system/queries/impl/validate-repository.query.js.map +1 -0
- package/dist/features/system/queries/index.js +9 -0
- package/dist/features/system/queries/index.js.map +1 -0
- package/dist/features/system/system-api.module.js +23 -0
- package/dist/features/system/system-api.module.js.map +1 -0
- package/dist/features/system/system-api.service.js +47 -0
- package/dist/features/system/system-api.service.js.map +1 -0
- package/dist/host/daemon.js +99 -0
- package/dist/host/daemon.js.map +1 -0
- package/dist/host/dbos-identity.js +42 -0
- package/dist/host/dbos-identity.js.map +1 -0
- package/dist/host/ensure-host.js +120 -0
- package/dist/host/ensure-host.js.map +1 -0
- package/dist/host/host-runtime.js +90 -0
- package/dist/host/host-runtime.js.map +1 -0
- package/dist/host/host.lifecycle.js +16 -3
- package/dist/host/host.lifecycle.js.map +1 -1
- package/dist/host/queue-ownership.js +70 -0
- package/dist/host/queue-ownership.js.map +1 -0
- package/dist/host/queue-poller-census.js +47 -0
- package/dist/host/queue-poller-census.js.map +1 -0
- package/dist/http/graphql-host.js +56 -0
- package/dist/http/graphql-host.js.map +1 -0
- package/dist/{mcp/mcp.module.js → http/graphql-host.module.js} +12 -10
- package/dist/http/graphql-host.module.js.map +1 -0
- package/dist/infrastructure/metrics/graphql/graphql-metrics.js +91 -0
- package/dist/infrastructure/metrics/graphql/graphql-metrics.js.map +1 -0
- package/dist/mcp/mcp-capabilities.js +9 -1
- package/dist/mcp/mcp-capabilities.js.map +1 -1
- package/dist/mcp/mcp-facade.service.js +68 -5
- package/dist/mcp/mcp-facade.service.js.map +1 -1
- package/dist/mcp/mcp-http.service.js +95 -0
- package/dist/mcp/mcp-http.service.js.map +1 -0
- package/dist/mcp/mcp-tools.js +94 -7
- package/dist/mcp/mcp-tools.js.map +1 -1
- package/dist/observability/agent-activity-reporter.js +185 -0
- package/dist/observability/agent-activity-reporter.js.map +1 -0
- package/dist/observability/agent-observability.service.js +1142 -0
- package/dist/observability/agent-observability.service.js.map +1 -0
- package/dist/observability/index.js +4 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/types.js +11 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/pipeline/await-human.js +8 -4
- package/dist/pipeline/await-human.js.map +1 -1
- package/dist/pipeline/data-driven-task.workflow.js +727 -0
- package/dist/pipeline/data-driven-task.workflow.js.map +1 -0
- package/dist/pipeline/data-driven-template.js +57 -0
- package/dist/pipeline/data-driven-template.js.map +1 -0
- package/dist/pipeline/pipeline.module.js +2 -2
- package/dist/pipeline/pipeline.module.js.map +1 -1
- package/dist/pipeline/pipeline.service.js +412 -0
- package/dist/pipeline/pipeline.service.js.map +1 -0
- package/dist/pipeline/route-contract.js +82 -0
- package/dist/pipeline/route-contract.js.map +1 -0
- package/dist/pipeline-core/index.js +16 -0
- package/dist/pipeline-core/index.js.map +1 -0
- package/dist/pipeline-core/interpret.js +353 -0
- package/dist/pipeline-core/interpret.js.map +1 -0
- package/dist/pipeline-core/kit/assertions.js +61 -0
- package/dist/pipeline-core/kit/assertions.js.map +1 -0
- package/dist/pipeline-core/kit/builders.js +138 -0
- package/dist/pipeline-core/kit/builders.js.map +1 -0
- package/dist/pipeline-core/kit/drive.js +96 -0
- package/dist/pipeline-core/kit/drive.js.map +1 -0
- package/dist/pipeline-core/kit/fixtures.js +342 -0
- package/dist/pipeline-core/kit/fixtures.js.map +1 -0
- package/dist/pipeline-core/kit/index.js +13 -0
- package/dist/pipeline-core/kit/index.js.map +1 -0
- package/dist/pipeline-core/types.js +134 -0
- package/dist/pipeline-core/types.js.map +1 -0
- package/dist/pipeline-core/validate-capability.js +23 -0
- package/dist/pipeline-core/validate-capability.js.map +1 -0
- package/dist/pipeline-core/validate-conflicts.js +37 -0
- package/dist/pipeline-core/validate-conflicts.js.map +1 -0
- package/dist/pipeline-core/validate-dataflow.js +212 -0
- package/dist/pipeline-core/validate-dataflow.js.map +1 -0
- package/dist/pipeline-core/validate-diff.js +158 -0
- package/dist/pipeline-core/validate-diff.js.map +1 -0
- package/dist/pipeline-core/validate-edges.js +44 -0
- package/dist/pipeline-core/validate-edges.js.map +1 -0
- package/dist/pipeline-core/validate-graph.js +123 -0
- package/dist/pipeline-core/validate-graph.js.map +1 -0
- package/dist/pipeline-core/validate-loops.js +226 -0
- package/dist/pipeline-core/validate-loops.js.map +1 -0
- package/dist/pipeline-core/validate-parallel.js +132 -0
- package/dist/pipeline-core/validate-parallel.js.map +1 -0
- package/dist/pipeline-core/validate-sink.js +27 -0
- package/dist/pipeline-core/validate-sink.js.map +1 -0
- package/dist/pipeline-core/validate-topology.js +140 -0
- package/dist/pipeline-core/validate-topology.js.map +1 -0
- package/dist/pipeline-core/validate-verdict.js +72 -0
- package/dist/pipeline-core/validate-verdict.js.map +1 -0
- package/dist/pipeline-core/validate.js +119 -0
- package/dist/pipeline-core/validate.js.map +1 -0
- package/dist/playbook/catalog-loader.js +14 -1
- package/dist/playbook/catalog-loader.js.map +1 -1
- package/dist/playbook/import-mapper.js +22 -39
- package/dist/playbook/import-mapper.js.map +1 -1
- package/dist/playbook/manifest.js +1 -1
- package/dist/poller/pr-readiness-core.js +42 -0
- package/dist/poller/pr-readiness-core.js.map +1 -1
- package/dist/revisium/playbooks.service.js +107 -19
- package/dist/revisium/playbooks.service.js.map +1 -1
- package/dist/revisium/roles.service.js +1 -1
- package/dist/revisium/roles.service.js.map +1 -1
- package/dist/revisium/run.service.js +55 -8
- package/dist/revisium/run.service.js.map +1 -1
- package/dist/run/append-event.js +24 -1
- package/dist/run/append-event.js.map +1 -1
- package/dist/run/block-run.js +17 -0
- package/dist/run/block-run.js.map +1 -0
- package/dist/run/complete-run.js +18 -0
- package/dist/run/complete-run.js.map +1 -0
- package/dist/run/create-run.js +33 -36
- package/dist/run/create-run.js.map +1 -1
- package/dist/run/inspect-run.js +35 -32
- package/dist/run/inspect-run.js.map +1 -1
- package/dist/run/run-outputs.js +88 -0
- package/dist/run/run-outputs.js.map +1 -0
- package/dist/run/terminal-run-status.js +66 -7
- package/dist/run/terminal-run-status.js.map +1 -1
- package/dist/runners/claude-code.service.js +5 -0
- package/dist/runners/claude-code.service.js.map +1 -1
- package/dist/runners/codex.service.js +51 -0
- package/dist/runners/codex.service.js.map +1 -0
- package/dist/runners/integrator-branch-naming.js +39 -0
- package/dist/runners/integrator-branch-naming.js.map +1 -0
- package/dist/runners/integrator-git.js +84 -0
- package/dist/runners/integrator-git.js.map +1 -0
- package/dist/runners/integrator-remote.js +34 -0
- package/dist/runners/integrator-remote.js.map +1 -0
- package/dist/runners/integrator-types.js +9 -0
- package/dist/runners/integrator-types.js.map +1 -0
- package/dist/runners/integrator.js +364 -152
- package/dist/runners/integrator.js.map +1 -1
- package/dist/runners/runner.module.js +7 -3
- package/dist/runners/runner.module.js.map +1 -1
- package/dist/runners/worktree.service.js +63 -0
- package/dist/runners/worktree.service.js.map +1 -0
- package/dist/smoke/cli.js +47 -0
- package/dist/smoke/cli.js.map +1 -0
- package/dist/smoke/isolation.js +113 -0
- package/dist/smoke/isolation.js.map +1 -0
- package/dist/task-control-plane/run-watch.service.js +281 -0
- package/dist/task-control-plane/run-watch.service.js.map +1 -0
- package/dist/task-control-plane/task-control-plane-api.service.js +586 -24
- package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -1
- package/dist/task-control-plane/task-control-plane.module.js +22 -3
- package/dist/task-control-plane/task-control-plane.module.js.map +1 -1
- package/dist/worker/artifact-store.js +118 -0
- package/dist/worker/artifact-store.js.map +1 -0
- package/dist/worker/build-context.js +169 -2
- package/dist/worker/build-context.js.map +1 -1
- package/dist/worker/claude-code-runner.js +175 -70
- package/dist/worker/claude-code-runner.js.map +1 -1
- package/dist/worker/codex-runner.js +475 -0
- package/dist/worker/codex-runner.js.map +1 -0
- package/dist/worker/git-worktree-manager.js +129 -65
- package/dist/worker/git-worktree-manager.js.map +1 -1
- package/dist/worker/process-executor.js +23 -2
- package/dist/worker/process-executor.js.map +1 -1
- package/dist/worker/result-envelope.js +115 -57
- package/dist/worker/result-envelope.js.map +1 -1
- package/dist/worker/runner-common.js +106 -0
- package/dist/worker/runner-common.js.map +1 -0
- package/dist/worker/runner-dispatch.js +4 -1
- package/dist/worker/runner-dispatch.js.map +1 -1
- package/dist/worker/runner.js +11 -1
- package/dist/worker/runner.js.map +1 -1
- package/dist/worker/stub-runner.js +7 -45
- package/dist/worker/stub-runner.js.map +1 -1
- package/package.json +16 -6
- package/dist/app.module.js +0 -28
- package/dist/app.module.js.map +0 -1
- package/dist/cli/commands/bootstrap.js +0 -39
- package/dist/cli/commands/bootstrap.js.map +0 -1
- package/dist/cli/commands/dev.js +0 -143
- package/dist/cli/commands/dev.js.map +0 -1
- package/dist/cli/commands/inbox.js +0 -288
- package/dist/cli/commands/inbox.js.map +0 -1
- package/dist/cli/commands/playbook.js +0 -74
- package/dist/cli/commands/playbook.js.map +0 -1
- package/dist/cli/commands/poll-workflow-state.js +0 -144
- package/dist/cli/commands/poll-workflow-state.js.map +0 -1
- package/dist/cli/commands/revisium-context.js +0 -23
- package/dist/cli/commands/revisium-context.js.map +0 -1
- package/dist/cli/commands/revisium.js +0 -89
- package/dist/cli/commands/revisium.js.map +0 -1
- package/dist/cli/commands/run.js +0 -426
- package/dist/cli/commands/run.js.map +0 -1
- package/dist/cli/commands/work.js +0 -149
- package/dist/cli/commands/work.js.map +0 -1
- package/dist/cli/live-guard.js +0 -49
- package/dist/cli/live-guard.js.map +0 -1
- package/dist/cli/needs-host.js +0 -78
- package/dist/cli/needs-host.js.map +0 -1
- package/dist/mcp/mcp-stdio.service.js +0 -48
- package/dist/mcp/mcp-stdio.service.js.map +0 -1
- package/dist/mcp/mcp.module.js.map +0 -1
- package/dist/pipeline/develop-task.workflow.js +0 -497
- package/dist/pipeline/develop-task.workflow.js.map +0 -1
- package/dist/worker/loop.js +0 -122
- package/dist/worker/loop.js.map +0 -1
- package/dist/worker/script-runner.js +0 -28
- package/dist/worker/script-runner.js.map +0 -1
- package/dist/worker/worker-id.js +0 -18
- package/dist/worker/worker-id.js.map +0 -1
- package/dist/worker/worktree-manager.js +0 -7
- package/dist/worker/worktree-manager.js.map +0 -1
|
@@ -7,22 +7,32 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
10
13
|
import { execFile } from 'node:child_process';
|
|
11
14
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
12
15
|
import { basename, join, resolve } from 'node:path';
|
|
13
16
|
import { promisify } from 'node:util';
|
|
14
|
-
import { Injectable } from '@nestjs/common';
|
|
17
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
15
18
|
import { baseUrl, getConfig, isAlive, isHealthy, readRuntime } from '../cli/config.js';
|
|
19
|
+
import { AgentObservabilityService } from '../observability/agent-observability.service.js';
|
|
16
20
|
import { ControlPlaneError } from '../control-plane/errors.js';
|
|
17
21
|
import { DbosService } from '../engine/dbos.service.js';
|
|
18
|
-
import { PipelineService } from '../pipeline/
|
|
22
|
+
import { PipelineService } from '../pipeline/pipeline.service.js';
|
|
23
|
+
import { RUN_PROGRESS_EVENT_KEY } from '../pipeline/data-driven-task.workflow.js';
|
|
24
|
+
import { templateFromExecutionPolicy } from '../pipeline/data-driven-template.js';
|
|
25
|
+
import { normalizeExecutionProfile, normalizeParams, normalizeRouteGates, resolveRunnerForProfile, } from '../pipeline/route-contract.js';
|
|
19
26
|
import { InboxService } from '../revisium/inbox.service.js';
|
|
20
27
|
import { PlaybooksService } from '../revisium/playbooks.service.js';
|
|
21
28
|
import { RolesService } from '../revisium/roles.service.js';
|
|
22
29
|
import { RunService } from '../revisium/run.service.js';
|
|
23
30
|
import { PrReadinessService } from './pr-readiness.service.js';
|
|
24
31
|
const execFileAsync = promisify(execFile);
|
|
25
|
-
const GATE_TOPICS = new Set(['plan', 'merge']);
|
|
32
|
+
const GATE_TOPICS = new Set(['plan', 'merge', 'question']);
|
|
33
|
+
const WORKFLOW_SUCCESS_EVENT_TYPES = new Set(['step_succeeded', 'gate_signaled']);
|
|
34
|
+
const WORKFLOW_FAILURE_EVENT_TYPES = new Set(['step_failed', 'attempt_failed']);
|
|
35
|
+
const BUILTIN_RUNNERS = new Set(['claude-code', 'codex', 'script', 'stub-agent', 'revo-integrator', 'revo-merger', 'revo-deterministic']);
|
|
26
36
|
function asErrorMessage(error) {
|
|
27
37
|
if (error instanceof Error)
|
|
28
38
|
return error.message;
|
|
@@ -33,6 +43,14 @@ function asRecord(value) {
|
|
|
33
43
|
return null;
|
|
34
44
|
return value;
|
|
35
45
|
}
|
|
46
|
+
function dateOrEpoch(value) {
|
|
47
|
+
if (value instanceof Date)
|
|
48
|
+
return Number.isNaN(value.getTime()) ? new Date(0) : value;
|
|
49
|
+
if (value === undefined || value === '')
|
|
50
|
+
return new Date(0);
|
|
51
|
+
const parsed = new Date(value);
|
|
52
|
+
return Number.isNaN(parsed.getTime()) ? new Date(0) : parsed;
|
|
53
|
+
}
|
|
36
54
|
function gateTopic(item) {
|
|
37
55
|
if (item.kind !== 'approval' || !item.runId)
|
|
38
56
|
return null;
|
|
@@ -99,6 +117,175 @@ function summarizeAttempts(attempts) {
|
|
|
99
117
|
costAmount: acc.costAmount + attempt.costAmount,
|
|
100
118
|
}), { inputTokens: 0, outputTokens: 0, costAmount: 0 });
|
|
101
119
|
}
|
|
120
|
+
function normalizedRunStatus(status) {
|
|
121
|
+
return status === 'paused' ? 'blocked' : status;
|
|
122
|
+
}
|
|
123
|
+
function payloadRecord(event) {
|
|
124
|
+
return asRecord(event.payload);
|
|
125
|
+
}
|
|
126
|
+
function eventStepKey(event) {
|
|
127
|
+
const payload = payloadRecord(event);
|
|
128
|
+
const stepKey = payload?.stepKey;
|
|
129
|
+
return typeof stepKey === 'string' ? stepKey : '';
|
|
130
|
+
}
|
|
131
|
+
function eventSummary(event) {
|
|
132
|
+
const payload = payloadRecord(event);
|
|
133
|
+
const reason = payload?.reason;
|
|
134
|
+
const output = payload?.output;
|
|
135
|
+
if (typeof reason === 'string' && reason)
|
|
136
|
+
return reason;
|
|
137
|
+
if (typeof output === 'string' && output)
|
|
138
|
+
return output.slice(0, 180);
|
|
139
|
+
return event.type;
|
|
140
|
+
}
|
|
141
|
+
function blockedReasonFromEvent(event) {
|
|
142
|
+
const reason = payloadRecord(event)?.reason;
|
|
143
|
+
return typeof reason === 'string' && reason ? reason : undefined;
|
|
144
|
+
}
|
|
145
|
+
function stepKeyBase(stepKey) {
|
|
146
|
+
return stepKey.split('#')[0] ?? stepKey;
|
|
147
|
+
}
|
|
148
|
+
function activeNodeIds(progress) {
|
|
149
|
+
const cursor = asRecord(progress.graphCursor);
|
|
150
|
+
const value = cursor?.activeNodeIds;
|
|
151
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : [];
|
|
152
|
+
}
|
|
153
|
+
function cursorStatus(progress) {
|
|
154
|
+
const cursor = asRecord(progress.graphCursor);
|
|
155
|
+
const status = cursor?.status;
|
|
156
|
+
return typeof status === 'string' ? status : progress.workflowStatus;
|
|
157
|
+
}
|
|
158
|
+
function templateNodeLabel(node) {
|
|
159
|
+
return node.displayName ?? node.id.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/[-_]/g, ' ');
|
|
160
|
+
}
|
|
161
|
+
function roleFromRef(roleRef) {
|
|
162
|
+
if (!roleRef)
|
|
163
|
+
return null;
|
|
164
|
+
return roleRef.startsWith('role:') ? roleRef.slice('role:'.length) : roleRef;
|
|
165
|
+
}
|
|
166
|
+
function scriptFromRef(scriptRef) {
|
|
167
|
+
if (!scriptRef)
|
|
168
|
+
return null;
|
|
169
|
+
return scriptRef.startsWith('script:') ? scriptRef.slice('script:'.length) : scriptRef;
|
|
170
|
+
}
|
|
171
|
+
function mapAttemptForWorkflow(runId, attempt) {
|
|
172
|
+
return {
|
|
173
|
+
id: attempt.attemptId,
|
|
174
|
+
runId,
|
|
175
|
+
stepId: attempt.stepId,
|
|
176
|
+
stepKey: attempt.stepId,
|
|
177
|
+
iteration: attempt.iteration,
|
|
178
|
+
status: attempt.status,
|
|
179
|
+
verdict: attempt.verdict,
|
|
180
|
+
modelProfile: attempt.modelProfile,
|
|
181
|
+
inputTokens: attempt.inputTokens,
|
|
182
|
+
outputTokens: attempt.outputTokens,
|
|
183
|
+
costAmount: attempt.costAmount,
|
|
184
|
+
currency: attempt.currency,
|
|
185
|
+
durationMs: attempt.durationMs,
|
|
186
|
+
outputSummary: attempt.outputSummary,
|
|
187
|
+
artifactRef: attempt.artifactRef,
|
|
188
|
+
lesson: attempt.lesson,
|
|
189
|
+
error: attempt.error,
|
|
190
|
+
startedAt: dateOrEpoch(attempt.startedAt),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function mapInboxForWorkflow(item) {
|
|
194
|
+
return {
|
|
195
|
+
...item,
|
|
196
|
+
runId: item.runId || null,
|
|
197
|
+
taskId: item.taskId || null,
|
|
198
|
+
stepId: item.stepId || null,
|
|
199
|
+
projectId: item.projectId || null,
|
|
200
|
+
resolvedBy: item.resolvedBy || null,
|
|
201
|
+
createdAt: dateOrEpoch(item.createdAt),
|
|
202
|
+
resolvedAt: item.resolvedAt ? dateOrEpoch(item.resolvedAt) : null,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function mapRunForWorkflow(run) {
|
|
206
|
+
return {
|
|
207
|
+
id: run.runId ?? run.id ?? '',
|
|
208
|
+
title: run.title ?? '',
|
|
209
|
+
status: normalizedRunStatus(run.status ?? ''),
|
|
210
|
+
priority: run.priority ?? 0,
|
|
211
|
+
description: run.description,
|
|
212
|
+
scope: run.scope,
|
|
213
|
+
repos: run.repos ?? [],
|
|
214
|
+
createdAt: dateOrEpoch(run.createdAt),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function workflowNodeStatus(input) {
|
|
218
|
+
if (input.gate)
|
|
219
|
+
return 'awaiting_approval';
|
|
220
|
+
if (input.failed)
|
|
221
|
+
return 'failed';
|
|
222
|
+
if (input.active)
|
|
223
|
+
return 'running';
|
|
224
|
+
if (input.succeeded)
|
|
225
|
+
return 'succeeded';
|
|
226
|
+
return 'pending';
|
|
227
|
+
}
|
|
228
|
+
function workflowGateTopic(node) {
|
|
229
|
+
const metadata = asRecord(node.metadata);
|
|
230
|
+
const reason = metadata?.reason;
|
|
231
|
+
return typeof reason === 'string' && reason ? reason : node.id;
|
|
232
|
+
}
|
|
233
|
+
function addAttemptForWorkflowNode(attemptsByBase, seenAttemptIdsByBase, base, attempt) {
|
|
234
|
+
const seen = seenAttemptIdsByBase.get(base) ?? new Set();
|
|
235
|
+
if (seen.has(attempt.attemptId))
|
|
236
|
+
return;
|
|
237
|
+
seen.add(attempt.attemptId);
|
|
238
|
+
seenAttemptIdsByBase.set(base, seen);
|
|
239
|
+
attemptsByBase.set(base, [...(attemptsByBase.get(base) ?? []), attempt]);
|
|
240
|
+
}
|
|
241
|
+
function workflowEdges(node) {
|
|
242
|
+
const record = node;
|
|
243
|
+
const edges = [];
|
|
244
|
+
const add = (to, label = '', kind = 'next') => {
|
|
245
|
+
if (typeof to === 'string' && to)
|
|
246
|
+
edges.push({ from: node.id, to, label, kind });
|
|
247
|
+
};
|
|
248
|
+
add(record.next);
|
|
249
|
+
add(record.join, 'join', 'join');
|
|
250
|
+
const branches = Array.isArray(record.branches) ? record.branches : [];
|
|
251
|
+
for (const branch of branches) {
|
|
252
|
+
const item = asRecord(branch);
|
|
253
|
+
add(item?.goto ?? item?.entry, typeof item?.id === 'string' ? item.id : '', node.kind === 'humanGate' ? 'gate' : 'branch');
|
|
254
|
+
}
|
|
255
|
+
return edges;
|
|
256
|
+
}
|
|
257
|
+
function words(value) {
|
|
258
|
+
return new Set(value.toLowerCase().split(/[^a-z0-9]+/).filter((part) => part.length > 2));
|
|
259
|
+
}
|
|
260
|
+
function routeScore(pipeline, text) {
|
|
261
|
+
const input = words(text);
|
|
262
|
+
let score = 0;
|
|
263
|
+
for (const trigger of pipeline.triggers) {
|
|
264
|
+
for (const word of words(trigger)) {
|
|
265
|
+
if (input.has(word))
|
|
266
|
+
score += 1;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return score;
|
|
270
|
+
}
|
|
271
|
+
function isRouteDecision(value) {
|
|
272
|
+
const record = asRecord(value);
|
|
273
|
+
return Boolean(record?.playbookId && record?.pipelineRowId && Array.isArray(record.roleBindings));
|
|
274
|
+
}
|
|
275
|
+
function assertRunnerAvailable(runnerId, profile, roleId) {
|
|
276
|
+
const available = profile.availableRunners;
|
|
277
|
+
if (available && !available.includes(runnerId)) {
|
|
278
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `runner unavailable for role ${roleId}: ${runnerId}`);
|
|
279
|
+
}
|
|
280
|
+
if (!available && !BUILTIN_RUNNERS.has(runnerId)) {
|
|
281
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `runner implementation is not registered for role ${roleId}: ${runnerId}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function assertProductionRunnerBinding(runnerId, runnerSource, roleId) {
|
|
285
|
+
if (runnerId !== 'stub-agent' || runnerSource === 'execution-profile')
|
|
286
|
+
return;
|
|
287
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `role ${roleId} binds production runner stub-agent; use an execution profile override for test stubs`);
|
|
288
|
+
}
|
|
102
289
|
let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
103
290
|
runs;
|
|
104
291
|
inbox;
|
|
@@ -106,14 +293,16 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
106
293
|
playbooks;
|
|
107
294
|
pipeline;
|
|
108
295
|
dbos;
|
|
296
|
+
observability;
|
|
109
297
|
prReadiness;
|
|
110
|
-
constructor(runs, inbox, roles, playbooks, pipeline, dbos, prReadiness = new PrReadinessService()) {
|
|
298
|
+
constructor(runs, inbox, roles, playbooks, pipeline, dbos, observability, prReadiness = new PrReadinessService()) {
|
|
111
299
|
this.runs = runs;
|
|
112
300
|
this.inbox = inbox;
|
|
113
301
|
this.roles = roles;
|
|
114
302
|
this.playbooks = playbooks;
|
|
115
303
|
this.pipeline = pipeline;
|
|
116
304
|
this.dbos = dbos;
|
|
305
|
+
this.observability = observability;
|
|
117
306
|
this.prReadiness = prReadiness;
|
|
118
307
|
}
|
|
119
308
|
async getStatus() {
|
|
@@ -214,19 +403,36 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
214
403
|
return { ...validation, files, ...packageContext };
|
|
215
404
|
}
|
|
216
405
|
async createRun(input) {
|
|
406
|
+
const route = await this.resolveRouteDecision({
|
|
407
|
+
title: input.title,
|
|
408
|
+
repo: input.repo,
|
|
409
|
+
description: input.description,
|
|
410
|
+
scope: input.scope,
|
|
411
|
+
playbookId: input.playbookId,
|
|
412
|
+
pipelineId: input.pipelineId,
|
|
413
|
+
params: input.params,
|
|
414
|
+
executionProfile: input.executionProfile,
|
|
415
|
+
source: input.pipelineId ? 'explicit' : 'deterministic-installed-playbook',
|
|
416
|
+
});
|
|
217
417
|
const result = await this.runs.createRun({
|
|
218
418
|
title: input.title,
|
|
219
419
|
repo: input.repo,
|
|
220
420
|
description: input.description,
|
|
221
421
|
scope: input.scope,
|
|
222
422
|
priority: input.priority ?? 0,
|
|
223
|
-
role: input.role ?? 'architect',
|
|
423
|
+
role: route.roleBindings[0]?.rowId ?? input.role ?? 'architect',
|
|
424
|
+
playbookId: route.playbookId,
|
|
425
|
+
pipelineId: route.pipelineId,
|
|
426
|
+
params: route.params,
|
|
427
|
+
routeDecision: route,
|
|
428
|
+
executionProfile: route.executionProfile,
|
|
224
429
|
});
|
|
225
430
|
if (!input.start)
|
|
226
|
-
return { ...result, started: false };
|
|
431
|
+
return { ...result, started: false, route };
|
|
227
432
|
const started = await this.startRun({
|
|
228
433
|
runId: result.runId,
|
|
229
|
-
runnerMode: input.runnerMode
|
|
434
|
+
runnerMode: input.runnerMode,
|
|
435
|
+
route,
|
|
230
436
|
});
|
|
231
437
|
return { ...result, started: true, workflow: started };
|
|
232
438
|
}
|
|
@@ -234,15 +440,25 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
234
440
|
const run = await this.runs.getRun(input.runId);
|
|
235
441
|
if (!run)
|
|
236
442
|
throw new ControlPlaneError('ROW_NOT_FOUND', `run not found: ${input.runId}`);
|
|
443
|
+
const route = input.route ?? await this.routeForRun(run);
|
|
237
444
|
const existingStatus = await this.dbos.getWorkflowStatus(input.runId);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
445
|
+
// CUTOVER (plan 0015 slice 3): the data-driven engine is the SOLE pipeline engine. EVERY pipeline
|
|
446
|
+
// routes to the data-driven workflow, executing the state-machine template carried in its
|
|
447
|
+
// execution_policy (template_json). A pipeline lacking a valid template FAILS LOUD here
|
|
448
|
+
// (PIPELINE_NOT_DATA_DRIVEN) rather than silently no-op-ing — there is no hardcoded fallback engine.
|
|
449
|
+
// A present-but-malformed/invalid template likewise throws (templateFromExecutionPolicy).
|
|
450
|
+
const template = templateFromExecutionPolicy(route.executionPolicy);
|
|
451
|
+
if (!template) {
|
|
452
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `PIPELINE_NOT_DATA_DRIVEN: pipeline ${route.pipelineId} carries no state-machine template ` +
|
|
453
|
+
`(execution_policy.template_json); the data-driven engine is the only engine`);
|
|
454
|
+
}
|
|
455
|
+
const handle = await this.pipeline.startDataDrivenTask(input.runId, { route, template });
|
|
241
456
|
return {
|
|
242
457
|
runId: input.runId,
|
|
243
458
|
workflowID: handle.workflowID,
|
|
244
459
|
alreadyStarted: existingStatus !== null,
|
|
245
|
-
|
|
460
|
+
route,
|
|
461
|
+
engine: 'data-driven',
|
|
246
462
|
};
|
|
247
463
|
}
|
|
248
464
|
resumeRun(input) {
|
|
@@ -268,11 +484,148 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
268
484
|
};
|
|
269
485
|
}
|
|
270
486
|
getRunEvents(input) {
|
|
271
|
-
return this.runs.listRunEvents(input.runId, { type: input.type, limit: input.limit });
|
|
487
|
+
return this.runs.listRunEvents(input.runId, { type: input.type, limit: input.limit, expand: input.expand });
|
|
488
|
+
}
|
|
489
|
+
async getRunProgress(runId) {
|
|
490
|
+
const detail = await this.runs.showRun(runId);
|
|
491
|
+
if (!detail)
|
|
492
|
+
throw new ControlPlaneError('ROW_NOT_FOUND', `run not found: ${runId}`);
|
|
493
|
+
const workflow = await this.dbos.getWorkflowStatus(runId);
|
|
494
|
+
if (!workflow) {
|
|
495
|
+
return {
|
|
496
|
+
workflowStatus: 'NOT_STARTED',
|
|
497
|
+
graphCursor: null,
|
|
498
|
+
updatedAt: dateOrEpoch(detail.run.createdAt),
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
const graphCursor = await this.dbos.getEvent(workflow.workflowID, RUN_PROGRESS_EVENT_KEY, { timeoutSeconds: 0 });
|
|
502
|
+
return {
|
|
503
|
+
workflowStatus: workflow.status,
|
|
504
|
+
graphCursor,
|
|
505
|
+
updatedAt: dateOrEpoch(workflow.updatedAt ?? workflow.createdAt),
|
|
506
|
+
};
|
|
272
507
|
}
|
|
273
508
|
getRunLog(input) {
|
|
274
509
|
return this.runs.listRunAttempts(input.runId, { limit: input.limit });
|
|
275
510
|
}
|
|
511
|
+
async getRunWorkflow(runId) {
|
|
512
|
+
const [detail, runRow, events, attempts, pendingInbox, progress] = await Promise.all([
|
|
513
|
+
this.getRun({ runId }),
|
|
514
|
+
this.runs.getRun(runId),
|
|
515
|
+
this.runs.listRunEvents(runId, { limit: 500 }),
|
|
516
|
+
this.runs.listRunAttempts(runId, { limit: 500 }),
|
|
517
|
+
this.inbox.listInbox({ runId, status: 'pending', limit: 100 }),
|
|
518
|
+
this.getRunProgress(runId),
|
|
519
|
+
]);
|
|
520
|
+
if (!runRow)
|
|
521
|
+
throw new ControlPlaneError('ROW_NOT_FOUND', `run not found: ${runId}`);
|
|
522
|
+
const route = await this.routeForRun(runRow);
|
|
523
|
+
const template = templateFromExecutionPolicy(route.executionPolicy);
|
|
524
|
+
const activeIds = activeNodeIds(progress);
|
|
525
|
+
const active = new Set(activeIds);
|
|
526
|
+
const succeeded = new Set(events
|
|
527
|
+
.filter((event) => WORKFLOW_SUCCESS_EVENT_TYPES.has(event.type))
|
|
528
|
+
.map(eventStepKey)
|
|
529
|
+
.filter(Boolean)
|
|
530
|
+
.map(stepKeyBase));
|
|
531
|
+
const failed = new Set(events
|
|
532
|
+
.filter((event) => WORKFLOW_FAILURE_EVENT_TYPES.has(event.type))
|
|
533
|
+
.map(eventStepKey)
|
|
534
|
+
.filter(Boolean)
|
|
535
|
+
.map(stepKeyBase));
|
|
536
|
+
const inboxByNode = new Map();
|
|
537
|
+
for (const item of pendingInbox) {
|
|
538
|
+
const context = asRecord(item.context);
|
|
539
|
+
const summary = asRecord(context?.summary);
|
|
540
|
+
const nodeId = typeof summary?.nodeId === 'string' ? summary.nodeId : '';
|
|
541
|
+
if (nodeId)
|
|
542
|
+
inboxByNode.set(nodeId, item);
|
|
543
|
+
}
|
|
544
|
+
const attemptsByBase = new Map();
|
|
545
|
+
const seenAttemptIdsByBase = new Map();
|
|
546
|
+
for (const event of events) {
|
|
547
|
+
const key = eventStepKey(event);
|
|
548
|
+
if (!key)
|
|
549
|
+
continue;
|
|
550
|
+
const base = stepKeyBase(key);
|
|
551
|
+
const eventAttempts = attempts.filter((attempt) => attempt.attemptId === asRecord(event.payload)?.attemptId);
|
|
552
|
+
for (const attempt of eventAttempts) {
|
|
553
|
+
addAttemptForWorkflowNode(attemptsByBase, seenAttemptIdsByBase, base, attempt);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
const nodes = Object.values(template?.nodes ?? {}).map((node) => {
|
|
557
|
+
const record = node;
|
|
558
|
+
const nodeAttempts = attemptsByBase.get(node.id) ?? [];
|
|
559
|
+
const roleId = roleFromRef(record.roleRef);
|
|
560
|
+
const binding = roleId ? route.roleBindings.find((item) => item.roleId === roleId) : undefined;
|
|
561
|
+
const isActive = active.has(node.id);
|
|
562
|
+
const gate = inboxByNode.get(node.id);
|
|
563
|
+
const status = workflowNodeStatus({
|
|
564
|
+
gate,
|
|
565
|
+
failed: failed.has(node.id),
|
|
566
|
+
active: isActive,
|
|
567
|
+
succeeded: succeeded.has(node.id),
|
|
568
|
+
});
|
|
569
|
+
return {
|
|
570
|
+
id: node.id,
|
|
571
|
+
label: templateNodeLabel(node),
|
|
572
|
+
kind: node.kind,
|
|
573
|
+
roleId,
|
|
574
|
+
scriptId: scriptFromRef(record.scriptRef),
|
|
575
|
+
modelLevel: binding?.modelLevel ?? null,
|
|
576
|
+
runner: binding?.resolvedRunnerId ?? null,
|
|
577
|
+
status,
|
|
578
|
+
attemptCount: nodeAttempts.length,
|
|
579
|
+
inputTokens: nodeAttempts.reduce((sum, attempt) => sum + attempt.inputTokens, 0),
|
|
580
|
+
outputTokens: nodeAttempts.reduce((sum, attempt) => sum + attempt.outputTokens, 0),
|
|
581
|
+
costAmount: nodeAttempts.reduce((sum, attempt) => sum + attempt.costAmount, 0),
|
|
582
|
+
verdict: nodeAttempts.at(-1)?.verdict ?? null,
|
|
583
|
+
inboxId: gate?.id ?? null,
|
|
584
|
+
metadata: node,
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
const edges = Object.values(template?.nodes ?? {}).flatMap((node) => workflowEdges(node));
|
|
588
|
+
return {
|
|
589
|
+
run: {
|
|
590
|
+
...mapRunForWorkflow(detail.run),
|
|
591
|
+
},
|
|
592
|
+
pipeline: {
|
|
593
|
+
id: route.pipelineRowId,
|
|
594
|
+
pipelineId: route.pipelineId,
|
|
595
|
+
playbookId: route.playbookId,
|
|
596
|
+
title: template?.title ?? route.pipelineId,
|
|
597
|
+
routeGates: route.routeGates,
|
|
598
|
+
activeNodeIds: activeIds,
|
|
599
|
+
status: cursorStatus(progress),
|
|
600
|
+
},
|
|
601
|
+
nodes,
|
|
602
|
+
edges,
|
|
603
|
+
currentNodeIds: activeIds,
|
|
604
|
+
gates: nodes
|
|
605
|
+
.filter((node) => node.kind === 'humanGate')
|
|
606
|
+
.map((node) => {
|
|
607
|
+
const inbox = inboxByNode.get(node.id);
|
|
608
|
+
return {
|
|
609
|
+
nodeId: node.id,
|
|
610
|
+
topic: workflowGateTopic(node),
|
|
611
|
+
status: inbox ? 'pending' : node.status,
|
|
612
|
+
inboxId: inbox?.id ?? null,
|
|
613
|
+
answer: inbox?.answer ?? null,
|
|
614
|
+
};
|
|
615
|
+
}),
|
|
616
|
+
attempts: attempts.map((attempt) => mapAttemptForWorkflow(runId, attempt)),
|
|
617
|
+
pendingInbox: pendingInbox.map(mapInboxForWorkflow),
|
|
618
|
+
usage: summarizeAttempts(attempts),
|
|
619
|
+
activity: events.slice(-50).reverse().map((event) => ({
|
|
620
|
+
id: event.eventId,
|
|
621
|
+
type: event.type,
|
|
622
|
+
actor: event.actor,
|
|
623
|
+
createdAt: dateOrEpoch(event.createdAt),
|
|
624
|
+
summary: eventSummary(event),
|
|
625
|
+
payload: event.payload,
|
|
626
|
+
})),
|
|
627
|
+
};
|
|
628
|
+
}
|
|
276
629
|
async getRunDigest(runId) {
|
|
277
630
|
const detail = await this.runs.showRun(runId);
|
|
278
631
|
if (!detail)
|
|
@@ -282,12 +635,108 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
282
635
|
this.runs.listRunAttempts(runId, { limit: 100 }),
|
|
283
636
|
this.inbox.listInbox({ runId, status: 'pending', limit: 50 }),
|
|
284
637
|
]);
|
|
638
|
+
const latestBlockingEvent = [...events].reverse().find((e) => e.type === 'pipeline_blocked');
|
|
639
|
+
const blockedReason = latestBlockingEvent ? blockedReasonFromEvent(latestBlockingEvent) : undefined;
|
|
285
640
|
return {
|
|
286
641
|
run: detail.run,
|
|
287
642
|
tasks: detail.tasks,
|
|
288
643
|
pendingInbox: inbox,
|
|
289
644
|
latestEvents: events.slice(-10),
|
|
290
645
|
usage: summarizeAttempts(attempts),
|
|
646
|
+
...(blockedReason !== undefined ? { blockedReason } : {}),
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
async waitForRun(input) {
|
|
650
|
+
const timeoutMs = input.timeoutMs ?? 0;
|
|
651
|
+
const intervalMs = input.intervalMs ?? 1000;
|
|
652
|
+
const deadline = Date.now() + timeoutMs;
|
|
653
|
+
for (;;) {
|
|
654
|
+
const state = await this.resolveRunState(input.runId);
|
|
655
|
+
if (state.state !== 'running' || Date.now() >= deadline)
|
|
656
|
+
return state;
|
|
657
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Resolve a single run to its actionable state. Public so `RunWatchService` (slice 141 D2) can
|
|
662
|
+
* fan it out across many runs; it is a point-in-time level read (gate = `inbox.find(approval)`),
|
|
663
|
+
* not an event cursor — the watch primitive layers at-least-once + idempotent delivery on top.
|
|
664
|
+
*/
|
|
665
|
+
async resolveRunState(runId) {
|
|
666
|
+
const detail = await this.runs.showRun(runId);
|
|
667
|
+
if (!detail)
|
|
668
|
+
throw new ControlPlaneError('ROW_NOT_FOUND', `run not found: ${runId}`);
|
|
669
|
+
const [inbox, events, workflow] = await Promise.all([
|
|
670
|
+
this.inbox.listInbox({ runId, status: 'pending', limit: 20 }),
|
|
671
|
+
this.runs.listRunEvents(runId, { limit: 20 }),
|
|
672
|
+
this.dbos.getWorkflowStatus(runId),
|
|
673
|
+
]);
|
|
674
|
+
const gate = inbox.find((item) => item.kind === 'approval');
|
|
675
|
+
if (gate) {
|
|
676
|
+
return {
|
|
677
|
+
runId,
|
|
678
|
+
state: 'pending_gate',
|
|
679
|
+
nextAction: 'resolve approval with approve_gate or reject_gate',
|
|
680
|
+
runStatus: detail.run.status,
|
|
681
|
+
workflowStatus: workflow?.status ?? '',
|
|
682
|
+
inbox: gate,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const question = inbox.find((item) => item.kind === 'question');
|
|
686
|
+
if (question) {
|
|
687
|
+
return {
|
|
688
|
+
runId,
|
|
689
|
+
state: 'question',
|
|
690
|
+
nextAction: 'answer question with answer_question',
|
|
691
|
+
runStatus: detail.run.status,
|
|
692
|
+
workflowStatus: workflow?.status ?? '',
|
|
693
|
+
inbox: question,
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
if (detail.run.status === 'completed') {
|
|
697
|
+
return { runId, state: 'completed', nextAction: 'none', runStatus: detail.run.status, workflowStatus: workflow?.status ?? '' };
|
|
698
|
+
}
|
|
699
|
+
if (detail.run.status === 'failed') {
|
|
700
|
+
return { runId, state: 'failed', nextAction: 'inspect get_run_events/get_run_log', runStatus: detail.run.status, workflowStatus: workflow?.status ?? '' };
|
|
701
|
+
}
|
|
702
|
+
if (detail.run.status === 'cancelled') {
|
|
703
|
+
return { runId, state: 'blocked', nextAction: 'run was cancelled; create or resume a different run', runStatus: detail.run.status, workflowStatus: workflow?.status ?? '' };
|
|
704
|
+
}
|
|
705
|
+
const blockingEvent = [...events].reverse().find((event) => event.type === 'pipeline_blocked');
|
|
706
|
+
const blockedReason = blockingEvent ? blockedReasonFromEvent(blockingEvent) : undefined;
|
|
707
|
+
if (detail.run.status === 'paused') {
|
|
708
|
+
return {
|
|
709
|
+
runId,
|
|
710
|
+
state: 'blocked',
|
|
711
|
+
nextAction: 'inspect blocking event and decide whether to create a follow-up run',
|
|
712
|
+
runStatus: detail.run.status,
|
|
713
|
+
workflowStatus: workflow?.status ?? '',
|
|
714
|
+
...(blockedReason !== undefined ? { blockedReason } : {}),
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
if (blockingEvent) {
|
|
718
|
+
return {
|
|
719
|
+
runId,
|
|
720
|
+
state: 'blocked',
|
|
721
|
+
nextAction: 'inspect blocking event and decide whether to create a follow-up run',
|
|
722
|
+
runStatus: detail.run.status,
|
|
723
|
+
workflowStatus: workflow?.status ?? '',
|
|
724
|
+
latestBlockingEvent: blockingEvent,
|
|
725
|
+
...(blockedReason !== undefined ? { blockedReason } : {}),
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (workflow?.status === 'ERROR') {
|
|
729
|
+
return { runId, state: 'failed', nextAction: 'inspect get_run_events/get_run_log', runStatus: detail.run.status, workflowStatus: workflow.status };
|
|
730
|
+
}
|
|
731
|
+
if (workflow?.status === 'SUCCESS') {
|
|
732
|
+
return { runId, state: 'completed', nextAction: 'none', runStatus: detail.run.status, workflowStatus: workflow.status };
|
|
733
|
+
}
|
|
734
|
+
return {
|
|
735
|
+
runId,
|
|
736
|
+
state: 'running',
|
|
737
|
+
nextAction: 'wait_for_run again or inspect get_run_digest',
|
|
738
|
+
runStatus: detail.run.status,
|
|
739
|
+
workflowStatus: workflow?.status ?? '',
|
|
291
740
|
};
|
|
292
741
|
}
|
|
293
742
|
listInbox(filter) {
|
|
@@ -403,37 +852,150 @@ let TaskControlPlaneApiService = class TaskControlPlaneApiService {
|
|
|
403
852
|
return result;
|
|
404
853
|
}
|
|
405
854
|
simulateRoute(input) {
|
|
406
|
-
|
|
407
|
-
return {
|
|
855
|
+
return this.resolveRouteDecision({
|
|
408
856
|
title: input.title,
|
|
409
857
|
repo: input.repo ?? '',
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
858
|
+
playbookId: input.playbookId,
|
|
859
|
+
pipelineId: input.pipeline,
|
|
860
|
+
params: input.params,
|
|
861
|
+
source: input.pipeline ? 'explicit' : 'deterministic-installed-playbook',
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
async routeForRun(run) {
|
|
865
|
+
if (isRouteDecision(run.data.route_decision))
|
|
866
|
+
return run.data.route_decision;
|
|
867
|
+
return this.resolveRouteDecision({
|
|
868
|
+
title: typeof run.data.title === 'string' ? run.data.title : 'Run',
|
|
869
|
+
repo: Array.isArray(run.data.repos) && typeof run.data.repos[0] === 'string' ? run.data.repos[0] : '',
|
|
870
|
+
description: typeof run.data.description === 'string' ? run.data.description : '',
|
|
871
|
+
scope: typeof run.data.scope === 'string' ? run.data.scope : '',
|
|
872
|
+
playbookId: typeof run.data.playbook_id === 'string' ? run.data.playbook_id : undefined,
|
|
873
|
+
pipelineId: typeof run.data.pipeline_id === 'string' ? run.data.pipeline_id : undefined,
|
|
874
|
+
params: run.data.params,
|
|
875
|
+
source: run.data.pipeline_id ? 'explicit' : 'deterministic-installed-playbook',
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
async resolveRouteDecision(input) {
|
|
879
|
+
const params = normalizeParams(input.params);
|
|
880
|
+
const executionProfile = normalizeExecutionProfile(input.executionProfile);
|
|
881
|
+
const playbook = await this.playbooks.resolvePlaybook(input.playbookId);
|
|
882
|
+
const pipeline = input.pipelineId
|
|
883
|
+
? await this.playbooks.resolvePipeline({ playbookId: playbook.id, pipelineId: input.pipelineId })
|
|
884
|
+
: await this.resolveAutoPipeline(playbook.id, [input.title, input.description, input.scope].join(' '));
|
|
885
|
+
const roleBindings = await this.resolveRouteRoles(playbook.id, pipeline, executionProfile);
|
|
886
|
+
return {
|
|
887
|
+
playbookId: playbook.id,
|
|
888
|
+
pipelineId: pipeline.pipelineId,
|
|
889
|
+
pipelineRowId: pipeline.id,
|
|
890
|
+
source: input.source,
|
|
891
|
+
roles: roleBindings.map((binding) => binding.roleId),
|
|
892
|
+
requiredRoles: pipeline.requiredRoles,
|
|
893
|
+
optionalRoles: pipeline.optionalRoles,
|
|
894
|
+
routeGates: normalizeRouteGates(pipeline.routeGates),
|
|
895
|
+
executionPolicy: pipeline.executionPolicy,
|
|
896
|
+
executionProfile,
|
|
897
|
+
roleBindings,
|
|
898
|
+
params,
|
|
420
899
|
};
|
|
421
900
|
}
|
|
901
|
+
async resolveAutoPipeline(playbookId, text) {
|
|
902
|
+
const pipelines = (await this.playbooks.listPipelines())
|
|
903
|
+
.filter((pipeline) => pipeline.playbookId === playbookId)
|
|
904
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
905
|
+
if (pipelines.length === 0) {
|
|
906
|
+
throw new ControlPlaneError('ROW_NOT_FOUND', `no installed pipelines found for playbook ${playbookId}`);
|
|
907
|
+
}
|
|
908
|
+
const scored = pipelines
|
|
909
|
+
.map((pipeline) => ({ pipeline, score: routeScore(pipeline, text) }))
|
|
910
|
+
.sort((left, right) => right.score - left.score || left.pipeline.id.localeCompare(right.pipeline.id));
|
|
911
|
+
const best = scored[0];
|
|
912
|
+
const second = scored[1];
|
|
913
|
+
if (!best || best.score <= 0) {
|
|
914
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `unable to choose a pipeline confidently; provide pipelineId`);
|
|
915
|
+
}
|
|
916
|
+
if (second?.score === best.score) {
|
|
917
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `ambiguous pipeline route; provide pipelineId`);
|
|
918
|
+
}
|
|
919
|
+
return best.pipeline;
|
|
920
|
+
}
|
|
921
|
+
async resolveRouteRoles(playbookId, pipeline, executionProfile) {
|
|
922
|
+
const roles = (await this.roles.listRoles()).filter((role) => role.playbookId === playbookId);
|
|
923
|
+
const byPlaybookRole = new Map(roles.map((role) => [role.playbookRoleId || role.name, role]));
|
|
924
|
+
// The route selects WHICH roles a pipeline binds (capability handles the data-driven engine
|
|
925
|
+
// resolves). Order is no longer load-bearing — the data-driven template owns node sequencing — so
|
|
926
|
+
// alternative-group selections simply append (the old `insertBeforeFirstDeveloperRole` phase-order
|
|
927
|
+
// hardcode is removed with the rest of the hardcoded engine, plan 0015 slice 3).
|
|
928
|
+
const selected = [...pipeline.requiredRoles];
|
|
929
|
+
for (const group of pipeline.alternativeRoles) {
|
|
930
|
+
const match = group.roles.find((roleId) => byPlaybookRole.has(roleId));
|
|
931
|
+
if (!match) {
|
|
932
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `pipeline ${pipeline.pipelineId} alternative group ${group.group_id} has no installed role`);
|
|
933
|
+
}
|
|
934
|
+
if (!selected.includes(match))
|
|
935
|
+
selected.push(match);
|
|
936
|
+
}
|
|
937
|
+
for (const roleId of selected) {
|
|
938
|
+
if (!byPlaybookRole.has(roleId)) {
|
|
939
|
+
throw new ControlPlaneError('VALIDATION_FAILURE', `pipeline ${pipeline.pipelineId} references missing installed role: ${roleId}`);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return selected.map((roleId) => {
|
|
943
|
+
const role = byPlaybookRole.get(roleId);
|
|
944
|
+
assertProductionRunnerBinding(role.runner, 'playbook', roleId);
|
|
945
|
+
const resolved = resolveRunnerForProfile(role.runner, executionProfile);
|
|
946
|
+
assertProductionRunnerBinding(resolved.runnerId, resolved.source, roleId);
|
|
947
|
+
assertRunnerAvailable(resolved.runnerId, executionProfile, roleId);
|
|
948
|
+
return {
|
|
949
|
+
roleId,
|
|
950
|
+
rowId: role.id,
|
|
951
|
+
modelLevel: role.modelLevel,
|
|
952
|
+
runnerId: role.runner,
|
|
953
|
+
resolvedRunnerId: resolved.runnerId,
|
|
954
|
+
runnerSource: resolved.source,
|
|
955
|
+
};
|
|
956
|
+
});
|
|
957
|
+
}
|
|
422
958
|
getPrReadiness(input) {
|
|
423
959
|
return this.prReadiness.getPrReadiness(input);
|
|
424
960
|
}
|
|
425
961
|
listPrFeedback(input) {
|
|
426
962
|
return this.prReadiness.listPrFeedback(input);
|
|
427
963
|
}
|
|
964
|
+
getAgentActivity(runId) {
|
|
965
|
+
return this.observability.getAgentActivity(runId);
|
|
966
|
+
}
|
|
967
|
+
getAgentAttempts(runId) {
|
|
968
|
+
return this.observability.listAgentAttempts(runId);
|
|
969
|
+
}
|
|
970
|
+
getAgentLog(input) {
|
|
971
|
+
return this.observability.getAgentLog(input);
|
|
972
|
+
}
|
|
973
|
+
readAgentOutputEvents(input) {
|
|
974
|
+
return this.observability.readAgentOutputEvents(input);
|
|
975
|
+
}
|
|
976
|
+
watchAgentActivity(input) {
|
|
977
|
+
return this.observability.watchAgentActivity(input);
|
|
978
|
+
}
|
|
979
|
+
watchAgentOutput(input) {
|
|
980
|
+
return this.observability.watchAgentOutput(input);
|
|
981
|
+
}
|
|
428
982
|
};
|
|
429
983
|
TaskControlPlaneApiService = __decorate([
|
|
430
984
|
Injectable(),
|
|
985
|
+
__param(0, Inject(RunService)),
|
|
986
|
+
__param(1, Inject(InboxService)),
|
|
987
|
+
__param(2, Inject(RolesService)),
|
|
988
|
+
__param(3, Inject(PlaybooksService)),
|
|
989
|
+
__param(4, Inject(PipelineService)),
|
|
990
|
+
__param(5, Inject(DbosService)),
|
|
991
|
+
__param(6, Inject(AgentObservabilityService)),
|
|
431
992
|
__metadata("design:paramtypes", [RunService,
|
|
432
993
|
InboxService,
|
|
433
994
|
RolesService,
|
|
434
995
|
PlaybooksService,
|
|
435
996
|
PipelineService,
|
|
436
997
|
DbosService,
|
|
998
|
+
AgentObservabilityService,
|
|
437
999
|
PrReadinessService])
|
|
438
1000
|
], TaskControlPlaneApiService);
|
|
439
1001
|
export { TaskControlPlaneApiService };
|