@relaycast/engine 8.8.0 → 8.9.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/adapters/node/realtime.d.ts.map +1 -1
- package/dist/adapters/node/realtime.js +13 -4
- package/dist/adapters/node/realtime.js.map +1 -1
- package/dist/db/migrations/0053_agent_retention_indexes.sql +8 -0
- package/dist/db/migrations/0054_node_status_heartbeat_index.sql +8 -0
- package/dist/db/migrations/0055_session_event_idempotency.sql +8 -0
- package/dist/db/migrations/0056_session_event_status_completion.sql +38 -0
- package/dist/db/schema.d.ts +89 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +27 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/engine/action.d.ts +4 -0
- package/dist/engine/action.d.ts.map +1 -1
- package/dist/engine/action.js +104 -35
- package/dist/engine/action.js.map +1 -1
- package/dist/engine/agentRetention.d.ts +39 -0
- package/dist/engine/agentRetention.d.ts.map +1 -0
- package/dist/engine/agentRetention.js +117 -0
- package/dist/engine/agentRetention.js.map +1 -0
- package/dist/engine/delivery.d.ts.map +1 -1
- package/dist/engine/delivery.js +6 -1
- package/dist/engine/delivery.js.map +1 -1
- package/dist/engine/node.d.ts +51 -28
- package/dist/engine/node.d.ts.map +1 -1
- package/dist/engine/node.js +140 -10
- package/dist/engine/node.js.map +1 -1
- package/dist/engine/retention.d.ts +12 -0
- package/dist/engine/retention.d.ts.map +1 -1
- package/dist/engine/retention.js +3 -0
- package/dist/engine/retention.js.map +1 -1
- package/dist/engine/rowidRetention.d.ts +33 -0
- package/dist/engine/rowidRetention.d.ts.map +1 -0
- package/dist/engine/rowidRetention.js +190 -0
- package/dist/engine/rowidRetention.js.map +1 -0
- package/dist/engine/sessionEvent.d.ts +54 -1
- package/dist/engine/sessionEvent.d.ts.map +1 -1
- package/dist/engine/sessionEvent.js +195 -2
- package/dist/engine/sessionEvent.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ports/realtime.d.ts +7 -2
- package/dist/ports/realtime.d.ts.map +1 -1
- package/dist/ports/realtime.js.map +1 -1
- package/dist/routes/agent.d.ts.map +1 -1
- package/dist/routes/agent.js +113 -10
- package/dist/routes/agent.js.map +1 -1
- package/dist/routes/deliveryRouting.d.ts +1 -0
- package/dist/routes/deliveryRouting.d.ts.map +1 -1
- package/dist/routes/deliveryRouting.js +8 -4
- package/dist/routes/deliveryRouting.js.map +1 -1
- package/dist/routes/node.js +39 -15
- package/dist/routes/node.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { EngineDb } from '../ports/database.js';
|
|
3
|
+
import type { PruneOptions, PruneResult } from './retention.js';
|
|
4
|
+
declare const stateSchema: z.ZodObject<{
|
|
5
|
+
version: z.ZodLiteral<1>;
|
|
6
|
+
next: z.ZodNumber;
|
|
7
|
+
tables: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
8
|
+
cursor: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
high: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export type RowidRetentionState = z.infer<typeof stateSchema>;
|
|
13
|
+
/**
|
|
14
|
+
* Host-owned durable state for the schema-free retention path. Hosts must
|
|
15
|
+
* serialize maintenance calls for a database, and `save` must resolve only
|
|
16
|
+
* after the checkpoint is durable. This path creates no engine table or index.
|
|
17
|
+
*/
|
|
18
|
+
export interface RetentionCursorStore {
|
|
19
|
+
load(): Promise<unknown>;
|
|
20
|
+
save(state: RowidRetentionState): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/** Worst-case statement count for one cursor-store invocation, below D1's 1000-query ceiling. */
|
|
23
|
+
export declare const ROWID_RETENTION_D1_QUERY_CEILING: number;
|
|
24
|
+
/**
|
|
25
|
+
* Schema-free recovery mode. It pages by SQLite rowid before policy and
|
|
26
|
+
* eligibility filtering, so retained history cannot turn a bounded run into a
|
|
27
|
+
* full scan. A saved high-water mark makes each traversal finite under writes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pruneRowidPages(db: EngineDb, opts: PruneOptions & {
|
|
30
|
+
cursorStore: RetentionCursorStore;
|
|
31
|
+
}): Promise<PruneResult>;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=rowidRetention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rowidRetention.d.ts","sourceRoot":"","sources":["../../src/engine/rowidRetention.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AAInF,QAAA,MAAM,WAAW;;;;;;;iBAIf,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAgDD,iGAAiG;AACjG,eAAO,MAAM,gCAAgC,QAEP,CAAC;AAqDvC;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,YAAY,GAAG;IAAE,WAAW,EAAE,oBAAoB,CAAA;CAAE,GACzD,OAAO,CAAC,WAAW,CAAC,CAuGtB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { snowflakeIdLowerBound } from './snowflake.js';
|
|
4
|
+
const safeRowid = z.number().int().min(Number.MIN_SAFE_INTEGER).max(Number.MAX_SAFE_INTEGER);
|
|
5
|
+
const stateSchema = z.object({
|
|
6
|
+
version: z.literal(1),
|
|
7
|
+
next: z.number().int().min(0).max(4),
|
|
8
|
+
tables: z.record(z.string(), z.object({ cursor: safeRowid.optional(), high: safeRowid.optional() })),
|
|
9
|
+
});
|
|
10
|
+
const SETTLED_DELIVERIES = "deliveries.status IN ('acked', 'failed', 'dead_lettered')";
|
|
11
|
+
const DEFAULT_EXPIRED_DELIVERY_GRACE_DAYS = 7;
|
|
12
|
+
const MAX_ACTIVE_EXPIRY_RECOVERY_BATCHES = 4;
|
|
13
|
+
const ACTIVE_EXPIRY_RECOVERY_DELETE_LIMIT = 1_000;
|
|
14
|
+
const ROWID_PAGE_LIMIT = 200;
|
|
15
|
+
const ROWID_MAX_BATCHES_PER_TABLE = 5;
|
|
16
|
+
const ROWID_DELETE_CHUNK_SIZE = 10;
|
|
17
|
+
const tables = [
|
|
18
|
+
{ name: 'messages', result: 'messages', columns: 'id, workspace_id',
|
|
19
|
+
setting: 'message_ttl_days', fallback: 'messageTtlDays', snowflake: true,
|
|
20
|
+
guard: 'NOT EXISTS (SELECT 1 FROM messages replies WHERE replies.thread_id = messages.id)' },
|
|
21
|
+
{ name: 'deliveries', result: 'deliveries', columns: 'id, workspace_id, created_at, status, expires_at',
|
|
22
|
+
setting: 'delivery_ttl_days', fallback: 'deliveryTtlDays', guard: SETTLED_DELIVERIES },
|
|
23
|
+
{ name: 'message_logs', result: 'messageLogs', columns: 'id, workspace_id',
|
|
24
|
+
setting: 'message_log_ttl_days', fallback: 'messageLogTtlDays', snowflake: true, guard: '1' },
|
|
25
|
+
{ name: 'workspace_events', result: 'workspaceEvents', columns: 'workspace_id, seq, created_at',
|
|
26
|
+
setting: 'workspace_event_ttl_days', fallback: 'workspaceEventTtlDays',
|
|
27
|
+
guard: 'EXISTS (SELECT 1 FROM workspace_events hw WHERE hw.workspace_id = workspace_events.workspace_id AND hw.seq > workspace_events.seq LIMIT 1)' },
|
|
28
|
+
{ name: 'read_receipts', result: 'readReceipts', columns: 'message_id, agent_id',
|
|
29
|
+
guard: 'NOT EXISTS (SELECT 1 FROM messages m WHERE m.id = read_receipts.message_id)' },
|
|
30
|
+
];
|
|
31
|
+
/** Worst-case statement count for one cursor-store invocation, below D1's 1000-query ceiling. */
|
|
32
|
+
export const ROWID_RETENTION_D1_QUERY_CEILING = tables.length * (1 + ROWID_MAX_BATCHES_PER_TABLE + ROWID_MAX_BATCHES_PER_TABLE * Math.ceil(ROWID_PAGE_LIMIT / ROWID_DELETE_CHUNK_SIZE)) + MAX_ACTIVE_EXPIRY_RECOVERY_BATCHES;
|
|
33
|
+
/** Delete only long-expired active deliveries through the existing bounded index. */
|
|
34
|
+
async function recoverExpiredActiveDeliveries(db, nowMs, graceDays, maxBatches) {
|
|
35
|
+
const cutoffSeconds = Math.floor((nowMs - Math.max(0, Math.floor(graceDays * 86_400_000))) / 1_000);
|
|
36
|
+
const batches = bounded(maxBatches, MAX_ACTIVE_EXPIRY_RECOVERY_BATCHES, MAX_ACTIVE_EXPIRY_RECOVERY_BATCHES);
|
|
37
|
+
let deleted = 0;
|
|
38
|
+
for (let batch = 0; batch < batches; batch++) {
|
|
39
|
+
// This is the pre-existing global active-expiry index from migration 0031;
|
|
40
|
+
// the outer predicate repeats every condition so extension/status races are safe.
|
|
41
|
+
const changed = await db.all(sql `
|
|
42
|
+
DELETE FROM deliveries
|
|
43
|
+
WHERE status IN ('queued', 'delivered')
|
|
44
|
+
AND expires_at IS NOT NULL AND expires_at < ${cutoffSeconds}
|
|
45
|
+
AND id IN (
|
|
46
|
+
SELECT id FROM deliveries INDEXED BY idx_deliveries_active_expiry
|
|
47
|
+
WHERE status IN ('queued', 'delivered')
|
|
48
|
+
AND expires_at IS NOT NULL AND expires_at < ${cutoffSeconds}
|
|
49
|
+
ORDER BY expires_at, id LIMIT ${ACTIVE_EXPIRY_RECOVERY_DELETE_LIMIT}
|
|
50
|
+
)
|
|
51
|
+
RETURNING id
|
|
52
|
+
`);
|
|
53
|
+
deleted += changed.length;
|
|
54
|
+
if (changed.length < ACTIVE_EXPIRY_RECOVERY_DELETE_LIMIT)
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
return deleted;
|
|
58
|
+
}
|
|
59
|
+
/** Clamp an optional maintenance budget to a positive, finite row count. */
|
|
60
|
+
function bounded(value, fallback, maximum) {
|
|
61
|
+
return value !== undefined && Number.isFinite(value)
|
|
62
|
+
? Math.max(1, Math.min(maximum, Math.floor(value)))
|
|
63
|
+
: fallback;
|
|
64
|
+
}
|
|
65
|
+
/** Evaluate one candidate against its workspace retention policy and clock. */
|
|
66
|
+
function isExpired(row, table, defaults, nowMs) {
|
|
67
|
+
if (!table.setting || !table.fallback)
|
|
68
|
+
return true;
|
|
69
|
+
const settings = row.retention ? JSON.parse(row.retention) : {};
|
|
70
|
+
const days = settings[table.setting] === undefined ? defaults[table.fallback] : settings[table.setting];
|
|
71
|
+
if (days == null || !Number.isFinite(days) || days <= 0)
|
|
72
|
+
return false;
|
|
73
|
+
const cutoff = nowMs - days * 86_400_000;
|
|
74
|
+
if (!Number.isFinite(cutoff))
|
|
75
|
+
return false;
|
|
76
|
+
if (!table.snowflake)
|
|
77
|
+
return row.created_at * 1_000 < cutoff;
|
|
78
|
+
const bound = snowflakeIdLowerBound(cutoff);
|
|
79
|
+
return row.id.length < bound.length || (row.id.length === bound.length && row.id < bound);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Schema-free recovery mode. It pages by SQLite rowid before policy and
|
|
83
|
+
* eligibility filtering, so retained history cannot turn a bounded run into a
|
|
84
|
+
* full scan. A saved high-water mark makes each traversal finite under writes.
|
|
85
|
+
*/
|
|
86
|
+
export async function pruneRowidPages(db, opts) {
|
|
87
|
+
const nowMs = (opts.now ?? new Date()).getTime();
|
|
88
|
+
if (!Number.isFinite(nowMs))
|
|
89
|
+
throw new Error('Invalid retention clock');
|
|
90
|
+
const limit = bounded(opts.batchLimit, ROWID_PAGE_LIMIT, ROWID_PAGE_LIMIT);
|
|
91
|
+
const pageBudget = bounded(opts.maxBatches, ROWID_MAX_BATCHES_PER_TABLE, ROWID_MAX_BATCHES_PER_TABLE) * tables.length;
|
|
92
|
+
const deadline = Date.now() + bounded(opts.maxDurationMs, 10_000, 30_000);
|
|
93
|
+
const defaults = {
|
|
94
|
+
messageTtlDays: null,
|
|
95
|
+
deliveryTtlDays: 90,
|
|
96
|
+
messageLogTtlDays: 90,
|
|
97
|
+
workspaceEventTtlDays: 30,
|
|
98
|
+
...Object.fromEntries(Object.entries(opts.defaults ?? {}).filter(([, value]) => value !== undefined)),
|
|
99
|
+
};
|
|
100
|
+
const saved = await opts.cursorStore.load();
|
|
101
|
+
// Cursor documents are advisory checkpoints owned by the host. A stale,
|
|
102
|
+
// partial, or legacy document must not take scheduled retention offline, and
|
|
103
|
+
// must never be trusted to construct a delete predicate. Restarting from an
|
|
104
|
+
// empty state is safe because every delete below rechecks row identity and
|
|
105
|
+
// current policy before mutating anything.
|
|
106
|
+
const parsed = saved == null ? undefined : stateSchema.safeParse(saved);
|
|
107
|
+
const state = parsed?.success
|
|
108
|
+
? parsed.data
|
|
109
|
+
: { version: 1, next: 0, tables: {} };
|
|
110
|
+
const save = () => opts.cursorStore.save(structuredClone(state));
|
|
111
|
+
const result = { messages: 0, deliveries: 0, messageLogs: 0, readReceipts: 0, workspaceEvents: 0 };
|
|
112
|
+
const finished = new Set();
|
|
113
|
+
// Active expiry is opt-in because it intentionally skips delivery.failed
|
|
114
|
+
// fanout; normal scheduled expiry remains the default notification path.
|
|
115
|
+
if (opts.activeExpiryRecovery === true) {
|
|
116
|
+
result.deliveries += await recoverExpiredActiveDeliveries(db, nowMs, opts.expiredDeliveryGraceDays ?? DEFAULT_EXPIRED_DELIVERY_GRACE_DAYS, opts.activeExpiryRecoveryMaxBatches ?? MAX_ACTIVE_EXPIRY_RECOVERY_BATCHES);
|
|
117
|
+
}
|
|
118
|
+
for (let step = 0; step < pageBudget && Date.now() < deadline; step++) {
|
|
119
|
+
const index = state.next;
|
|
120
|
+
state.next = (index + 1) % tables.length;
|
|
121
|
+
if (finished.has(index))
|
|
122
|
+
continue;
|
|
123
|
+
const table = tables[index];
|
|
124
|
+
await save(); // fairness is durable before an admitted page
|
|
125
|
+
const position = state.tables[table.name] ??= {};
|
|
126
|
+
if (Date.now() >= deadline)
|
|
127
|
+
break;
|
|
128
|
+
if (position.high === undefined) {
|
|
129
|
+
const [last] = await db.all(sql `
|
|
130
|
+
SELECT rowid AS _rowid FROM ${sql.raw(table.name)} NOT INDEXED ORDER BY rowid DESC LIMIT 1
|
|
131
|
+
`);
|
|
132
|
+
if (!last) {
|
|
133
|
+
delete state.tables[table.name];
|
|
134
|
+
finished.add(index);
|
|
135
|
+
await save();
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
position.high = safeRowid.parse(last._rowid);
|
|
139
|
+
}
|
|
140
|
+
if (Date.now() >= deadline)
|
|
141
|
+
break;
|
|
142
|
+
const page = await db.all(sql `
|
|
143
|
+
WITH page AS MATERIALIZED (
|
|
144
|
+
SELECT rowid AS _rowid, ${sql.raw(table.columns)} FROM ${sql.raw(table.name)} NOT INDEXED
|
|
145
|
+
WHERE rowid <= ${position.high}
|
|
146
|
+
${position.cursor === undefined ? sql `` : sql `AND rowid > ${position.cursor}`}
|
|
147
|
+
ORDER BY rowid LIMIT ${limit}
|
|
148
|
+
) SELECT page.*, ${sql.raw(table.guard.replaceAll(table.name + '.', 'page.'))} AS eligible,
|
|
149
|
+
${table.setting ? sql `w.retention` : sql `NULL`} AS retention
|
|
150
|
+
FROM page ${table.setting ? sql `LEFT JOIN workspaces w ON w.id = page.workspace_id` : sql ``}
|
|
151
|
+
ORDER BY page._rowid
|
|
152
|
+
`);
|
|
153
|
+
for (const row of page)
|
|
154
|
+
safeRowid.parse(row._rowid);
|
|
155
|
+
const removable = page.filter(row => row.eligible && isExpired(row, table, defaults, nowMs));
|
|
156
|
+
for (let offset = 0; offset < removable.length; offset += ROWID_DELETE_CHUNK_SIZE) {
|
|
157
|
+
if (Date.now() >= deadline) {
|
|
158
|
+
await save();
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
const chunk = removable.slice(offset, offset + ROWID_DELETE_CHUNK_SIZE);
|
|
162
|
+
const guards = chunk.map(row => {
|
|
163
|
+
const identity = table.result === 'workspaceEvents'
|
|
164
|
+
? sql `workspace_id = ${row.workspace_id} AND seq = ${row.seq}`
|
|
165
|
+
: table.result === 'readReceipts'
|
|
166
|
+
? sql `message_id = ${row.message_id} AND agent_id = ${row.agent_id}`
|
|
167
|
+
: sql `id = ${row.id} AND workspace_id = ${row.workspace_id}`;
|
|
168
|
+
const policy = table.setting ? sql `AND (SELECT retention FROM workspaces WHERE id = ${row.workspace_id}) IS ${row.retention}` : sql ``;
|
|
169
|
+
const created = table.setting && !table.snowflake ? sql `AND created_at = ${row.created_at}` : sql ``;
|
|
170
|
+
const status = table.result === 'deliveries' ? sql `AND status = ${row.status}` : sql ``;
|
|
171
|
+
return sql `(rowid = ${row._rowid} AND ${identity} ${policy} ${created} ${status})`;
|
|
172
|
+
});
|
|
173
|
+
const deleted = await db.all(sql `DELETE FROM ${sql.raw(table.name)} NOT INDEXED
|
|
174
|
+
WHERE (${sql.join(guards, sql ` OR `)}) AND ${sql.raw(table.guard)} RETURNING 1`);
|
|
175
|
+
result[table.result] += deleted.length;
|
|
176
|
+
}
|
|
177
|
+
if (page.length < limit || page.at(-1)?._rowid === position.high) {
|
|
178
|
+
delete state.tables[table.name];
|
|
179
|
+
finished.add(index);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
position.cursor = page.at(-1)._rowid;
|
|
183
|
+
}
|
|
184
|
+
await save();
|
|
185
|
+
if (finished.size === tables.length)
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=rowidRetention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rowidRetention.js","sourceRoot":"","sources":["../../src/engine/rowidRetention.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,71 @@
|
|
|
1
1
|
import type { getDb } from '../db/index.js';
|
|
2
|
+
import { sessionEvents } from '../db/schema.js';
|
|
2
3
|
type Db = ReturnType<typeof getDb>;
|
|
3
4
|
export type SessionEventType = 'status.changed' | 'status.idle' | 'status.active' | 'status.blocked' | 'status.waiting' | 'status.offline' | 'tool.called' | 'tool.completed' | 'tool.failed' | 'tool.output' | 'message.received' | 'message.sent' | 'delivery.accepted' | 'delivery.delivered' | 'delivery.deferred' | 'delivery.failed' | 'action.invoked' | 'action.completed' | 'action.failed' | 'action.denied' | 'transcript.chunk' | 'file.changed' | 'command.started' | 'command.completed' | 'command.failed' | 'terminal.output' | 'terminal.screen' | 'usage.updated' | 'session.started' | 'session.released' | 'session.resumed' | 'session.forked' | 'log' | 'error';
|
|
4
5
|
export declare function isValidEventType(type: string): type is SessionEventType;
|
|
6
|
+
/** `status.*` events are the only ones with a side-effecting agent-row mutation to track. */
|
|
7
|
+
export declare function isStatusEventType(type: string): boolean;
|
|
8
|
+
export interface StatusEventEffectResult {
|
|
9
|
+
/** Whether this request won the durable completion-marker claim. */
|
|
10
|
+
claimed: boolean;
|
|
11
|
+
/** Whether the current agent row was actually changed by this event. */
|
|
12
|
+
mutated: boolean;
|
|
13
|
+
}
|
|
5
14
|
export declare function recordSessionEvent(db: Db, workspaceId: string, agentId: string, data: {
|
|
6
15
|
type: SessionEventType;
|
|
7
16
|
payload: Record<string, unknown>;
|
|
8
17
|
}): Promise<{
|
|
18
|
+
event: ReturnType<typeof toPublicEvent>;
|
|
19
|
+
replayed: boolean;
|
|
20
|
+
pendingStatusApplication: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Record an event with a durable caller-provided identity.
|
|
24
|
+
*
|
|
25
|
+
* The key is hashed before persistence and scoped by workspace + agent in the
|
|
26
|
+
* unique index. The request digest is retained beside the event so reusing a
|
|
27
|
+
* key with a different event cannot accidentally replay the first event.
|
|
28
|
+
*/
|
|
29
|
+
export declare function recordSessionEventWithIdempotency(db: Db, workspaceId: string, agentId: string, data: {
|
|
30
|
+
type: SessionEventType;
|
|
31
|
+
payload: Record<string, unknown>;
|
|
32
|
+
}, idempotencyKey: string): Promise<{
|
|
33
|
+
event: ReturnType<typeof toPublicEvent>;
|
|
34
|
+
replayed: boolean;
|
|
35
|
+
pendingStatusApplication: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Apply a `status.*` event's agent-row mutation and claim its completion
|
|
39
|
+
* durably, as one atomic unit.
|
|
40
|
+
*
|
|
41
|
+
* This is the fix for the crash window between "the event/idempotency claim
|
|
42
|
+
* committed" and "the agent's status row is updated": if either statement
|
|
43
|
+
* here failed independently, a retry could see `replayed: true` and return
|
|
44
|
+
* 201 while the agent row stayed stale forever. Batching both writes through
|
|
45
|
+
* `runAtomicWrites` means a failure here rolls back *both* the status change
|
|
46
|
+
* and the completion marker, so `pendingStatusApplication` stays true and the
|
|
47
|
+
* next replay retries the whole mutation — it can never observe "claimed but
|
|
48
|
+
* never applied" as a terminal state.
|
|
49
|
+
*
|
|
50
|
+
* The completion update is the single-winner claim for side effects: a replay
|
|
51
|
+
* that loses a concurrent claim gets `claimed: false` and must not fan out or
|
|
52
|
+
* enqueue another webhook. The agent update also carries a durable ordering
|
|
53
|
+
* fence: an older pending event may be terminalized, but it cannot overwrite
|
|
54
|
+
* a newer status event that was recorded while the older event was pending.
|
|
55
|
+
* A released agent's row is intentionally not updated (matching
|
|
56
|
+
* `updateAgentById`), but the event is still marked applied: there is no
|
|
57
|
+
* agent row left to reconcile, and retrying forever would just repeat the
|
|
58
|
+
* same no-op.
|
|
59
|
+
*/
|
|
60
|
+
export declare function applyStatusEventEffect(db: Db, workspaceId: string, agentId: string, eventId: string, status: string): Promise<StatusEventEffectResult>;
|
|
61
|
+
declare function toPublicEvent(event: typeof sessionEvents.$inferSelect, agentId: string): {
|
|
9
62
|
id: string;
|
|
10
63
|
agent_id: string;
|
|
11
64
|
type: string;
|
|
12
65
|
payload: unknown;
|
|
13
66
|
sequence: number;
|
|
14
67
|
created_at: string;
|
|
15
|
-
}
|
|
68
|
+
};
|
|
16
69
|
export declare function listSessionEvents(db: Db, workspaceId: string, agentId: string, options?: {
|
|
17
70
|
type?: string;
|
|
18
71
|
limit?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionEvent.d.ts","sourceRoot":"","sources":["../../src/engine/sessionEvent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionEvent.d.ts","sourceRoot":"","sources":["../../src/engine/sessionEvent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAU,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOxD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AAEnC,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,aAAa,GACb,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,cAAc,GACd,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB,KAAK,GACL,OAAO,CAAC;AAkBZ,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAEvE;AAED,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,MAAM,WAAW,uBAAuB;IACtC,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,GACA,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,wBAAwB,EAAE,OAAO,CAAA;CAAE,CAAC,CAyB5G;AAED;;;;;;GAMG;AACH,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,EACD,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,wBAAwB,EAAE,OAAO,CAAA;CAAE,CAAC,CAmE5G;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,uBAAuB,CAAC,CA2FlC;AAaD,iBAAS,aAAa,CAAC,KAAK,EAAE,OAAO,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM;;;;;;;EAS/E;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;KA0BF;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,gBAAgB,GAC1B,MAAM,GAAG,IAAI,CAUf"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { eq, and, desc, sql } from 'drizzle-orm';
|
|
2
|
-
import { sessionEvents } from '../db/schema.js';
|
|
1
|
+
import { eq, and, ne, desc, isNull, sql } from 'drizzle-orm';
|
|
2
|
+
import { agents, sessionEvents } from '../db/schema.js';
|
|
3
3
|
import { generateId } from './snowflake.js';
|
|
4
|
+
import { sha256Hex } from '../lib/crypto.js';
|
|
5
|
+
import { codedError } from '../lib/httpError.js';
|
|
6
|
+
import { runAtomicWrites } from '../ports/database.js';
|
|
7
|
+
import { RELEASED_AGENT_STATUS } from './agent.js';
|
|
4
8
|
const VALID_EVENT_TYPES = new Set([
|
|
5
9
|
'status.changed', 'status.idle', 'status.active', 'status.blocked',
|
|
6
10
|
'status.waiting', 'status.offline',
|
|
@@ -19,6 +23,10 @@ const VALID_EVENT_TYPES = new Set([
|
|
|
19
23
|
export function isValidEventType(type) {
|
|
20
24
|
return VALID_EVENT_TYPES.has(type);
|
|
21
25
|
}
|
|
26
|
+
/** `status.*` events are the only ones with a side-effecting agent-row mutation to track. */
|
|
27
|
+
export function isStatusEventType(type) {
|
|
28
|
+
return type.startsWith('status.');
|
|
29
|
+
}
|
|
22
30
|
export async function recordSessionEvent(db, workspaceId, agentId, data) {
|
|
23
31
|
const id = `evt_${generateId()}`;
|
|
24
32
|
// Sequence is assigned atomically via a scalar subquery — read and write in
|
|
@@ -34,6 +42,191 @@ export async function recordSessionEvent(db, workspaceId, agentId, data) {
|
|
|
34
42
|
sequence: sql `(SELECT COALESCE(MAX(sequence), 0) + 1 FROM session_events WHERE agent_id = ${agentId})`,
|
|
35
43
|
})
|
|
36
44
|
.returning();
|
|
45
|
+
return {
|
|
46
|
+
event: toPublicEvent(event, agentId),
|
|
47
|
+
replayed: false,
|
|
48
|
+
// Unkeyed events have no durable claim to replay against — the caller
|
|
49
|
+
// always applies the status mutation immediately after this call, so
|
|
50
|
+
// there is nothing to recover across a retry.
|
|
51
|
+
pendingStatusApplication: isStatusEventType(data.type),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record an event with a durable caller-provided identity.
|
|
56
|
+
*
|
|
57
|
+
* The key is hashed before persistence and scoped by workspace + agent in the
|
|
58
|
+
* unique index. The request digest is retained beside the event so reusing a
|
|
59
|
+
* key with a different event cannot accidentally replay the first event.
|
|
60
|
+
*/
|
|
61
|
+
export async function recordSessionEventWithIdempotency(db, workspaceId, agentId, data, idempotencyKey) {
|
|
62
|
+
const [idempotencyKeyHash, requestDigest] = await Promise.all([
|
|
63
|
+
sha256Hex(`session-event-key-v1\0${idempotencyKey}`),
|
|
64
|
+
sha256Hex(`session-event-payload-v1\0${canonicalJson({ type: data.type, payload: data.payload })}`),
|
|
65
|
+
]);
|
|
66
|
+
const id = `evt_${generateId()}`;
|
|
67
|
+
// The insert and the unique identity claim are one durable operation. A
|
|
68
|
+
// conflict is followed by a scoped lookup so concurrent retries return the
|
|
69
|
+
// winner's exact event rather than allocating a second sequence number.
|
|
70
|
+
const [created] = await db
|
|
71
|
+
.insert(sessionEvents)
|
|
72
|
+
.values({
|
|
73
|
+
id,
|
|
74
|
+
workspaceId,
|
|
75
|
+
agentId,
|
|
76
|
+
type: data.type,
|
|
77
|
+
payload: data.payload,
|
|
78
|
+
idempotencyKeyHash,
|
|
79
|
+
requestDigest,
|
|
80
|
+
sequence: sql `(SELECT COALESCE(MAX(sequence), 0) + 1 FROM session_events WHERE agent_id = ${agentId})`,
|
|
81
|
+
})
|
|
82
|
+
.onConflictDoNothing()
|
|
83
|
+
.returning();
|
|
84
|
+
if (created) {
|
|
85
|
+
return {
|
|
86
|
+
event: toPublicEvent(created, agentId),
|
|
87
|
+
replayed: false,
|
|
88
|
+
pendingStatusApplication: isStatusEventType(data.type),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const [existing] = await db
|
|
92
|
+
.select()
|
|
93
|
+
.from(sessionEvents)
|
|
94
|
+
.where(and(eq(sessionEvents.workspaceId, workspaceId), eq(sessionEvents.agentId, agentId), eq(sessionEvents.idempotencyKeyHash, idempotencyKeyHash)));
|
|
95
|
+
if (!existing) {
|
|
96
|
+
throw codedError('The event idempotency claim could not be read after a storage conflict; retry with the same Idempotency-Key', 'idempotency_unavailable', 503);
|
|
97
|
+
}
|
|
98
|
+
if (existing.requestDigest !== requestDigest) {
|
|
99
|
+
throw codedError('Idempotency-Key was reused with a different request payload', 'idempotency_key_reused', 409);
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
event: toPublicEvent(existing, agentId),
|
|
103
|
+
replayed: true,
|
|
104
|
+
// `status_applied_at` is set atomically with the agent-row status write
|
|
105
|
+
// (see `applyStatusEventEffect`). NULL here means either the mutation
|
|
106
|
+
// never ran, or it ran but the process crashed before marking it durable
|
|
107
|
+
// — both cases are indistinguishable from "not yet applied" and safe to
|
|
108
|
+
// retry, because the write that sets this column is the same atomic unit
|
|
109
|
+
// as the status mutation itself. A replay that is still pending finishes
|
|
110
|
+
// the interrupted work instead of returning 201 with a stale agent row.
|
|
111
|
+
pendingStatusApplication: isStatusEventType(existing.type) && existing.statusAppliedAt == null,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Apply a `status.*` event's agent-row mutation and claim its completion
|
|
116
|
+
* durably, as one atomic unit.
|
|
117
|
+
*
|
|
118
|
+
* This is the fix for the crash window between "the event/idempotency claim
|
|
119
|
+
* committed" and "the agent's status row is updated": if either statement
|
|
120
|
+
* here failed independently, a retry could see `replayed: true` and return
|
|
121
|
+
* 201 while the agent row stayed stale forever. Batching both writes through
|
|
122
|
+
* `runAtomicWrites` means a failure here rolls back *both* the status change
|
|
123
|
+
* and the completion marker, so `pendingStatusApplication` stays true and the
|
|
124
|
+
* next replay retries the whole mutation — it can never observe "claimed but
|
|
125
|
+
* never applied" as a terminal state.
|
|
126
|
+
*
|
|
127
|
+
* The completion update is the single-winner claim for side effects: a replay
|
|
128
|
+
* that loses a concurrent claim gets `claimed: false` and must not fan out or
|
|
129
|
+
* enqueue another webhook. The agent update also carries a durable ordering
|
|
130
|
+
* fence: an older pending event may be terminalized, but it cannot overwrite
|
|
131
|
+
* a newer status event that was recorded while the older event was pending.
|
|
132
|
+
* A released agent's row is intentionally not updated (matching
|
|
133
|
+
* `updateAgentById`), but the event is still marked applied: there is no
|
|
134
|
+
* agent row left to reconcile, and retrying forever would just repeat the
|
|
135
|
+
* same no-op.
|
|
136
|
+
*/
|
|
137
|
+
export async function applyStatusEventEffect(db, workspaceId, agentId, eventId, status) {
|
|
138
|
+
// The agent mutation runs first in the atomic unit. This ordering is
|
|
139
|
+
// important for D1 batches: the completion marker must still be NULL when
|
|
140
|
+
// the conditional status update is evaluated. The following marker update
|
|
141
|
+
// then claims the event; Node transactions and D1 batches serialize this
|
|
142
|
+
// pair, so an identical concurrent retry cannot mutate after the winner has
|
|
143
|
+
// claimed it.
|
|
144
|
+
const [mutationResult, claimResult] = await runAtomicWrites(db, (tx) => [
|
|
145
|
+
tx.update(agents)
|
|
146
|
+
.set({ status })
|
|
147
|
+
.where(and(eq(agents.workspaceId, workspaceId), eq(agents.id, agentId), ne(agents.status, RELEASED_AGENT_STATUS),
|
|
148
|
+
// Do not let an interrupted older event roll a newer status back.
|
|
149
|
+
// The sequence is allocated per agent and is durable across retries;
|
|
150
|
+
// an event that is newer than this one wins the status row. A newer
|
|
151
|
+
// event that is itself pending will be responsible for applying its
|
|
152
|
+
// own status when it replays.
|
|
153
|
+
sql `EXISTS (
|
|
154
|
+
SELECT 1
|
|
155
|
+
FROM session_events AS current_event
|
|
156
|
+
WHERE current_event.id = ${eventId}
|
|
157
|
+
AND current_event.workspace_id = ${workspaceId}
|
|
158
|
+
AND current_event.agent_id = ${agentId}
|
|
159
|
+
AND current_event.status_applied_at IS NULL
|
|
160
|
+
)`, sql `NOT EXISTS (
|
|
161
|
+
SELECT 1
|
|
162
|
+
FROM session_events AS newer_event
|
|
163
|
+
WHERE newer_event.workspace_id = ${workspaceId}
|
|
164
|
+
AND newer_event.agent_id = ${agentId}
|
|
165
|
+
AND newer_event.type LIKE 'status.%'
|
|
166
|
+
AND newer_event.sequence > (
|
|
167
|
+
SELECT current_event.sequence
|
|
168
|
+
FROM session_events AS current_event
|
|
169
|
+
WHERE current_event.id = ${eventId}
|
|
170
|
+
AND current_event.workspace_id = ${workspaceId}
|
|
171
|
+
AND current_event.agent_id = ${agentId}
|
|
172
|
+
)
|
|
173
|
+
)`,
|
|
174
|
+
// Migration 0056 cannot know whether the pre-marker route reached
|
|
175
|
+
// this agent write: it inserted the event and updated the agent in
|
|
176
|
+
// separate operations. Its write-time witness is therefore the only
|
|
177
|
+
// safe evidence available. Reapply a legacy event only when the agent
|
|
178
|
+
// row demonstrably predates the event; an equal or newer witness may
|
|
179
|
+
// be the original status write, a heartbeat, or another status writer.
|
|
180
|
+
// In those ambiguous cases claim the event but never clobber the row,
|
|
181
|
+
// regardless of whether its current status matches the event.
|
|
182
|
+
sql `(
|
|
183
|
+
NOT EXISTS (
|
|
184
|
+
SELECT 1
|
|
185
|
+
FROM session_events AS legacy_event
|
|
186
|
+
WHERE legacy_event.id = ${eventId}
|
|
187
|
+
AND legacy_event.workspace_id = ${workspaceId}
|
|
188
|
+
AND legacy_event.agent_id = ${agentId}
|
|
189
|
+
AND legacy_event.status_legacy_pending = 1
|
|
190
|
+
)
|
|
191
|
+
OR (
|
|
192
|
+
${agents.status} <> ${status}
|
|
193
|
+
AND
|
|
194
|
+
${agents.statusUpdatedAt} IS NOT NULL
|
|
195
|
+
AND ${agents.statusUpdatedAt} < (
|
|
196
|
+
SELECT legacy_event.created_at
|
|
197
|
+
FROM session_events AS legacy_event
|
|
198
|
+
WHERE legacy_event.id = ${eventId}
|
|
199
|
+
AND legacy_event.workspace_id = ${workspaceId}
|
|
200
|
+
AND legacy_event.agent_id = ${agentId}
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
)`))
|
|
204
|
+
.returning({ id: agents.id }),
|
|
205
|
+
tx.update(sessionEvents)
|
|
206
|
+
.set({ statusAppliedAt: sql `(unixepoch())` })
|
|
207
|
+
.where(and(eq(sessionEvents.id, eventId), eq(sessionEvents.workspaceId, workspaceId), eq(sessionEvents.agentId, agentId), isNull(sessionEvents.statusAppliedAt)))
|
|
208
|
+
.returning({ id: sessionEvents.id }),
|
|
209
|
+
], { requireAtomic: true });
|
|
210
|
+
const claimed = Array.isArray(claimResult) && claimResult.length > 0;
|
|
211
|
+
const mutated = Array.isArray(mutationResult) && mutationResult.length > 0;
|
|
212
|
+
// Only the caller that both changed the current row and claimed the marker
|
|
213
|
+
// may emit external status side effects. The claim may intentionally win
|
|
214
|
+
// with `mutated === false` when a newer event superseded this one or the
|
|
215
|
+
// agent was released between route validation and this atomic write.
|
|
216
|
+
return { claimed, mutated: claimed && mutated };
|
|
217
|
+
}
|
|
218
|
+
function canonicalJson(value) {
|
|
219
|
+
if (Array.isArray(value))
|
|
220
|
+
return `[${value.map(canonicalJson).join(',')}]`;
|
|
221
|
+
if (value && typeof value === 'object') {
|
|
222
|
+
return `{${Object.keys(value)
|
|
223
|
+
.sort()
|
|
224
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
|
|
225
|
+
.join(',')}}`;
|
|
226
|
+
}
|
|
227
|
+
return JSON.stringify(value);
|
|
228
|
+
}
|
|
229
|
+
function toPublicEvent(event, agentId) {
|
|
37
230
|
return {
|
|
38
231
|
id: event.id,
|
|
39
232
|
agent_id: agentId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionEvent.js","sourceRoot":"","sources":["../../src/engine/sessionEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionEvent.js","sourceRoot":"","sources":["../../src/engine/sessionEvent.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { enqueueEvent, claimDueEvents, completeEvent, failEvent, rescheduleEvent
|
|
|
24
24
|
export type { ClaimedEvent, SweptEvent } from './engine/eventQueue.js';
|
|
25
25
|
export { pruneExpired, resolveEffectiveMessageRetention, DEFAULT_DELIVERY_TTL_DAYS, DEFAULT_MESSAGE_LOG_TTL_DAYS, DEFAULT_WORKSPACE_EVENT_TTL_DAYS, } from './engine/retention.js';
|
|
26
26
|
export type { PruneOptions, PruneResult, RetentionDefaults } from './engine/retention.js';
|
|
27
|
+
export type { RetentionCursorStore, RowidRetentionState } from './engine/rowidRetention.js';
|
|
27
28
|
export type { WorkspaceRetentionSettings } from './db/schema.js';
|
|
28
29
|
export { reapExpiredWorkspaces, drainFileCleanup, DEFAULT_WORKSPACE_REAP_LIMIT, DEFAULT_FILE_CLEANUP_LIMIT, } from './engine/workspace.js';
|
|
29
30
|
export { appendWorkspaceEvent, appendAndPublishWorkspaceEvent, listWorkspaceEvents, WORKSPACE_EVENT_LIST_DEFAULT_LIMIT, WORKSPACE_EVENT_LIST_MAX_LIMIT, } from './engine/workspaceEvents.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,OAAgB,CAAC;AAE/C,2DAA2D;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiC3C,4DAA4D;AAC5D,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,yDAAyD;AACzD,OAAO,EAAE,KAAK,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,wEAAwE;AACxE,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,gFAAgF;AAChF,yCAAyC;AACzC,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAElG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,4CAA4C;AAC5C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAGhC,yEAAyE;AACzE,8EAA8E;AAC9E,4EAA4E;AAC5E,qBAAqB;AACrB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,OAAgB,CAAC;AAE/C,2DAA2D;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiC3C,4DAA4D;AAC5D,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,yDAAyD;AACzD,OAAO,EAAE,KAAK,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,wEAAwE;AACxE,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,gFAAgF;AAChF,yCAAyC;AACzC,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACjG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAElG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,4CAA4C;AAC5C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAGhC,yEAAyE;AACzE,8EAA8E;AAC9E,4EAA4E;AAC5E,qBAAqB;AACrB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;AAK/B,yEAAyE;AACzE,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAE/B,2EAA2E;AAC3E,+EAA+E;AAC/E,8BAA8B;AAC9B,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAC9B,mBAAmB,EACnB,kCAAkC,EAClC,8BAA8B,GAC/B,MAAM,6BAA6B,CAAC;AAGrC,iBAAiB;AACjB,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC"}
|
package/dist/ports/realtime.d.ts
CHANGED
|
@@ -75,12 +75,17 @@ export interface AgentActionProviderAuthorization {
|
|
|
75
75
|
recordAttempt: boolean;
|
|
76
76
|
}
|
|
77
77
|
/** Exact token-generation proof for a release accepted by the socket owner. */
|
|
78
|
-
export
|
|
78
|
+
export type ReleaseActionProviderAuthorization = {
|
|
79
79
|
kind: 'release-generation-v1';
|
|
80
80
|
invocationId: string;
|
|
81
81
|
agentName: string;
|
|
82
|
+
} & ({
|
|
82
83
|
expectedTokenHash: string;
|
|
83
|
-
|
|
84
|
+
expectedAgentId?: string;
|
|
85
|
+
} | {
|
|
86
|
+
expectedTokenHash?: string;
|
|
87
|
+
expectedAgentId: string;
|
|
88
|
+
});
|
|
84
89
|
/** Legacy registered action proof, retained only so current owners fail it closed. */
|
|
85
90
|
export interface LegacyRegisteredNodeActionProviderAuthorization {
|
|
86
91
|
kind: 'registered-node-action-v1';
|