@cat-factory/kernel 0.308.0 → 0.310.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/domain/binary-generator-registration.d.ts +1 -18
- package/dist/domain/binary-generator-registration.d.ts.map +1 -1
- package/dist/domain/binary-generator-registration.js +1 -53
- package/dist/domain/binary-generator-registration.js.map +1 -1
- package/dist/domain/binary-generators.js +3 -3
- package/dist/domain/binary-generators.js.map +1 -1
- package/dist/domain/binary-outputs.d.ts.map +1 -1
- package/dist/domain/binary-outputs.js +26 -1
- package/dist/domain/binary-outputs.js.map +1 -1
- package/dist/domain/define-pipeline.d.ts +75 -0
- package/dist/domain/define-pipeline.d.ts.map +1 -0
- package/dist/domain/define-pipeline.js +48 -0
- package/dist/domain/define-pipeline.js.map +1 -0
- package/dist/domain/foundational-service-registry.d.ts +7 -1
- package/dist/domain/foundational-service-registry.d.ts.map +1 -1
- package/dist/domain/foundational-service-registry.js +4 -0
- package/dist/domain/foundational-service-registry.js.map +1 -1
- package/dist/domain/foundational-services.d.ts +67 -1
- package/dist/domain/foundational-services.d.ts.map +1 -1
- package/dist/domain/foundational-services.js +58 -1
- package/dist/domain/foundational-services.js.map +1 -1
- package/dist/domain/seed.d.ts.map +1 -1
- package/dist/domain/seed.js +2 -42
- package/dist/domain/seed.js.map +1 -1
- package/dist/domain/vcs-errors.d.ts +21 -0
- package/dist/domain/vcs-errors.d.ts.map +1 -1
- package/dist/domain/vcs-errors.js +26 -0
- package/dist/domain/vcs-errors.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/ports/agent-definition.d.ts +17 -4
- package/dist/ports/agent-definition.d.ts.map +1 -1
- package/dist/ports/agent-executor.d.ts +20 -0
- package/dist/ports/agent-executor.d.ts.map +1 -1
- package/dist/ports/agent-executor.js.map +1 -1
- package/dist/ports/agent-tools.d.ts +14 -0
- package/dist/ports/agent-tools.d.ts.map +1 -1
- package/dist/ports/github-client.d.ts +11 -0
- package/dist/ports/github-client.d.ts.map +1 -1
- package/dist/ports/index.d.ts +3 -2
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -1
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/repo-files.d.ts +20 -0
- package/dist/ports/repo-files.d.ts.map +1 -1
- package/dist/ports/runner-transport.d.ts +67 -34
- package/dist/ports/runner-transport.d.ts.map +1 -1
- package/dist/ports/runner-transport.js +85 -33
- package/dist/ports/runner-transport.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { CloudProvider, InstanceSize, StepSubtasks } from '../domain/types.js';
|
|
2
2
|
import type { HarnessFailureCause } from '../domain/harness-failure.js';
|
|
3
3
|
import type { LlmToolSpan } from './llm-trace-sink.js';
|
|
4
|
-
import type { AgentEffortReport } from '@cat-factory/contracts';
|
|
4
|
+
import type { AgentEffortReport, PlatformImageVariant } from '@cat-factory/contracts';
|
|
5
|
+
import { isImageVariantName, isPlatformImageVariant, PLATFORM_IMAGE_VARIANTS } from '@cat-factory/contracts';
|
|
5
6
|
/** Live subtask counts a running job reports (from the coding tool's todo list). */
|
|
6
7
|
export type RunnerJobProgress = StepSubtasks;
|
|
7
8
|
/**
|
|
@@ -248,42 +249,61 @@ interface RunnerInfraSetup {
|
|
|
248
249
|
*/
|
|
249
250
|
export type RunnerDispatchKind = 'agent' | 'deploy';
|
|
250
251
|
/**
|
|
251
|
-
* Which executor image a job runs on
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
252
|
+
* Which executor image a job runs on, by NAME.
|
|
253
|
+
*
|
|
254
|
+
* Three names are the PLATFORM's, because it publishes those images ({@link
|
|
255
|
+
* PLATFORM_IMAGE_VARIANTS}): `default` is the standard harness image; `ui` is the heavier
|
|
256
|
+
* UI-tester image that bundles Playwright + a browser (the `tester-ui` kind needs it, and only
|
|
257
|
+
* it, so the browser never bloats every other kind's cold-start); `deploy` is the separate
|
|
258
|
+
* deploy-harness image (slim base + `kubectl`/`kustomize`/`helm`).
|
|
259
|
+
*
|
|
260
|
+
* Anything else is a DEPLOYMENT's own variant: a slug one of its agent kinds declares
|
|
261
|
+
* (`AgentStepSpec.image`) and its runner backend maps to an image. That is the whole reason the
|
|
262
|
+
* type is open rather than a union of the three. The split exists because different kinds need
|
|
263
|
+
* different images, and a deployment whose own agent needs a tool the harness image has no
|
|
264
|
+
* reason to carry had two options: install it inside every run, or put it in every kind's cold
|
|
265
|
+
* start. The platform cannot enumerate those names, and it does not have to: what it owns is the
|
|
266
|
+
* ROUTING (a variant is part of the container's identity, {@link containerKeyForRef}) and the
|
|
267
|
+
* REFUSAL below.
|
|
255
268
|
*
|
|
256
269
|
* A backend that cannot serve a declared variant REFUSES the dispatch rather than running the
|
|
257
270
|
* job on its default image. The two are not interchangeable in the direction that matters: a
|
|
258
271
|
* browser-driven tester on the plain image has no browser, and it discovers that only after a
|
|
259
272
|
* checkout, an install and a model's first turns have been paid for, then reports an `abort`
|
|
260
|
-
* indistinguishable from an app that would not boot.
|
|
261
|
-
*
|
|
273
|
+
* indistinguishable from an app that would not boot. A deployment's own variant is worse still,
|
|
274
|
+
* because nothing in the platform knows what it carried, so the job would report a missing
|
|
275
|
+
* artifact with no cause anywhere. Naming the missing wiring at dispatch costs nothing and says
|
|
276
|
+
* which knob to set.
|
|
262
277
|
*/
|
|
263
|
-
export type RunnerImageVariant =
|
|
278
|
+
export type RunnerImageVariant = string;
|
|
279
|
+
export { PLATFORM_IMAGE_VARIANTS, isPlatformImageVariant, isImageVariantName };
|
|
280
|
+
export type { PlatformImageVariant };
|
|
264
281
|
/**
|
|
265
|
-
* The
|
|
266
|
-
*
|
|
267
|
-
*
|
|
282
|
+
* The `default:` arm of a backend's exhaustive switch over {@link PlatformImageVariant}: it takes
|
|
283
|
+
* `never`, so publishing a fourth platform image fails the BUILD in every backend until each
|
|
284
|
+
* decides what to do with it, and it still refuses honestly at RUN time for the case the type
|
|
285
|
+
* cannot see, a value an older job body or a stored step still carries after this build retired it.
|
|
286
|
+
*
|
|
287
|
+
* The compile-time half is the load-bearing one, because the alternative is silent in the worst
|
|
288
|
+
* direction: a backend that fell through would run the job on its default image, and nothing
|
|
289
|
+
* downstream can say what the variant was supposed to carry. The DEPLOYMENT-owned half of the
|
|
290
|
+
* vocabulary is open and gets {@link deploymentImageVariantMessage} instead; this arm is only ever
|
|
291
|
+
* reached by a name the platform itself claimed.
|
|
268
292
|
*/
|
|
269
|
-
export declare
|
|
270
|
-
/** Whether a string names a variant THIS build can serve. */
|
|
271
|
-
export declare function isRunnerImageVariant(value: string | null | undefined): value is RunnerImageVariant;
|
|
293
|
+
export declare function unservablePlatformImageVariant(variant: never): never;
|
|
272
294
|
/**
|
|
273
|
-
* The
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
295
|
+
* The refusal a DEPLOYMENT-named image variant earns when the resolved runner backend maps it to
|
|
296
|
+
* nothing, with the per-backend knob named by the caller.
|
|
297
|
+
*
|
|
298
|
+
* One message, in kernel, because three backends refuse it and an operator reading three
|
|
299
|
+
* wordings for one misconfiguration learns three things instead of one. The platform's own
|
|
300
|
+
* variants keep their bespoke messages: the platform knows what `ui` is FOR, so it can say what
|
|
301
|
+
* a deployment loses by leaving it unwired and what to do instead, and this one cannot say
|
|
302
|
+
* anything about a variant it has never heard of beyond where the mapping goes.
|
|
278
303
|
*/
|
|
304
|
+
export declare function deploymentImageVariantMessage(variant: string, setting: string): string;
|
|
305
|
+
/** The `details.reason` every unwired-image refusal carries, whoever raises it. */
|
|
279
306
|
export declare const RUNNER_IMAGE_UNWIRED_REASON = "runner_image_unwired";
|
|
280
|
-
/**
|
|
281
|
-
* The `default:` arm of a backend's exhaustive switch over {@link RunnerImageVariant}: it takes
|
|
282
|
-
* `never`, so adding a member to the union fails the BUILD until that backend decides what to do
|
|
283
|
-
* with it, and it still refuses honestly at RUN time for the case the type cannot see — a value
|
|
284
|
-
* this build retired that an older row or an older job body still carries.
|
|
285
|
-
*/
|
|
286
|
-
export declare function unservableImageVariant(variant: never): never;
|
|
287
307
|
/**
|
|
288
308
|
* Optional, transport-level provisioning hints resolved per-service at dispatch.
|
|
289
309
|
* A self-hosted pool forwards `instanceTypeId` (and `provider`) so it can provision
|
|
@@ -613,13 +633,27 @@ export declare function containerKeyForRef(ref: RunnerJobRef): string;
|
|
|
613
633
|
/**
|
|
614
634
|
* The parts a container key encodes, the exact inverse of {@link containerKeyForRef}.
|
|
615
635
|
*
|
|
616
|
-
* The prefix is stripped ONLY when it
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
636
|
+
* The prefix is stripped ONLY when it is SHAPED like a variant name. A bare "everything before
|
|
637
|
+
* the first colon is a variant" split is lossy in the direction that destroys data: a key
|
|
638
|
+
* carrying a colon for any OTHER reason (a job-id scheme, an operator-created label) would be
|
|
639
|
+
* truncated to a run id that matches no run, and the orphan sweep below then kills a live
|
|
640
|
+
* container for being unrecognised, the very misread this inverse exists to prevent. A prefix
|
|
641
|
+
* that is not variant-shaped therefore answers "the whole key is the run id", which at worst
|
|
642
|
+
* leaves a container for the next sweep.
|
|
643
|
+
*
|
|
644
|
+
* SHAPE rather than membership, because variant names are open: a deployment's own is a slug
|
|
645
|
+
* only its runner backend can map, and this function is read by a reaper that holds no backend
|
|
646
|
+
* config. The rule is the one every declaring boundary already enforces (`checkAgentImageVariants`
|
|
647
|
+
* at boot, the backends' variant-map schemas), so a prefix this rejects is one no registration
|
|
648
|
+
* could have produced.
|
|
649
|
+
*
|
|
650
|
+
* What that leaves is a prefix which IS slug-shaped and was never a variant. Open names make that
|
|
651
|
+
* case unknowable HERE, so it is not decided here: {@link containerKeyForRef} refuses to mint a key
|
|
652
|
+
* this function would read back differently, which is what makes the pair exact rather than merely
|
|
653
|
+
* careful. Every key the inventory holds was written by that producer, so a prefix reaching this
|
|
654
|
+
* point and passing the shape test came from a variant a registration declared. The split of
|
|
655
|
+
* responsibility is the point: the reader refuses anything UNSHAPED, and the writer refuses
|
|
656
|
+
* anything AMBIGUOUS, because only one of them holds the ref to compare against.
|
|
623
657
|
*/
|
|
624
658
|
export declare function parseContainerKey(containerKey: string): {
|
|
625
659
|
runId: string;
|
|
@@ -722,5 +756,4 @@ export interface RunnerTransport {
|
|
|
722
756
|
*/
|
|
723
757
|
stopJob?(ref: RunnerJobRef): Promise<RunnerJobStopOutcome>;
|
|
724
758
|
}
|
|
725
|
-
export {};
|
|
726
759
|
//# sourceMappingURL=runner-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-transport.d.ts","sourceRoot":"","sources":["../../src/ports/runner-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"runner-transport.d.ts","sourceRoot":"","sources":["../../src/ports/runner-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isImageVariantName, isPlatformImageVariant, PLATFORM_IMAGE_VARIANTS, } from '@cat-factory/contracts';
|
|
2
|
+
import { UnavailableError, ValidationError } from '../domain/errors.js';
|
|
2
3
|
/**
|
|
3
4
|
* The one-line `error` a transport reports beside `evicted` when the job's container/runner is
|
|
4
5
|
* simply GONE — the poll found no such job. Owned here rather than copied per transport because
|
|
@@ -23,35 +24,46 @@ export const CONTAINER_EVICTION_ERROR = 'Job not found (container evicted or cra
|
|
|
23
24
|
* killed its container each time and reported infrastructure churn.
|
|
24
25
|
*/
|
|
25
26
|
export const HARNESS_SHUTDOWN_ERROR = 'The executor-harness shut down while this job was still running';
|
|
27
|
+
// The reserved-name half of the vocabulary lives on the WIRE (`@cat-factory/contracts`), because
|
|
28
|
+
// a runner backend's variant map is edited in the SPA and an agent kind's declaration is written
|
|
29
|
+
// by a deployment: both must be held to one list of names the platform has already claimed.
|
|
30
|
+
export { PLATFORM_IMAGE_VARIANTS, isPlatformImageVariant, isImageVariantName };
|
|
26
31
|
/**
|
|
27
|
-
* The
|
|
28
|
-
*
|
|
29
|
-
*
|
|
32
|
+
* The `default:` arm of a backend's exhaustive switch over {@link PlatformImageVariant}: it takes
|
|
33
|
+
* `never`, so publishing a fourth platform image fails the BUILD in every backend until each
|
|
34
|
+
* decides what to do with it, and it still refuses honestly at RUN time for the case the type
|
|
35
|
+
* cannot see, a value an older job body or a stored step still carries after this build retired it.
|
|
36
|
+
*
|
|
37
|
+
* The compile-time half is the load-bearing one, because the alternative is silent in the worst
|
|
38
|
+
* direction: a backend that fell through would run the job on its default image, and nothing
|
|
39
|
+
* downstream can say what the variant was supposed to carry. The DEPLOYMENT-owned half of the
|
|
40
|
+
* vocabulary is open and gets {@link deploymentImageVariantMessage} instead; this arm is only ever
|
|
41
|
+
* reached by a name the platform itself claimed.
|
|
30
42
|
*/
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
export function unservablePlatformImageVariant(variant) {
|
|
44
|
+
throw new UnavailableError(`This step declared the '${String(variant)}' executor image, which this backend does not ` +
|
|
45
|
+
'serve. It is a platform image this build does not know: re-pick the executor image on the ' +
|
|
46
|
+
"agent kind's registration.", RUNNER_IMAGE_UNWIRED_REASON, { image: String(variant) });
|
|
35
47
|
}
|
|
36
48
|
/**
|
|
37
|
-
* The
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* The `default:` arm of a backend's exhaustive switch over {@link RunnerImageVariant}: it takes
|
|
46
|
-
* `never`, so adding a member to the union fails the BUILD until that backend decides what to do
|
|
47
|
-
* with it, and it still refuses honestly at RUN time for the case the type cannot see — a value
|
|
48
|
-
* this build retired that an older row or an older job body still carries.
|
|
49
|
+
* The refusal a DEPLOYMENT-named image variant earns when the resolved runner backend maps it to
|
|
50
|
+
* nothing, with the per-backend knob named by the caller.
|
|
51
|
+
*
|
|
52
|
+
* One message, in kernel, because three backends refuse it and an operator reading three
|
|
53
|
+
* wordings for one misconfiguration learns three things instead of one. The platform's own
|
|
54
|
+
* variants keep their bespoke messages: the platform knows what `ui` is FOR, so it can say what
|
|
55
|
+
* a deployment loses by leaving it unwired and what to do instead, and this one cannot say
|
|
56
|
+
* anything about a variant it has never heard of beyond where the mapping goes.
|
|
49
57
|
*/
|
|
50
|
-
export function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
export function deploymentImageVariantMessage(variant, setting) {
|
|
59
|
+
return (`This step's agent kind declares the "${variant}" executor image, which this deployment's ` +
|
|
60
|
+
`runner backend maps to no image. Add "${variant}" to ${setting}, or drop the kind's ` +
|
|
61
|
+
`\`image\` declaration if the default harness image is enough: running the default instead ` +
|
|
62
|
+
`would produce a job without whatever "${variant}" carries, and a step reporting a missing ` +
|
|
63
|
+
`result with nothing naming the cause.`);
|
|
54
64
|
}
|
|
65
|
+
/** The `details.reason` every unwired-image refusal carries, whoever raises it. */
|
|
66
|
+
export const RUNNER_IMAGE_UNWIRED_REASON = 'runner_image_unwired';
|
|
55
67
|
/**
|
|
56
68
|
* The container identity a ref addresses on a per-run container backend: the run id for the
|
|
57
69
|
* default image, qualified by the variant for anything else.
|
|
@@ -62,18 +74,58 @@ export function unservableImageVariant(variant) {
|
|
|
62
74
|
* a reap from a cron all land on the same container with nothing passed between them.
|
|
63
75
|
*/
|
|
64
76
|
export function containerKeyForRef(ref) {
|
|
65
|
-
|
|
77
|
+
const key = ref.image && ref.image !== 'default' ? `${ref.image}:${ref.runId}` : ref.runId;
|
|
78
|
+
// The two must be EXACT inverses, and the PRODUCER is the only side that can check it:
|
|
79
|
+
// `parseContainerKey` reads keys with no ref in hand, so it cannot tell a run id that merely
|
|
80
|
+
// LOOKS variant-qualified from one that is (see its own doc for why the test it makes is a shape
|
|
81
|
+
// and not a lookup). Checking here converts the one input class that would break the inverse into
|
|
82
|
+
// a refused dispatch that NAMES the cause, instead of a key the reaper later maps to no run and
|
|
83
|
+
// kills a live container for.
|
|
84
|
+
//
|
|
85
|
+
// Unreachable for every run-id scheme the platform mints today (all `[A-Za-z0-9_-]`, which cannot
|
|
86
|
+
// contain the separator), which is exactly why this is a guard and not an escaping scheme: the
|
|
87
|
+
// invariant the pair rests on is "a run id carries no `:`", and it was previously assumed rather
|
|
88
|
+
// than stated anywhere. A future scheme that wants one has to pick a different separator, and this
|
|
89
|
+
// is where it finds out: at the first dispatch, in one place, rather than as a sweep deleting
|
|
90
|
+
// containers weeks later.
|
|
91
|
+
const parsed = parseContainerKey(key);
|
|
92
|
+
if (parsed.runId !== ref.runId || (parsed.image ?? 'default') !== (ref.image || 'default')) {
|
|
93
|
+
throw new ValidationError(`Cannot address a container for run "${ref.runId}"${ref.image ? ` on the "${ref.image}" executor image` : ''}: ` +
|
|
94
|
+
`the container key "${key}" does not read back as the run and image it was built from, so ` +
|
|
95
|
+
`every reader of it (the dispatch, the poll, the orphan sweep) would disagree about which ` +
|
|
96
|
+
`run owns the container. A run id may not put a variant-shaped segment before a ":", and a ` +
|
|
97
|
+
`variant name must be a lower-kebab slug.`, {
|
|
98
|
+
reason: 'container_key_not_reversible',
|
|
99
|
+
runId: ref.runId,
|
|
100
|
+
...(ref.image ? { image: ref.image } : {}),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return key;
|
|
66
104
|
}
|
|
67
105
|
/**
|
|
68
106
|
* The parts a container key encodes, the exact inverse of {@link containerKeyForRef}.
|
|
69
107
|
*
|
|
70
|
-
* The prefix is stripped ONLY when it
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
108
|
+
* The prefix is stripped ONLY when it is SHAPED like a variant name. A bare "everything before
|
|
109
|
+
* the first colon is a variant" split is lossy in the direction that destroys data: a key
|
|
110
|
+
* carrying a colon for any OTHER reason (a job-id scheme, an operator-created label) would be
|
|
111
|
+
* truncated to a run id that matches no run, and the orphan sweep below then kills a live
|
|
112
|
+
* container for being unrecognised, the very misread this inverse exists to prevent. A prefix
|
|
113
|
+
* that is not variant-shaped therefore answers "the whole key is the run id", which at worst
|
|
114
|
+
* leaves a container for the next sweep.
|
|
115
|
+
*
|
|
116
|
+
* SHAPE rather than membership, because variant names are open: a deployment's own is a slug
|
|
117
|
+
* only its runner backend can map, and this function is read by a reaper that holds no backend
|
|
118
|
+
* config. The rule is the one every declaring boundary already enforces (`checkAgentImageVariants`
|
|
119
|
+
* at boot, the backends' variant-map schemas), so a prefix this rejects is one no registration
|
|
120
|
+
* could have produced.
|
|
121
|
+
*
|
|
122
|
+
* What that leaves is a prefix which IS slug-shaped and was never a variant. Open names make that
|
|
123
|
+
* case unknowable HERE, so it is not decided here: {@link containerKeyForRef} refuses to mint a key
|
|
124
|
+
* this function would read back differently, which is what makes the pair exact rather than merely
|
|
125
|
+
* careful. Every key the inventory holds was written by that producer, so a prefix reaching this
|
|
126
|
+
* point and passing the shape test came from a variant a registration declared. The split of
|
|
127
|
+
* responsibility is the point: the reader refuses anything UNSHAPED, and the writer refuses
|
|
128
|
+
* anything AMBIGUOUS, because only one of them holds the ref to compare against.
|
|
77
129
|
*/
|
|
78
130
|
export function parseContainerKey(containerKey) {
|
|
79
131
|
const separator = containerKey.indexOf(':');
|
|
@@ -82,7 +134,7 @@ export function parseContainerKey(containerKey) {
|
|
|
82
134
|
const prefix = containerKey.slice(0, separator);
|
|
83
135
|
// `default` is never a prefix (`containerKeyForRef` emits the bare run id for it), so a key
|
|
84
136
|
// spelling it out is not one this function produced and is left whole.
|
|
85
|
-
if (prefix === 'default' || !
|
|
137
|
+
if (prefix === 'default' || !isImageVariantName(prefix))
|
|
86
138
|
return { runId: containerKey };
|
|
87
139
|
return { runId: containerKey.slice(separator + 1), image: prefix };
|
|
88
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-transport.js","sourceRoot":"","sources":["../../src/ports/runner-transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-transport.js","sourceRoot":"","sources":["../../src/ports/runner-transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/kernel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.310.0",
|
|
4
4
|
"description": "Shared vocabulary, pure logic, and port interfaces for the Agent Architecture Board.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"ai": "^7.0.64",
|
|
28
28
|
"yaml": "^2.9.0",
|
|
29
|
-
"@cat-factory/contracts": "0.
|
|
29
|
+
"@cat-factory/contracts": "0.320.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@stryker-mutator/core": "9.6.1",
|