@cat-factory/kernel 0.214.1 → 0.216.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-registry.d.ts +66 -0
- package/dist/domain/binary-generator-registry.d.ts.map +1 -0
- package/dist/domain/binary-generator-registry.js +89 -0
- package/dist/domain/binary-generator-registry.js.map +1 -0
- package/dist/domain/binary-generators.d.ts +97 -0
- package/dist/domain/binary-generators.d.ts.map +1 -0
- package/dist/domain/binary-generators.js +212 -0
- package/dist/domain/binary-generators.js.map +1 -0
- package/dist/domain/binary-output-paths.d.ts +25 -0
- package/dist/domain/binary-output-paths.d.ts.map +1 -0
- package/dist/domain/binary-output-paths.js +47 -0
- package/dist/domain/binary-output-paths.js.map +1 -0
- package/dist/domain/binary-outputs.d.ts +37 -18
- package/dist/domain/binary-outputs.d.ts.map +1 -1
- package/dist/domain/binary-outputs.js +97 -45
- package/dist/domain/binary-outputs.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/ports/agent-executor.d.ts +13 -0
- package/dist/ports/agent-executor.d.ts.map +1 -1
- package/dist/ports/agent-executor.js.map +1 -1
- package/dist/ports/agent-runs.d.ts +22 -0
- package/dist/ports/agent-runs.d.ts.map +1 -1
- package/dist/ports/agent-tools.d.ts +36 -13
- package/dist/ports/agent-tools.d.ts.map +1 -1
- package/dist/ports/binary-generators.d.ts +49 -0
- package/dist/ports/binary-generators.d.ts.map +1 -0
- package/dist/ports/binary-generators.js +45 -0
- package/dist/ports/binary-generators.js.map +1 -0
- package/dist/ports/index.d.ts +3 -2
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -0
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/llm-trace-sink.d.ts +26 -5
- package/dist/ports/llm-trace-sink.d.ts.map +1 -1
- package/dist/ports/llm-trace-sink.js +52 -56
- package/dist/ports/llm-trace-sink.js.map +1 -1
- package/dist/ports/operational-metrics.d.ts +87 -0
- package/dist/ports/operational-metrics.d.ts.map +1 -0
- package/dist/ports/operational-metrics.js +67 -0
- package/dist/ports/operational-metrics.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The closed set of operational counters. A closed union rather than a free string, so
|
|
3
|
+
* adding a signal is a typecheck-visible decision (with a metric name and a documented
|
|
4
|
+
* meaning) instead of a name typo that reports zero forever.
|
|
5
|
+
*/
|
|
6
|
+
export type OperationalCounter =
|
|
7
|
+
/** A stale run whose durable instance was lost and was re-created by a sweeper. */
|
|
8
|
+
'sweep.run_redriven'
|
|
9
|
+
/** A stale run whose durable instance was terminal, so the sweeper settled it instead. */
|
|
10
|
+
| 'sweep.run_finalized'
|
|
11
|
+
/** A run failed `stalled`: re-driving never resurrected it past the hard deadline. */
|
|
12
|
+
| 'sweep.run_stalled'
|
|
13
|
+
/** A sweeper pass threw. Dimensioned by `sweep`, so one sick sweeper is identifiable. */
|
|
14
|
+
| 'sweep.failed'
|
|
15
|
+
/** A container job dispatch threw — the job never existed, so no poll can report it. */
|
|
16
|
+
| 'container.dispatch_failed'
|
|
17
|
+
/** A container job settled as evicted/crashed. Dimensioned by the eviction kind. */
|
|
18
|
+
| 'container.evicted'
|
|
19
|
+
/** An observability export was dropped (a trace sink, a metrics POST). */
|
|
20
|
+
| 'telemetry.export_dropped'
|
|
21
|
+
/** An outbound notification delivery failed after its retries. */
|
|
22
|
+
| 'notification.delivery_failed'
|
|
23
|
+
/** An app-cache read served from memory. Dimensioned by cache name. */
|
|
24
|
+
| 'cache.hit'
|
|
25
|
+
/** An app-cache read that had to run its loader. Dimensioned by cache name. */
|
|
26
|
+
| 'cache.miss';
|
|
27
|
+
/** The closed set of operational gauges — point-in-time readings, never accumulated. */
|
|
28
|
+
export type OperationalGauge =
|
|
29
|
+
/** Jobs waiting in a durable queue right now. Dimensioned by `queue`. */
|
|
30
|
+
'queue.depth';
|
|
31
|
+
/**
|
|
32
|
+
* The split dimensions of one sample. Values MUST be bounded — a queue name, a cache name,
|
|
33
|
+
* an eviction kind — never a run/workspace/job id: every distinct value is its own metric
|
|
34
|
+
* time series in the operator's backend, so an unbounded dimension is a cardinality
|
|
35
|
+
* explosion that costs money and eventually gets the series dropped. The correlation ids
|
|
36
|
+
* belong on the LOG line (which is why every increment site also logs), not here.
|
|
37
|
+
*/
|
|
38
|
+
export type OperationalDimensions = Readonly<Record<string, string>>;
|
|
39
|
+
/** One accumulated counter delta, ready to export. */
|
|
40
|
+
export interface OperationalCounterSample {
|
|
41
|
+
counter: OperationalCounter;
|
|
42
|
+
dimensions: OperationalDimensions;
|
|
43
|
+
/** The delta accumulated since the previous drain (always > 0 — empty keys aren't emitted). */
|
|
44
|
+
value: number;
|
|
45
|
+
}
|
|
46
|
+
/** One point-in-time gauge reading. */
|
|
47
|
+
export interface OperationalGaugeSample {
|
|
48
|
+
gauge: OperationalGauge;
|
|
49
|
+
dimensions: OperationalDimensions;
|
|
50
|
+
value: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Where operational events are counted. Injected the same way `Logger` is, so a domain
|
|
54
|
+
* service can count an event without knowing whether the deployment exports metrics at all.
|
|
55
|
+
*/
|
|
56
|
+
export interface OperationalMetrics {
|
|
57
|
+
/**
|
|
58
|
+
* Add `value` (default 1) to `counter` under `dimensions`. Never throws, never awaits —
|
|
59
|
+
* a call site on a hot path (a cache read) pays a Map lookup and an add.
|
|
60
|
+
*/
|
|
61
|
+
increment(counter: OperationalCounter, dimensions?: OperationalDimensions, value?: number): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* An {@link OperationalMetrics} that accumulates in memory until drained. The accumulate/drain
|
|
65
|
+
* split is what makes delta export correct: whoever drains owns a set of deltas nobody else
|
|
66
|
+
* will report, so two processes (or two Worker isolates) can flush independently and the
|
|
67
|
+
* backend's sum is still right.
|
|
68
|
+
*/
|
|
69
|
+
export interface OperationalMetricsCollector extends OperationalMetrics {
|
|
70
|
+
/**
|
|
71
|
+
* Take everything accumulated since the last call and RESET. Returns `[]` when nothing
|
|
72
|
+
* happened, which a caller should treat as "nothing to flush" — never as a reason to
|
|
73
|
+
* publish zeroes (an unflushed zero and a genuine zero are different facts, and only the
|
|
74
|
+
* absence of a data point states the first one honestly).
|
|
75
|
+
*/
|
|
76
|
+
drain(): OperationalCounterSample[];
|
|
77
|
+
}
|
|
78
|
+
/** The disposition for a deployment that exports nothing: count into the void, cheaply. */
|
|
79
|
+
export declare const noopOperationalMetrics: OperationalMetrics;
|
|
80
|
+
/**
|
|
81
|
+
* Build an in-memory {@link OperationalMetricsCollector}. One per process (Node/local, drained
|
|
82
|
+
* by the platform-metrics sweep) or one per isolate (the Worker, drained at the end of each
|
|
83
|
+
* invocation — an isolate can be discarded at any moment, so anything it holds unflushed is
|
|
84
|
+
* simply lost).
|
|
85
|
+
*/
|
|
86
|
+
export declare function createOperationalMetricsCollector(): OperationalMetricsCollector;
|
|
87
|
+
//# sourceMappingURL=operational-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operational-metrics.d.ts","sourceRoot":"","sources":["../../src/ports/operational-metrics.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,MAAM,kBAAkB;AAC5B,mFAAmF;AACjF,oBAAoB;AACtB,0FAA0F;GACxF,qBAAqB;AACvB,sFAAsF;GACpF,mBAAmB;AACrB,yFAAyF;GACvF,cAAc;AAChB,wFAAwF;GACtF,2BAA2B;AAC7B,oFAAoF;GAClF,mBAAmB;AACrB,0EAA0E;GACxE,0BAA0B;AAC5B,kEAAkE;GAChE,8BAA8B;AAChC,uEAAuE;GACrE,WAAW;AACb,+EAA+E;GAC7E,YAAY,CAAA;AAUhB,wFAAwF;AACxF,MAAM,MAAM,gBAAgB;AAC1B,yEAAyE;AACzE,aAAa,CAAA;AAEf;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAEpE,sDAAsD;AACtD,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,kBAAkB,CAAA;IAC3B,UAAU,EAAE,qBAAqB,CAAA;IACjC,+FAA+F;IAC/F,KAAK,EAAE,MAAM,CAAA;CACd;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,gBAAgB,CAAA;IACvB,UAAU,EAAE,qBAAqB,CAAA;IACjC,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,qBAAqB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACjG;AAED;;;;;GAKG;AACH,MAAM,WAAW,2BAA4B,SAAQ,kBAAkB;IACrE;;;;;OAKG;IACH,KAAK,IAAI,wBAAwB,EAAE,CAAA;CACpC;AAED,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,EAAE,kBAA4C,CAAA;AAYjF;;;;;GAKG;AACH,wBAAgB,iCAAiC,IAAI,2BAA2B,CA8B/E"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// The operational-metrics port: the counters and gauges that describe how the DEPLOYMENT is
|
|
2
|
+
// behaving, as opposed to how a run went.
|
|
3
|
+
//
|
|
4
|
+
// `PlatformMetricsRepository` already answers "how are the RUNS doing" by aggregating
|
|
5
|
+
// `agent_runs` per account. It structurally cannot answer the questions an operator asks
|
|
6
|
+
// during an incident — how often a container dispatch is failing, how many stale runs the
|
|
7
|
+
// sweeper is re-driving, whether the queue is draining, whether telemetry batches are being
|
|
8
|
+
// dropped — because none of those are rows in a table. They are EVENTS that happen and are
|
|
9
|
+
// gone. This port is where they are counted.
|
|
10
|
+
//
|
|
11
|
+
// Two shapes, because the two facts have different lifetimes:
|
|
12
|
+
// - a COUNTER is a delta accumulated since the last flush (evictions, re-drives, cache
|
|
13
|
+
// misses). Exported with delta temporality, so a partial flush from one process/isolate
|
|
14
|
+
// still sums correctly with every other one.
|
|
15
|
+
// - a GAUGE is read at export time from something that already knows the answer (queue
|
|
16
|
+
// depth). It is never accumulated here; the sweep probes for it.
|
|
17
|
+
//
|
|
18
|
+
// The whole surface is fire-and-forget and MUST NOT throw, for the same reason `Logger` must
|
|
19
|
+
// not: instrumentation that can fail turns observability into a new failure class.
|
|
20
|
+
/** The disposition for a deployment that exports nothing: count into the void, cheaply. */
|
|
21
|
+
export const noopOperationalMetrics = { increment: () => { } };
|
|
22
|
+
/**
|
|
23
|
+
* A dimension map's stable identity, so `{a:'1',b:'2'}` and `{b:'2',a:'1'}` accumulate onto
|
|
24
|
+
* the same counter rather than two. Keys are sorted; the separators are control characters
|
|
25
|
+
* that cannot appear in a metric dimension value.
|
|
26
|
+
*/
|
|
27
|
+
function dimensionKey(dimensions) {
|
|
28
|
+
const keys = Object.keys(dimensions).sort();
|
|
29
|
+
return keys.map((k) => `${k}${dimensions[k]}`).join('');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build an in-memory {@link OperationalMetricsCollector}. One per process (Node/local, drained
|
|
33
|
+
* by the platform-metrics sweep) or one per isolate (the Worker, drained at the end of each
|
|
34
|
+
* invocation — an isolate can be discarded at any moment, so anything it holds unflushed is
|
|
35
|
+
* simply lost).
|
|
36
|
+
*/
|
|
37
|
+
export function createOperationalMetricsCollector() {
|
|
38
|
+
// Keyed by `counter` then by the dimension identity, so a drain can rebuild both halves
|
|
39
|
+
// without parsing the composite key back apart.
|
|
40
|
+
const counters = new Map();
|
|
41
|
+
return {
|
|
42
|
+
increment(counter, dimensions = {}, value = 1) {
|
|
43
|
+
let byDimensions = counters.get(counter);
|
|
44
|
+
if (!byDimensions) {
|
|
45
|
+
byDimensions = new Map();
|
|
46
|
+
counters.set(counter, byDimensions);
|
|
47
|
+
}
|
|
48
|
+
const key = dimensionKey(dimensions);
|
|
49
|
+
const existing = byDimensions.get(key);
|
|
50
|
+
if (existing)
|
|
51
|
+
existing.value += value;
|
|
52
|
+
else
|
|
53
|
+
byDimensions.set(key, { dims: dimensions, value });
|
|
54
|
+
},
|
|
55
|
+
drain() {
|
|
56
|
+
const samples = [];
|
|
57
|
+
for (const [counter, byDimensions] of counters) {
|
|
58
|
+
for (const { dims, value } of byDimensions.values()) {
|
|
59
|
+
samples.push({ counter, dimensions: dims, value });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
counters.clear();
|
|
63
|
+
return samples;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=operational-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operational-metrics.js","sourceRoot":"","sources":["../../src/ports/operational-metrics.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,0CAA0C;AAC1C,EAAE;AACF,sFAAsF;AACtF,yFAAyF;AACzF,0FAA0F;AAC1F,4FAA4F;AAC5F,2FAA2F;AAC3F,6CAA6C;AAC7C,EAAE;AACF,8DAA8D;AAC9D,yFAAyF;AACzF,4FAA4F;AAC5F,iDAAiD;AACjD,yFAAyF;AACzF,qEAAqE;AACrE,EAAE;AACF,6FAA6F;AAC7F,mFAAmF;AA8FnF,2FAA2F;AAC3F,MAAM,CAAC,MAAM,sBAAsB,GAAuB,EAAE,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAA;AAEjF;;;;GAIG;AACH,SAAS,YAAY,CAAC,UAAiC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;IAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iCAAiC;IAC/C,wFAAwF;IACxF,gDAAgD;IAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAGrB,CAAA;IACH,OAAO;QACL,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;YAC3C,IAAI,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,GAAG,IAAI,GAAG,EAAE,CAAA;gBACxB,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;YACrC,CAAC;YACD,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;YACpC,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACtC,IAAI,QAAQ;gBAAE,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAA;;gBAChC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAA;QACzD,CAAC;QACD,KAAK;YACH,MAAM,OAAO,GAA+B,EAAE,CAAA;YAC9C,KAAK,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC/C,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;oBACpD,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;gBACpD,CAAC;YACH,CAAC;YACD,QAAQ,CAAC,KAAK,EAAE,CAAA;YAChB,OAAO,OAAO,CAAA;QAChB,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/kernel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.216.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.47",
|
|
28
28
|
"yaml": "^2.9.0",
|
|
29
|
-
"@cat-factory/contracts": "0.
|
|
29
|
+
"@cat-factory/contracts": "0.213.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@vitest/coverage-v8": "^4.1.10",
|