@evelinka-ai/core 0.1.3 → 0.2.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/agent-lib/managed-tool.d.ts +13 -1
- package/dist/agent-lib/managed-tool.d.ts.map +1 -1
- package/dist/agent-lib/managed-tool.js +20 -1
- package/dist/agent-lib/managed-tool.js.map +1 -1
- package/dist/channels/model-providers.d.ts +31 -0
- package/dist/channels/model-providers.d.ts.map +1 -0
- package/dist/channels/model-providers.js +81 -0
- package/dist/channels/model-providers.js.map +1 -0
- package/dist/lib/coordination/checkpoints.d.ts +33 -0
- package/dist/lib/coordination/checkpoints.d.ts.map +1 -0
- package/dist/lib/coordination/checkpoints.js +105 -0
- package/dist/lib/coordination/checkpoints.js.map +1 -0
- package/dist/lib/coordination/head-lease.d.ts +91 -0
- package/dist/lib/coordination/head-lease.d.ts.map +1 -0
- package/dist/lib/coordination/head-lease.js +402 -0
- package/dist/lib/coordination/head-lease.js.map +1 -0
- package/dist/lib/coordination/pg.d.ts +30 -0
- package/dist/lib/coordination/pg.d.ts.map +1 -0
- package/dist/lib/coordination/pg.js +52 -0
- package/dist/lib/coordination/pg.js.map +1 -0
- package/dist/lib/coordination/reconciler.d.ts +156 -0
- package/dist/lib/coordination/reconciler.d.ts.map +1 -0
- package/dist/lib/coordination/reconciler.js +287 -0
- package/dist/lib/coordination/reconciler.js.map +1 -0
- package/dist/lib/coordination/work-queue.d.ts +81 -0
- package/dist/lib/coordination/work-queue.d.ts.map +1 -0
- package/dist/lib/coordination/work-queue.js +305 -0
- package/dist/lib/coordination/work-queue.js.map +1 -0
- package/dist/lib/observability/event-bus.d.ts +1 -0
- package/dist/lib/observability/event-bus.d.ts.map +1 -1
- package/dist/lib/observability/event-bus.js.map +1 -1
- package/dist/lib/observability/recorder.d.ts +26 -0
- package/dist/lib/observability/recorder.d.ts.map +1 -1
- package/dist/lib/observability/recorder.js +60 -1
- package/dist/lib/observability/recorder.js.map +1 -1
- package/package.json +21 -1
|
@@ -20,10 +20,22 @@ interface ManagedToolDef<TSchema, TOutput> {
|
|
|
20
20
|
interface ManagedToolOpts {
|
|
21
21
|
approvalFloor?: (ctx: NeedsApprovalCtx) => boolean;
|
|
22
22
|
}
|
|
23
|
+
export interface ToolGateCall {
|
|
24
|
+
slug: string;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
rootId: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolGateRefusal {
|
|
29
|
+
ok: false;
|
|
30
|
+
message: string;
|
|
31
|
+
[k: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
export type ToolGate = (call: ToolGateCall) => ToolGateRefusal | null;
|
|
34
|
+
export declare function registerToolGate(gate: ToolGate): () => void;
|
|
23
35
|
export declare function defineManagedTool<TSchema, TOutput>(slug: string, def: ManagedToolDef<TSchema, TOutput>, opts?: ManagedToolOpts): ToolDefinition<InferOutput<TSchema>, TOutput | {
|
|
24
36
|
ok: false;
|
|
25
37
|
disabled: true;
|
|
26
38
|
message: string;
|
|
27
|
-
}>;
|
|
39
|
+
} | ToolGateRefusal>;
|
|
28
40
|
export {};
|
|
29
41
|
//# sourceMappingURL=managed-tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-tool.d.ts","sourceRoot":"","sources":["../../src/agent-lib/managed-tool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAI9E,KAAK,gBAAgB,GAAG;IACtB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,KAAK,cAAc,CAAC,MAAM,IAAI;IAC5B,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAC;CACpF,CAAC;AACF,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtF,UAAU,cAAc,CAAC,OAAO,EAAE,OAAO;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACxF;AAED,UAAU,eAAe;IAGvB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACpD;
|
|
1
|
+
{"version":3,"file":"managed-tool.d.ts","sourceRoot":"","sources":["../../src/agent-lib/managed-tool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAI9E,KAAK,gBAAgB,GAAG;IACtB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,KAAK,cAAc,CAAC,MAAM,IAAI;IAC5B,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAC;CACpF,CAAC;AACF,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtF,UAAU,cAAc,CAAC,OAAO,EAAE,OAAO;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACxF;AAED,UAAU,eAAe;IAGvB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACpD;AAWD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,eAAe,GAAG,IAAI,CAAC;AAItE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAK3D;AAUD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAChD,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,EACrC,IAAI,GAAE,eAAoB,GACzB,cAAc,CACf,WAAW,CAAC,OAAO,CAAC,EACpB,OAAO,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAC3E,CA6BA"}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { defineTool } from "eve/tools";
|
|
2
2
|
import { withCallContext } from "../lib/control-plane/call-context.js";
|
|
3
3
|
import { isEnabled, mapApproval, toolConfig } from "../lib/control-plane/tools-config.js";
|
|
4
|
+
const toolGates = new Set();
|
|
5
|
+
export function registerToolGate(gate) {
|
|
6
|
+
toolGates.add(gate);
|
|
7
|
+
return () => {
|
|
8
|
+
toolGates.delete(gate);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function consultToolGates(call) {
|
|
12
|
+
for (const gate of toolGates) {
|
|
13
|
+
const refusal = gate(call);
|
|
14
|
+
if (refusal)
|
|
15
|
+
return refusal;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
4
19
|
export function defineManagedTool(slug, def, opts = {}) {
|
|
5
20
|
return defineTool({
|
|
6
21
|
description: def.description,
|
|
@@ -21,7 +36,11 @@ export function defineManagedTool(slug, def, opts = {}) {
|
|
|
21
36
|
const sessionId = toolCtx.session?.id;
|
|
22
37
|
if (!sessionId)
|
|
23
38
|
return def.execute(input, toolCtx);
|
|
24
|
-
|
|
39
|
+
const rootId = toolCtx.session.parent?.rootSessionId ?? sessionId;
|
|
40
|
+
const refused = consultToolGates({ slug, sessionId, rootId });
|
|
41
|
+
if (refused)
|
|
42
|
+
return refused;
|
|
43
|
+
return withCallContext({ sessionId, rootId }, () => def.execute(input, toolCtx));
|
|
25
44
|
},
|
|
26
45
|
});
|
|
27
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-tool.js","sourceRoot":"","sources":["../../src/agent-lib/managed-tool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAyC,MAAM,WAAW,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"managed-tool.js","sourceRoot":"","sources":["../../src/agent-lib/managed-tool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAyC,MAAM,WAAW,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAgD1F,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;AAEtC,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAkB;IAC1C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,GAAqC,EACrC,OAAwB,EAAE;IAK1B,OAAO,UAAU,CAAC;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAoB;QACrC,aAAa,EAAE,CAAC,GAAqB,EAAE,EAAE;YACvC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC3C,OAAO,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,EAAE,CAAC,KAA2B,EAAE,OAAoB,EAAE,EAAE;YAC7D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,OAAO;oBACL,EAAE,EAAE,KAAc;oBAClB,QAAQ,EAAE,IAAa;oBACvB,OAAO,EAAE,QAAQ,IAAI,6CAA6C;iBACnE,CAAC;YACJ,CAAC;YAGD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,SAAS;gBAAE,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,SAAS,CAAC;YAClE,MAAM,OAAO,GAAG,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9D,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC;YAC5B,OAAO,eAAe,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QACnF,CAAC;KACF,CAGA,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Channel } from "eve/channels";
|
|
2
|
+
export interface ModelProviderFeatures {
|
|
3
|
+
loginComplete?: boolean;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
config?: boolean;
|
|
6
|
+
restart?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ModelProviderSpec {
|
|
9
|
+
id: string;
|
|
10
|
+
gatewayUrlEnv: string;
|
|
11
|
+
tokenEnv: string;
|
|
12
|
+
defaultGatewayUrl: string;
|
|
13
|
+
features?: ModelProviderFeatures;
|
|
14
|
+
}
|
|
15
|
+
export type ModelProviderMethod = "GET" | "POST" | "DELETE";
|
|
16
|
+
export interface ModelProviderRoute {
|
|
17
|
+
method: ModelProviderMethod;
|
|
18
|
+
path: string;
|
|
19
|
+
upstream: string;
|
|
20
|
+
json: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function modelProviderRoutes(spec: ModelProviderSpec): ModelProviderRoute[];
|
|
23
|
+
export type AdminProxy = (method: string, path: string, body?: unknown) => Promise<Response>;
|
|
24
|
+
export declare function createAdminProxy(spec: ModelProviderSpec): AdminProxy;
|
|
25
|
+
export interface ModelProviderChannel {
|
|
26
|
+
proxyAdmin: AdminProxy;
|
|
27
|
+
routes: ModelProviderRoute[];
|
|
28
|
+
channel: Channel;
|
|
29
|
+
}
|
|
30
|
+
export declare function defineModelProviderChannel(spec: ModelProviderSpec): ModelProviderChannel;
|
|
31
|
+
//# sourceMappingURL=model-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-providers.d.ts","sourceRoot":"","sources":["../../src/channels/model-providers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAMb,MAAM,cAAc,CAAC;AAyBtB,MAAM,WAAW,qBAAqB;IAGpC,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAGhC,EAAE,EAAE,MAAM,CAAC;IAGX,aAAa,EAAE,MAAM,CAAC;IAEtB,QAAQ,EAAE,MAAM,CAAC;IAEjB,iBAAiB,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,mBAAmB,CAAC;IAE5B,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,MAAM,CAAC;IAEjB,IAAI,EAAE,OAAO,CAAC;CACf;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,EAAE,CA6BjF;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAI7F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAuCpE;AAED,MAAM,WAAW,oBAAoB;IAEnC,UAAU,EAAE,UAAU,CAAC;IAEvB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAE7B,OAAO,EAAE,OAAO,CAAC;CAClB;AAKD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,iBAAiB,GAAG,oBAAoB,CAsBxF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { DELETE, defineChannel, GET, POST, } from "eve/channels";
|
|
2
|
+
import { logger } from "../lib/observability/logger.js";
|
|
3
|
+
export function modelProviderRoutes(spec) {
|
|
4
|
+
const base = `/eve/v1/${spec.id}`;
|
|
5
|
+
const f = spec.features ?? {};
|
|
6
|
+
const route = (method, suffix, json = false) => ({
|
|
7
|
+
method,
|
|
8
|
+
path: `${base}${suffix}`,
|
|
9
|
+
upstream: `/admin${suffix}`,
|
|
10
|
+
json,
|
|
11
|
+
});
|
|
12
|
+
const routes = [
|
|
13
|
+
route("GET", "/accounts"),
|
|
14
|
+
route("POST", "/accounts", true),
|
|
15
|
+
route("POST", "/accounts/order", true),
|
|
16
|
+
route("DELETE", "/accounts/:id"),
|
|
17
|
+
route("POST", "/accounts/:id/login"),
|
|
18
|
+
route("GET", "/accounts/:id/login"),
|
|
19
|
+
route("GET", "/accounts/:id/usage"),
|
|
20
|
+
];
|
|
21
|
+
if (f.loginComplete)
|
|
22
|
+
routes.push(route("POST", "/accounts/:id/login/complete", true));
|
|
23
|
+
if (f.enabled)
|
|
24
|
+
routes.push(route("POST", "/accounts/:id/enabled", true));
|
|
25
|
+
if (f.config)
|
|
26
|
+
routes.push(route("GET", "/config"), route("POST", "/config", true));
|
|
27
|
+
if (f.restart)
|
|
28
|
+
routes.push(route("POST", "/restart"));
|
|
29
|
+
return routes;
|
|
30
|
+
}
|
|
31
|
+
export function createAdminProxy(spec) {
|
|
32
|
+
const log = logger.child({ module: `${spec.id}-channel` });
|
|
33
|
+
const gatewayBase = () => process.env[spec.gatewayUrlEnv] ?? spec.defaultGatewayUrl;
|
|
34
|
+
return async (method, path, body) => {
|
|
35
|
+
const headers = {};
|
|
36
|
+
const token = process.env[spec.tokenEnv];
|
|
37
|
+
if (token)
|
|
38
|
+
headers.authorization = `Bearer ${token}`;
|
|
39
|
+
const init = { method, headers };
|
|
40
|
+
if (body !== undefined) {
|
|
41
|
+
headers["content-type"] = "application/json";
|
|
42
|
+
init.body = JSON.stringify(body);
|
|
43
|
+
}
|
|
44
|
+
let res;
|
|
45
|
+
try {
|
|
46
|
+
res = await fetch(`${gatewayBase()}${path}`, init);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
log.error({ err, path }, `${spec.id} gateway admin unreachable`);
|
|
50
|
+
return Response.json({ error: "gateway admin unreachable" }, { status: 502 });
|
|
51
|
+
}
|
|
52
|
+
if (res.status === 204 || res.status === 205 || res.status === 304) {
|
|
53
|
+
return new Response(null, { status: res.status });
|
|
54
|
+
}
|
|
55
|
+
const text = await res.text();
|
|
56
|
+
return new Response(text, {
|
|
57
|
+
status: res.status,
|
|
58
|
+
headers: { "content-type": res.headers.get("content-type") ?? "application/json" },
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const DEFINE = { GET, POST, DELETE };
|
|
63
|
+
export function defineModelProviderChannel(spec) {
|
|
64
|
+
const proxyAdmin = createAdminProxy(spec);
|
|
65
|
+
const routes = modelProviderRoutes(spec);
|
|
66
|
+
const definitions = routes.map((route) => DEFINE[route.method](route.path, async (req, { params }) => {
|
|
67
|
+
let body;
|
|
68
|
+
if (route.json) {
|
|
69
|
+
try {
|
|
70
|
+
body = await req.json();
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return Response.json({ error: "invalid JSON body" }, { status: 400 });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const upstream = route.upstream.replace(":id", encodeURIComponent(params.id ?? ""));
|
|
77
|
+
return proxyAdmin(route.method, `${upstream}${new URL(req.url).search}`, body);
|
|
78
|
+
}));
|
|
79
|
+
return { proxyAdmin, routes, channel: defineChannel({ routes: definitions }) };
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=model-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-providers.js","sourceRoot":"","sources":["../../src/channels/model-providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,aAAa,EACb,GAAG,EAEH,IAAI,GACL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAmExD,MAAM,UAAU,mBAAmB,CAAC,IAAuB;IACzD,MAAM,IAAI,GAAG,WAAW,IAAI,CAAC,EAAE,EAAE,CAAC;IAClC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,CACZ,MAA2B,EAC3B,MAAc,EACd,IAAI,GAAG,KAAK,EACQ,EAAE,CAAC,CAAC;QACxB,MAAM;QACN,IAAI,EAAE,GAAG,IAAI,GAAG,MAAM,EAAE;QACxB,QAAQ,EAAE,SAAS,MAAM,EAAE;QAC3B,IAAI;KACL,CAAC,CAAC;IACH,MAAM,MAAM,GAAyB;QACnC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC;QACzB,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC;QAEhC,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC;QACtC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC;QAChC,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC;QACpC,KAAK,CAAC,KAAK,EAAE,qBAAqB,CAAC;QAEnC,KAAK,CAAC,KAAK,EAAE,qBAAqB,CAAC;KACpC,CAAC;IACF,IAAI,CAAC,CAAC,aAAa;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,8BAA8B,EAAE,IAAI,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,CAAC,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,CAAC,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC;IAEpF,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAClC,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,KAAK;YAAE,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;QACrD,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAGb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,4BAA4B,CAAC,CAAC;YACjE,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAChF,CAAC;QAQD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACnE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;YACxB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,kBAAkB,EAAE;SACnF,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAWD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAW,CAAC;AAG9C,MAAM,UAAU,0BAA0B,CAAC,IAAuB;IAChE,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEzC,MAAM,WAAW,GAA0B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC9D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACzD,IAAI,IAAa,CAAC;QAClB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAGpF,OAAO,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IACjF,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AACjF,CAAC"}
|
|
@@ -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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"}
|