@relaycast/engine 4.2.0 → 5.0.1
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/adapters/node/index.d.ts.map +1 -1
- package/dist/adapters/node/index.js +23 -1
- package/dist/adapters/node/index.js.map +1 -1
- package/dist/adapters/node/presence.d.ts +7 -3
- package/dist/adapters/node/presence.d.ts.map +1 -1
- package/dist/adapters/node/presence.js +10 -8
- package/dist/adapters/node/presence.js.map +1 -1
- package/dist/adapters/node/realtime.d.ts +9 -1
- package/dist/adapters/node/realtime.d.ts.map +1 -1
- package/dist/adapters/node/realtime.js +72 -10
- package/dist/adapters/node/realtime.js.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +31 -9
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/tokenKind.d.ts +40 -0
- package/dist/auth/tokenKind.d.ts.map +1 -0
- package/dist/auth/tokenKind.js +89 -0
- package/dist/auth/tokenKind.js.map +1 -0
- package/dist/bin/serve.js +2 -4
- package/dist/bin/serve.js.map +1 -1
- package/dist/db/migrations/0021_node_delivery_contracts.sql +70 -0
- package/dist/db/migrations/0022_http_push_redrive.sql +13 -0
- package/dist/db/migrations/0023_direct_ws_nodes.sql +124 -0
- package/dist/db/migrations/0024_binding_workspace_constraints.sql +109 -0
- package/dist/db/migrations/0025_node_kind_role_adapter.sql +45 -0
- package/dist/db/migrations/0026_observer_tokens.sql +32 -0
- package/dist/db/schema.d.ts +727 -59
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +78 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/engine/action.d.ts +2 -9
- package/dist/engine/action.d.ts.map +1 -1
- package/dist/engine/action.js +182 -14
- package/dist/engine/action.js.map +1 -1
- package/dist/engine/activity.d.ts +6 -0
- package/dist/engine/activity.d.ts.map +1 -1
- package/dist/engine/activity.js +9 -2
- package/dist/engine/activity.js.map +1 -1
- package/dist/engine/agent.d.ts +0 -33
- package/dist/engine/agent.d.ts.map +1 -1
- package/dist/engine/agent.js +4 -153
- package/dist/engine/agent.js.map +1 -1
- package/dist/engine/attachments.d.ts +6 -0
- package/dist/engine/attachments.d.ts.map +1 -1
- package/dist/engine/attachments.js +37 -0
- package/dist/engine/attachments.js.map +1 -1
- package/dist/engine/console.d.ts +78 -1
- package/dist/engine/console.d.ts.map +1 -1
- package/dist/engine/console.js +175 -19
- package/dist/engine/console.js.map +1 -1
- package/dist/engine/delivery.d.ts +26 -0
- package/dist/engine/delivery.d.ts.map +1 -1
- package/dist/engine/delivery.js +194 -74
- package/dist/engine/delivery.js.map +1 -1
- package/dist/engine/deliveryWire.d.ts +4 -0
- package/dist/engine/deliveryWire.d.ts.map +1 -1
- package/dist/engine/deliveryWire.js +2 -0
- package/dist/engine/deliveryWire.js.map +1 -1
- package/dist/engine/deliveryWrites.d.ts +6 -0
- package/dist/engine/deliveryWrites.d.ts.map +1 -1
- package/dist/engine/deliveryWrites.js +58 -13
- package/dist/engine/deliveryWrites.js.map +1 -1
- package/dist/engine/dm.d.ts.map +1 -1
- package/dist/engine/dm.js +11 -33
- package/dist/engine/dm.js.map +1 -1
- package/dist/engine/dmAll.d.ts.map +1 -1
- package/dist/engine/dmAll.js +2 -0
- package/dist/engine/dmAll.js.map +1 -1
- package/dist/engine/groupDm.d.ts +2 -3
- package/dist/engine/groupDm.d.ts.map +1 -1
- package/dist/engine/groupDm.js +8 -26
- package/dist/engine/groupDm.js.map +1 -1
- package/dist/engine/invocationCompletion.d.ts +1 -1
- package/dist/engine/invocationCompletion.d.ts.map +1 -1
- package/dist/engine/invocationCompletion.js +10 -18
- package/dist/engine/invocationCompletion.js.map +1 -1
- package/dist/engine/message.d.ts.map +1 -1
- package/dist/engine/message.js +16 -44
- package/dist/engine/message.js.map +1 -1
- package/dist/engine/node.d.ts +97 -0
- package/dist/engine/node.d.ts.map +1 -1
- package/dist/engine/node.js +555 -27
- package/dist/engine/node.js.map +1 -1
- package/dist/engine/nodeContext.d.ts +22 -0
- package/dist/engine/nodeContext.d.ts.map +1 -0
- package/dist/engine/nodeContext.js +80 -0
- package/dist/engine/nodeContext.js.map +1 -0
- package/dist/engine/nodeDeliver.d.ts +23 -0
- package/dist/engine/nodeDeliver.d.ts.map +1 -0
- package/dist/engine/nodeDeliver.js +81 -0
- package/dist/engine/nodeDeliver.js.map +1 -0
- package/dist/engine/observerToken.d.ts +110 -0
- package/dist/engine/observerToken.d.ts.map +1 -0
- package/dist/engine/observerToken.js +528 -0
- package/dist/engine/observerToken.js.map +1 -0
- package/dist/engine/search.d.ts +4 -0
- package/dist/engine/search.d.ts.map +1 -1
- package/dist/engine/search.js +6 -1
- package/dist/engine/search.js.map +1 -1
- package/dist/engine/thread.d.ts +4 -3
- package/dist/engine/thread.d.ts.map +1 -1
- package/dist/engine/thread.js +45 -17
- package/dist/engine/thread.js.map +1 -1
- package/dist/engine/wsAuth.d.ts +32 -0
- package/dist/engine/wsAuth.d.ts.map +1 -0
- package/dist/engine/wsAuth.js +65 -0
- package/dist/engine/wsAuth.js.map +1 -0
- package/dist/engine/wsTransform.d.ts.map +1 -1
- package/dist/engine/wsTransform.js +52 -36
- package/dist/engine/wsTransform.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +37 -86
- package/dist/engine.js.map +1 -1
- package/dist/entrypoints/node.d.ts.map +1 -1
- package/dist/entrypoints/node.js +20 -57
- package/dist/entrypoints/node.js.map +1 -1
- package/dist/env.d.ts +3 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/httpError.d.ts +5 -1
- package/dist/lib/httpError.d.ts.map +1 -1
- package/dist/lib/httpError.js +5 -2
- package/dist/lib/httpError.js.map +1 -1
- package/dist/lib/httpQuery.d.ts +28 -0
- package/dist/lib/httpQuery.d.ts.map +1 -0
- package/dist/lib/httpQuery.js +32 -0
- package/dist/lib/httpQuery.js.map +1 -0
- package/dist/lib/httpResponse.d.ts +15 -2
- package/dist/lib/httpResponse.d.ts.map +1 -1
- package/dist/lib/httpResponse.js +35 -7
- package/dist/lib/httpResponse.js.map +1 -1
- package/dist/middleware/auth.d.ts +8 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +65 -2
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +30 -0
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +14 -0
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/logger.d.ts.map +1 -1
- package/dist/middleware/logger.js +4 -4
- package/dist/middleware/logger.js.map +1 -1
- package/dist/middleware/planLimits.d.ts.map +1 -1
- package/dist/middleware/planLimits.js +11 -9
- package/dist/middleware/planLimits.js.map +1 -1
- package/dist/middleware/rateLimit.d.ts.map +1 -1
- package/dist/middleware/rateLimit.js +15 -8
- package/dist/middleware/rateLimit.js.map +1 -1
- package/dist/middleware/usageTracker.d.ts.map +1 -1
- package/dist/middleware/usageTracker.js +2 -1
- package/dist/middleware/usageTracker.js.map +1 -1
- package/dist/ports/auth.d.ts +6 -2
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/entitlements.d.ts +3 -1
- package/dist/ports/entitlements.d.ts.map +1 -1
- package/dist/ports/index.d.ts +0 -14
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/realtime.d.ts +4 -1
- package/dist/ports/realtime.d.ts.map +1 -1
- package/dist/providers/static-entitlements.js +4 -4
- package/dist/providers/static-entitlements.js.map +1 -1
- package/dist/routes/a2a.d.ts.map +1 -1
- package/dist/routes/a2a.js +41 -83
- package/dist/routes/a2a.js.map +1 -1
- package/dist/routes/action.d.ts.map +1 -1
- package/dist/routes/action.js +45 -42
- package/dist/routes/action.js.map +1 -1
- package/dist/routes/agent.d.ts.map +1 -1
- package/dist/routes/agent.js +172 -120
- package/dist/routes/agent.js.map +1 -1
- package/dist/routes/certify.d.ts.map +1 -1
- package/dist/routes/certify.js +21 -35
- package/dist/routes/certify.js.map +1 -1
- package/dist/routes/channel.d.ts.map +1 -1
- package/dist/routes/channel.js +69 -81
- package/dist/routes/channel.js.map +1 -1
- package/dist/routes/console.d.ts.map +1 -1
- package/dist/routes/console.js +60 -40
- package/dist/routes/console.js.map +1 -1
- package/dist/routes/delivery.d.ts.map +1 -1
- package/dist/routes/delivery.js +22 -54
- package/dist/routes/delivery.js.map +1 -1
- package/dist/routes/deliveryRouting.d.ts +6 -0
- package/dist/routes/deliveryRouting.d.ts.map +1 -1
- package/dist/routes/deliveryRouting.js +297 -34
- package/dist/routes/deliveryRouting.js.map +1 -1
- package/dist/routes/directory.d.ts.map +1 -1
- package/dist/routes/directory.js +47 -63
- package/dist/routes/directory.js.map +1 -1
- package/dist/routes/dm.d.ts.map +1 -1
- package/dist/routes/dm.js +21 -42
- package/dist/routes/dm.js.map +1 -1
- package/dist/routes/fanout.d.ts +2 -1
- package/dist/routes/fanout.d.ts.map +1 -1
- package/dist/routes/fanout.js +38 -20
- package/dist/routes/fanout.js.map +1 -1
- package/dist/routes/file.d.ts.map +1 -1
- package/dist/routes/file.js +48 -44
- package/dist/routes/file.js.map +1 -1
- package/dist/routes/groupDm.d.ts.map +1 -1
- package/dist/routes/groupDm.js +23 -48
- package/dist/routes/groupDm.js.map +1 -1
- package/dist/routes/inboundWebhook.d.ts.map +1 -1
- package/dist/routes/inboundWebhook.js +17 -35
- package/dist/routes/inboundWebhook.js.map +1 -1
- package/dist/routes/inbox.d.ts.map +1 -1
- package/dist/routes/inbox.js +2 -1
- package/dist/routes/inbox.js.map +1 -1
- package/dist/routes/message.d.ts.map +1 -1
- package/dist/routes/message.js +60 -53
- package/dist/routes/message.js.map +1 -1
- package/dist/routes/node.d.ts.map +1 -1
- package/dist/routes/node.js +173 -10
- package/dist/routes/node.js.map +1 -1
- package/dist/routes/observerToken.d.ts +4 -0
- package/dist/routes/observerToken.d.ts.map +1 -0
- package/dist/routes/observerToken.js +105 -0
- package/dist/routes/observerToken.js.map +1 -0
- package/dist/routes/presence.d.ts.map +1 -1
- package/dist/routes/presence.js +10 -6
- package/dist/routes/presence.js.map +1 -1
- package/dist/routes/reaction.d.ts.map +1 -1
- package/dist/routes/reaction.js +69 -28
- package/dist/routes/reaction.js.map +1 -1
- package/dist/routes/receipt.d.ts.map +1 -1
- package/dist/routes/receipt.js +20 -3
- package/dist/routes/receipt.js.map +1 -1
- package/dist/routes/routing.d.ts.map +1 -1
- package/dist/routes/routing.js +38 -51
- package/dist/routes/routing.js.map +1 -1
- package/dist/routes/search.d.ts.map +1 -1
- package/dist/routes/search.js +21 -15
- package/dist/routes/search.js.map +1 -1
- package/dist/routes/thread.d.ts.map +1 -1
- package/dist/routes/thread.js +36 -37
- package/dist/routes/thread.js.map +1 -1
- package/dist/routes/workspace.d.ts.map +1 -1
- package/dist/routes/workspace.js +57 -225
- package/dist/routes/workspace.js.map +1 -1
- package/package.json +3 -3
- package/dist/lib/fleetNodes.d.ts +0 -9
- package/dist/lib/fleetNodes.d.ts.map +0 -1
- package/dist/lib/fleetNodes.js +0 -66
- package/dist/lib/fleetNodes.js.map +0 -1
- package/dist/lib/workspaceStream.d.ts +0 -9
- package/dist/lib/workspaceStream.d.ts.map +0 -1
- package/dist/lib/workspaceStream.js +0 -53
- package/dist/lib/workspaceStream.js.map +0 -1
- package/dist/middleware/fleetNodes.d.ts +0 -10
- package/dist/middleware/fleetNodes.d.ts.map +0 -1
- package/dist/middleware/fleetNodes.js +0 -18
- package/dist/middleware/fleetNodes.js.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const tokenKindConfig = {
|
|
3
|
+
workspace: {
|
|
4
|
+
prefix: 'rk_live_',
|
|
5
|
+
requiredMessage: 'Workspace key required (rk_live_...)',
|
|
6
|
+
},
|
|
7
|
+
agent: {
|
|
8
|
+
prefix: 'at_live_',
|
|
9
|
+
requiredMessage: 'Agent token required (at_live_...)',
|
|
10
|
+
},
|
|
11
|
+
node: {
|
|
12
|
+
prefix: 'nt_live_',
|
|
13
|
+
requiredMessage: 'Node token required (nt_live_...)',
|
|
14
|
+
},
|
|
15
|
+
observer: {
|
|
16
|
+
prefix: 'ot_live_',
|
|
17
|
+
requiredMessage: 'Observer token required (ot_live_...)',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
const workspaceTokenSchema = z
|
|
21
|
+
.string()
|
|
22
|
+
.startsWith(tokenKindConfig.workspace.prefix)
|
|
23
|
+
.transform((token) => ({ kind: 'workspace', token }));
|
|
24
|
+
const agentTokenSchema = z
|
|
25
|
+
.string()
|
|
26
|
+
.startsWith(tokenKindConfig.agent.prefix)
|
|
27
|
+
.transform((token) => ({ kind: 'agent', token }));
|
|
28
|
+
const nodeTokenSchema = z
|
|
29
|
+
.string()
|
|
30
|
+
.startsWith(tokenKindConfig.node.prefix)
|
|
31
|
+
.transform((token) => ({ kind: 'node', token }));
|
|
32
|
+
const observerTokenSchema = z
|
|
33
|
+
.string()
|
|
34
|
+
.startsWith(tokenKindConfig.observer.prefix)
|
|
35
|
+
.transform((token) => ({ kind: 'observer', token }));
|
|
36
|
+
export const authTokenSchema = z.union([
|
|
37
|
+
workspaceTokenSchema,
|
|
38
|
+
agentTokenSchema,
|
|
39
|
+
nodeTokenSchema,
|
|
40
|
+
observerTokenSchema,
|
|
41
|
+
]);
|
|
42
|
+
export function parseAuthToken(token) {
|
|
43
|
+
const parsed = authTokenSchema.safeParse(token);
|
|
44
|
+
return parsed.success ? parsed.data : undefined;
|
|
45
|
+
}
|
|
46
|
+
export function getAuthTokenKind(token) {
|
|
47
|
+
return parseAuthToken(token)?.kind;
|
|
48
|
+
}
|
|
49
|
+
export function requiredTokenMessage(kind) {
|
|
50
|
+
return tokenKindConfig[kind].requiredMessage;
|
|
51
|
+
}
|
|
52
|
+
const allowedKindsByRequire = {
|
|
53
|
+
workspace: ['workspace'],
|
|
54
|
+
agent: ['agent'],
|
|
55
|
+
node: ['node'],
|
|
56
|
+
observer: ['observer'],
|
|
57
|
+
// `any` intentionally means user/workspace API credentials, not transport-only
|
|
58
|
+
// node credentials or scoped observer credentials.
|
|
59
|
+
any: ['workspace', 'agent'],
|
|
60
|
+
};
|
|
61
|
+
export function validateTokenRequirement(tokenKind, require) {
|
|
62
|
+
const allowedKinds = allowedKindsByRequire[require];
|
|
63
|
+
if (allowedKinds.includes(tokenKind)) {
|
|
64
|
+
return { ok: true };
|
|
65
|
+
}
|
|
66
|
+
if (tokenKind === 'node') {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
code: 'node_token_forbidden',
|
|
70
|
+
message: 'Node token cannot perform this operation',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (tokenKind === 'observer') {
|
|
74
|
+
return {
|
|
75
|
+
ok: false,
|
|
76
|
+
code: 'observer_token_forbidden',
|
|
77
|
+
message: 'Observer token cannot perform this operation',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (require === 'any') {
|
|
81
|
+
return { ok: false, code: 'unauthorized', message: 'Invalid token format' };
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
code: 'unauthorized',
|
|
86
|
+
message: requiredTokenMessage(require),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=tokenKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenKind.js","sourceRoot":"","sources":["../../src/auth/tokenKind.ts"],"names":[],"mappings":"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"}
|
package/dist/bin/serve.js
CHANGED
|
@@ -50,9 +50,8 @@ async function main() {
|
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
const baseUrl = opts.baseUrl ?? `http://localhost:${opts.port}`;
|
|
53
|
-
// Optional self-host tuning via env:
|
|
54
|
-
//
|
|
55
|
-
// TTL / small depth cap without code changes.
|
|
53
|
+
// Optional self-host tuning via env: bounded mailbox TTL / depth cap. Lets
|
|
54
|
+
// operators configure a short TTL / small depth cap without code changes.
|
|
56
55
|
const num = (v) => {
|
|
57
56
|
if (v == null || v.trim() === '')
|
|
58
57
|
return undefined;
|
|
@@ -69,7 +68,6 @@ async function main() {
|
|
|
69
68
|
baseUrl,
|
|
70
69
|
config: {
|
|
71
70
|
environment: opts.environment,
|
|
72
|
-
...(process.env.RELAYCAST_FLEET_NODES_ENABLED === '1' ? { fleetNodesEnabled: true } : {}),
|
|
73
71
|
...(Object.keys(mailbox).length > 0 ? { mailbox } : {}),
|
|
74
72
|
},
|
|
75
73
|
});
|
package/dist/bin/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/bin/serve.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,IAAI,GAAG;;;;;;;;;;;;;;CAcZ,CAAC;AAUF,SAAS,SAAS,CAAC,IAAc,EAAE,GAAsB;IACvD,MAAM,GAAG,GAAc;QACrB,EAAE,EAAE,GAAG,CAAC,iBAAiB,IAAI,gBAAgB;QAC7C,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACxC,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,GAAG,CAAC,aAAa,IAAI,YAAY;QAC9C,IAAI,EAAE,KAAK;KACZ,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;YAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;aACjD,IAAI,GAAG,KAAK,MAAM;YAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;aACjD,IAAI,GAAG,KAAK,QAAQ;YAAE,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;aAC/D,IAAI,GAAG,KAAK,YAAY;YAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;aAClD,IAAI,GAAG,KAAK,OAAO;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC;IAC3E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;IAChE
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/bin/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
-- Nodes as routeable delivery hosts, with explicit delivery contracts.
|
|
2
|
+
|
|
3
|
+
ALTER TABLE nodes ADD COLUMN kind TEXT NOT NULL DEFAULT 'fleet_ws';
|
|
4
|
+
ALTER TABLE nodes ADD COLUMN delivery_adapter TEXT NOT NULL DEFAULT 'fleet.ws.v1';
|
|
5
|
+
ALTER TABLE nodes ADD COLUMN delivery_config TEXT DEFAULT NULL;
|
|
6
|
+
|
|
7
|
+
CREATE TABLE IF NOT EXISTS agent_node_bindings (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
10
|
+
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
|
11
|
+
node_id TEXT NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
12
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
13
|
+
session_ref TEXT,
|
|
14
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
15
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
16
|
+
updated_at INTEGER,
|
|
17
|
+
UNIQUE(agent_id, node_id)
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_workspace
|
|
21
|
+
ON agent_node_bindings(workspace_id, status);
|
|
22
|
+
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_agent
|
|
24
|
+
ON agent_node_bindings(workspace_id, agent_id, status);
|
|
25
|
+
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_node
|
|
27
|
+
ON agent_node_bindings(workspace_id, node_id, status);
|
|
28
|
+
|
|
29
|
+
-- Backfill explicit bindings for existing fleet-hosted agents.
|
|
30
|
+
INSERT OR IGNORE INTO agent_node_bindings (
|
|
31
|
+
id,
|
|
32
|
+
workspace_id,
|
|
33
|
+
agent_id,
|
|
34
|
+
node_id,
|
|
35
|
+
status,
|
|
36
|
+
session_ref,
|
|
37
|
+
priority,
|
|
38
|
+
created_at
|
|
39
|
+
)
|
|
40
|
+
SELECT
|
|
41
|
+
'anb_' || id,
|
|
42
|
+
workspace_id,
|
|
43
|
+
id,
|
|
44
|
+
location_node_id,
|
|
45
|
+
'active',
|
|
46
|
+
session_ref,
|
|
47
|
+
0,
|
|
48
|
+
unixepoch()
|
|
49
|
+
FROM agents
|
|
50
|
+
WHERE location_type = 'via_node'
|
|
51
|
+
AND location_node_id IS NOT NULL;
|
|
52
|
+
|
|
53
|
+
ALTER TABLE deliveries ADD COLUMN route_node_id TEXT DEFAULT NULL REFERENCES nodes(id) ON DELETE SET NULL;
|
|
54
|
+
ALTER TABLE deliveries ADD COLUMN route_node_kind TEXT DEFAULT NULL;
|
|
55
|
+
ALTER TABLE deliveries ADD COLUMN delivery_adapter TEXT DEFAULT NULL;
|
|
56
|
+
ALTER TABLE deliveries ADD COLUMN dispatch_attempts INTEGER NOT NULL DEFAULT 0;
|
|
57
|
+
ALTER TABLE deliveries ADD COLUMN next_attempt_at INTEGER DEFAULT NULL;
|
|
58
|
+
ALTER TABLE deliveries ADD COLUMN last_dispatch_error TEXT DEFAULT NULL;
|
|
59
|
+
|
|
60
|
+
UPDATE deliveries
|
|
61
|
+
SET
|
|
62
|
+
route_node_id = location_node_id,
|
|
63
|
+
route_node_kind = CASE WHEN location_node_id IS NOT NULL THEN 'fleet_ws' ELSE NULL END,
|
|
64
|
+
delivery_adapter = CASE WHEN location_node_id IS NOT NULL THEN 'fleet.ws.v1' ELSE NULL END;
|
|
65
|
+
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_deliveries_route_node
|
|
67
|
+
ON deliveries(workspace_id, route_node_id, status, seq);
|
|
68
|
+
|
|
69
|
+
CREATE INDEX IF NOT EXISTS idx_deliveries_next_attempt
|
|
70
|
+
ON deliveries(workspace_id, status, next_attempt_at);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Keep due HTTP push retries cheap and reconcile binding-backed capacity counts.
|
|
2
|
+
|
|
3
|
+
CREATE INDEX IF NOT EXISTS idx_deliveries_http_push_due
|
|
4
|
+
ON deliveries(workspace_id, route_node_kind, status, next_attempt_at);
|
|
5
|
+
|
|
6
|
+
UPDATE nodes
|
|
7
|
+
SET active_agents = (
|
|
8
|
+
SELECT COUNT(*)
|
|
9
|
+
FROM agent_node_bindings b
|
|
10
|
+
WHERE b.workspace_id = nodes.workspace_id
|
|
11
|
+
AND b.node_id = nodes.id
|
|
12
|
+
AND b.status = 'active'
|
|
13
|
+
);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
-- Every agent has exactly one node route. Backfill legacy self-connected agents
|
|
2
|
+
-- as implicit direct_ws nodes-of-one.
|
|
3
|
+
|
|
4
|
+
INSERT OR IGNORE INTO nodes (
|
|
5
|
+
id,
|
|
6
|
+
workspace_id,
|
|
7
|
+
name,
|
|
8
|
+
token_hash,
|
|
9
|
+
kind,
|
|
10
|
+
delivery_adapter,
|
|
11
|
+
delivery_config,
|
|
12
|
+
capabilities,
|
|
13
|
+
max_agents,
|
|
14
|
+
active_agents,
|
|
15
|
+
reserved_agents,
|
|
16
|
+
tags,
|
|
17
|
+
version,
|
|
18
|
+
status,
|
|
19
|
+
handlers_live,
|
|
20
|
+
load,
|
|
21
|
+
last_heartbeat_at,
|
|
22
|
+
created_at
|
|
23
|
+
)
|
|
24
|
+
SELECT
|
|
25
|
+
'node_direct_' || a.id,
|
|
26
|
+
a.workspace_id,
|
|
27
|
+
'direct-' || a.id,
|
|
28
|
+
'implicit_direct:' || a.workspace_id || ':' || a.id,
|
|
29
|
+
'direct_ws',
|
|
30
|
+
'direct.ws.v1',
|
|
31
|
+
json_object('implicit', 1, 'agent_id', a.id, 'agent_name', a.name),
|
|
32
|
+
json_array(),
|
|
33
|
+
1,
|
|
34
|
+
1,
|
|
35
|
+
0,
|
|
36
|
+
json_array('implicit', 'direct_ws'),
|
|
37
|
+
'implicit',
|
|
38
|
+
CASE WHEN a.status IN ('active', 'online') THEN 'online' ELSE 'offline' END,
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
CASE WHEN a.status IN ('active', 'online') THEN unixepoch() ELSE NULL END,
|
|
42
|
+
unixepoch()
|
|
43
|
+
FROM agents a
|
|
44
|
+
WHERE NOT EXISTS (
|
|
45
|
+
SELECT 1
|
|
46
|
+
FROM agent_node_bindings b
|
|
47
|
+
WHERE b.workspace_id = a.workspace_id
|
|
48
|
+
AND b.agent_id = a.id
|
|
49
|
+
AND b.status = 'active'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
INSERT OR IGNORE INTO agent_node_bindings (
|
|
53
|
+
id,
|
|
54
|
+
workspace_id,
|
|
55
|
+
agent_id,
|
|
56
|
+
node_id,
|
|
57
|
+
status,
|
|
58
|
+
session_ref,
|
|
59
|
+
priority,
|
|
60
|
+
created_at,
|
|
61
|
+
updated_at
|
|
62
|
+
)
|
|
63
|
+
SELECT
|
|
64
|
+
'anb_direct_' || a.id,
|
|
65
|
+
a.workspace_id,
|
|
66
|
+
a.id,
|
|
67
|
+
'node_direct_' || a.id,
|
|
68
|
+
'active',
|
|
69
|
+
a.session_ref,
|
|
70
|
+
0,
|
|
71
|
+
unixepoch(),
|
|
72
|
+
unixepoch()
|
|
73
|
+
FROM agents a
|
|
74
|
+
WHERE EXISTS (
|
|
75
|
+
SELECT 1
|
|
76
|
+
FROM nodes n
|
|
77
|
+
WHERE n.workspace_id = a.workspace_id
|
|
78
|
+
AND n.id = 'node_direct_' || a.id
|
|
79
|
+
AND n.kind = 'direct_ws'
|
|
80
|
+
)
|
|
81
|
+
AND NOT EXISTS (
|
|
82
|
+
SELECT 1
|
|
83
|
+
FROM agent_node_bindings b
|
|
84
|
+
WHERE b.workspace_id = a.workspace_id
|
|
85
|
+
AND b.agent_id = a.id
|
|
86
|
+
AND b.status = 'active'
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
UPDATE agents
|
|
90
|
+
SET
|
|
91
|
+
location_type = 'via_node',
|
|
92
|
+
location_node_id = 'node_direct_' || id,
|
|
93
|
+
origin_node_id = COALESCE(origin_node_id, 'node_direct_' || id)
|
|
94
|
+
WHERE EXISTS (
|
|
95
|
+
SELECT 1
|
|
96
|
+
FROM agent_node_bindings b
|
|
97
|
+
WHERE b.workspace_id = agents.workspace_id
|
|
98
|
+
AND b.agent_id = agents.id
|
|
99
|
+
AND b.node_id = 'node_direct_' || agents.id
|
|
100
|
+
AND b.status = 'active'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
UPDATE deliveries
|
|
104
|
+
SET
|
|
105
|
+
route_node_id = 'node_direct_' || agent_id,
|
|
106
|
+
route_node_kind = 'direct_ws',
|
|
107
|
+
delivery_adapter = 'direct.ws.v1'
|
|
108
|
+
WHERE route_node_id IS NULL
|
|
109
|
+
AND EXISTS (
|
|
110
|
+
SELECT 1
|
|
111
|
+
FROM agents a
|
|
112
|
+
WHERE a.workspace_id = deliveries.workspace_id
|
|
113
|
+
AND a.id = deliveries.agent_id
|
|
114
|
+
AND a.location_node_id = 'node_direct_' || a.id
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
UPDATE nodes
|
|
118
|
+
SET active_agents = (
|
|
119
|
+
SELECT COUNT(*)
|
|
120
|
+
FROM agent_node_bindings b
|
|
121
|
+
WHERE b.workspace_id = nodes.workspace_id
|
|
122
|
+
AND b.node_id = nodes.id
|
|
123
|
+
AND b.status = 'active'
|
|
124
|
+
);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
-- Additive follow-up for environments that already ran 0021 before
|
|
2
|
+
-- workspace-consistent binding constraints were introduced.
|
|
3
|
+
|
|
4
|
+
CREATE UNIQUE INDEX IF NOT EXISTS agents_workspace_id_unique
|
|
5
|
+
ON agents(workspace_id, id);
|
|
6
|
+
|
|
7
|
+
CREATE UNIQUE INDEX IF NOT EXISTS nodes_workspace_id_unique
|
|
8
|
+
ON nodes(workspace_id, id);
|
|
9
|
+
|
|
10
|
+
CREATE TABLE IF NOT EXISTS agent_node_bindings_constrained (
|
|
11
|
+
id TEXT PRIMARY KEY,
|
|
12
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
13
|
+
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
|
14
|
+
node_id TEXT NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
15
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
16
|
+
session_ref TEXT,
|
|
17
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
18
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
19
|
+
updated_at INTEGER,
|
|
20
|
+
FOREIGN KEY(workspace_id, agent_id) REFERENCES agents(workspace_id, id) ON DELETE CASCADE,
|
|
21
|
+
FOREIGN KEY(workspace_id, node_id) REFERENCES nodes(workspace_id, id) ON DELETE CASCADE,
|
|
22
|
+
UNIQUE(agent_id, node_id)
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
INSERT OR IGNORE INTO agent_node_bindings_constrained (
|
|
26
|
+
id,
|
|
27
|
+
workspace_id,
|
|
28
|
+
agent_id,
|
|
29
|
+
node_id,
|
|
30
|
+
status,
|
|
31
|
+
session_ref,
|
|
32
|
+
priority,
|
|
33
|
+
created_at,
|
|
34
|
+
updated_at
|
|
35
|
+
)
|
|
36
|
+
SELECT
|
|
37
|
+
b.id,
|
|
38
|
+
b.workspace_id,
|
|
39
|
+
b.agent_id,
|
|
40
|
+
b.node_id,
|
|
41
|
+
b.status,
|
|
42
|
+
b.session_ref,
|
|
43
|
+
b.priority,
|
|
44
|
+
b.created_at,
|
|
45
|
+
b.updated_at
|
|
46
|
+
FROM agent_node_bindings b
|
|
47
|
+
INNER JOIN agents a
|
|
48
|
+
ON a.workspace_id = b.workspace_id
|
|
49
|
+
AND a.id = b.agent_id
|
|
50
|
+
INNER JOIN nodes n
|
|
51
|
+
ON n.workspace_id = b.workspace_id
|
|
52
|
+
AND n.id = b.node_id;
|
|
53
|
+
|
|
54
|
+
DROP TABLE agent_node_bindings;
|
|
55
|
+
|
|
56
|
+
ALTER TABLE agent_node_bindings_constrained RENAME TO agent_node_bindings;
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_workspace
|
|
59
|
+
ON agent_node_bindings(workspace_id, status);
|
|
60
|
+
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_agent
|
|
62
|
+
ON agent_node_bindings(workspace_id, agent_id, status);
|
|
63
|
+
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_agent_node_bindings_node
|
|
65
|
+
ON agent_node_bindings(workspace_id, node_id, status);
|
|
66
|
+
|
|
67
|
+
CREATE TRIGGER IF NOT EXISTS agent_node_bindings_workspace_agent_insert
|
|
68
|
+
BEFORE INSERT ON agent_node_bindings
|
|
69
|
+
WHEN NOT EXISTS (
|
|
70
|
+
SELECT 1 FROM agents a
|
|
71
|
+
WHERE a.workspace_id = NEW.workspace_id
|
|
72
|
+
AND a.id = NEW.agent_id
|
|
73
|
+
)
|
|
74
|
+
BEGIN
|
|
75
|
+
SELECT RAISE(ABORT, 'agent_node_bindings workspace/agent mismatch');
|
|
76
|
+
END;
|
|
77
|
+
|
|
78
|
+
CREATE TRIGGER IF NOT EXISTS agent_node_bindings_workspace_node_insert
|
|
79
|
+
BEFORE INSERT ON agent_node_bindings
|
|
80
|
+
WHEN NOT EXISTS (
|
|
81
|
+
SELECT 1 FROM nodes n
|
|
82
|
+
WHERE n.workspace_id = NEW.workspace_id
|
|
83
|
+
AND n.id = NEW.node_id
|
|
84
|
+
)
|
|
85
|
+
BEGIN
|
|
86
|
+
SELECT RAISE(ABORT, 'agent_node_bindings workspace/node mismatch');
|
|
87
|
+
END;
|
|
88
|
+
|
|
89
|
+
CREATE TRIGGER IF NOT EXISTS agent_node_bindings_workspace_agent_update
|
|
90
|
+
BEFORE UPDATE OF workspace_id, agent_id ON agent_node_bindings
|
|
91
|
+
WHEN NOT EXISTS (
|
|
92
|
+
SELECT 1 FROM agents a
|
|
93
|
+
WHERE a.workspace_id = NEW.workspace_id
|
|
94
|
+
AND a.id = NEW.agent_id
|
|
95
|
+
)
|
|
96
|
+
BEGIN
|
|
97
|
+
SELECT RAISE(ABORT, 'agent_node_bindings workspace/agent mismatch');
|
|
98
|
+
END;
|
|
99
|
+
|
|
100
|
+
CREATE TRIGGER IF NOT EXISTS agent_node_bindings_workspace_node_update
|
|
101
|
+
BEFORE UPDATE OF workspace_id, node_id ON agent_node_bindings
|
|
102
|
+
WHEN NOT EXISTS (
|
|
103
|
+
SELECT 1 FROM nodes n
|
|
104
|
+
WHERE n.workspace_id = NEW.workspace_id
|
|
105
|
+
AND n.id = NEW.node_id
|
|
106
|
+
)
|
|
107
|
+
BEGIN
|
|
108
|
+
SELECT RAISE(ABORT, 'agent_node_bindings workspace/node mismatch');
|
|
109
|
+
END;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
-- Split node kind (transport) from node role (ownership/capability) and
|
|
2
|
+
-- collapse WebSocket delivery onto one node envelope.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE nodes ADD COLUMN role TEXT NOT NULL DEFAULT 'broker';
|
|
5
|
+
ALTER TABLE deliveries ADD COLUMN route_node_role TEXT DEFAULT NULL;
|
|
6
|
+
|
|
7
|
+
UPDATE nodes
|
|
8
|
+
SET
|
|
9
|
+
role = CASE
|
|
10
|
+
WHEN kind = 'direct_ws' THEN 'direct'
|
|
11
|
+
WHEN kind = 'fleet_ws' THEN 'broker'
|
|
12
|
+
WHEN kind = 'http_push' AND max_agents = 1 THEN 'direct'
|
|
13
|
+
WHEN kind = 'http_push' THEN 'broker'
|
|
14
|
+
ELSE role
|
|
15
|
+
END,
|
|
16
|
+
kind = CASE
|
|
17
|
+
WHEN kind IN ('direct_ws', 'fleet_ws') THEN 'ws'
|
|
18
|
+
ELSE kind
|
|
19
|
+
END,
|
|
20
|
+
delivery_adapter = CASE
|
|
21
|
+
WHEN delivery_adapter IN ('direct.ws.v1', 'fleet.ws.v1') THEN 'ws.node.v1'
|
|
22
|
+
ELSE delivery_adapter
|
|
23
|
+
END;
|
|
24
|
+
|
|
25
|
+
UPDATE deliveries
|
|
26
|
+
SET
|
|
27
|
+
route_node_role = CASE
|
|
28
|
+
WHEN route_node_kind = 'direct_ws' THEN 'direct'
|
|
29
|
+
WHEN route_node_kind = 'fleet_ws' THEN 'broker'
|
|
30
|
+
WHEN route_node_id IS NOT NULL THEN (
|
|
31
|
+
SELECT n.role
|
|
32
|
+
FROM nodes n
|
|
33
|
+
WHERE n.workspace_id = deliveries.workspace_id
|
|
34
|
+
AND n.id = deliveries.route_node_id
|
|
35
|
+
)
|
|
36
|
+
ELSE NULL
|
|
37
|
+
END,
|
|
38
|
+
route_node_kind = CASE
|
|
39
|
+
WHEN route_node_kind IN ('direct_ws', 'fleet_ws') THEN 'ws'
|
|
40
|
+
ELSE route_node_kind
|
|
41
|
+
END,
|
|
42
|
+
delivery_adapter = CASE
|
|
43
|
+
WHEN delivery_adapter IN ('direct.ws.v1', 'fleet.ws.v1') THEN 'ws.node.v1'
|
|
44
|
+
ELSE delivery_adapter
|
|
45
|
+
END;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Add scoped observer tokens for workspace realtime and read-only REST.
|
|
2
|
+
|
|
3
|
+
CREATE TABLE observer_tokens (
|
|
4
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
5
|
+
workspace_id TEXT NOT NULL,
|
|
6
|
+
name TEXT NOT NULL,
|
|
7
|
+
description TEXT,
|
|
8
|
+
token_hash TEXT NOT NULL,
|
|
9
|
+
scopes TEXT NOT NULL DEFAULT '[]',
|
|
10
|
+
filters TEXT NOT NULL DEFAULT '{}',
|
|
11
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
12
|
+
expires_at INTEGER,
|
|
13
|
+
created_by TEXT,
|
|
14
|
+
created_by_type TEXT NOT NULL DEFAULT 'workspace',
|
|
15
|
+
last_used_at INTEGER,
|
|
16
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
17
|
+
updated_at INTEGER,
|
|
18
|
+
revoked_at INTEGER,
|
|
19
|
+
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE UNIQUE INDEX observer_tokens_workspace_name_unique
|
|
23
|
+
ON observer_tokens (workspace_id, name);
|
|
24
|
+
|
|
25
|
+
CREATE UNIQUE INDEX observer_tokens_token_hash_unique
|
|
26
|
+
ON observer_tokens (token_hash);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX idx_observer_tokens_workspace_status
|
|
29
|
+
ON observer_tokens (workspace_id, status);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX idx_observer_tokens_expires_at
|
|
32
|
+
ON observer_tokens (expires_at);
|