@evelinka-ai/core 0.1.6 → 0.3.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.
Files changed (77) hide show
  1. package/dist/agent-lib/managed-tool.d.ts +13 -1
  2. package/dist/agent-lib/managed-tool.d.ts.map +1 -1
  3. package/dist/agent-lib/managed-tool.js +20 -1
  4. package/dist/agent-lib/managed-tool.js.map +1 -1
  5. package/dist/channels/model-catalog.d.ts.map +1 -1
  6. package/dist/channels/model-catalog.js +4 -1
  7. package/dist/channels/model-catalog.js.map +1 -1
  8. package/dist/channels/model-providers.d.ts +33 -0
  9. package/dist/channels/model-providers.d.ts.map +1 -0
  10. package/dist/channels/model-providers.js +86 -0
  11. package/dist/channels/model-providers.js.map +1 -0
  12. package/dist/channels/providers.d.ts +41 -0
  13. package/dist/channels/providers.d.ts.map +1 -0
  14. package/dist/channels/providers.js +168 -0
  15. package/dist/channels/providers.js.map +1 -0
  16. package/dist/lib/budgets/api-keys.d.ts +15 -0
  17. package/dist/lib/budgets/api-keys.d.ts.map +1 -0
  18. package/dist/lib/budgets/api-keys.js +83 -0
  19. package/dist/lib/budgets/api-keys.js.map +1 -0
  20. package/dist/lib/budgets/prepaid-call.d.ts +46 -0
  21. package/dist/lib/budgets/prepaid-call.d.ts.map +1 -0
  22. package/dist/lib/budgets/prepaid-call.js +32 -0
  23. package/dist/lib/budgets/prepaid-call.js.map +1 -0
  24. package/dist/lib/budgets/prepaid-response-store.d.ts +17 -0
  25. package/dist/lib/budgets/prepaid-response-store.d.ts.map +1 -0
  26. package/dist/lib/budgets/prepaid-response-store.js +85 -0
  27. package/dist/lib/budgets/prepaid-response-store.js.map +1 -0
  28. package/dist/lib/coordination/checkpoints.d.ts +33 -0
  29. package/dist/lib/coordination/checkpoints.d.ts.map +1 -0
  30. package/dist/lib/coordination/checkpoints.js +105 -0
  31. package/dist/lib/coordination/checkpoints.js.map +1 -0
  32. package/dist/lib/coordination/head-lease.d.ts +91 -0
  33. package/dist/lib/coordination/head-lease.d.ts.map +1 -0
  34. package/dist/lib/coordination/head-lease.js +402 -0
  35. package/dist/lib/coordination/head-lease.js.map +1 -0
  36. package/dist/lib/coordination/pg.d.ts +30 -0
  37. package/dist/lib/coordination/pg.d.ts.map +1 -0
  38. package/dist/lib/coordination/pg.js +52 -0
  39. package/dist/lib/coordination/pg.js.map +1 -0
  40. package/dist/lib/coordination/reconciler.d.ts +156 -0
  41. package/dist/lib/coordination/reconciler.d.ts.map +1 -0
  42. package/dist/lib/coordination/reconciler.js +287 -0
  43. package/dist/lib/coordination/reconciler.js.map +1 -0
  44. package/dist/lib/coordination/work-queue.d.ts +81 -0
  45. package/dist/lib/coordination/work-queue.d.ts.map +1 -0
  46. package/dist/lib/coordination/work-queue.js +305 -0
  47. package/dist/lib/coordination/work-queue.js.map +1 -0
  48. package/dist/lib/media/webp.d.ts +8 -0
  49. package/dist/lib/media/webp.d.ts.map +1 -0
  50. package/dist/lib/media/webp.js +15 -0
  51. package/dist/lib/media/webp.js.map +1 -0
  52. package/dist/lib/models/custom-providers.d.ts +44 -0
  53. package/dist/lib/models/custom-providers.d.ts.map +1 -0
  54. package/dist/lib/models/custom-providers.js +183 -0
  55. package/dist/lib/models/custom-providers.js.map +1 -0
  56. package/dist/lib/models/model-catalog.d.ts.map +1 -1
  57. package/dist/lib/models/model-catalog.js +2 -1
  58. package/dist/lib/models/model-catalog.js.map +1 -1
  59. package/dist/lib/models/model-config.d.ts +5 -1
  60. package/dist/lib/models/model-config.d.ts.map +1 -1
  61. package/dist/lib/models/model-config.js +37 -8
  62. package/dist/lib/models/model-config.js.map +1 -1
  63. package/dist/lib/observability/event-bus.d.ts +1 -0
  64. package/dist/lib/observability/event-bus.d.ts.map +1 -1
  65. package/dist/lib/observability/event-bus.js.map +1 -1
  66. package/dist/lib/observability/recorder-hook.d.ts +1 -0
  67. package/dist/lib/observability/recorder-hook.d.ts.map +1 -1
  68. package/dist/lib/observability/recorder-hook.js +2 -2
  69. package/dist/lib/observability/recorder-hook.js.map +1 -1
  70. package/dist/lib/observability/recorder.d.ts +28 -0
  71. package/dist/lib/observability/recorder.d.ts.map +1 -1
  72. package/dist/lib/observability/recorder.js +123 -34
  73. package/dist/lib/observability/recorder.js.map +1 -1
  74. package/dist/tenant.d.ts +12 -0
  75. package/dist/tenant.d.ts.map +1 -1
  76. package/dist/tenant.js.map +1 -1
  77. package/package.json +47 -2
