@cat-factory/orchestration 0.123.3 → 0.123.5
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/dist/modules/execution/DeployerStepController.d.ts +185 -0
- package/dist/modules/execution/DeployerStepController.d.ts.map +1 -0
- package/dist/modules/execution/DeployerStepController.js +670 -0
- package/dist/modules/execution/DeployerStepController.js.map +1 -0
- package/dist/modules/execution/ExecutionService.d.ts +8 -211
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
- package/dist/modules/execution/ExecutionService.js +59 -805
- package/dist/modules/execution/ExecutionService.js.map +1 -1
- package/dist/modules/execution/FollowUpGateController.d.ts +104 -0
- package/dist/modules/execution/FollowUpGateController.d.ts.map +1 -0
- package/dist/modules/execution/FollowUpGateController.js +317 -0
- package/dist/modules/execution/FollowUpGateController.js.map +1 -0
- package/dist/modules/execution/RunAdmission.d.ts +204 -0
- package/dist/modules/execution/RunAdmission.d.ts.map +1 -0
- package/dist/modules/execution/RunAdmission.js +571 -0
- package/dist/modules/execution/RunAdmission.js.map +1 -0
- package/dist/modules/execution/RunDispatcher.d.ts +24 -196
- package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
- package/dist/modules/execution/RunDispatcher.js +70 -929
- package/dist/modules/execution/RunDispatcher.js.map +1 -1
- package/dist/modules/execution/review-kinds.d.ts +41 -0
- package/dist/modules/execution/review-kinds.d.ts.map +1 -0
- package/dist/modules/execution/review-kinds.js +241 -0
- package/dist/modules/execution/review-kinds.js.map +1 -0
- package/dist/modules/observability/AgentContextObservabilityService.d.ts +24 -2
- package/dist/modules/observability/AgentContextObservabilityService.d.ts.map +1 -1
- package/dist/modules/observability/AgentContextObservabilityService.js +39 -7
- package/dist/modules/observability/AgentContextObservabilityService.js.map +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { AgentRunResult, Block, BlockRepository, ContainerEvictionKind, ExecutionInstance, PipelineStep, ProvisionContext } from '@cat-factory/kernel';
|
|
2
|
+
import type { EnvironmentProvisioningService } from '@cat-factory/integrations';
|
|
3
|
+
import type { AgentContextBuilder } from './AgentContextBuilder.js';
|
|
4
|
+
import type { RunStateMachine } from './RunStateMachine.js';
|
|
5
|
+
import type { AdvanceResult } from './advance.js';
|
|
6
|
+
/**
|
|
7
|
+
* Collaborators + the {@link RunDispatcher} seams the deployer step family needs. The
|
|
8
|
+
* completion hub (`recordStepResult`) and the shared poll folds / eviction recovery stay on
|
|
9
|
+
* the dispatcher (the agent path uses them too) and are injected as callbacks, so the two
|
|
10
|
+
* paths can't drift on budgets or fold semantics.
|
|
11
|
+
*/
|
|
12
|
+
export interface DeployerStepControllerDeps {
|
|
13
|
+
blockRepository: BlockRepository;
|
|
14
|
+
contextBuilder: AgentContextBuilder;
|
|
15
|
+
runStateMachine: RunStateMachine;
|
|
16
|
+
environmentProvisioning?: EnvironmentProvisioningService;
|
|
17
|
+
recordStepResult: (workspaceId: string, instance: ExecutionInstance, step: PipelineStep, isFinalStep: boolean, result: AgentRunResult) => Promise<AdvanceResult>;
|
|
18
|
+
applyContainerRunning: (step: PipelineStep, update: {
|
|
19
|
+
phase?: string;
|
|
20
|
+
container?: {
|
|
21
|
+
id?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
};
|
|
24
|
+
}) => boolean;
|
|
25
|
+
applySubtaskProgress: (step: PipelineStep, counts: PipelineStep['subtasks']) => boolean;
|
|
26
|
+
recoverContainerEviction: (workspaceId: string, instance: ExecutionInstance, step: PipelineStep, error: string | undefined, evicted: ContainerEvictionKind | undefined, onBeforeRedispatch?: () => Promise<void>) => Promise<AdvanceResult | null>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The deterministic `deployer` step family, extracted out of {@link RunDispatcher}: the
|
|
30
|
+
* multi-frame provision fan-out (own frame + involved-service peers, provider-before-consumer),
|
|
31
|
+
* the async container-backed deploy-job poll, the per-frame settle/failure bookkeeping on
|
|
32
|
+
* `step.deployEnvs`, and the environment projection every env-aware step surfaces on its run
|
|
33
|
+
* details. No LLM and no token usage anywhere in this family — the deployer provisions
|
|
34
|
+
* environments through the {@link EnvironmentProvisioningService} provider only. Pure code
|
|
35
|
+
* movement from the dispatcher; no behaviour changes.
|
|
36
|
+
*/
|
|
37
|
+
export declare class DeployerStepController {
|
|
38
|
+
private readonly blockRepository;
|
|
39
|
+
private readonly contextBuilder;
|
|
40
|
+
private readonly runStateMachine;
|
|
41
|
+
private readonly environmentProvisioning?;
|
|
42
|
+
private readonly recordStepResult;
|
|
43
|
+
private readonly applyContainerRunning;
|
|
44
|
+
private readonly applySubtaskProgress;
|
|
45
|
+
private readonly recoverContainerEviction;
|
|
46
|
+
constructor(deps: DeployerStepControllerDeps);
|
|
47
|
+
/**
|
|
48
|
+
* Stamp `step.environment` from the block's live ephemeral environment so a run's
|
|
49
|
+
* details show its spinning-up / running / shut-down / errored state + the exact
|
|
50
|
+
* error. Best-effort: a no-op when the env integration isn't wired, and never
|
|
51
|
+
* throws (a projection failure must not break the run). Returns whether it changed,
|
|
52
|
+
* so the poll path can fold it into its single emit. The `human-test` gate keeps
|
|
53
|
+
* its own `humanTest.environment`, so this is for the other env-consuming steps
|
|
54
|
+
* (tester/coder/deployer).
|
|
55
|
+
*/
|
|
56
|
+
attachEnvironmentProjection(workspaceId: string, blockId: string, step: PipelineStep, frameId?: string): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Deterministically provision an ephemeral environment for a `deployer` step and turn the
|
|
59
|
+
* outcome into the step's advance result (no LLM, no token usage). On success the env
|
|
60
|
+
* summary is recorded as the step output. On a provisioning failure — the provider threw
|
|
61
|
+
* OR returned `status:'failed'` — the breakage is surfaced as a real, DISPLAYED step
|
|
62
|
+
* failure rather than a green step with the error buried in its prose output: `step.environment`
|
|
63
|
+
* is stamped with the errored env (its `lastError` renders in the step's Environment panel)
|
|
64
|
+
* and a structured `environment` failure is returned (the board's failure card). A deployer
|
|
65
|
+
* that can't provision IS failed — the downstream tester/coder steps need that environment.
|
|
66
|
+
*
|
|
67
|
+
* The failure is TERMINAL and surfaced for a human/`Retry`, NOT auto-retried by the durable
|
|
68
|
+
* driver — DELIBERATELY, and symmetric with `handleAgentStep`'s dispatch-failure path
|
|
69
|
+
* (a container that never started is likewise terminal regardless of `rethrowAgentErrors`).
|
|
70
|
+
* Environment provisioning is infra spin-up, not agent execution: treating it like the
|
|
71
|
+
* `dispatch` failure (surface the verbatim cause + one-click retry) keeps the `environment`
|
|
72
|
+
* classification and the provider's real error visible, where rethrowing for the driver's
|
|
73
|
+
* per-step retry would re-collapse it into a generic `agent` failure on exhaustion and bury
|
|
74
|
+
* the root cause. So do NOT reintroduce a `rethrowAgentErrors` branch here.
|
|
75
|
+
*/
|
|
76
|
+
runDeployerStep(workspaceId: string, instance: ExecutionInstance, step: PipelineStep, block: Block, isFinalStep: boolean): Promise<AdvanceResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Advance a `deployer` fan-out over its already-resolved `targets`: dispatch the first un-settled
|
|
79
|
+
* frame (parking on an async deploy job) or, once every frame has settled, complete the step. One
|
|
80
|
+
* deploy job per frame, dispatched SEQUENTIALLY (parking between) so a later provider can receive
|
|
81
|
+
* the already-ready peers' URLs. `step.deployEnvs` records each frame's TERMINAL outcome, so a
|
|
82
|
+
* replay resumes at the first un-settled frame. Re-entered (with the SAME targets) after each
|
|
83
|
+
* synchronous/infraless/failed-peer frame settles — never re-reading the block list per frame.
|
|
84
|
+
*/
|
|
85
|
+
private advanceDeployerFrames;
|
|
86
|
+
/**
|
|
87
|
+
* Resolve the ordered set of service frames a `deployer` step provisions environments for: the
|
|
88
|
+
* task's OWN service frame (always, `isPrimary`) plus each involved-service frame (read-time
|
|
89
|
+
* stale-filtered to ids that are still a connection neighbour AND resolve to a `service` frame
|
|
90
|
+
* WITH declared provisioning — an involved frame with none stands nothing up here). Ordered
|
|
91
|
+
* PROVIDER-before-CONSUMER over the connection edges among the targets (see
|
|
92
|
+
* {@link orderProvisionTargets}) so a later provision can receive its ready peers' URLs. One
|
|
93
|
+
* workspace block-list read; no per-frame point read.
|
|
94
|
+
*
|
|
95
|
+
* `pinnedPrimaryFrameId` (from {@link PipelineStep.deployPrimaryFrameId}, set on the first
|
|
96
|
+
* resolution) keeps the OWN/primary frame STABLE across re-entries: once the fan-out has started,
|
|
97
|
+
* a mid-flight reparent must not re-classify which frame is primary — that would flip an
|
|
98
|
+
* own-frame failure from terminal to a non-terminal peer failure. Prefer the pinned frame when it
|
|
99
|
+
* still resolves; fall back to a fresh `frameOf` walk otherwise.
|
|
100
|
+
*/
|
|
101
|
+
private resolveDeployTargets;
|
|
102
|
+
/**
|
|
103
|
+
* Record one frame's TERMINAL deploy outcome onto `step.deployEnvs`, then continue the fan-out.
|
|
104
|
+
* A `ready` handle records the env and re-enters {@link advanceDeployerFrames} for the next
|
|
105
|
+
* frame; a `failed` handle routes to {@link settleDeployerFailure} (terminal only for the own
|
|
106
|
+
* frame). Shared by the synchronous-provision and async-finalized paths.
|
|
107
|
+
*/
|
|
108
|
+
private settleDeployerFrame;
|
|
109
|
+
/**
|
|
110
|
+
* Record a frame's FAILED deploy outcome and decide whether it is terminal. The task's OWN
|
|
111
|
+
* (primary) service frame failing fails the whole deploy step (unchanged from the single-env
|
|
112
|
+
* path). An involved PEER frame failing is NON-terminal — the peer's env is best-effort context
|
|
113
|
+
* enrichment, so the run proceeds to the remaining frames without that peer's URL rather than
|
|
114
|
+
* failing a task because a service it merely "involves" has a misconfigured provider. The failed
|
|
115
|
+
* outcome is still recorded (surfaced in {@link completeDeployerStep}).
|
|
116
|
+
*/
|
|
117
|
+
private settleDeployerFailure;
|
|
118
|
+
/**
|
|
119
|
+
* Poll a `deployer` step's dispatched CONTAINER-backed deploy job (the async kustomize/helm
|
|
120
|
+
* path) through the environment provisioning service — NOT the agent executor. Mirrors
|
|
121
|
+
* `pollAgentJob`: surfaces live container/subtask progress while running, recovers a
|
|
122
|
+
* container eviction by re-dispatching a fresh deploy job (within the same budgets), and on a
|
|
123
|
+
* genuine terminal state finalizes the job into an environment record + the step result.
|
|
124
|
+
*/
|
|
125
|
+
pollDeployerJob(workspaceId: string, instance: ExecutionInstance, step: PipelineStep): Promise<AdvanceResult>;
|
|
126
|
+
/**
|
|
127
|
+
* The {@link ProvisionArgs} for provisioning ONE target frame's environment (synchronous or
|
|
128
|
+
* async). The env is keyed by the task `block.id` + the target `frameId` — so a task's own env
|
|
129
|
+
* and each involved-service env coexist under the same block, discriminated by frame (see the
|
|
130
|
+
* per-`(blockId, frameId)` supersede). The repo/clone the provider resolves is the TARGET
|
|
131
|
+
* FRAME's (via `frameId`), so an involved-service env clones that peer's repo at its default
|
|
132
|
+
* branch, while the OWN frame targets the task's PR branch (its git/PR context); a peer carries
|
|
133
|
+
* no PR context. The `{{input.*}}` identity (blockId/title/…) is the TARGET FRAME's for a peer
|
|
134
|
+
* (see {@link deployTargetInputs}) so each peer's provider namespace is distinct — the task-
|
|
135
|
+
* scoped inputs would collapse every peer onto one namespace. Injects `frontendOrigins` (the
|
|
136
|
+
* browser origins binding this service) and `peerEnvUrls` (the already-ready peers) too.
|
|
137
|
+
*/
|
|
138
|
+
private deployerProvisionArgs;
|
|
139
|
+
/**
|
|
140
|
+
* The `{{input.*}}` identity a target frame provisions with. The OWN frame keeps the historical
|
|
141
|
+
* task-scoped inputs (its namespace is uniquified by the task's PR repo/number). An involved PEER
|
|
142
|
+
* frame is scoped to the PEER FRAME's identity, with a `(task, peer)` composite `blockId` — so
|
|
143
|
+
* the provider namespace derived from `{{input.blockId}}` is distinct per peer AND per task,
|
|
144
|
+
* where the task-scoped inputs would collapse every peer of a task onto ONE namespace (each
|
|
145
|
+
* clobbering the previous, teardown deleting the wrong one).
|
|
146
|
+
*/
|
|
147
|
+
private deployTargetInputs;
|
|
148
|
+
/**
|
|
149
|
+
* The `frontendOrigins` provision input for a service frame: the comma-joined browser origins
|
|
150
|
+
* of every `frontend` frame that binds this service (see `frontendOriginsForService`), for a
|
|
151
|
+
* manifest to fold into the backend's CORS allow-list via `{{input.frontendOrigins}}`. Empty
|
|
152
|
+
* string when no frontend binds it (the key is then omitted). One workspace block-list read —
|
|
153
|
+
* no per-frame point read (mirrors the visual-pipeline gate).
|
|
154
|
+
*/
|
|
155
|
+
frontendOriginsInput(workspaceId: string, serviceFrameId: string): Promise<string>;
|
|
156
|
+
/**
|
|
157
|
+
* Turn a provisioned environment handle into the `deployer` step's advance result: a `failed`
|
|
158
|
+
* env is surfaced as a displayed step failure (its `lastError` renders in the Environment
|
|
159
|
+
* panel); otherwise the env summary (status / URL / provision type / engine) is recorded as the
|
|
160
|
+
* step output. Shared by the synchronous and async-finalized provision paths.
|
|
161
|
+
*/
|
|
162
|
+
private completeDeployerStep;
|
|
163
|
+
/**
|
|
164
|
+
* Resolve the SERVICE frame's declared provisioning for a run block. The run may target a
|
|
165
|
+
* task/module nested under the frame, so walk up to the frame (mirrors the blueprint /
|
|
166
|
+
* tester-gate resolution) and read its `provisioning`. Returns null when undeclared.
|
|
167
|
+
*/
|
|
168
|
+
private resolveServiceProvisioning;
|
|
169
|
+
/**
|
|
170
|
+
* Stamp the errored environment onto the deployer step (so its details show the verbatim
|
|
171
|
+
* `lastError`), persist + emit, then return a structured `environment` failure carrying the
|
|
172
|
+
* provider's message as the detail. Mirrors `handleAgentStep`'s dispatch-failure path.
|
|
173
|
+
*/
|
|
174
|
+
private failDeployerStep;
|
|
175
|
+
/** Provision inputs (`{{input.*}}`) derived from the block under deployment. */
|
|
176
|
+
deployInputs(block: Block): Record<string, string>;
|
|
177
|
+
/**
|
|
178
|
+
* Typed git/PR/repo context for the deployer, derived from the block's PR ref. A
|
|
179
|
+
* PR-environment provider (e.g. an in-house adapter) needs the branch/repo to target
|
|
180
|
+
* the right environment; the same values are also flattened into `{{input.*}}` for
|
|
181
|
+
* the manifest path. `owner`/`repo` are parsed from the PR url when present.
|
|
182
|
+
*/
|
|
183
|
+
deployContext(block: Block): ProvisionContext;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=DeployerStepController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeployerStepController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/DeployerStepController.ts"],"names":[],"mappings":"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"}
|