@cat-factory/orchestration 0.190.0 → 0.191.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/container/dependencies.d.ts +1 -1
- package/dist/container/engine-dependent-modules.d.ts.map +1 -1
- package/dist/container/engine-dependent-modules.js +1 -1
- package/dist/container/engine-dependent-modules.js.map +1 -1
- package/dist/container/modules.d.ts +1 -1
- package/dist/container/modules.d.ts.map +1 -1
- package/dist/container/modules.js +26 -1
- package/dist/container/modules.js.map +1 -1
- package/dist/container.d.ts +1 -1
- package/dist/modules/execution/GateHelperDispatcher.js +1 -1
- package/dist/modules/execution/GateHelperDispatcher.js.map +1 -1
- package/dist/modules/execution/HumanTestController.js +1 -1
- package/dist/modules/execution/HumanTestController.js.map +1 -1
- package/dist/modules/execution/RalphController.js +1 -1
- package/dist/modules/execution/RalphController.js.map +1 -1
- package/dist/modules/execution/RunDispatcher.js +1 -1
- package/dist/modules/execution/RunDispatcher.js.map +1 -1
- package/dist/modules/execution/RunStateMachine.d.ts.map +1 -1
- package/dist/modules/execution/RunStateMachine.js +12 -0
- package/dist/modules/execution/RunStateMachine.js.map +1 -1
- package/dist/modules/execution/StepGraph.d.ts.map +1 -1
- package/dist/modules/execution/StepGraph.js +13 -1
- package/dist/modules/execution/StepGraph.js.map +1 -1
- package/dist/modules/execution/TesterController.js +2 -2
- package/dist/modules/execution/TesterController.js.map +1 -1
- package/dist/modules/execution/VisualConfirmationController.js +1 -1
- package/dist/modules/execution/VisualConfirmationController.js.map +1 -1
- package/dist/modules/execution/step-fold.logic.d.ts +11 -2
- package/dist/modules/execution/step-fold.logic.d.ts.map +1 -1
- package/dist/modules/execution/step-fold.logic.js +18 -2
- package/dist/modules/execution/step-fold.logic.js.map +1 -1
- package/dist/modules/observability/LlmObservabilityService.d.ts +22 -1
- package/dist/modules/observability/LlmObservabilityService.d.ts.map +1 -1
- package/dist/modules/observability/LlmObservabilityService.js +30 -0
- package/dist/modules/observability/LlmObservabilityService.js.map +1 -1
- package/dist/modules/observability/runTraceSpans.logic.d.ts +20 -0
- package/dist/modules/observability/runTraceSpans.logic.d.ts.map +1 -0
- package/dist/modules/observability/runTraceSpans.logic.js +127 -0
- package/dist/modules/observability/runTraceSpans.logic.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineService.d.ts +79 -14
- package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -1
- package/dist/modules/recurring/RecurringPipelineService.js +157 -24
- package/dist/modules/recurring/RecurringPipelineService.js.map +1 -1
- package/dist/modules/recurring/issueIntake.logic.d.ts +43 -0
- package/dist/modules/recurring/issueIntake.logic.d.ts.map +1 -0
- package/dist/modules/recurring/issueIntake.logic.js +69 -0
- package/dist/modules/recurring/issueIntake.logic.js.map +1 -0
- package/package.json +11 -11
|
@@ -10,7 +10,8 @@ import { shouldPersistActivity } from './job.logic.js';
|
|
|
10
10
|
// it and it is the exact counterpart the poll site reads back.
|
|
11
11
|
/**
|
|
12
12
|
* Persist the attribution a DISPATCH knows and the poll site cannot re-derive: the resolved
|
|
13
|
-
* model, plus (for a subscription-harness job) the leased pool row and the run's initiator
|
|
13
|
+
* model, plus (for a subscription-harness job) the leased pool row and the run's initiator,
|
|
14
|
+
* plus the agent kind the job actually ran AS.
|
|
14
15
|
*
|
|
15
16
|
* An async container job settles on the durable poll path, which rebuilds the job handle from
|
|
16
17
|
* the step alone — so anything not recorded here is lost by the time the usage lands. Dropping
|
|
@@ -18,14 +19,29 @@ import { shouldPersistActivity } from './job.logic.js';
|
|
|
18
19
|
* the other two silently skips the pooled-token usage feedback (usage-aware rotation) and leaves
|
|
19
20
|
* the quota-cycle counters with no target. Each field is written only when the handle carries it,
|
|
20
21
|
* so a re-dispatch that resolves less never erases what an earlier one knew.
|
|
22
|
+
*
|
|
23
|
+
* `dispatchedKind` is a REQUIRED parameter rather than something read off the step, because
|
|
24
|
+
* `step.agentKind` is routinely not what ran: a gate escalates to its helper, a Tester hands off
|
|
25
|
+
* to the fixer, a two-phase coder proposes forks first. Every telemetry row that job produces is
|
|
26
|
+
* tagged with the dispatched kind, so a consumer grouping by kind (the external trace's step
|
|
27
|
+
* spans) has nothing to attach to unless the run records it. Being a parameter is the point: a
|
|
28
|
+
* new dispatch site cannot compile without answering the question, which is the same reason this
|
|
29
|
+
* function exists at all.
|
|
21
30
|
*/
|
|
22
|
-
export function recordDispatchAttribution(step, handle) {
|
|
31
|
+
export function recordDispatchAttribution(step, handle, dispatchedKind) {
|
|
23
32
|
if (handle.model)
|
|
24
33
|
step.model = handle.model;
|
|
25
34
|
if (handle.subscriptionTokenId)
|
|
26
35
|
step.subscriptionTokenId = handle.subscriptionTokenId;
|
|
27
36
|
if (handle.initiatedByUserId)
|
|
28
37
|
step.initiatedByUserId = handle.initiatedByUserId;
|
|
38
|
+
// Order-preserving by FIRST dispatch, counting every one after it: the count is what makes a
|
|
39
|
+
// gate's fourth fixer round visible, so a re-dispatch increments rather than deduplicating.
|
|
40
|
+
const dispatches = step.dispatches ?? [];
|
|
41
|
+
const existing = dispatches.find((d) => d.agentKind === dispatchedKind);
|
|
42
|
+
step.dispatches = existing
|
|
43
|
+
? dispatches.map((d) => (d === existing ? { ...d, count: d.count + 1 } : d))
|
|
44
|
+
: [...dispatches, { agentKind: dispatchedKind, count: 1 }];
|
|
29
45
|
}
|
|
30
46
|
export function applyContainerRunning(step, update) {
|
|
31
47
|
const prev = step.container ?? undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-fold.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/step-fold.logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0C,MAAM,qBAAqB,CAAA;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,8FAA8F;AAC9F,kGAAkG;AAClG,gGAAgG;AAChG,kGAAkG;AAClG,iGAAiG;AACjG,gGAAgG;AAChG,iGAAiG;AACjG,+DAA+D;AAE/D
|
|
1
|
+
{"version":3,"file":"step-fold.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/step-fold.logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Clock, type IdGenerator } from '@cat-factory/kernel';
|
|
2
2
|
import type { GroupCacheHandle, InlineLlmCall, Logger, HarnessCallMetric, LlmCallMetric, LlmCallMetricRepository, LlmCallMetricSummary, LlmTraceSink, WorkspaceSettingsCacheValue, WorkspaceSettingsRepository } from '@cat-factory/kernel';
|
|
3
|
-
import type { LlmMetricsExport } from '@cat-factory/contracts';
|
|
3
|
+
import type { ExecutionInstance, LlmMetricsExport } from '@cat-factory/contracts';
|
|
4
4
|
export interface LlmObservabilityServiceDependencies {
|
|
5
5
|
llmCallMetricRepository: LlmCallMetricRepository;
|
|
6
6
|
idGenerator: IdGenerator;
|
|
@@ -152,6 +152,27 @@ export declare class LlmObservabilityService {
|
|
|
152
152
|
* still recorded.
|
|
153
153
|
*/
|
|
154
154
|
record(rawInput: RecordLlmCallInput): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Close a settled run's external trace by emitting the PARENTS its generations and tool
|
|
157
|
+
* spans have been naming all along: the run's root span and one span per agent kind that
|
|
158
|
+
* ran. Called from the engine's single terminal hook, so a run reaching `done`/`failed` by
|
|
159
|
+
* any of its four routes lands here exactly the same way.
|
|
160
|
+
*
|
|
161
|
+
* Best-effort and never throwing, like every other fan-out from this service: a trace whose
|
|
162
|
+
* root is missing is a degraded trace, and must never be a failed run. A sink that groups by
|
|
163
|
+
* something other than span parentage (Langfuse) simply omits the method and nothing here
|
|
164
|
+
* changes for it.
|
|
165
|
+
*
|
|
166
|
+
* AWAITED, where the per-call `recordGeneration` fan-out above is deliberately not. The two
|
|
167
|
+
* are on opposite sides of the same trade: a generation is one span among thousands on the
|
|
168
|
+
* metering hot path, so its round trip must never extend that path, and losing one costs one
|
|
169
|
+
* span. These are the PARENTS every other span of the run already named, they are emitted
|
|
170
|
+
* once per run on a path that has already committed the run's state, and losing them orphans
|
|
171
|
+
* the whole trace rather than thinning it. The wait is bounded by the sink's own per-request
|
|
172
|
+
* timeout, and on the Worker it is also what keeps the export from being cut off when the
|
|
173
|
+
* isolate finishes.
|
|
174
|
+
*/
|
|
175
|
+
recordRunTrace(workspaceId: string, instance: ExecutionInstance): Promise<void>;
|
|
155
176
|
/**
|
|
156
177
|
* Resolve this call's prompt to a delta against the chain tip of its
|
|
157
178
|
* `(workspace, execution, agentKind)` conversation (or the full array when it can't
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LlmObservabilityService.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/LlmObservabilityService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,WAAW,EAOjB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,MAAM,EACN,iBAAiB,EACjB,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"LlmObservabilityService.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/LlmObservabilityService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createStoreAgentContextGate, noopLogger, normalizeCallPhase, redactSecrets, runBestEffort, } from '@cat-factory/kernel';
|
|
2
2
|
import { buildLlmMetricsExport, computeStoredPrompt } from './observability.logic.js';
|
|
3
|
+
import { buildRunTraceSpans } from './runTraceSpans.logic.js';
|
|
3
4
|
/**
|
|
4
5
|
* Defensive upper bound on a stored prompt/response body (characters). Real agent
|
|
5
6
|
* prompts sit far below this; the cap exists only so a pathological body can't blow
|
|
@@ -156,6 +157,35 @@ export class LlmObservabilityService {
|
|
|
156
157
|
})));
|
|
157
158
|
}
|
|
158
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Close a settled run's external trace by emitting the PARENTS its generations and tool
|
|
162
|
+
* spans have been naming all along: the run's root span and one span per agent kind that
|
|
163
|
+
* ran. Called from the engine's single terminal hook, so a run reaching `done`/`failed` by
|
|
164
|
+
* any of its four routes lands here exactly the same way.
|
|
165
|
+
*
|
|
166
|
+
* Best-effort and never throwing, like every other fan-out from this service: a trace whose
|
|
167
|
+
* root is missing is a degraded trace, and must never be a failed run. A sink that groups by
|
|
168
|
+
* something other than span parentage (Langfuse) simply omits the method and nothing here
|
|
169
|
+
* changes for it.
|
|
170
|
+
*
|
|
171
|
+
* AWAITED, where the per-call `recordGeneration` fan-out above is deliberately not. The two
|
|
172
|
+
* are on opposite sides of the same trade: a generation is one span among thousands on the
|
|
173
|
+
* metering hot path, so its round trip must never extend that path, and losing one costs one
|
|
174
|
+
* span. These are the PARENTS every other span of the run already named, they are emitted
|
|
175
|
+
* once per run on a path that has already committed the run's state, and losing them orphans
|
|
176
|
+
* the whole trace rather than thinning it. The wait is bounded by the sink's own per-request
|
|
177
|
+
* timeout, and on the Worker it is also what keeps the export from being cut off when the
|
|
178
|
+
* isolate finishes.
|
|
179
|
+
*/
|
|
180
|
+
async recordRunTrace(workspaceId, instance) {
|
|
181
|
+
const traceSink = this.traceSink;
|
|
182
|
+
if (!traceSink?.recordRunSpans)
|
|
183
|
+
return;
|
|
184
|
+
const spans = buildRunTraceSpans(workspaceId, instance);
|
|
185
|
+
if (!spans)
|
|
186
|
+
return;
|
|
187
|
+
await runBestEffort(this.log, 'traceSink.recordRunSpans', () => Promise.resolve(traceSink.recordRunSpans?.(spans.run, spans.steps)));
|
|
188
|
+
}
|
|
159
189
|
/**
|
|
160
190
|
* Resolve this call's prompt to a delta against the chain tip of its
|
|
161
191
|
* `(workspace, execution, agentKind)` conversation (or the full array when it can't
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LlmObservabilityService.js","sourceRoot":"","sources":["../../../src/modules/observability/LlmObservabilityService.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,2BAA2B,EAC3B,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAA;AAe5B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"LlmObservabilityService.js","sourceRoot":"","sources":["../../../src/modules/observability/LlmObservabilityService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ExecutionInstance } from '@cat-factory/contracts';
|
|
2
|
+
import type { LlmRunSpan, LlmStepSpan } from '@cat-factory/kernel';
|
|
3
|
+
/** A settled run's root span plus the per-agent-kind step spans that hang under it. */
|
|
4
|
+
export interface RunTraceSpans {
|
|
5
|
+
run: LlmRunSpan;
|
|
6
|
+
steps: LlmStepSpan[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build the trace parents for a settled run, or null when the run has no observable extent at
|
|
10
|
+
* all (never stamped with a creation time and never started a step). Null rather than a
|
|
11
|
+
* zero-width span: a run that ran nothing emitted no children, so there is nothing to be the
|
|
12
|
+
* parent of, and inventing a root would put an empty trace in front of an operator.
|
|
13
|
+
*
|
|
14
|
+
* The steps fold by agent KIND rather than by index, because that is the only grain a
|
|
15
|
+
* generation can name (its event carries no step ordinal) and the grain the rest of the LLM
|
|
16
|
+
* telemetry already buckets by. Two `coder` steps in one pipeline therefore become one span
|
|
17
|
+
* covering both, reported as `stepCount: 2` rather than passed off as a single long step.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildRunTraceSpans(workspaceId: string | null, instance: ExecutionInstance): RunTraceSpans | null;
|
|
20
|
+
//# sourceMappingURL=runTraceSpans.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runTraceSpans.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/observability/runTraceSpans.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,wBAAwB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAmClE,uFAAuF;AACvF,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,UAAU,CAAA;IACf,KAAK,EAAE,WAAW,EAAE,CAAA;CACrB;AAwDD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,QAAQ,EAAE,iBAAiB,GAC1B,aAAa,GAAG,IAAI,CAyEtB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/** When a step actually began, across every attempt rather than only the one in flight. */
|
|
2
|
+
function stepStartedAt(step) {
|
|
3
|
+
const at = step.firstStartedAt ?? step.startedAt;
|
|
4
|
+
return typeof at === 'number' ? at : null;
|
|
5
|
+
}
|
|
6
|
+
/** Every epoch-ms stamp the run itself recorded, in no particular order. */
|
|
7
|
+
function observedStamps(instance) {
|
|
8
|
+
const stamps = [];
|
|
9
|
+
for (const step of instance.steps) {
|
|
10
|
+
// A step in flight when the run settled carries no `finishedAt` (it is stamped only on the
|
|
11
|
+
// transition to `done`), so its start and its last observed sign of life are what bound it.
|
|
12
|
+
for (const stamp of [stepStartedAt(step), step.finishedAt, step.lastActivityAt]) {
|
|
13
|
+
if (typeof stamp === 'number')
|
|
14
|
+
stamps.push(stamp);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// The exact instant a FAILED run settled. A `done` run's counterpart is its last step's
|
|
18
|
+
// `finishedAt`, already collected above, so both terminal states are bounded by a fact the
|
|
19
|
+
// run recorded rather than by how long the platform took to notice.
|
|
20
|
+
if (typeof instance.failure?.occurredAt === 'number')
|
|
21
|
+
stamps.push(instance.failure.occurredAt);
|
|
22
|
+
return stamps;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* How many times a step dispatched a given kind. Falls back to the step's own start count for
|
|
26
|
+
* its OWN kind, because an inline step (a judge, a consensus panel, a reviewer served without a
|
|
27
|
+
* container) never reaches the dispatch funnel and would otherwise report zero rounds for work
|
|
28
|
+
* that plainly ran.
|
|
29
|
+
*/
|
|
30
|
+
function dispatchCount(step, agentKind) {
|
|
31
|
+
const recorded = step.dispatches?.find((d) => d.agentKind === agentKind)?.count;
|
|
32
|
+
if (recorded)
|
|
33
|
+
return recorded;
|
|
34
|
+
return agentKind === step.agentKind ? (step.attempts ?? 1) : 1;
|
|
35
|
+
}
|
|
36
|
+
/** The kinds one step contributed a span for: its own, then any helper it dispatched. */
|
|
37
|
+
function kindsOf(step) {
|
|
38
|
+
const helpers = (step.dispatches ?? [])
|
|
39
|
+
.map((d) => d.agentKind)
|
|
40
|
+
.filter((kind) => kind !== step.agentKind)
|
|
41
|
+
.map((agentKind) => ({ agentKind, parentAgentKind: step.agentKind }));
|
|
42
|
+
return [{ agentKind: step.agentKind }, ...helpers];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build the trace parents for a settled run, or null when the run has no observable extent at
|
|
46
|
+
* all (never stamped with a creation time and never started a step). Null rather than a
|
|
47
|
+
* zero-width span: a run that ran nothing emitted no children, so there is nothing to be the
|
|
48
|
+
* parent of, and inventing a root would put an empty trace in front of an operator.
|
|
49
|
+
*
|
|
50
|
+
* The steps fold by agent KIND rather than by index, because that is the only grain a
|
|
51
|
+
* generation can name (its event carries no step ordinal) and the grain the rest of the LLM
|
|
52
|
+
* telemetry already buckets by. Two `coder` steps in one pipeline therefore become one span
|
|
53
|
+
* covering both, reported as `stepCount: 2` rather than passed off as a single long step.
|
|
54
|
+
*/
|
|
55
|
+
export function buildRunTraceSpans(workspaceId, instance) {
|
|
56
|
+
const started = instance.steps
|
|
57
|
+
.map(stepStartedAt)
|
|
58
|
+
.filter((at) => typeof at === 'number');
|
|
59
|
+
const runStartedAt = instance.createdAt ?? (started.length > 0 ? Math.min(...started) : null);
|
|
60
|
+
if (runStartedAt === null)
|
|
61
|
+
return null;
|
|
62
|
+
// The run's end is the latest thing it was OBSERVED to do. Taking the max against the start
|
|
63
|
+
// also covers a creation stamp that postdates every step, which would otherwise render as a
|
|
64
|
+
// negative-width span.
|
|
65
|
+
const runEndedAt = Math.max(runStartedAt, ...observedStamps(instance));
|
|
66
|
+
const failure = instance.failure ?? null;
|
|
67
|
+
const ok = instance.status === 'done';
|
|
68
|
+
// A failed run whose failure was never attributed to a step (`stepIndex` is optional, and a
|
|
69
|
+
// bootstrap failure has no step to point at) leaves every step span UNSET rather than
|
|
70
|
+
// guessing at one. The root still carries the error, so the failure is not lost; what is
|
|
71
|
+
// withheld is the single thing the run does not know, which is where it happened.
|
|
72
|
+
const failedStepIndex = ok ? null : (failure?.stepIndex ?? null);
|
|
73
|
+
const folds = new Map();
|
|
74
|
+
for (const [index, step] of instance.steps.entries()) {
|
|
75
|
+
// A step that never started contributed no telemetry, so it gets no span. A SKIPPED step is
|
|
76
|
+
// the case that matters: an estimate-gated step is absent from the run's work, and giving
|
|
77
|
+
// it a span would show an operator a step that was deliberately not run.
|
|
78
|
+
const startedAt = stepStartedAt(step);
|
|
79
|
+
if (startedAt === null)
|
|
80
|
+
continue;
|
|
81
|
+
// A helper shares its host step's window. That is not an approximation to apologise for: a
|
|
82
|
+
// parent span is REQUIRED to contain its children, and the helper ran inside the step, so
|
|
83
|
+
// the host's window is the tightest bound the run actually recorded.
|
|
84
|
+
const endedAt = Math.min(runEndedAt, step.finishedAt ?? runEndedAt);
|
|
85
|
+
for (const { agentKind, parentAgentKind } of kindsOf(step)) {
|
|
86
|
+
const existing = folds.get(agentKind);
|
|
87
|
+
folds.set(agentKind, {
|
|
88
|
+
startedAt: Math.min(existing?.startedAt ?? startedAt, startedAt),
|
|
89
|
+
endedAt: Math.max(existing?.endedAt ?? endedAt, endedAt),
|
|
90
|
+
stepCount: (existing?.stepCount ?? 0) + 1,
|
|
91
|
+
attemptCount: (existing?.attemptCount ?? 0) + dispatchCount(step, agentKind),
|
|
92
|
+
// Only the step the run actually failed ON is marked ERROR. Marking every step of a
|
|
93
|
+
// failed run would say the reviewer that passed had failed too.
|
|
94
|
+
failed: (existing?.failed ?? false) || failedStepIndex === index,
|
|
95
|
+
// A kind that is some step's OWN kind keeps its run-level parent even if another step
|
|
96
|
+
// also dispatched it as a helper: one span cannot hang in two places, and the spans
|
|
97
|
+
// underneath it cannot be told apart to split it.
|
|
98
|
+
parentAgentKind: existing ? existing.parentAgentKind : parentAgentKind,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const steps = [...folds].map(([agentKind, fold]) => ({
|
|
103
|
+
workspaceId,
|
|
104
|
+
executionId: instance.id,
|
|
105
|
+
agentKind,
|
|
106
|
+
...(fold.parentAgentKind ? { parentAgentKind: fold.parentAgentKind } : {}),
|
|
107
|
+
startedAt: fold.startedAt,
|
|
108
|
+
endedAt: Math.max(fold.startedAt, fold.endedAt),
|
|
109
|
+
stepCount: fold.stepCount,
|
|
110
|
+
attemptCount: fold.attemptCount,
|
|
111
|
+
ok: !fold.failed,
|
|
112
|
+
errorMessage: fold.failed ? (failure?.message ?? null) : null,
|
|
113
|
+
}));
|
|
114
|
+
return {
|
|
115
|
+
run: {
|
|
116
|
+
workspaceId,
|
|
117
|
+
executionId: instance.id,
|
|
118
|
+
pipelineName: instance.pipelineName,
|
|
119
|
+
startedAt: runStartedAt,
|
|
120
|
+
endedAt: runEndedAt,
|
|
121
|
+
ok,
|
|
122
|
+
errorMessage: ok ? null : (failure?.message ?? null),
|
|
123
|
+
},
|
|
124
|
+
steps,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=runTraceSpans.logic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runTraceSpans.logic.js","sourceRoot":"","sources":["../../../src/modules/observability/runTraceSpans.logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Clock, CreateScheduleInput, ExecutionEventPublisher, ExecutionRepository, IdGenerator, Logger, PipelineRepository, PipelineSchedule, PipelineScheduleRepository, ScheduleRun, ServiceRepository, TrackerIssueEvent, UpdateScheduleInput, WorkspaceMountRepository, WorkspaceRepository } from '@cat-factory/kernel';
|
|
1
|
+
import type { Clock, CreateScheduleInput, ExecutionEventPublisher, ExecutionRepository, IdGenerator, Logger, PipelineRepository, PipelineSchedule, PipelineScheduleRepository, ScheduleRun, ServiceRepository, TaskSourceKind, TrackerIssueEvent, UpdateScheduleInput, WorkspaceMountRepository, WorkspaceRepository } from '@cat-factory/kernel';
|
|
2
2
|
import type { BlockRepository } from '@cat-factory/kernel';
|
|
3
3
|
import { type TaskConnectionService } from '@cat-factory/integrations';
|
|
4
4
|
import type { ExecutionService } from '../execution/ExecutionService.js';
|
|
@@ -40,6 +40,28 @@ export interface RecurringPipelineServiceDependencies {
|
|
|
40
40
|
* only "push intake never happens". Absent ⇒ those paths stay silent, as they were.
|
|
41
41
|
*/
|
|
42
42
|
logger?: Logger;
|
|
43
|
+
/**
|
|
44
|
+
* PER-TICKET dispatch: import a pushed tracker issue and materialise it as its own task inside
|
|
45
|
+
* `containerId`, resolving to the created block — or to `null` when the issue is ALREADY linked
|
|
46
|
+
* to a block, which is how a redelivery is recognised.
|
|
47
|
+
*
|
|
48
|
+
* Declared structurally and bound at the composition root (to `TaskImportService` +
|
|
49
|
+
* `TaskLinkService`) rather than imported, for the layering reason `TrackerWebhookService`
|
|
50
|
+
* states about its own gateway: it keeps the import/link behaviour in the ONE place that owns
|
|
51
|
+
* it, so a per-ticket dispatch and a human's "create task from issue" cannot drift.
|
|
52
|
+
*
|
|
53
|
+
* Absent ⇒ a per-ticket config cannot dispatch and says so in the log; the queue mode is
|
|
54
|
+
* unaffected, so a deployment with no task sources is byte-for-byte unchanged.
|
|
55
|
+
*/
|
|
56
|
+
adoptIssueAsTask?: (input: {
|
|
57
|
+
workspaceId: string;
|
|
58
|
+
source: TaskSourceKind;
|
|
59
|
+
externalId: string;
|
|
60
|
+
containerId: string;
|
|
61
|
+
pipelineId: string;
|
|
62
|
+
}) => Promise<{
|
|
63
|
+
blockId: string;
|
|
64
|
+
} | null>;
|
|
43
65
|
}
|
|
44
66
|
/**
|
|
45
67
|
* Manages a workspace's recurring pipelines. Each schedule owns one reused
|
|
@@ -62,6 +84,7 @@ export declare class RecurringPipelineService {
|
|
|
62
84
|
private readonly taskConnectionService?;
|
|
63
85
|
private readonly events?;
|
|
64
86
|
private readonly log;
|
|
87
|
+
private readonly adoptIssueAsTask?;
|
|
65
88
|
constructor(deps: RecurringPipelineServiceDependencies);
|
|
66
89
|
private requireWorkspace;
|
|
67
90
|
/**
|
|
@@ -109,24 +132,66 @@ export declare class RecurringPipelineService {
|
|
|
109
132
|
* A tracker pushed an issue event: fire every ENABLED schedule in the workspace whose
|
|
110
133
|
* issue-intake configuration that event plausibly qualifies for. Returns how many started.
|
|
111
134
|
*
|
|
112
|
-
* This is the whole of push-driven intake (D3 of
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
135
|
+
* This is the whole of push-driven intake (D3 + D8 of
|
|
136
|
+
* `backend/docs/adr/0032-tracker-webhook-intake.md`), and what a qualifying event DOES depends on the
|
|
137
|
+
* schedule's dispatch mode:
|
|
138
|
+
*
|
|
139
|
+
* - **`queue`** (the default, and every pre-existing schedule) imports nothing and links
|
|
140
|
+
* nothing: {@link fire} runs the schedule's reused block and the `bug-intake` step does all of
|
|
141
|
+
* it through the unchanged `BugIntakeService`, so there is exactly ONE intake implementation
|
|
142
|
+
* and a pushed pickup is byte-for-byte a cadence pickup that happened sooner. The run may
|
|
143
|
+
* legitimately pick a DIFFERENT, older issue than the one that triggered it: intake is
|
|
144
|
+
* oldest-first fair queueing, and the webhook's job is to drain the queue promptly, not
|
|
145
|
+
* reorder it.
|
|
146
|
+
* - **`per-ticket`** dispatches the pushed ticket itself ({@link firePerTicket}), which DOES
|
|
147
|
+
* import and link.
|
|
148
|
+
*
|
|
149
|
+
* Neither path is FORCED. `force` is the human run-now lever (it throws on overlap and bypasses
|
|
150
|
+
* the on-demand guard) and a webhook has no human present to unlock a personal credential, which
|
|
151
|
+
* is exactly the situation the unattended-fire guards exist for. So a burst of deliveries cannot
|
|
152
|
+
* start a second run over one already running or parked (`fire` returns false and leaves
|
|
153
|
+
* `nextRunAt` for the sweeper), and an individual-usage model still refuses on BOTH paths.
|
|
119
154
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* is
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* `nextRunAt` for the sweeper).
|
|
155
|
+
* The on-demand guard reads differently per mode, and deliberately so. `fire` refuses an
|
|
156
|
+
* on-demand schedule outright, so a queue schedule is never webhook-fired unattended. A
|
|
157
|
+
* per-ticket schedule is REQUIRED to be on-demand (it has no cadence to be driven by), so
|
|
158
|
+
* `firePerTicket` does not consult that guard and applies the individual-usage check itself,
|
|
159
|
+
* against the block it just created rather than a reused one.
|
|
126
160
|
*
|
|
127
161
|
* ONE schedule read for the workspace, filtered in memory — never a point-read per schedule.
|
|
128
162
|
*/
|
|
129
163
|
triggerForIssueEvent(workspaceId: string, event: TrackerIssueEvent): Promise<number>;
|
|
164
|
+
/**
|
|
165
|
+
* PER-TICKET dispatch: import the pushed ticket, materialise it as its own task under the
|
|
166
|
+
* schedule's frame, and start the schedule's pipeline on THAT task. Returns whether a run
|
|
167
|
+
* started.
|
|
168
|
+
*
|
|
169
|
+
* The contrast with {@link fire} is the whole feature. `fire` re-runs one reused block and the
|
|
170
|
+
* run's `bug-intake` step decides what to work; this creates a block per ticket and the ticket
|
|
171
|
+
* IS the work, so a feature request enters the platform from the tracker it was filed in
|
|
172
|
+
* instead of through an API call.
|
|
173
|
+
*
|
|
174
|
+
* Three properties are load-bearing:
|
|
175
|
+
*
|
|
176
|
+
* - **Idempotency is the issue's existing single `linkedBlockId`**, not a new marker. A
|
|
177
|
+
* redelivery (or the `updated` event that follows a `created` one) finds the issue already
|
|
178
|
+
* linked, and `adoptIssueAsTask` reports that as `null`. The link already guarantees what a
|
|
179
|
+
* claim table would have bought. It is read off the row the import returns rather than by
|
|
180
|
+
* catching `createTaskFromIssue`'s conflict, because that refusal is PROSE: matching it would
|
|
181
|
+
* start double-dispatching the day someone rewords the message. A genuine RACE (two deliveries
|
|
182
|
+
* interleaving between that read and the create) still lands on the conflict and propagates,
|
|
183
|
+
* which is correct: the caller's per-schedule isolation logs it and the winner has already
|
|
184
|
+
* dispatched the ticket.
|
|
185
|
+
* - **The unattended-fire guard is the SAME one `fire` applies.** A webhook has no human present
|
|
186
|
+
* to unlock a personal credential, so an individual-usage model must refuse here too — checked
|
|
187
|
+
* against the CREATED block, which is the block that will actually run, rather than the
|
|
188
|
+
* schedule's reused one.
|
|
189
|
+
* - **`origin: 'manual'`**, because this run IS a one-off task run: a dedicated block, started
|
|
190
|
+
* once, never reused. That also makes `assertPipelineLaunchable` refuse a `recurring`-only
|
|
191
|
+
* pipeline, which is exactly right — a `bug-intake` pipeline would go and pick a DIFFERENT
|
|
192
|
+
* ticket — and it is the run-time half of the create-time `assertValidIssueIntake` rule.
|
|
193
|
+
*/
|
|
194
|
+
private firePerTicket;
|
|
130
195
|
/**
|
|
131
196
|
* Start a schedule's pipeline against its reused block. Finalises the prior run's
|
|
132
197
|
* history row (its execution is about to be replaced), records a new running row,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecurringPipelineService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/RecurringPipelineService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,KAAK,EACL,mBAAmB,EACnB,uBAAuB,EAEvB,mBAAmB,EACnB,WAAW,EACX,MAAM,EAEN,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,EAE1B,WAAW,EAEX,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAW1D,OAAO,
|
|
1
|
+
{"version":3,"file":"RecurringPipelineService.d.ts","sourceRoot":"","sources":["../../../src/modules/recurring/RecurringPipelineService.ts"],"names":[],"mappings":"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"}
|