@cat-factory/worker 0.166.3 → 0.168.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/index.d.ts.map +1 -1
- package/dist/index.js +13 -17
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/config/retention.d.ts.map +1 -1
- package/dist/infrastructure/config/retention.js +6 -0
- package/dist/infrastructure/config/retention.js.map +1 -1
- package/dist/infrastructure/container-assembly.d.ts.map +1 -1
- package/dist/infrastructure/container-assembly.js +17 -8
- package/dist/infrastructure/container-assembly.js.map +1 -1
- package/dist/infrastructure/env.d.ts +7 -0
- package/dist/infrastructure/env.d.ts.map +1 -1
- package/dist/infrastructure/env.js.map +1 -1
- package/dist/infrastructure/observability/logExport.d.ts.map +1 -1
- package/dist/infrastructure/observability/logExport.js +10 -4
- package/dist/infrastructure/observability/logExport.js.map +1 -1
- package/dist/infrastructure/observability/logSettings.d.ts +22 -0
- package/dist/infrastructure/observability/logSettings.d.ts.map +1 -0
- package/dist/infrastructure/observability/logSettings.js +42 -0
- package/dist/infrastructure/observability/logSettings.js.map +1 -0
- package/dist/infrastructure/repositories/D1AuditEventRepository.d.ts +1 -0
- package/dist/infrastructure/repositories/D1AuditEventRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1AuditEventRepository.js +6 -0
- package/dist/infrastructure/repositories/D1AuditEventRepository.js.map +1 -1
- package/dist/infrastructure/repositories/D1ReportsRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1ReportsRepository.js +9 -0
- package/dist/infrastructure/repositories/D1ReportsRepository.js.map +1 -1
- package/dist/infrastructure/repositories/D1SpendRollupRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/D1SpendRollupRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/D1SpendRollupRepository.js +243 -0
- package/dist/infrastructure/repositories/D1SpendRollupRepository.js.map +1 -0
- package/dist/infrastructure/repositories/D1UserRepository.d.ts +2 -0
- package/dist/infrastructure/repositories/D1UserRepository.d.ts.map +1 -1
- package/dist/infrastructure/repositories/D1UserRepository.js +26 -0
- package/dist/infrastructure/repositories/D1UserRepository.js.map +1 -1
- package/dist/infrastructure/workflows/BootstrapWorkflow.d.ts +1 -0
- package/dist/infrastructure/workflows/BootstrapWorkflow.d.ts.map +1 -1
- package/dist/infrastructure/workflows/BootstrapWorkflow.js +9 -2
- package/dist/infrastructure/workflows/BootstrapWorkflow.js.map +1 -1
- package/dist/infrastructure/workflows/EnvConfigRepairWorkflow.d.ts +1 -0
- package/dist/infrastructure/workflows/EnvConfigRepairWorkflow.d.ts.map +1 -1
- package/dist/infrastructure/workflows/EnvConfigRepairWorkflow.js +7 -2
- package/dist/infrastructure/workflows/EnvConfigRepairWorkflow.js.map +1 -1
- package/dist/infrastructure/workflows/EnvironmentTestWorkflow.d.ts +1 -0
- package/dist/infrastructure/workflows/EnvironmentTestWorkflow.d.ts.map +1 -1
- package/dist/infrastructure/workflows/EnvironmentTestWorkflow.js +7 -2
- package/dist/infrastructure/workflows/EnvironmentTestWorkflow.js.map +1 -1
- package/dist/infrastructure/workflows/ExecutionWorkflow.d.ts +1 -0
- package/dist/infrastructure/workflows/ExecutionWorkflow.d.ts.map +1 -1
- package/dist/infrastructure/workflows/ExecutionWorkflow.js +10 -2
- package/dist/infrastructure/workflows/ExecutionWorkflow.js.map +1 -1
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.d.ts.map +1 -1
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.js +11 -5
- package/dist/infrastructure/workflows/GitHubBackfillWorkflow.js.map +1 -1
- package/dist/infrastructure/workflows/logExport.d.ts +11 -0
- package/dist/infrastructure/workflows/logExport.d.ts.map +1 -0
- package/dist/infrastructure/workflows/logExport.js +110 -0
- package/dist/infrastructure/workflows/logExport.js.map +1 -0
- package/dist/infrastructure/workflows/retention.d.ts +20 -2
- package/dist/infrastructure/workflows/retention.d.ts.map +1 -1
- package/dist/infrastructure/workflows/retention.js +13 -2
- package/dist/infrastructure/workflows/retention.js.map +1 -1
- package/migrations/0084_spend_days.sql +72 -0
- package/migrations/0084_user_session_generation.sql +22 -0
- package/package.json +18 -18
|
@@ -4,6 +4,7 @@ import { failureFromAdvanceError, failureFromDriver, failureFromResult, } from '
|
|
|
4
4
|
import { buildContainer } from '../container';
|
|
5
5
|
import { loadConfig } from '../config';
|
|
6
6
|
import { logger } from '../observability/logger';
|
|
7
|
+
import { withWorkflowLogExport } from './logExport';
|
|
7
8
|
import { buildWorkflowRuntime } from './runtime';
|
|
8
9
|
/** Per-step retry policy: failures retry a few times before the run is failed. */
|
|
9
10
|
const STEP_CONFIG = {
|
|
@@ -109,8 +110,15 @@ async function driveGatePollLoop(deps, i, initial) {
|
|
|
109
110
|
* already-completed LLM call.
|
|
110
111
|
*/
|
|
111
112
|
export class ExecutionWorkflow extends WorkflowEntrypoint {
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
run(event, step) {
|
|
114
|
+
// The wake's logging bracket. It matters most HERE: this driver parks on `waitForEvent` for
|
|
115
|
+
// as long as a human takes to answer, so the wake that dispatched a step and the wake that
|
|
116
|
+
// settles it are different isolates, and only a drain in front of each suspension gets the
|
|
117
|
+
// first one's lines out. See `./logExport.ts`.
|
|
118
|
+
return withWorkflowLogExport(this.env, step, (step) => this.drive(event.payload, step));
|
|
119
|
+
}
|
|
120
|
+
async drive(params, step) {
|
|
121
|
+
const { workspaceId, executionId } = params;
|
|
114
122
|
// Bind the run's correlation ONCE, the way `BootstrapWorkflow`/`EnvConfigRepairWorkflow`
|
|
115
123
|
// already do and `driveExecution` does on the Node side. Re-spreading the ids per call is
|
|
116
124
|
// how a nested emit ends up with none of them (observability-logging-gaps.md, A3).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExecutionWorkflow.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/ExecutionWorkflow.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ExecutionWorkflow.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/ExecutionWorkflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitHubBackfillWorkflow.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workflows/GitHubBackfillWorkflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"GitHubBackfillWorkflow.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workflows/GitHubBackfillWorkflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAIjC,2DAA2D;AAC3D,UAAU,oBAAoB;IAC5B,cAAc,EAAE,MAAM,CAAA;CACvB;AAOD;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,CAAC;IACxE,GAAG,CAChB,KAAK,EAAE,aAAa,CAAC,oBAAoB,CAAC,EAC1C,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAWf;CACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { WorkflowEntrypoint, } from 'cloudflare:workers';
|
|
2
2
|
import { buildContainer } from '../container';
|
|
3
|
+
import { withWorkflowLogExport } from './logExport';
|
|
3
4
|
const STEP_CONFIG = {
|
|
4
5
|
retries: { limit: 3, delay: '10 seconds', backoff: 'exponential' },
|
|
5
6
|
timeout: '10 minutes',
|
|
@@ -13,11 +14,16 @@ const STEP_CONFIG = {
|
|
|
13
14
|
*/
|
|
14
15
|
export class GitHubBackfillWorkflow extends WorkflowEntrypoint {
|
|
15
16
|
async run(event, step) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// Every workflow wake brackets its body this way: the isolate workerd starts it in has had
|
|
18
|
+
// no other entry point apply the logging settings, and gives itself back at each durable
|
|
19
|
+
// suspension. See `./logExport.ts`.
|
|
20
|
+
await withWorkflowLogExport(this.env, step, async (step) => {
|
|
21
|
+
const { installationId } = event.payload;
|
|
22
|
+
await step.do(`backfill-${installationId}`, STEP_CONFIG, async () => {
|
|
23
|
+
const github = buildContainer(this.env).github;
|
|
24
|
+
if (github)
|
|
25
|
+
await github.syncService.backfillInstallation(installationId);
|
|
26
|
+
});
|
|
21
27
|
});
|
|
22
28
|
}
|
|
23
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitHubBackfillWorkflow.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/GitHubBackfillWorkflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAInB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"GitHubBackfillWorkflow.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/GitHubBackfillWorkflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAInB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAOnD,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE;IAClE,OAAO,EAAE,YAAY;CACO,CAAA;AAE9B;;;;;;GAMG;AACH,MAAM,OAAO,sBAAuB,SAAQ,kBAA6C;IAC9E,KAAK,CAAC,GAAG,CAChB,KAA0C,EAC1C,IAAkB;QAElB,2FAA2F;QAC3F,yFAAyF;QACzF,oCAAoC;QACpC,MAAM,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACzD,MAAM,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC,OAAO,CAAA;YACxC,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,cAAc,EAAE,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;gBAClE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;gBAC9C,IAAI,MAAM;oBAAE,MAAM,MAAM,CAAC,WAAW,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAA;YAC3E,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WorkflowStep } from 'cloudflare:workers';
|
|
2
|
+
import type { Env } from '../env';
|
|
3
|
+
/**
|
|
4
|
+
* Run one workflow wake with this isolate's log export installed and drained around it.
|
|
5
|
+
*
|
|
6
|
+
* `drive` receives an INSTRUMENTED step: identical to the one workerd passed, except that every
|
|
7
|
+
* durable wait exports what the wake has logged so far. Drivers must use that step and no other,
|
|
8
|
+
* which is why this hands it over rather than leaving the original in scope.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withWorkflowLogExport<T>(env: Env, step: WorkflowStep, drive: (step: WorkflowStep) => Promise<T>): Promise<T>;
|
|
11
|
+
//# sourceMappingURL=logExport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logExport.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workflows/logExport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAsCjC;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAQZ"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { applyLogSettings, flushIsolateLogs } from '../observability/logSettings';
|
|
2
|
+
// The log export's WORKFLOW half, and the reason it needs a half of its own.
|
|
3
|
+
//
|
|
4
|
+
// `fetch`/`scheduled`/`queue` each serve one invocation and then hand the drain to
|
|
5
|
+
// `ctx.waitUntil` after the response (`observability/logExport.ts`). A workflow wake is not
|
|
6
|
+
// shaped like that. It runs for as long as the run takes, and it gives its isolate BACK in the
|
|
7
|
+
// middle. A drain placed only at the end of `run()` would therefore export a poll loop's LAST
|
|
8
|
+
// wake and lose every wake before it, which for the durable drivers is essentially the whole run.
|
|
9
|
+
//
|
|
10
|
+
// Three things hand the isolate back, and all three are wrapped below:
|
|
11
|
+
//
|
|
12
|
+
// - `step.sleep` / `step.sleepUntil`, the poll cadence.
|
|
13
|
+
// - `step.waitForEvent`, a park that lasts as long as a human takes to answer.
|
|
14
|
+
// - a `step.do` attempt that THREW. The engine then holds the instance for the step's retry
|
|
15
|
+
// backoff (`STEP_CONFIG` is 5s exponential across three attempts), and an instance can be
|
|
16
|
+
// evicted during it. What that attempt logged on its way to throwing is the diagnostic half
|
|
17
|
+
// of the whole run, so it drains before the error goes back to the engine.
|
|
18
|
+
//
|
|
19
|
+
// So a wake is bracketed rather than trailed: settings applied on entry (the isolate may be
|
|
20
|
+
// brand new, since workerd instantiates a `WorkflowEntrypoint` in an isolate no other entry
|
|
21
|
+
// point has run in), a drain in front of each of those waits, and a drain in a `finally` so a
|
|
22
|
+
// wake that ends by THROWING still exports the lines explaining why.
|
|
23
|
+
//
|
|
24
|
+
// The drain is AWAITED rather than handed to `this.ctx.waitUntil`. A workflow's next act after
|
|
25
|
+
// each wait below is to give the isolate up, so "after this returns" is not a moment that
|
|
26
|
+
// reliably arrives.
|
|
27
|
+
//
|
|
28
|
+
// Cost, stated rather than assumed, and paid only by a deployment that opted in. An empty buffer
|
|
29
|
+
// sends nothing, so the polls and the steps that logged nothing (most of them) pay nothing. A
|
|
30
|
+
// non-empty one costs a POST, and up to the exporter's queued-batch cap of them back to back,
|
|
31
|
+
// each bounded by its per-POST timeout (both live in `@cat-factory/observability-otel`). So an
|
|
32
|
+
// UNREACHABLE collector does not just lose lines, it adds that bound in front of every wait of
|
|
33
|
+
// every wake. That is deliberate rather than overlooked: bounding the drain instead would
|
|
34
|
+
// abandon precisely the lines this file exists to deliver, and a deployment whose collector
|
|
35
|
+
// stopped answering is better off slow and observable than fast and blind.
|
|
36
|
+
/**
|
|
37
|
+
* Run one workflow wake with this isolate's log export installed and drained around it.
|
|
38
|
+
*
|
|
39
|
+
* `drive` receives an INSTRUMENTED step: identical to the one workerd passed, except that every
|
|
40
|
+
* durable wait exports what the wake has logged so far. Drivers must use that step and no other,
|
|
41
|
+
* which is why this hands it over rather than leaving the original in scope.
|
|
42
|
+
*/
|
|
43
|
+
export async function withWorkflowLogExport(env, step, drive) {
|
|
44
|
+
applyLogSettings(env);
|
|
45
|
+
const flush = () => flushIsolateLogs(env);
|
|
46
|
+
try {
|
|
47
|
+
return await drive(flushingBeforeDurableWaits(step, flush));
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await flush();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The step workerd passed, with every member that can hand the isolate back wrapped to drain
|
|
55
|
+
* first.
|
|
56
|
+
*
|
|
57
|
+
* Built by DELEGATION rather than by inheriting from the real step (`Object.create`): a wrapper
|
|
58
|
+
* on the prototype chain would receive `this` on the un-wrapped members too, so any state the
|
|
59
|
+
* host object writes through `this` would land on the wrapper and be lost with it. Bound
|
|
60
|
+
* delegates keep every call running against the object workerd actually gave us.
|
|
61
|
+
*
|
|
62
|
+
* `sleepUntil` is wrapped though nothing calls it today: an object literal typed as
|
|
63
|
+
* `WorkflowStep` cannot omit it, which is the point. A driver that reaches for it later gets the
|
|
64
|
+
* drain without having to know this file exists.
|
|
65
|
+
*/
|
|
66
|
+
function flushingBeforeDurableWaits(step, flush) {
|
|
67
|
+
const delegateDo = step.do.bind(step);
|
|
68
|
+
return {
|
|
69
|
+
// A SUCCEEDING `do` is not a wait: its callback ran in this isolate and whatever it logged is
|
|
70
|
+
// drained by the next sleep/park or by the `finally` above, so instrumenting the happy path
|
|
71
|
+
// would buy a POST per step for lines already accounted for. A FAILING one is a different
|
|
72
|
+
// event: the engine answers a thrown attempt with the step's retry backoff, which is a
|
|
73
|
+
// durable wait the instance can be evicted during, so the lines saying why it failed have to
|
|
74
|
+
// leave before the error does.
|
|
75
|
+
do: ((name, ...rest) => {
|
|
76
|
+
// The callback is the second argument on the plain overload and the third when a
|
|
77
|
+
// `WorkflowStepConfig` is given. Everything else (that config, `rollbackOptions`) is
|
|
78
|
+
// forwarded untouched, so this substitutes exactly the one argument it instruments.
|
|
79
|
+
const at = typeof rest[0] === 'function' ? 0 : 1;
|
|
80
|
+
const callback = rest[at];
|
|
81
|
+
rest[at] = async (ctx) => {
|
|
82
|
+
try {
|
|
83
|
+
return await callback(ctx);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
await flush();
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
return delegateDo(name, ...rest);
|
|
91
|
+
}),
|
|
92
|
+
sleep: async (name, duration) => {
|
|
93
|
+
await flush();
|
|
94
|
+
await step.sleep(name, duration);
|
|
95
|
+
},
|
|
96
|
+
sleepUntil: async (name, timestamp) => {
|
|
97
|
+
await flush();
|
|
98
|
+
await step.sleepUntil(name, timestamp);
|
|
99
|
+
},
|
|
100
|
+
// Cast because `waitForEvent` is generic in its event payload and this wrapper is not: it
|
|
101
|
+
// forwards the payload untouched, so there is nothing for the delegate to be generic OVER,
|
|
102
|
+
// and re-declaring the type parameter here would only restate a constraint the real
|
|
103
|
+
// signature already enforces at every call site.
|
|
104
|
+
waitForEvent: (async (name, options) => {
|
|
105
|
+
await flush();
|
|
106
|
+
return step.waitForEvent(name, options);
|
|
107
|
+
}),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=logExport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logExport.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/logExport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentContextSnapshotRepository, AgentSearchQueryRepository, AgentToolCallRepository, Clock, CommitProjectionRepository, LlmCallMetricRepository, GateOutcomeRepository, NotificationRepository, AuthAttemptRepository, MachineNodeRepository, PasswordResetTokenRepository, PlatformMetricsRepository, PipelineScheduleRepository, ProvisioningLogRepository, RateLimitRepository, SubscriptionQuotaCycleRepository, TokenUsageRepository, Logger } from '@cat-factory/kernel';
|
|
1
|
+
import type { AgentContextSnapshotRepository, AgentSearchQueryRepository, AgentToolCallRepository, AuditEventRepository, Clock, CommitProjectionRepository, LlmCallMetricRepository, GateOutcomeRepository, NotificationRepository, AuthAttemptRepository, MachineNodeRepository, PasswordResetTokenRepository, PlatformMetricsRepository, PipelineScheduleRepository, ProvisioningLogRepository, RateLimitRepository, SpendRollupRepository, SubscriptionQuotaCycleRepository, TokenUsageRepository, Logger } from '@cat-factory/kernel';
|
|
2
2
|
/** Per-table retention ages in milliseconds; 0 (or less) disables that table's pass. */
|
|
3
3
|
interface RetentionPolicy {
|
|
4
4
|
tokenUsageMs: number;
|
|
@@ -18,6 +18,8 @@ interface RetentionPolicy {
|
|
|
18
18
|
gateOutcomesMs: number;
|
|
19
19
|
/** Daily run rollup (`platform_run_days`) behind the `30d` / `90d` dashboard windows. */
|
|
20
20
|
runDaysMs: number;
|
|
21
|
+
/** The account audit log (`audit_events`), in its own AUDIT_DB. The longest window here. */
|
|
22
|
+
auditEventsMs: number;
|
|
21
23
|
}
|
|
22
24
|
export interface RetentionDeps {
|
|
23
25
|
tokenUsageRepository: TokenUsageRepository;
|
|
@@ -57,6 +59,19 @@ export interface RetentionDeps {
|
|
|
57
59
|
* pass self-heals) and prunes it to `runDaysMs`.
|
|
58
60
|
*/
|
|
59
61
|
platformMetricsRepository: PlatformMetricsRepository;
|
|
62
|
+
/**
|
|
63
|
+
* The account audit log, pruned to `auditEventsMs`. REQUIRED rather than optional, matching the
|
|
64
|
+
* roster and throttle above and for the same reason: both facades wire the store
|
|
65
|
+
* unconditionally, and an optional field would let a call-site regression silently drop the one
|
|
66
|
+
* prune on the one table that is otherwise unbounded for years.
|
|
67
|
+
*/
|
|
68
|
+
auditEventRepository: AuditEventRepository;
|
|
69
|
+
/**
|
|
70
|
+
* The durable cost-attribution rollup. This pass only WRITES it: `spend_days` has no prune,
|
|
71
|
+
* here or on Node, and no `deleteOlderThan` on its port to call. A TCO table that expires is
|
|
72
|
+
* just a slower ledger.
|
|
73
|
+
*/
|
|
74
|
+
spendRollupRepository: SpendRollupRepository;
|
|
60
75
|
clock: Clock;
|
|
61
76
|
policy: RetentionPolicy;
|
|
62
77
|
/** Names the table behind each isolated prune failure. Absent ⇒ the failures are silent. */
|
|
@@ -80,8 +95,11 @@ export interface RetentionResult {
|
|
|
80
95
|
notifications: number;
|
|
81
96
|
gateOutcomes: number;
|
|
82
97
|
runDays: number;
|
|
98
|
+
auditEvents: number;
|
|
83
99
|
/** Daily buckets (re)written by this pass's rollup: a WRITE, not rows reclaimed. */
|
|
84
100
|
runDaysRolledUp: number;
|
|
101
|
+
/** Durable cost-attribution buckets (re)written by this pass: a WRITE, never a prune. */
|
|
102
|
+
spendDaysRolledUp: number;
|
|
85
103
|
/**
|
|
86
104
|
* The tables whose prune threw this pass. EMPTY on a clean pass. Reported separately from
|
|
87
105
|
* the counts because a failed prune and an empty table both reclaim 0 rows, and only one of
|
|
@@ -100,6 +118,6 @@ export interface RetentionResult {
|
|
|
100
118
|
* since the same table failed on every subsequent pass too. Shared with the Node twin via
|
|
101
119
|
* `createRetentionPass`, so the two facades cannot drift on it.
|
|
102
120
|
*/
|
|
103
|
-
export declare function sweepRetention({ tokenUsageRepository, rateLimitRepository, commitRepository, llmCallMetricRepository, agentContextSnapshotRepository, agentSearchQueryRepository, agentToolCallRepository, subscriptionQuotaCycleRepository, pipelineScheduleRepository, provisioningLogRepository, passwordResetTokenRepository, machineNodeRepository, authAttemptRepository, notificationRepository, gateOutcomeRepository, platformMetricsRepository, clock, policy, logger, }: RetentionDeps): Promise<RetentionResult>;
|
|
121
|
+
export declare function sweepRetention({ tokenUsageRepository, rateLimitRepository, commitRepository, llmCallMetricRepository, agentContextSnapshotRepository, agentSearchQueryRepository, agentToolCallRepository, subscriptionQuotaCycleRepository, pipelineScheduleRepository, provisioningLogRepository, passwordResetTokenRepository, machineNodeRepository, authAttemptRepository, notificationRepository, gateOutcomeRepository, platformMetricsRepository, auditEventRepository, spendRollupRepository, clock, policy, logger, }: RetentionDeps): Promise<RetentionResult>;
|
|
104
122
|
export {};
|
|
105
123
|
//# sourceMappingURL=retention.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workflows/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,uBAAuB,EACvB,KAAK,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,gCAAgC,EAChC,oBAAoB,EACpB,MAAM,EACP,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/workflows/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,gCAAgC,EAChC,oBAAoB,EACpB,MAAM,EACP,MAAM,qBAAqB,CAAA;AAgC5B,wFAAwF;AACxF,UAAU,eAAe;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAA;IACvB,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAA;IACtB,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAA;IACjB,4FAA4F;IAC5F,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,oBAAoB,EAAE,oBAAoB,CAAA;IAC1C,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,gBAAgB,EAAE,0BAA0B,CAAA;IAC5C,uBAAuB,EAAE,uBAAuB,CAAA;IAChD,oFAAoF;IACpF,8BAA8B,EAAE,8BAA8B,CAAA;IAC9D,iFAAiF;IACjF,0BAA0B,EAAE,0BAA0B,CAAA;IACtD,qFAAqF;IACrF,uBAAuB,EAAE,uBAAuB,CAAA;IAChD,uFAAuF;IACvF,gCAAgC,EAAE,gCAAgC,CAAA;IAClE,4FAA4F;IAC5F,0BAA0B,CAAC,EAAE,0BAA0B,CAAA;IACvD,+FAA+F;IAC/F,yBAAyB,CAAC,EAAE,yBAAyB,CAAA;IACrD,mFAAmF;IACnF,4BAA4B,CAAC,EAAE,4BAA4B,CAAA;IAC3D;;;;;OAKG;IACH,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C;kDAC8C;IAC9C,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,sFAAsF;IACtF,sBAAsB,EAAE,sBAAsB,CAAA;IAC9C,2DAA2D;IAC3D,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C;;;OAGG;IACH,yBAAyB,EAAE,yBAAyB,CAAA;IACpD;;;;;OAKG;IACH,oBAAoB,EAAE,oBAAoB,CAAA;IAC1C;;;;OAIG;IACH,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,eAAe,CAAA;IACvB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,cAAc,EAAE,MAAM,CAAA;IACtB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,oFAAoF;IACpF,eAAe,EAAE,MAAM,CAAA;IACvB,yFAAyF;IACzF,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,EACnC,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,uBAAuB,EACvB,gCAAgC,EAChC,0BAA0B,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAuG1C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RUN_DAY_ROLLUP_LOOKBACK_MS, createRetentionPass } from '@cat-factory/orchestration';
|
|
1
|
+
import { RUN_DAY_ROLLUP_LOOKBACK_MS, createRetentionPass, materializeSpendRollup, } from '@cat-factory/orchestration';
|
|
2
2
|
/** Recurring-pipeline run history is kept ~1 week (the inspector's window). */
|
|
3
3
|
const SCHEDULE_RUN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
4
4
|
// Auth attempts are junk once the 15-minute throttle window closes; a 1-hour retention leaves
|
|
@@ -25,10 +25,18 @@ const SUBSCRIPTION_QUOTA_CYCLE_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
|
|
|
25
25
|
* since the same table failed on every subsequent pass too. Shared with the Node twin via
|
|
26
26
|
* `createRetentionPass`, so the two facades cannot drift on it.
|
|
27
27
|
*/
|
|
28
|
-
export async function sweepRetention({ tokenUsageRepository, rateLimitRepository, commitRepository, llmCallMetricRepository, agentContextSnapshotRepository, agentSearchQueryRepository, agentToolCallRepository, subscriptionQuotaCycleRepository, pipelineScheduleRepository, provisioningLogRepository, passwordResetTokenRepository, machineNodeRepository, authAttemptRepository, notificationRepository, gateOutcomeRepository, platformMetricsRepository, clock, policy, logger, }) {
|
|
28
|
+
export async function sweepRetention({ tokenUsageRepository, rateLimitRepository, commitRepository, llmCallMetricRepository, agentContextSnapshotRepository, agentSearchQueryRepository, agentToolCallRepository, subscriptionQuotaCycleRepository, pipelineScheduleRepository, provisioningLogRepository, passwordResetTokenRepository, machineNodeRepository, authAttemptRepository, notificationRepository, gateOutcomeRepository, platformMetricsRepository, auditEventRepository, spendRollupRepository, clock, policy, logger, }) {
|
|
29
29
|
const now = clock.now();
|
|
30
30
|
const pass = createRetentionPass(logger);
|
|
31
31
|
return {
|
|
32
|
+
// FIRST, and before the ledger prune below: the durable rollup folds `token_usage`, so a
|
|
33
|
+
// pass that pruned first would drop spend that had never been rolled up. It resumes from
|
|
34
|
+
// its own watermark rather than a fixed lookback, because a day missed here is missing
|
|
35
|
+
// from the only durable record of it, permanently, and this facade sweeps once a day, so
|
|
36
|
+
// a couple of skipped crons is a real gap. Its catch-up horizon is derived from the SAME
|
|
37
|
+
// `tokenUsageMs` the prune two lines down uses, so the walk never steps over a day the
|
|
38
|
+
// ledger still holds. See `spendRollupWindow`.
|
|
39
|
+
spendDaysRolledUp: await materializeSpendRollup(pass, spendRollupRepository, now, policy.tokenUsageMs, logger),
|
|
32
40
|
tokenUsage: await pass.prune('token_usage', policy.tokenUsageMs, now, (c) => tokenUsageRepository.deleteOlderThan(c)),
|
|
33
41
|
rateLimits: await pass.prune('github_rate_limits', policy.rateLimitMs, now, (c) => rateLimitRepository.deleteOlderThan(c)),
|
|
34
42
|
commits: await pass.prune('github_commits', policy.commitMs, now, (c) => commitRepository.deleteOlderThan(c)),
|
|
@@ -64,6 +72,9 @@ export async function sweepRetention({ tokenUsageRepository, rateLimitRepository
|
|
|
64
72
|
// rather than leaving a day permanently half-counted.
|
|
65
73
|
runDaysRolledUp: await pass.materialize('platform_run_days', () => platformMetricsRepository.rollupRunDays(now - RUN_DAY_ROLLUP_LOOKBACK_MS, now)),
|
|
66
74
|
runDays: await pass.prune('platform_run_days', policy.runDaysMs, now, (c) => platformMetricsRepository.deleteRunDaysOlderThan(c)),
|
|
75
|
+
// The audit log, in its own database. Last because it is the only pass whose window is
|
|
76
|
+
// measured in years: the others reclaim on most ticks, this one usually reclaims nothing.
|
|
77
|
+
auditEvents: await pass.prune('audit_events', policy.auditEventsMs, now, (c) => auditEventRepository.deleteOlderThan(c)),
|
|
67
78
|
failedTables: pass.failed,
|
|
68
79
|
};
|
|
69
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/retention.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../../src/infrastructure/workflows/retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- Durable cost attribution: the daily spend rollup behind the Reports view's TCO axes.
|
|
2
|
+
--
|
|
3
|
+
-- The ledger (`token_usage`) already carries every metered call, but it cannot answer a TCO
|
|
4
|
+
-- question durably. It is pruned to TOKEN_USAGE_RETENTION_DAYS, and every attribution beyond
|
|
5
|
+
-- the workspace is resolved at READ time by joining `agent_runs` (itself prunable) and then
|
|
6
|
+
-- the LIVE `services.repo_github_id` / `tasks.linked_block_id` links. Re-point a service at a
|
|
7
|
+
-- new repository, or re-import an issue, and last quarter's answer changes underneath the
|
|
8
|
+
-- reader with nothing to show that it did.
|
|
9
|
+
--
|
|
10
|
+
-- So this table folds the ledger once per sweep, per UTC day, and FREEZES the board shape the
|
|
11
|
+
-- spend happened under: the run, its block and title, its service and name, its repository id
|
|
12
|
+
-- and `owner/name`, its task type, and the tracker ticket its block was linked to. Reading it
|
|
13
|
+
-- touches no other table, so nothing downstream of it can be re-pointed or pruned.
|
|
14
|
+
--
|
|
15
|
+
-- It has NO RETENTION, deliberately, and is the only table in the deployment that has none.
|
|
16
|
+
-- A TCO table has to outlive the ledger it was folded from; a rollup with a window is just a
|
|
17
|
+
-- slower ledger. The grain keeps that affordable: one row per run per (agent kind, model,
|
|
18
|
+
-- billing kind), a handful of rows against the hundreds of ledger rows one run writes, so the
|
|
19
|
+
-- table grows with RUN volume, never with call volume. See docs/storage-and-retention.md §1c.
|
|
20
|
+
--
|
|
21
|
+
-- KEY COLUMNS carry '' rather than NULL (SQLite does not treat two NULLs in a primary key as
|
|
22
|
+
-- equal, so a nullable key column would not deduplicate a rewritten bucket); the repository
|
|
23
|
+
-- maps '' back to the unattributed bucket at the read boundary, exactly as `platform_run_days`
|
|
24
|
+
-- does with `failure_kind`. LABEL columns stay nullable, because "no name" and "the empty
|
|
25
|
+
-- name" are the same absence there and the wire shape reports a nullable label.
|
|
26
|
+
CREATE TABLE spend_days (
|
|
27
|
+
workspace_id TEXT NOT NULL,
|
|
28
|
+
day_start INTEGER NOT NULL,
|
|
29
|
+
-- The run the calls belong to; '' when the ledger row carried no execution id or the run
|
|
30
|
+
-- row is already gone (the unattributed bucket, a real slice rather than a dropped row).
|
|
31
|
+
execution_id TEXT NOT NULL DEFAULT '',
|
|
32
|
+
agent_kind TEXT NOT NULL DEFAULT '',
|
|
33
|
+
provider TEXT NOT NULL DEFAULT '',
|
|
34
|
+
model TEXT NOT NULL DEFAULT '',
|
|
35
|
+
-- Metered (real money) vs subscription (flat-rate quota usage, illustrative only). Part of
|
|
36
|
+
-- the key so the two never have to be separated after the fact.
|
|
37
|
+
billing TEXT NOT NULL DEFAULT 'metered',
|
|
38
|
+
vendor TEXT NOT NULL DEFAULT '',
|
|
39
|
+
-- The owning account, frozen so an account-scoped read never has to join `workspaces`: a
|
|
40
|
+
-- board deleted since the spend happened must not take its history's scope with it.
|
|
41
|
+
account_id TEXT NOT NULL DEFAULT '',
|
|
42
|
+
workspace_name TEXT,
|
|
43
|
+
block_id TEXT NOT NULL DEFAULT '',
|
|
44
|
+
block_title TEXT,
|
|
45
|
+
service_id TEXT NOT NULL DEFAULT '',
|
|
46
|
+
service_name TEXT,
|
|
47
|
+
-- The provider repo id as text (the `repo` dimension's key) and `owner/name` (its label).
|
|
48
|
+
repo_id TEXT NOT NULL DEFAULT '',
|
|
49
|
+
repo_name TEXT,
|
|
50
|
+
task_type TEXT NOT NULL DEFAULT '',
|
|
51
|
+
-- `source:externalId` of the lowest-sorting ticket linked to the run's block, matching the
|
|
52
|
+
-- ledger-side dimension's deterministic pick. No title: a second MIN over another column
|
|
53
|
+
-- need not come from the same row, and a label naming a different ticket than the key is
|
|
54
|
+
-- worse than no label.
|
|
55
|
+
ticket_ref TEXT NOT NULL DEFAULT '',
|
|
56
|
+
calls INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
58
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
59
|
+
metered_cost REAL NOT NULL DEFAULT 0,
|
|
60
|
+
subscription_cost REAL NOT NULL DEFAULT 0,
|
|
61
|
+
PRIMARY KEY (
|
|
62
|
+
workspace_id, day_start, execution_id, agent_kind, provider, model, billing, vendor
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
-- The read's access path: one account's (optionally one board's) buckets over a day window.
|
|
67
|
+
CREATE INDEX idx_spend_days_account ON spend_days (account_id, day_start);
|
|
68
|
+
-- The rewrite's access path: each pass DELETEs its whole day window across every workspace
|
|
69
|
+
-- before re-inserting it (an upsert is not a rewrite: see the repository).
|
|
70
|
+
CREATE INDEX idx_spend_days_day ON spend_days (day_start);
|
|
71
|
+
-- Per-run lookup (the finest TCO axis), independent of when the run happened.
|
|
72
|
+
CREATE INDEX idx_spend_days_execution ON spend_days (workspace_id, execution_id);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Per-user SESSION GENERATION: the one row write that revokes every bearer a person holds.
|
|
2
|
+
--
|
|
3
|
+
-- Sessions are stateless HMAC-signed tokens, so before this column there was nothing to revoke:
|
|
4
|
+
-- logout dropped the token client-side and a leaked (or offboarded) bearer stayed valid until it
|
|
5
|
+
-- expired. That is the gap enterprise SSO cannot close on its own — the whole offboarding promise
|
|
6
|
+
-- is "we disabled them in the IdP and they lost access", and re-reading the directory on sign-in
|
|
7
|
+
-- only stops a NEW session being minted, never the one they already hold.
|
|
8
|
+
--
|
|
9
|
+
-- A GENERATION rather than a token blocklist. The token carries the generation it was minted
|
|
10
|
+
-- under; verification compares that claim against this column and refuses a mismatch. Revoking
|
|
11
|
+
-- every session is therefore `session_generation + 1`, one write, with nothing to enumerate and no
|
|
12
|
+
-- second table to grow and prune. A blocklist would need a row per outstanding token, a retention
|
|
13
|
+
-- sweep of its own, and would still be unable to answer for a token it never saw minted.
|
|
14
|
+
--
|
|
15
|
+
-- DEFAULT 0 so every existing row is valid without a backfill. Note that existing TOKENS are not:
|
|
16
|
+
-- they carry no generation claim at all and are refused after this ships, which logs everyone out
|
|
17
|
+
-- once. That is the deliberate pre-1.0 internal break (CLAUDE.md → "Internals: backwards
|
|
18
|
+
-- compatibility is NOT a goal") rather than a dual-read that would leave a permanent
|
|
19
|
+
-- claim-less-means-valid hole — precisely the hole an attacker would aim at.
|
|
20
|
+
--
|
|
21
|
+
-- Mirrors the Drizzle `users.session_generation` column on the Node facade.
|
|
22
|
+
ALTER TABLE users ADD COLUMN session_generation INTEGER NOT NULL DEFAULT 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.168.0",
|
|
4
4
|
"description": "Reusable Cloudflare Worker library (Hono + D1) exposing the Agent Architecture Board core: the `createApp()` Hono factory, the default fetch/scheduled/queue handler, and the Durable Object + Workflow classes. Deployments (see deploy/backend) supply the wrangler.toml + config and re-export these.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,22 +43,22 @@
|
|
|
43
43
|
"pino": "^10.3.1",
|
|
44
44
|
"valibot": "^1.4.2",
|
|
45
45
|
"workers-ai-provider": "^4.0.0",
|
|
46
|
-
"@cat-factory/agents": "0.116.
|
|
47
|
-
"@cat-factory/caching": "0.
|
|
48
|
-
"@cat-factory/consensus": "0.14.
|
|
49
|
-
"@cat-factory/contracts": "0.
|
|
50
|
-
"@cat-factory/eks": "0.1.
|
|
51
|
-
"@cat-factory/gates": "0.9.
|
|
52
|
-
"@cat-factory/gitlab": "0.16.
|
|
53
|
-
"@cat-factory/integrations": "0.
|
|
54
|
-
"@cat-factory/kernel": "0.
|
|
55
|
-
"@cat-factory/observability-langfuse": "0.10.
|
|
56
|
-
"@cat-factory/observability-otel": "0.16.
|
|
57
|
-
"@cat-factory/orchestration": "0.
|
|
58
|
-
"@cat-factory/prompt-fragments": "1.0.
|
|
59
|
-
"@cat-factory/provider-cloudflare": "0.7.
|
|
60
|
-
"@cat-factory/server": "0.
|
|
61
|
-
"@cat-factory/spend": "0.15.
|
|
46
|
+
"@cat-factory/agents": "0.116.6",
|
|
47
|
+
"@cat-factory/caching": "0.17.0",
|
|
48
|
+
"@cat-factory/consensus": "0.14.43",
|
|
49
|
+
"@cat-factory/contracts": "0.261.0",
|
|
50
|
+
"@cat-factory/eks": "0.1.255",
|
|
51
|
+
"@cat-factory/gates": "0.9.23",
|
|
52
|
+
"@cat-factory/gitlab": "0.16.14",
|
|
53
|
+
"@cat-factory/integrations": "0.140.0",
|
|
54
|
+
"@cat-factory/kernel": "0.259.0",
|
|
55
|
+
"@cat-factory/observability-langfuse": "0.10.27",
|
|
56
|
+
"@cat-factory/observability-otel": "0.16.7",
|
|
57
|
+
"@cat-factory/orchestration": "0.228.0",
|
|
58
|
+
"@cat-factory/prompt-fragments": "1.0.7",
|
|
59
|
+
"@cat-factory/provider-cloudflare": "0.7.405",
|
|
60
|
+
"@cat-factory/server": "0.239.0",
|
|
61
|
+
"@cat-factory/spend": "0.15.25"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@cloudflare/vitest-pool-workers": "^0.20.1",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"typescript": "7.0.2",
|
|
67
67
|
"vitest": "^4.1.10",
|
|
68
68
|
"wrangler": "^4.118.0",
|
|
69
|
-
"@cat-factory/conformance": "0.31.
|
|
69
|
+
"@cat-factory/conformance": "0.31.19"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsc -b tsconfig.build.json",
|