@@ -0,0 +1,32 @@
1
+ function nonnegativeInteger(value) {
2
+ return Number.isSafeInteger(value) && value >= 0;
3
+ }
4
+ export async function executePrepaidCall(call, ledger, dispatch) {
5
+ if (!call.sessionId ||
6
+ !call.operationId ||
7
+ !call.provider ||
8
+ !call.model ||
9
+ !call.priceVersion ||
10
+ !nonnegativeInteger(call.maxChargeMicroUsd) ||
11
+ call.maxChargeMicroUsd === 0) {
12
+ throw new Error("PREPAID_INVALID_QUOTE");
13
+ }
14
+ const reservation = await ledger.reserve(call);
15
+ if (reservation.replay || reservation.state !== "reserved") {
16
+ throw new Error("PREPAID_OPERATION_ALREADY_DISPATCHED_OR_UNAVAILABLE");
17
+ }
18
+ const { result, receipt } = await dispatch();
19
+ if (receipt.costKind !== "actual" ||
20
+ !nonnegativeInteger(receipt.providerCostMicroUsd) ||
21
+ ![
22
+ receipt.usage.inputTokens,
23
+ receipt.usage.outputTokens,
24
+ receipt.usage.cacheReadTokens,
25
+ receipt.usage.cacheWriteTokens,
26
+ ].every(nonnegativeInteger)) {
27
+ throw new Error("PREPAID_INVALID_PROVIDER_RECEIPT");
28
+ }
29
+ await ledger.settle(call, receipt);
30
+ return result;
31
+ }
32
+ //# sourceMappingURL=prepaid-call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepaid-call.js","sourceRoot":"","sources":["../../../src/lib/budgets/prepaid-call.ts"],"names":[],"mappings":"AAgDA,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAiB,EACjB,MAAqB,EAGrB,QAAgE;IAEhE,IACE,CAAC,IAAI,CAAC,SAAS;QACf,CAAC,IAAI,CAAC,WAAW;QACjB,CAAC,IAAI,CAAC,QAAQ;QACd,CAAC,IAAI,CAAC,KAAK;QACX,CAAC,IAAI,CAAC,YAAY;QAClB,CAAC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC3C,IAAI,CAAC,iBAAiB,KAAK,CAAC,EAC5B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAGD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC7C,IACE,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC7B,CAAC,kBAAkB,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACjD,CAAC;YACC,OAAO,CAAC,KAAK,CAAC,WAAW;YACzB,OAAO,CAAC,KAAK,CAAC,YAAY;YAC1B,OAAO,CAAC,KAAK,CAAC,eAAe;YAC7B,OAAO,CAAC,KAAK,CAAC,gBAAgB;SAC/B,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAC3B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { PrepaidCall, ProviderReceipt } from "./prepaid-call.js";
2
+ export interface CompletedProviderCall {
3
+ call: PrepaidCall;
4
+ receipt: ProviderReceipt;
5
+ body: string;
6
+ contentType: string;
7
+ }
8
+ export declare class PrepaidResponseStore {
9
+ private readonly directory;
10
+ constructor(directory: string);
11
+ ready(): void;
12
+ private path;
13
+ prepare(call: PrepaidCall, requestHash: string): PrepaidCall;
14
+ read(id: string): CompletedProviderCall | undefined;
15
+ write(value: CompletedProviderCall): void;
16
+ }
17
+ //# sourceMappingURL=prepaid-response-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepaid-response-store.d.ts","sourceRoot":"","sources":["../../../src/lib/budgets/prepaid-response-store.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEtE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAKD,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAC9C,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW;IA+B5D,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAcnD,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;CAmB1C"}
@@ -0,0 +1,85 @@
1
+ import { accessSync, constants, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ export class PrepaidResponseStore {
4
+ directory;
5
+ constructor(directory) {
6
+ this.directory = directory;
7
+ }
8
+ ready() {
9
+ mkdirSync(this.directory, { recursive: true, mode: 0o700 });
10
+ accessSync(this.directory, constants.W_OK);
11
+ }
12
+ path(id) {
13
+ if (!/^[a-f0-9]{64}$/.test(id))
14
+ throw new Error("PREPAID_INVALID_OPERATION_ID");
15
+ return join(this.directory, `${id}.json`);
16
+ }
17
+ prepare(call, requestHash) {
18
+ this.ready();
19
+ const path = `${this.path(call.operationId)}.intent`;
20
+ if (!/^[a-f0-9]{64}$/.test(requestHash))
21
+ throw new Error("PREPAID_INVALID_REQUEST_HASH");
22
+ let fd;
23
+ try {
24
+ fd = openSync(path, "wx", 0o600);
25
+ }
26
+ catch (err) {
27
+ if (err.code !== "EEXIST")
28
+ throw err;
29
+ const saved = JSON.parse(readFileSync(path, "utf8"));
30
+ if (saved.call?.operationId !== call.operationId || saved.requestHash !== requestHash)
31
+ throw new Error("PREPAID_INVOCATION_PAYLOAD_CHANGED");
32
+ return saved.call;
33
+ }
34
+ try {
35
+ writeFileSync(fd, JSON.stringify({ call, requestHash }));
36
+ fsyncSync(fd);
37
+ }
38
+ finally {
39
+ closeSync(fd);
40
+ }
41
+ const directoryFd = openSync(this.directory, "r");
42
+ try {
43
+ fsyncSync(directoryFd);
44
+ }
45
+ finally {
46
+ closeSync(directoryFd);
47
+ }
48
+ return call;
49
+ }
50
+ read(id) {
51
+ const path = this.path(id);
52
+ if (!existsSync(path))
53
+ return undefined;
54
+ const value = JSON.parse(readFileSync(path, "utf8"));
55
+ if (value.call?.operationId !== id ||
56
+ typeof value.body !== "string" ||
57
+ value.receipt?.costKind !== "actual" ||
58
+ typeof value.contentType !== "string") {
59
+ throw new Error("PREPAID_CORRUPT_RESPONSE");
60
+ }
61
+ return value;
62
+ }
63
+ write(value) {
64
+ this.ready();
65
+ const path = this.path(value.call.operationId);
66
+ const temporary = `${path}.${process.pid}.tmp`;
67
+ const fd = openSync(temporary, "w", 0o600);
68
+ try {
69
+ writeFileSync(fd, JSON.stringify(value));
70
+ fsyncSync(fd);
71
+ }
72
+ finally {
73
+ closeSync(fd);
74
+ }
75
+ renameSync(temporary, path);
76
+ const directoryFd = openSync(this.directory, "r");
77
+ try {
78
+ fsyncSync(directoryFd);
79
+ }
80
+ finally {
81
+ closeSync(directoryFd);
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=prepaid-response-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepaid-response-store.js","sourceRoot":"","sources":["../../../src/lib/budgets/prepaid-response-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type PgDeps, type QueryPool } from "./pg.js";
2
+ export type CheckpointPool = QueryPool;
3
+ export interface CheckpointDeps extends PgDeps {
4
+ now?: () => number;
5
+ }
6
+ export declare const CHECKPOINT_TTL_MS: number;
7
+ export type CheckpointRun<K> = K & {
8
+ head: string;
9
+ runId: string;
10
+ scope: string;
11
+ };
12
+ export type Checkpoints<Phase extends string> = Partial<Record<Phase, unknown>>;
13
+ export interface CheckpointsConfig<M extends Record<string, string>, Phases extends readonly string[]> {
14
+ table: string;
15
+ key: M;
16
+ phases: Phases;
17
+ ttlMs?: number;
18
+ }
19
+ type KeyOf<M extends Record<string, string>> = {
20
+ [F in keyof M]: number;
21
+ };
22
+ export interface CheckpointStore<K, Phase extends string> {
23
+ readonly table: string;
24
+ readonly ttlMs: number;
25
+ ensureSchema(p: QueryPool): Promise<void>;
26
+ save(run: CheckpointRun<K>, phase: Phase, payload: unknown, deps?: CheckpointDeps): Promise<boolean>;
27
+ load(run: CheckpointRun<K>, deps?: CheckpointDeps): Promise<Checkpoints<Phase>>;
28
+ clear(key: K, deps?: CheckpointDeps): Promise<number>;
29
+ sweepExpired(ttlMs?: number, deps?: CheckpointDeps): Promise<number>;
30
+ }
31
+ export declare function defineCheckpoints<M extends Record<string, string>, const Phases extends readonly string[]>(config: CheckpointsConfig<M, Phases>): CheckpointStore<KeyOf<M>, Phases[number]>;
32
+ export {};
33
+ //# sourceMappingURL=checkpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../../../src/lib/coordination/checkpoints.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAuB,KAAK,MAAM,EAAW,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpF,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC;AAEvC,MAAM,WAAW,cAAe,SAAQ,MAAM;IAI5C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IAEd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhF,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,SAAS,SAAS,MAAM,EAAE;IAGhC,KAAK,EAAE,MAAM,CAAC;IAEd,GAAG,EAAE,CAAC,CAAC;IAEP,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAAE,CAAC;AAE1E,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C,IAAI,CACF,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,OAAO,CAAC,CAAC;IAQpB,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAEhF,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtD,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtE;AAED,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,KAAK,CAAC,MAAM,SAAS,SAAS,MAAM,EAAE,EACtC,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAkHjF"}
@@ -0,0 +1,105 @@
1
+ import { logger } from "../observability/logger.js";
2
+ import { intervalMs, keyPlan, pgBrick } from "./pg.js";
3
+ const log = logger.child({ module: "checkpoints" });
4
+ export const CHECKPOINT_TTL_MS = 24 * 3_600_000;
5
+ export function defineCheckpoints(config) {
6
+ const { table } = config;
7
+ const key = keyPlan(config.key);
8
+ const ttlMs = config.ttlMs ?? CHECKPOINT_TTL_MS;
9
+ const kn = key.columns.length;
10
+ const p = (i) => `$${kn + i}`;
11
+ const index = `${table}_${key.columns[kn - 1]}_idx`;
12
+ const pg = pgBrick([
13
+ `CREATE TABLE IF NOT EXISTS ${table} (
14
+ ${key.columns[0]} bigint NOT NULL,
15
+ ${key.columns
16
+ .slice(1)
17
+ .map((c) => ` ${c} integer NOT NULL,\n`)
18
+ .join("")} head text NOT NULL,
19
+ run_id text NOT NULL,
20
+ phase text NOT NULL,
21
+ payload jsonb NOT NULL,
22
+ scope text NOT NULL DEFAULT '',
23
+ created_at timestamptz NOT NULL DEFAULT now(),
24
+ PRIMARY KEY (run_id, phase)
25
+ )`,
26
+ `ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS scope text NOT NULL DEFAULT ''`,
27
+ `CREATE INDEX IF NOT EXISTS ${index} ON ${table} (${key.list})`,
28
+ ]);
29
+ const save = async (run, phase, payload, deps = {}) => {
30
+ try {
31
+ const pool = await pg.poolFor(deps);
32
+ if (!pool)
33
+ return false;
34
+ const r = await pool.query(`INSERT INTO ${table} (${key.list}, head, run_id, phase, payload, scope, created_at)
35
+ VALUES (${key.params()}, ${p(1)}, ${p(2)}, ${p(3)}, ${p(4)}::jsonb, ${p(5)}, now())
36
+ ON CONFLICT (run_id, phase) DO UPDATE
37
+ SET payload = EXCLUDED.payload, head = EXCLUDED.head, scope = EXCLUDED.scope,
38
+ created_at = now()
39
+ RETURNING run_id`, [
40
+ ...key.values(run),
41
+ run.head,
42
+ run.runId,
43
+ phase,
44
+ JSON.stringify(payload ?? null),
45
+ run.scope,
46
+ ]);
47
+ return (r.rowCount ?? 0) > 0;
48
+ }
49
+ catch (err) {
50
+ log.warn({ err: String(err), runId: run.runId, phase }, "checkpoint save failed (phase re-runs)");
51
+ return false;
52
+ }
53
+ };
54
+ const load = async (run, deps = {}) => {
55
+ try {
56
+ const pool = await pg.poolFor(deps);
57
+ if (!pool)
58
+ return {};
59
+ const r = await pool.query(`SELECT phase, payload, run_id FROM ${table}
60
+ WHERE ${key.where()} AND head = ${p(1)} AND scope = ${p(4)}
61
+ AND created_at > now() - (${p(2)} || ' milliseconds')::interval
62
+ ORDER BY (run_id = ${p(3)}) DESC, created_at DESC`, [...key.values(run), run.head, intervalMs(ttlMs), run.runId, run.scope]);
63
+ const out = {};
64
+ for (const row of r.rows) {
65
+ const phase = row.phase;
66
+ if (!config.phases.includes(phase) || phase in out)
67
+ continue;
68
+ out[phase] = row.payload;
69
+ }
70
+ return out;
71
+ }
72
+ catch (err) {
73
+ log.warn({ err: String(err), runId: run.runId }, "checkpoint load failed (full re-run)");
74
+ return {};
75
+ }
76
+ };
77
+ const clear = async (k, deps = {}) => {
78
+ try {
79
+ const pool = await pg.poolFor(deps);
80
+ if (!pool)
81
+ return 0;
82
+ const r = await pool.query(`DELETE FROM ${table} WHERE ${key.where()}`, key.values(k));
83
+ return r.rowCount ?? 0;
84
+ }
85
+ catch (err) {
86
+ log.warn({ err: String(err), key: k }, "checkpoint clear failed");
87
+ return 0;
88
+ }
89
+ };
90
+ const sweepExpired = async (ttl = ttlMs, deps = {}) => {
91
+ try {
92
+ const pool = await pg.poolFor(deps);
93
+ if (!pool)
94
+ return 0;
95
+ const r = await pool.query(`DELETE FROM ${table} WHERE created_at < now() - ($1 || ' milliseconds')::interval`, [intervalMs(ttl)]);
96
+ return r.rowCount ?? 0;
97
+ }
98
+ catch (err) {
99
+ log.warn({ err: String(err) }, "checkpoint sweep failed");
100
+ return 0;
101
+ }
102
+ };
103
+ return { table, ttlMs, ensureSchema: pg.ensureSchema, save, load, clear, sweepExpired };
104
+ }
105
+ //# sourceMappingURL=checkpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.js","sourceRoot":"","sources":["../../../src/lib/coordination/checkpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { type PgDeps, type QueryPool } from "./pg.js";
2
+ export declare const LEASE_HEARTBEAT_MS = 20000;
3
+ export declare const LEASE_TTL_MS = 75000;
4
+ export declare const LEASE_PROGRESS_STALL_MS: number;
5
+ export declare const SAME_BOOT_REAP_GRACE_MS = 60000;
6
+ export declare const STALLED_LEASE_MS: number;
7
+ export declare const PROCESS_BOOT_ID: `${string}-${string}-${string}-${string}-${string}`;
8
+ export declare function leaseKey(itemKey: string, head: string): string;
9
+ export declare function splitLeaseKey(key: string): {
10
+ itemKey: string;
11
+ head: string;
12
+ } | null;
13
+ export type LeasePool = QueryPool;
14
+ export type RunState = "active" | "terminal" | "absent" | "error";
15
+ export interface LeaseDeps extends PgDeps {
16
+ now?: () => number;
17
+ bootId?: string;
18
+ runState?: (lease: {
19
+ runId: string;
20
+ sessionId: string | null;
21
+ }) => Promise<RunState>;
22
+ runsTable?: string;
23
+ }
24
+ export declare function workflowRunState(p: LeasePool, runId: string, runsTable?: string): Promise<RunState>;
25
+ export declare function workflowRunStates(p: LeasePool, runIds: readonly string[], runsTable?: string): Promise<Map<string, RunState>>;
26
+ export interface LeaseHolder {
27
+ owner: string;
28
+ runId: string;
29
+ sessionId: string | null;
30
+ bootId: string;
31
+ phase: string;
32
+ heartbeatAt: string;
33
+ progressAt: string;
34
+ }
35
+ export type HolderVerdict = "take" | "refuse";
36
+ export declare function holderVerdict(holder: {
37
+ runId: string;
38
+ sessionId: string | null;
39
+ }, p: LeasePool, deps: LeaseDeps, known?: RunState): Promise<{
40
+ verdict: HolderVerdict;
41
+ state: RunState | "reservation";
42
+ }>;
43
+ export interface LeaseReservation {
44
+ held: boolean;
45
+ owner?: string;
46
+ holder?: LeaseHolder;
47
+ release: () => Promise<void>;
48
+ }
49
+ export interface HeadLease {
50
+ held: boolean;
51
+ isOwner: () => boolean;
52
+ progress: (phase: string) => Promise<boolean>;
53
+ owner?: string;
54
+ runId?: string;
55
+ holder?: LeaseHolder;
56
+ release: () => Promise<void>;
57
+ }
58
+ export interface LeaseRow extends LeaseHolder {
59
+ key: string;
60
+ claimedAt: string;
61
+ reapReason?: "dead" | "stalled";
62
+ }
63
+ export interface ReapResult {
64
+ reaped: LeaseRow[];
65
+ deferred: LeaseRow[];
66
+ }
67
+ export declare function isLeaseDead(row: Pick<LeaseRow, "heartbeatAt" | "bootId">, opts: {
68
+ now: number;
69
+ bootId: string;
70
+ }): boolean;
71
+ export interface HeadLeaseConfig {
72
+ table: string;
73
+ bootId?: string;
74
+ }
75
+ export interface HeadLeaseStore {
76
+ readonly table: string;
77
+ ensureSchema(p: QueryPool): Promise<void>;
78
+ reserve(key: string, deps?: LeaseDeps): Promise<LeaseReservation>;
79
+ adopt(key: string, meta: {
80
+ runId: string;
81
+ sessionId?: string;
82
+ }, deps?: LeaseDeps): Promise<HeadLease>;
83
+ liveFor(itemKey: string, deps?: LeaseDeps): Promise<(LeaseHolder & {
84
+ key: string;
85
+ }) | null | undefined>;
86
+ list(deps?: LeaseDeps): Promise<LeaseRow[] | null>;
87
+ reapDetailed(deps?: LeaseDeps): Promise<ReapResult>;
88
+ reap(deps?: LeaseDeps): Promise<LeaseRow[]>;
89
+ }
90
+ export declare function defineHeadLease(config: HeadLeaseConfig): HeadLeaseStore;
91
+ //# sourceMappingURL=head-lease.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head-lease.d.ts","sourceRoot":"","sources":["../../../src/lib/coordination/head-lease.ts"],"names":[],"mappings":"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"}