@cat-factory/server 0.325.1 → 0.326.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/CompositeAgentExecutor.d.ts +22 -3
- package/dist/agents/CompositeAgentExecutor.d.ts.map +1 -1
- package/dist/agents/CompositeAgentExecutor.js +91 -5
- package/dist/agents/CompositeAgentExecutor.js.map +1 -1
- package/dist/agents/DelegatedAgentExecutor.d.ts +147 -0
- package/dist/agents/DelegatedAgentExecutor.d.ts.map +1 -0
- package/dist/agents/DelegatedAgentExecutor.js +537 -0
- package/dist/agents/DelegatedAgentExecutor.js.map +1 -0
- package/dist/agents/brief.d.ts +61 -0
- package/dist/agents/brief.d.ts.map +1 -0
- package/dist/agents/brief.js +94 -0
- package/dist/agents/brief.js.map +1 -0
- package/dist/agents/containerJobAddressing.d.ts +1 -20
- package/dist/agents/containerJobAddressing.d.ts.map +1 -1
- package/dist/agents/containerJobAddressing.js +5 -23
- package/dist/agents/containerJobAddressing.js.map +1 -1
- package/dist/agents/delegatedExecutorHost.d.ts +90 -0
- package/dist/agents/delegatedExecutorHost.d.ts.map +1 -0
- package/dist/agents/delegatedExecutorHost.js +124 -0
- package/dist/agents/delegatedExecutorHost.js.map +1 -0
- package/dist/agents/delegationCredentials.d.ts +20 -0
- package/dist/agents/delegationCredentials.d.ts.map +1 -0
- package/dist/agents/delegationCredentials.js +63 -0
- package/dist/agents/delegationCredentials.js.map +1 -0
- package/dist/agents/delegationWorkBranch.d.ts +31 -0
- package/dist/agents/delegationWorkBranch.d.ts.map +1 -0
- package/dist/agents/delegationWorkBranch.js +103 -0
- package/dist/agents/delegationWorkBranch.js.map +1 -0
- package/dist/agents/jobBody.d.ts.map +1 -1
- package/dist/agents/jobBody.js +8 -9
- package/dist/agents/jobBody.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js.map +1 -1
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -1
- package/dist/modules/workspaces/WorkspaceController.js +42 -1
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -1
- package/package.json +14 -14
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import { ConflictError, UnavailableError, describeError, getErrorMessage, stepJobId, } from '@cat-factory/kernel';
|
|
2
|
+
import { delegatedExecutorFor } from '@cat-factory/agents';
|
|
3
|
+
import { resolveAprioriWorkingBranch } from '@cat-factory/contracts';
|
|
4
|
+
import { composeDelegationBrief, briefRepoProvider } from './brief.js';
|
|
5
|
+
import { ensureDelegatedWorkBranch } from './delegationWorkBranch.js';
|
|
6
|
+
import { recordAgentContextSnapshot } from './agentContextRecord.js';
|
|
7
|
+
import { resolveDelegationCredentials } from './delegationCredentials.js';
|
|
8
|
+
/**
|
|
9
|
+
* Runs a `delegated`-surface step on a registered external executor.
|
|
10
|
+
*
|
|
11
|
+
* Async by construction: an external run is polled, never awaited, which is the same shape the
|
|
12
|
+
* container executor has and the reason both durable drivers already know how to drive it.
|
|
13
|
+
*/
|
|
14
|
+
export class DelegatedAgentExecutor {
|
|
15
|
+
deps;
|
|
16
|
+
log;
|
|
17
|
+
/**
|
|
18
|
+
* Built executors, memoised per id for the life of this instance.
|
|
19
|
+
*
|
|
20
|
+
* A definition's `create` may build a client, and this executor is constructed once per app
|
|
21
|
+
* (per isolate on the Worker), so building per dispatch would discard whatever an executor
|
|
22
|
+
* warmed. Memoising on the INSTANCE rather than a module map is what keeps it out of the
|
|
23
|
+
* module-global trap every registry in this codebase is built to avoid.
|
|
24
|
+
*/
|
|
25
|
+
built = new Map();
|
|
26
|
+
constructor(deps) {
|
|
27
|
+
this.deps = deps;
|
|
28
|
+
this.log = deps.logger.child({ component: 'delegatedAgent' });
|
|
29
|
+
}
|
|
30
|
+
/** Every delegated step is polled: an external run outlives any request of ours. */
|
|
31
|
+
runsAsync(_context) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A delegated step resolves NO model, and that is the honest answer rather than a gap.
|
|
36
|
+
*
|
|
37
|
+
* The external executor picks its own, through its own credentials, and the platform never sees
|
|
38
|
+
* it. Returning a guess would put a model on the board that nothing ran, and every reader
|
|
39
|
+
* downstream (the run card, the spend rollup, the debug overview) would treat it as the thing
|
|
40
|
+
* that spent the tokens it also cannot see.
|
|
41
|
+
*/
|
|
42
|
+
resolveModel(_context) {
|
|
43
|
+
return Promise.resolve(undefined);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Not quota-based. A delegated run spends nothing of OURS: no pooled subscription token is
|
|
47
|
+
* leased and no proxy call is metered, so it is neither quota nor budget.
|
|
48
|
+
*/
|
|
49
|
+
isQuotaBased(_context) {
|
|
50
|
+
return Promise.resolve(false);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Start (or RE-ATTACH to) this step's external work.
|
|
54
|
+
*
|
|
55
|
+
* Idempotent per correlation key, which is what the port asks of every executor and what the
|
|
56
|
+
* engine's claim-before-effect makes possible on this side: the key is derived from the run, the
|
|
57
|
+
* kind and the dispatch epoch, so a replayed dispatch produces the same key and the executor is
|
|
58
|
+
* asked to recognise its own run rather than start another.
|
|
59
|
+
*/
|
|
60
|
+
async startJob(context) {
|
|
61
|
+
const { workspaceId, executionId, blockId } = requireIds(context);
|
|
62
|
+
const definition = this.requireDefinition(context.agentKind);
|
|
63
|
+
const executor = this.executorFor(definition);
|
|
64
|
+
const correlationKey = stepJobId(executionId, context.agentKind, context.dispatchEpoch);
|
|
65
|
+
const { brief, aprioriWork } = await this.composeBrief(context, {
|
|
66
|
+
workspaceId,
|
|
67
|
+
executionId,
|
|
68
|
+
blockId,
|
|
69
|
+
correlationKey,
|
|
70
|
+
});
|
|
71
|
+
const jobLog = this.log.child({
|
|
72
|
+
workspaceId,
|
|
73
|
+
executionId,
|
|
74
|
+
jobId: correlationKey,
|
|
75
|
+
agentKind: context.agentKind,
|
|
76
|
+
executor: definition.id,
|
|
77
|
+
});
|
|
78
|
+
const credentials = await resolveDelegationCredentials({
|
|
79
|
+
definition,
|
|
80
|
+
workspaceId,
|
|
81
|
+
blockId,
|
|
82
|
+
resolveToolSecrets: this.deps.resolveToolSecrets,
|
|
83
|
+
logger: jobLog,
|
|
84
|
+
});
|
|
85
|
+
// After everything the platform can refuse on its own (the repo, the brief, the credentials),
|
|
86
|
+
// so a step that was never going to dispatch leaves no ref behind. It cannot move later: a CI
|
|
87
|
+
// system handed a branch that is not there fails at checkout rather than reporting anything
|
|
88
|
+
// this platform can act on, so `start` must find it already made. What that ordering does NOT
|
|
89
|
+
// buy is a ref-free failure INSIDE the dispatch; a create followed by an executor that refuses
|
|
90
|
+
// leaves the branch, and the next attempt re-uses it.
|
|
91
|
+
await this.prepareWorkBranch(definition, brief, aprioriWork, jobLog);
|
|
92
|
+
let started;
|
|
93
|
+
try {
|
|
94
|
+
started = await executor.start(brief, credentials);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
jobLog.warn('delegated executor refused the dispatch', describeError(error));
|
|
98
|
+
throw new UnavailableError(`The "${definition.id}" executor could not start this step: ${getErrorMessage(error)}`, 'delegated_executor_failed', { executor: definition.id });
|
|
99
|
+
}
|
|
100
|
+
if (!started.externalId) {
|
|
101
|
+
// Refused rather than recorded, because a dispatch with no external id can never be polled:
|
|
102
|
+
// the step would park on a job nothing can settle and fail hours later on its poll budget,
|
|
103
|
+
// naming a timeout instead of the contract the executor broke.
|
|
104
|
+
throw new UnavailableError(`The "${definition.id}" executor started this step and returned no external id, so the ` +
|
|
105
|
+
'platform has nothing to poll. An executor whose system reports no id at start is ' +
|
|
106
|
+
"expected to recover one by the brief's correlation key before returning.", 'delegated_executor_failed', { executor: definition.id });
|
|
107
|
+
}
|
|
108
|
+
jobLog.info('delegated work started', {
|
|
109
|
+
externalId: started.externalId,
|
|
110
|
+
...(started.url ? { externalUrl: started.url } : {}),
|
|
111
|
+
});
|
|
112
|
+
// The same snapshot a container dispatch files, from the same allow-list: what the agent was
|
|
113
|
+
// told is auditable through `/api/v1/debug/runs/:runId/agent-context` whoever ran it. The
|
|
114
|
+
// credentials resolved above are deliberately not in scope of the body handed to it.
|
|
115
|
+
await recordAgentContextSnapshot(this.deps.agentContextObservability, jobLog, {
|
|
116
|
+
context,
|
|
117
|
+
body: snapshotBody(brief),
|
|
118
|
+
// There is no model to name: the executor chose one we never saw. Naming the EXECUTOR under
|
|
119
|
+
// a provider of `delegated` says exactly that, where a blank would read as a dispatch that
|
|
120
|
+
// resolved nothing and a borrowed default would name a model that ran nowhere.
|
|
121
|
+
model: `delegated:${definition.id}`,
|
|
122
|
+
workspaceId,
|
|
123
|
+
executionId,
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
jobId: correlationKey,
|
|
127
|
+
runId: executionId,
|
|
128
|
+
workspaceId,
|
|
129
|
+
// The block, so the POLL resolves this executor's credentials in the scope the dispatch
|
|
130
|
+
// did. The engine re-supplies it from the run, but a handle that answers for itself is
|
|
131
|
+
// what keeps a non-durable caller (`run()`'s own drive, a test) on the same path.
|
|
132
|
+
blockId,
|
|
133
|
+
agentKind: context.agentKind,
|
|
134
|
+
...(context.initiatedByUserId ? { initiatedByUserId: context.initiatedByUserId } : {}),
|
|
135
|
+
repo: {
|
|
136
|
+
owner: brief.repo.owner,
|
|
137
|
+
name: brief.repo.name,
|
|
138
|
+
baseBranch: brief.branches.base,
|
|
139
|
+
provider: brief.repo.provider,
|
|
140
|
+
},
|
|
141
|
+
delegated: {
|
|
142
|
+
executor: definition.id,
|
|
143
|
+
externalId: started.externalId,
|
|
144
|
+
...(started.url ? { url: started.url } : {}),
|
|
145
|
+
// What a later poll cannot derive: a handle carries the run, and the work branch is named
|
|
146
|
+
// from the BLOCK. An executor reading back what its own system produced needs it, and
|
|
147
|
+
// guessing puts the wrong pull request on the block.
|
|
148
|
+
branches: brief.branches,
|
|
149
|
+
// The repo the WORK targets, for the same reason and with a sharper edge: it is routinely
|
|
150
|
+
// not the repo the executor's own job lives in (an automation repo dispatching against many
|
|
151
|
+
// product repos is the ordinary shape), so an executor reading back what it produced from
|
|
152
|
+
// its OWN configured repository finds nothing on every such deployment.
|
|
153
|
+
repo: { owner: brief.repo.owner, name: brief.repo.name },
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Poll the external work, re-resolving the executor's credentials FIRST.
|
|
159
|
+
*
|
|
160
|
+
* Re-resolved rather than carried on the handle, and that is not a caching miss: a delegated
|
|
161
|
+
* poll can run hours after the dispatch, a GitHub App token lives one hour, and a credential
|
|
162
|
+
* frozen at dispatch would be dead exactly on the long runs this executor class exists for.
|
|
163
|
+
*/
|
|
164
|
+
async pollJob(handle) {
|
|
165
|
+
const delegated = handle.delegated;
|
|
166
|
+
if (!delegated) {
|
|
167
|
+
throw new ConflictError('A delegated poll arrived with no delegation on its handle, so there is nothing to ' +
|
|
168
|
+
'address. The step records which executor it dispatched to; a handle without it was ' +
|
|
169
|
+
'rebuilt from a step that never claimed one.',
|
|
170
|
+
// The fault is in THIS RUN's state, not in what the deployment registers, so it does not
|
|
171
|
+
// borrow `delegated_executor_unwired`: that copy would send an operator to inspect a
|
|
172
|
+
// registration with nothing wrong in it.
|
|
173
|
+
'delegated_claim_missing');
|
|
174
|
+
}
|
|
175
|
+
const scope = requireHandleScope(handle);
|
|
176
|
+
const definition = this.requireDefinition(scope.agentKind, delegated.executor);
|
|
177
|
+
const executor = this.executorFor(definition);
|
|
178
|
+
const jobLog = this.log.child({
|
|
179
|
+
workspaceId: scope.workspaceId,
|
|
180
|
+
executionId: scope.runId,
|
|
181
|
+
jobId: handle.jobId,
|
|
182
|
+
agentKind: scope.agentKind,
|
|
183
|
+
executor: definition.id,
|
|
184
|
+
});
|
|
185
|
+
const target = {
|
|
186
|
+
executor: definition.id,
|
|
187
|
+
correlationKey: handle.jobId,
|
|
188
|
+
externalId: delegated.externalId,
|
|
189
|
+
...(delegated.url ? { url: delegated.url } : {}),
|
|
190
|
+
...(delegated.branches ? { branches: delegated.branches } : {}),
|
|
191
|
+
...(delegated.repo ? { repo: delegated.repo } : {}),
|
|
192
|
+
...scope,
|
|
193
|
+
};
|
|
194
|
+
const credentials = await resolveDelegationCredentials({
|
|
195
|
+
definition,
|
|
196
|
+
workspaceId: scope.workspaceId,
|
|
197
|
+
// The SAME scope the dispatch resolved in. Dropped here, a deployment whose credential
|
|
198
|
+
// store is per service resolves an empty bag on every poll of a run it started perfectly
|
|
199
|
+
// well, and the step dies on an unreadable status while the external work carries on.
|
|
200
|
+
blockId: scope.blockId,
|
|
201
|
+
resolveToolSecrets: this.deps.resolveToolSecrets,
|
|
202
|
+
logger: jobLog,
|
|
203
|
+
});
|
|
204
|
+
const update = await executor.poll(target, credentials);
|
|
205
|
+
return toJobUpdate(update, definition, this.deps.clock.now());
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Stop every delegated unit this run holds, and REPORT what that achieved.
|
|
209
|
+
*
|
|
210
|
+
* The report is the point. An executor that declares no `cancel` leaves its run alive: it will
|
|
211
|
+
* finish, open its pull request and bill its tokens long after the platform recorded this run as
|
|
212
|
+
* stopped, and the person who stopped it is the one who needs to know to go and stop it there.
|
|
213
|
+
* Best-effort throughout (a teardown must never propagate) but never SILENT: a failure to
|
|
214
|
+
* cancel is reported as "not cancelled" with its cause, which is a different fact from a clean
|
|
215
|
+
* stop and renders differently on the step.
|
|
216
|
+
*/
|
|
217
|
+
async reclaimRun(target) {
|
|
218
|
+
const handles = target.delegations ?? [];
|
|
219
|
+
if (handles.length === 0)
|
|
220
|
+
return;
|
|
221
|
+
const delegations = await Promise.all(handles.map((handle) => this.cancelOne(handle)));
|
|
222
|
+
return { delegations };
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* A delegated step cannot be run SYNCHRONOUSLY: `run()` exists for non-durable callers and
|
|
226
|
+
* tests, and an external system that answers in hours is exactly what that shape cannot serve.
|
|
227
|
+
* Refused loudly rather than looped in-process, which would hold a request open for the duration
|
|
228
|
+
* of somebody else's CI.
|
|
229
|
+
*/
|
|
230
|
+
run(context) {
|
|
231
|
+
return Promise.reject(new ConflictError(`The \`${context.agentKind}\` step runs on an external executor, which is polled rather ` +
|
|
232
|
+
'than awaited. Drive it through the async path (`startJob` / `pollJob`).',
|
|
233
|
+
// NOT `delegated_executor_unwired`: the executor here is registered and correct, and that
|
|
234
|
+
// reason's copy tells an operator to go and register it. What is wrong is the drive path
|
|
235
|
+
// the caller chose.
|
|
236
|
+
'delegated_step_async_only'));
|
|
237
|
+
}
|
|
238
|
+
async cancelOne(handle) {
|
|
239
|
+
const definition = this.deps.delegatedExecutorRegistry.get(handle.executor);
|
|
240
|
+
if (!definition) {
|
|
241
|
+
return {
|
|
242
|
+
correlationKey: handle.correlationKey,
|
|
243
|
+
cancelled: false,
|
|
244
|
+
note: `This deployment no longer registers the "${handle.executor}" executor, so the external work could not be stopped.`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const executor = this.executorFor(definition);
|
|
248
|
+
if (!executor.cancel) {
|
|
249
|
+
return {
|
|
250
|
+
correlationKey: handle.correlationKey,
|
|
251
|
+
cancelled: false,
|
|
252
|
+
note: `The "${definition.id}" executor declares no cancel, so the external work was left running.`,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const jobLog = this.log.child({
|
|
256
|
+
workspaceId: handle.workspaceId,
|
|
257
|
+
executionId: handle.runId,
|
|
258
|
+
jobId: handle.correlationKey,
|
|
259
|
+
executor: definition.id,
|
|
260
|
+
});
|
|
261
|
+
try {
|
|
262
|
+
const credentials = await resolveDelegationCredentials({
|
|
263
|
+
definition,
|
|
264
|
+
workspaceId: handle.workspaceId,
|
|
265
|
+
// Scoped like the dispatch and the poll: a cancel resolving an empty bag reports work as
|
|
266
|
+
// possibly-still-running that this executor could have stopped.
|
|
267
|
+
blockId: handle.blockId,
|
|
268
|
+
resolveToolSecrets: this.deps.resolveToolSecrets,
|
|
269
|
+
logger: jobLog,
|
|
270
|
+
});
|
|
271
|
+
await executor.cancel(handle, credentials);
|
|
272
|
+
return { correlationKey: handle.correlationKey, cancelled: true };
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
jobLog.warn('delegated cancel failed; the external work may still be running', {
|
|
276
|
+
...describeError(error),
|
|
277
|
+
});
|
|
278
|
+
return {
|
|
279
|
+
correlationKey: handle.correlationKey,
|
|
280
|
+
cancelled: false,
|
|
281
|
+
note: `Stopping the external work failed (${getErrorMessage(error)}); it may still be running.`,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** The registered definition for a kind, refusing the two ways it can be missing. */
|
|
286
|
+
requireDefinition(agentKind, knownExecutor) {
|
|
287
|
+
const id = knownExecutor ?? delegatedExecutorFor(agentKind, this.deps.agentKindRegistry);
|
|
288
|
+
if (!id) {
|
|
289
|
+
throw new ConflictError(`The \`${agentKind}\` step was routed to the delegated executor and declares none.`, 'delegated_executor_unwired');
|
|
290
|
+
}
|
|
291
|
+
const definition = this.deps.delegatedExecutorRegistry.get(id);
|
|
292
|
+
if (!definition) {
|
|
293
|
+
throw new ConflictError(`The \`${agentKind}\` step runs on the delegated executor "${id}", which this ` +
|
|
294
|
+
`deployment does not register` +
|
|
295
|
+
(this.deps.delegatedExecutorRegistry.size > 0
|
|
296
|
+
? ` (registered: ${this.deps.delegatedExecutorRegistry.ids().join(', ')}).`
|
|
297
|
+
: '.'), 'delegated_executor_unwired');
|
|
298
|
+
}
|
|
299
|
+
return definition;
|
|
300
|
+
}
|
|
301
|
+
executorFor(definition) {
|
|
302
|
+
const existing = this.built.get(definition.id);
|
|
303
|
+
if (existing)
|
|
304
|
+
return existing;
|
|
305
|
+
const built = definition.create(this.deps.executorDeps);
|
|
306
|
+
this.built.set(definition.id, built);
|
|
307
|
+
return built;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Honour the executor's {@link DelegatedExecutorDefinition.workBranch} declaration.
|
|
311
|
+
*
|
|
312
|
+
* `executor-creates` writes nothing and probes nothing, which is what keeps a run whose external
|
|
313
|
+
* work never landed from leaving an empty ref behind.
|
|
314
|
+
*/
|
|
315
|
+
async prepareWorkBranch(definition, brief, aprioriWork, jobLog) {
|
|
316
|
+
if (definition.workBranch !== 'platform-creates')
|
|
317
|
+
return;
|
|
318
|
+
await ensureDelegatedWorkBranch({ resolveRepoFiles: this.deps.resolveRepoFiles, logger: jobLog }, brief, { executorId: definition.id, apriori: aprioriWork });
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Resolve the repo + branches this dispatch targets, then compose the brief over them.
|
|
322
|
+
*
|
|
323
|
+
* `aprioriWork` rides back out because the brief carries the branch NAME and not who is allowed
|
|
324
|
+
* to create it, and only this method knows which of the two answers produced the name.
|
|
325
|
+
*/
|
|
326
|
+
async composeBrief(context, ids) {
|
|
327
|
+
const repo = await this.deps.resolveRepoTarget(ids.workspaceId, ids.blockId);
|
|
328
|
+
if (!repo) {
|
|
329
|
+
throw new ConflictError(`No connected repository found for workspace '${ids.workspaceId}'. A delegated step is ` +
|
|
330
|
+
'still work on a repository: link one to this service before running it.', 'github_not_connected');
|
|
331
|
+
}
|
|
332
|
+
const origin = this.deps.resolveRepoOrigin(repo);
|
|
333
|
+
const trackerRef = await this.resolveTrackerRef(ids.workspaceId, ids.blockId);
|
|
334
|
+
// The task's own WORKING branch when it declared one, through the shared rule the container
|
|
335
|
+
// dispatch and the repo-ops controller resolve it with, so the three cannot drift on which
|
|
336
|
+
// branch a run builds inside (it also refuses a working branch equal to the base). Delegating
|
|
337
|
+
// the step changes nothing about that choice: the pull request, the `ci` gate and the merger
|
|
338
|
+
// all ride the branch the task named, so a dispatch onto `cat-factory/<blockId>` instead would
|
|
339
|
+
// land the external work on a ref nothing downstream looks at.
|
|
340
|
+
const aprioriWork = resolveAprioriWorkingBranch(context.aprioriBranches, repo.baseBranch);
|
|
341
|
+
const brief = composeDelegationBrief(context, this.deps.agentKindRegistry, {
|
|
342
|
+
correlationKey: ids.correlationKey,
|
|
343
|
+
workspaceId: ids.workspaceId,
|
|
344
|
+
blockId: ids.blockId,
|
|
345
|
+
runId: ids.executionId,
|
|
346
|
+
stepIndex: context.stepIndex ?? 0,
|
|
347
|
+
target: {
|
|
348
|
+
repo: {
|
|
349
|
+
owner: repo.owner,
|
|
350
|
+
name: repo.name,
|
|
351
|
+
cloneUrl: origin.cloneUrl,
|
|
352
|
+
provider: briefRepoProvider(repo.provider ?? origin.provider),
|
|
353
|
+
...(repo.serviceDirectory ? { directory: repo.serviceDirectory } : {}),
|
|
354
|
+
},
|
|
355
|
+
branches: {
|
|
356
|
+
base: repo.baseBranch,
|
|
357
|
+
// The task's declared working branch, else the deterministic per-task branch every step
|
|
358
|
+
// of this run's pipeline shares: the same name the container path resolves, so a
|
|
359
|
+
// delegated producer and a later container fixer work on ONE branch. Whether the REF
|
|
360
|
+
// exists when the executor is called is its own `workBranch` declaration, honoured just
|
|
361
|
+
// before `start`.
|
|
362
|
+
work: aprioriWork ?? `cat-factory/${ids.blockId}`,
|
|
363
|
+
},
|
|
364
|
+
...(trackerRef ? { trackerRef } : {}),
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
return { brief, aprioriWork: aprioriWork !== undefined };
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Where the work came from, when it came from a tracker: ONE batch read of the block's linked
|
|
371
|
+
* issues, and the first live one.
|
|
372
|
+
*
|
|
373
|
+
* First rather than all, because the brief names the ticket the work is FOR and a block carries
|
|
374
|
+
* one such link by construction (`claimBlockLink` makes "one task per ticket" an invariant). Any
|
|
375
|
+
* further attachments are reference material, and they already reach the agent as context files.
|
|
376
|
+
*/
|
|
377
|
+
async resolveTrackerRef(workspaceId, blockId) {
|
|
378
|
+
const repository = this.deps.taskRepository;
|
|
379
|
+
if (!repository)
|
|
380
|
+
return undefined;
|
|
381
|
+
const linked = await repository.listByBlock(workspaceId, blockId);
|
|
382
|
+
const first = linked[0];
|
|
383
|
+
if (!first)
|
|
384
|
+
return undefined;
|
|
385
|
+
return {
|
|
386
|
+
provider: first.source,
|
|
387
|
+
key: first.externalId,
|
|
388
|
+
...(first.url ? { url: first.url } : {}),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* The four run facts a poll addresses by, refused rather than defaulted when the handle carries
|
|
394
|
+
* none.
|
|
395
|
+
*
|
|
396
|
+
* They are optional on {@link AgentJobHandle} because the container executor does not need them
|
|
397
|
+
* all, and REQUIRED on {@link DelegationHandle} because a delegated call does. Filling the gap
|
|
398
|
+
* with `''` is what makes that requirement a lie, and every consequence of it is silent:
|
|
399
|
+
* credentials resolved without the block come back empty on a per-service store, so a poll of a
|
|
400
|
+
* perfectly healthy external run cannot read its status and the step dies hours later reporting a
|
|
401
|
+
* timeout; and a deployment whose executor picks which workflow to address from the scope it is
|
|
402
|
+
* handed (its repository, its agent kind) would dispatch against one and then poll another,
|
|
403
|
+
* reporting a live run as one that never appeared. The engine supplies all four at the one place
|
|
404
|
+
* a handle is rebuilt (`pollHandleFor`), so an absent one is a new call site rather than a state a
|
|
405
|
+
* deployment can reach.
|
|
406
|
+
*/
|
|
407
|
+
function requireHandleScope(handle) {
|
|
408
|
+
const { workspaceId, blockId, runId, agentKind } = handle;
|
|
409
|
+
if (!workspaceId || !blockId || !runId || !agentKind) {
|
|
410
|
+
throw new ConflictError('A delegated poll arrived with an incomplete handle (it needs the workspace, the block, ' +
|
|
411
|
+
'the run and the agent kind), so neither the credentials this executor declares nor the ' +
|
|
412
|
+
'external work it addresses can be resolved in the scope its dispatch used. The engine ' +
|
|
413
|
+
'supplies all four from the run; a handle without them was built somewhere that does not.', 'delegated_claim_missing', { missing: missingScopeFields(handle) });
|
|
414
|
+
}
|
|
415
|
+
return { workspaceId, blockId, runId, agentKind };
|
|
416
|
+
}
|
|
417
|
+
/** Which of the four a handle was short, so the refusal names the call site's actual gap. */
|
|
418
|
+
function missingScopeFields(handle) {
|
|
419
|
+
return ['workspaceId', 'blockId', 'runId', 'agentKind'].filter((field) => !handle[field]);
|
|
420
|
+
}
|
|
421
|
+
/** The delegated dispatch's ids, refused together so a caller cannot proceed on half of them. */
|
|
422
|
+
function requireIds(context) {
|
|
423
|
+
const { workspaceId, executionId } = context;
|
|
424
|
+
const blockId = context.block.id;
|
|
425
|
+
if (!workspaceId || !executionId || !blockId) {
|
|
426
|
+
throw new Error('DelegatedAgentExecutor requires workspaceId, executionId and block.id');
|
|
427
|
+
}
|
|
428
|
+
return { workspaceId, executionId, blockId };
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* The brief, shaped as the agent-context snapshot's allow-list reads it.
|
|
432
|
+
*
|
|
433
|
+
* It reuses that allow-list rather than adding a second projection, because the rule it enforces
|
|
434
|
+
* (copy the prompts, the fragment bodies and the context files; never a credential) is exactly as
|
|
435
|
+
* binding here. `mode: 'delegated'` is what tells a reader of the snapshot that no container ran.
|
|
436
|
+
*/
|
|
437
|
+
function snapshotBody(brief) {
|
|
438
|
+
return {
|
|
439
|
+
mode: 'delegated',
|
|
440
|
+
systemPrompt: brief.systemPrompt,
|
|
441
|
+
userPrompt: brief.userPrompt,
|
|
442
|
+
contextFiles: brief.contextFiles,
|
|
443
|
+
repo: { owner: brief.repo.owner, name: brief.repo.name, baseBranch: brief.branches.base },
|
|
444
|
+
branch: brief.branches.work,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Map an executor's own answer into the engine's poll vocabulary.
|
|
449
|
+
*
|
|
450
|
+
* The four places this is NOT a rename:
|
|
451
|
+
*
|
|
452
|
+
* - `retryable` decides whether a failure is re-driven on the job-failure budget or is terminal.
|
|
453
|
+
* An executor that says nothing means TERMINAL, because a verdict its own system called final is
|
|
454
|
+
* not something a second dispatch improves on, and the alternative spends the budget re-running
|
|
455
|
+
* somebody else's CI to reach the same answer. It travels on the DELEGATED channel, under a name
|
|
456
|
+
* that describes a delegated step, never on the container path's `harnessShutdown`.
|
|
457
|
+
* - `usage` rides straight through, and its ABSENCE is the honest state for an executor that does
|
|
458
|
+
* not report it. Nothing here invents a zero: a zero would be summed into the run's total and
|
|
459
|
+
* read as work that cost nothing.
|
|
460
|
+
* - `externalId` and `url` are the two facts a poll can LEARN, for a system that answers its
|
|
461
|
+
* dispatch with neither (`workflow_dispatch` replies 204). Carried back so the record stops
|
|
462
|
+
* addressing the run by the correlation key: left uncarried, every later poll re-ran the bounded
|
|
463
|
+
* scan that recovered it, and on a busy repository the run scrolls off that page mid-flight and
|
|
464
|
+
* a live external run reads as one that never appeared.
|
|
465
|
+
* - `lastActivityAt` gains a FLOOR the executor did not report, because the poll itself is the
|
|
466
|
+
* evidence. This is the one field where "the executor said nothing" and "nothing is happening"
|
|
467
|
+
* are different facts and only one of them is true.
|
|
468
|
+
* - `branch` is carried rather than dropped: it is the entire product of an executor that pushes
|
|
469
|
+
* without opening a pull request, a case the port names as legitimate.
|
|
470
|
+
*
|
|
471
|
+
* `polledAt` is a parameter rather than a captured clock so this stays a pure mapping the tests can
|
|
472
|
+
* drive at a fixed instant.
|
|
473
|
+
*/
|
|
474
|
+
function toJobUpdate(update, definition, polledAt) {
|
|
475
|
+
if (update.state === 'running') {
|
|
476
|
+
const learned = {
|
|
477
|
+
...(update.externalId ? { externalId: update.externalId } : {}),
|
|
478
|
+
...(update.url ? { url: update.url } : {}),
|
|
479
|
+
};
|
|
480
|
+
return {
|
|
481
|
+
state: 'running',
|
|
482
|
+
...(update.phase ? { phase: update.phase } : {}),
|
|
483
|
+
// A successful poll IS the sign of life, so the poll's own clock is the floor when the
|
|
484
|
+
// executor reports no timestamp of its own. Without it a long, quiet external run (an Actions
|
|
485
|
+
// run sitting at `in_progress` reports an identical answer every time) folds no change at all,
|
|
486
|
+
// nothing persists, the step's `lastActivityAt` and the run's `updated_at` freeze at the first
|
|
487
|
+
// poll, and the stale-run sweeper re-collects a run that is perfectly alive. The engine's
|
|
488
|
+
// existing throttle decides how often that actually lands.
|
|
489
|
+
lastActivityAt: update.lastActivityAt ?? polledAt,
|
|
490
|
+
...(Object.keys(learned).length > 0 ? { delegated: learned } : {}),
|
|
491
|
+
// The executor's own name, so the run diagnostics say where the step ran rather than
|
|
492
|
+
// reporting the container backend a delegated step never had.
|
|
493
|
+
backend: `delegated:${definition.id}`,
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
if (update.state === 'failed') {
|
|
497
|
+
// A NON-retryable failure is TERMINAL: the driver must not spend a recovery budget re-running
|
|
498
|
+
// somebody else's CI to reach the verdict it already reached. A retryable one buys exactly one
|
|
499
|
+
// fresh dispatch (`MAX_DELEGATED_RETRIES`). Reported on the DELEGATED channel rather than as
|
|
500
|
+
// `harnessShutdown`, which is the container path's signal for the same disposition under a
|
|
501
|
+
// name that misdescribes this one: a delegated step never had a harness, and the operator was
|
|
502
|
+
// shown "Harness shut down" for an external workflow that simply failed.
|
|
503
|
+
return {
|
|
504
|
+
state: 'failed',
|
|
505
|
+
error: update.error,
|
|
506
|
+
...(update.detail ? { detail: update.detail } : {}),
|
|
507
|
+
delegated: {
|
|
508
|
+
...(update.url ? { url: update.url } : {}),
|
|
509
|
+
// Stated on every delegated failure, both ways round. Read as "absent means retryable"
|
|
510
|
+
// the engine had one flag with an unstated default and no re-drive behind it, so an
|
|
511
|
+
// executor's `retryable: true` was silently the same as a final verdict.
|
|
512
|
+
disposition: update.retryable === true ? 'retryable' : 'terminal',
|
|
513
|
+
},
|
|
514
|
+
backend: `delegated:${definition.id}`,
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
const result = update.result;
|
|
518
|
+
return {
|
|
519
|
+
state: 'done',
|
|
520
|
+
result: {
|
|
521
|
+
output: result.summary,
|
|
522
|
+
...(result.pullRequest ? { pullRequest: result.pullRequest } : {}),
|
|
523
|
+
...(result.custom !== undefined ? { custom: result.custom } : {}),
|
|
524
|
+
// Tagged `subscription`, never `metered`. The tokens were spent on the EXECUTOR's own
|
|
525
|
+
// account, so counting them against this workspace's budget would pause runs over money the
|
|
526
|
+
// platform did not spend. `subscription` is the disposition that already means exactly this:
|
|
527
|
+
// recorded for the usage report, excluded from every spend rollup.
|
|
528
|
+
...(result.usage ? { usage: result.usage, usageBilling: 'subscription' } : {}),
|
|
529
|
+
},
|
|
530
|
+
// The branch the work LANDED on, when the executor pushed without opening a pull request. The
|
|
531
|
+
// port names that case as legitimate, and the engine settles it onto the delegation record:
|
|
532
|
+
// dropped here, such a run reports done with no product anywhere, which reads exactly like a
|
|
533
|
+
// run that produced nothing.
|
|
534
|
+
...(result.branch ? { delegated: { branch: result.branch } } : {}),
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
//# sourceMappingURL=DelegatedAgentExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelegatedAgentExecutor.js","sourceRoot":"","sources":["../../src/agents/DelegatedAgentExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AgentDispatchContext, AgentRunContext, DelegationBrief, InjectedContextFile, VcsProvider } from '@cat-factory/kernel';
|
|
2
|
+
import { type AgentKindRegistry } from '@cat-factory/agents';
|
|
3
|
+
/** The half of an agent's instructions that is the same whatever executes the step. */
|
|
4
|
+
export interface AgentBriefCore {
|
|
5
|
+
/**
|
|
6
|
+
* The role prompt with the workspace's override applied, the block's best-practice standards
|
|
7
|
+
* folded at this kind's verbosity, and its trait guidance. NOT the finished container system
|
|
8
|
+
* prompt: the container-dispatch directives, the follow-up sentinel, the skills fold and the
|
|
9
|
+
* tool-server section are layered onto this at the container chokepoint.
|
|
10
|
+
*/
|
|
11
|
+
roleSystemPrompt: string;
|
|
12
|
+
/** The generic block-context prompt (or the kind's own), with its wrappers already applied. */
|
|
13
|
+
userPrompt: string;
|
|
14
|
+
/** The `.cat-context/` files this dispatch was prepared with. */
|
|
15
|
+
contextFiles: InjectedContextFile[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Compose the executor-independent half of a dispatch's instructions.
|
|
19
|
+
*
|
|
20
|
+
* `dispatch` carries the resolved checkout facts for the kinds whose own prompt names a branch.
|
|
21
|
+
* Both callers have one (a delegated executor gets a checkout too: its own), which is the
|
|
22
|
+
* difference between this and an inline caller, and it is why the parameter is required here
|
|
23
|
+
* rather than optional as it is on `userPromptFor`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function composeAgentBriefCore(context: AgentRunContext, registry: AgentKindRegistry, dispatch: AgentDispatchContext): AgentBriefCore;
|
|
26
|
+
/**
|
|
27
|
+
* The role prompt for one dispatch: the workspace's override (or the shipped track prompt), the
|
|
28
|
+
* block's resolved standards at this kind's verbosity, and its trait guidance.
|
|
29
|
+
*
|
|
30
|
+
* Its own exported function because two dispatch paths must produce the identical string from one
|
|
31
|
+
* context. It is the piece a workspace actually EDITS, so a drift here is the failure that matters
|
|
32
|
+
* most: the standards a team agreed on reaching one executor and not the other, with nothing
|
|
33
|
+
* anywhere reporting it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function composeRoleSystemPrompt(context: AgentRunContext, registry: AgentKindRegistry): string;
|
|
36
|
+
/** The repo + branch facts a delegated dispatch resolved, as the brief names them. */
|
|
37
|
+
export interface DelegationBriefTarget {
|
|
38
|
+
repo: DelegationBrief['repo'];
|
|
39
|
+
branches: DelegationBrief['branches'];
|
|
40
|
+
/** Where the work came from, when it came from a tracker. */
|
|
41
|
+
trackerRef?: NonNullable<DelegationBrief['task']['trackerRef']>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build the {@link DelegationBrief} for one delegated dispatch.
|
|
45
|
+
*
|
|
46
|
+
* `ownService` is FILLED IN rather than forwarded optionally: the brief's contract is a
|
|
47
|
+
* discriminated result, and an omitted one reads to a model exactly like a task whose product is
|
|
48
|
+
* obvious. A context that carries none genuinely does not know which system the work belongs to,
|
|
49
|
+
* and `not-under-a-service` is what says so.
|
|
50
|
+
*/
|
|
51
|
+
export declare function composeDelegationBrief(context: AgentRunContext, registry: AgentKindRegistry, args: {
|
|
52
|
+
correlationKey: string;
|
|
53
|
+
workspaceId: string;
|
|
54
|
+
blockId: string;
|
|
55
|
+
runId: string;
|
|
56
|
+
stepIndex: number;
|
|
57
|
+
target: DelegationBriefTarget;
|
|
58
|
+
}): DelegationBrief;
|
|
59
|
+
/** Narrow a repo projection's stored provider to the union, defaulting to the pre-column value. */
|
|
60
|
+
export declare function briefRepoProvider(provider: VcsProvider | undefined): VcsProvider;
|
|
61
|
+
//# sourceMappingURL=brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../src/agents/brief.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,EAEnB,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,qBAAqB,CAAA;AAqB5B,uFAAuF;AACvF,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAA;IACxB,+FAA+F;IAC/F,UAAU,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,YAAY,EAAE,mBAAmB,EAAE,CAAA;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,oBAAoB,GAC7B,cAAc,CAYhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,MAAM,CAQR;AAED,sFAAsF;AACtF,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACrC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;CAChE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE;IACJ,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,qBAAqB,CAAA;CAC9B,GACA,eAAe,CAyCjB;AAOD,mGAAmG;AACnG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAEhF"}
|