@intentface/latch-drizzle 0.9.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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/adapter.d.ts +18 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +33 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/adapter.pg.d.ts +10 -0
  8. package/dist/adapter.pg.d.ts.map +1 -0
  9. package/dist/adapter.pg.js +18 -0
  10. package/dist/adapter.pg.js.map +1 -0
  11. package/dist/adapter.shared.d.ts +55 -0
  12. package/dist/adapter.shared.d.ts.map +1 -0
  13. package/dist/adapter.shared.js +527 -0
  14. package/dist/adapter.shared.js.map +1 -0
  15. package/dist/agent-store.d.ts +34 -0
  16. package/dist/agent-store.d.ts.map +1 -0
  17. package/dist/agent-store.js +236 -0
  18. package/dist/agent-store.js.map +1 -0
  19. package/dist/agent-store.smoke.d.ts +2 -0
  20. package/dist/agent-store.smoke.d.ts.map +1 -0
  21. package/dist/agent-store.smoke.js +77 -0
  22. package/dist/agent-store.smoke.js.map +1 -0
  23. package/dist/index.d.ts +24 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +22 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/limit-store.d.ts +5 -0
  28. package/dist/limit-store.d.ts.map +1 -0
  29. package/dist/limit-store.js +7 -0
  30. package/dist/limit-store.js.map +1 -0
  31. package/dist/limit-store.pg.d.ts +5 -0
  32. package/dist/limit-store.pg.d.ts.map +1 -0
  33. package/dist/limit-store.pg.js +7 -0
  34. package/dist/limit-store.pg.js.map +1 -0
  35. package/dist/limit-store.shared.d.ts +14 -0
  36. package/dist/limit-store.shared.d.ts.map +1 -0
  37. package/dist/limit-store.shared.js +60 -0
  38. package/dist/limit-store.shared.js.map +1 -0
  39. package/dist/limit-store.smoke.shared.d.ts +7 -0
  40. package/dist/limit-store.smoke.shared.d.ts.map +1 -0
  41. package/dist/limit-store.smoke.shared.js +33 -0
  42. package/dist/limit-store.smoke.shared.js.map +1 -0
  43. package/dist/memory-job-store.d.ts +5 -0
  44. package/dist/memory-job-store.d.ts.map +1 -0
  45. package/dist/memory-job-store.js +7 -0
  46. package/dist/memory-job-store.js.map +1 -0
  47. package/dist/memory-job-store.pg.d.ts +5 -0
  48. package/dist/memory-job-store.pg.d.ts.map +1 -0
  49. package/dist/memory-job-store.pg.js +7 -0
  50. package/dist/memory-job-store.pg.js.map +1 -0
  51. package/dist/memory-job-store.shared.d.ts +23 -0
  52. package/dist/memory-job-store.shared.d.ts.map +1 -0
  53. package/dist/memory-job-store.shared.js +294 -0
  54. package/dist/memory-job-store.shared.js.map +1 -0
  55. package/dist/memory-job-store.smoke.shared.d.ts +18 -0
  56. package/dist/memory-job-store.smoke.shared.d.ts.map +1 -0
  57. package/dist/memory-job-store.smoke.shared.js +149 -0
  58. package/dist/memory-job-store.smoke.shared.js.map +1 -0
  59. package/dist/migrate.d.ts +10 -0
  60. package/dist/migrate.d.ts.map +1 -0
  61. package/dist/migrate.js +202 -0
  62. package/dist/migrate.js.map +1 -0
  63. package/dist/migrate.pg.d.ts +3 -0
  64. package/dist/migrate.pg.d.ts.map +1 -0
  65. package/dist/migrate.pg.js +120 -0
  66. package/dist/migrate.pg.js.map +1 -0
  67. package/dist/run-lease.smoke.shared.d.ts +13 -0
  68. package/dist/run-lease.smoke.shared.d.ts.map +1 -0
  69. package/dist/run-lease.smoke.shared.js +65 -0
  70. package/dist/run-lease.smoke.shared.js.map +1 -0
  71. package/dist/schedule.smoke.shared.d.ts +16 -0
  72. package/dist/schedule.smoke.shared.d.ts.map +1 -0
  73. package/dist/schedule.smoke.shared.js +104 -0
  74. package/dist/schedule.smoke.shared.js.map +1 -0
  75. package/dist/schema.d.ts +2348 -0
  76. package/dist/schema.d.ts.map +1 -0
  77. package/dist/schema.js +225 -0
  78. package/dist/schema.js.map +1 -0
  79. package/dist/schema.pg.d.ts +2215 -0
  80. package/dist/schema.pg.d.ts.map +1 -0
  81. package/dist/schema.pg.js +197 -0
  82. package/dist/schema.pg.js.map +1 -0
  83. package/dist/secret-store.d.ts +11 -0
  84. package/dist/secret-store.d.ts.map +1 -0
  85. package/dist/secret-store.js +11 -0
  86. package/dist/secret-store.js.map +1 -0
  87. package/dist/secret-store.pg.d.ts +6 -0
  88. package/dist/secret-store.pg.d.ts.map +1 -0
  89. package/dist/secret-store.pg.js +7 -0
  90. package/dist/secret-store.pg.js.map +1 -0
  91. package/dist/secret-store.shared.d.ts +25 -0
  92. package/dist/secret-store.shared.d.ts.map +1 -0
  93. package/dist/secret-store.shared.js +67 -0
  94. package/dist/secret-store.shared.js.map +1 -0
  95. package/dist/smoke.d.ts +2 -0
  96. package/dist/smoke.d.ts.map +1 -0
  97. package/dist/smoke.js +108 -0
  98. package/dist/smoke.js.map +1 -0
  99. package/dist/smoke.pg.d.ts +2 -0
  100. package/dist/smoke.pg.d.ts.map +1 -0
  101. package/dist/smoke.pg.js +107 -0
  102. package/dist/smoke.pg.js.map +1 -0
  103. package/package.json +62 -0
@@ -0,0 +1,527 @@
1
+ import { and, asc, eq, getTableColumns, getTableName, isNotNull, isNull, lt, lte, ne, or, sql, } from "drizzle-orm";
2
+ import { ChatBusyError, ChatConflictError, } from "@intentface/latch-core";
3
+ function newId(prefix) {
4
+ return `${prefix}_${crypto.randomUUID().replace(/-/g, "").slice(0, 24)}`;
5
+ }
6
+ /**
7
+ * True if a driver error is a primary-key / unique-constraint violation. Walks
8
+ * the cause chain: drizzle wraps driver errors in a "Failed query: …" error and
9
+ * the constraint code lives on the cause (libsql `SQLITE_CONSTRAINT_UNIQUE`, pg
10
+ * `23505`), two levels down for libsql.
11
+ */
12
+ export function isUniqueViolation(error) {
13
+ let e = error;
14
+ for (let depth = 0; e && depth < 5; depth++) {
15
+ const code = e.code;
16
+ if (typeof code === "string" && (/^SQLITE_CONSTRAINT/i.test(code) || code === "23505"))
17
+ return true;
18
+ const message = e instanceof Error ? e.message : typeof e === "string" ? e : "";
19
+ if (/unique constraint|primary key|duplicate key|sqlite_constraint/i.test(message))
20
+ return true;
21
+ e = e.cause;
22
+ }
23
+ return false;
24
+ }
25
+ /**
26
+ * How long a NON-durable (T1) active run may stay active before a new turn in
27
+ * its chat supersedes it. T1 has no heartbeat, so without this a crashed T1
28
+ * turn would block its chat forever. Durable runs use their lease instead.
29
+ */
30
+ export const STALE_RUN_MS = 10 * 60_000;
31
+ /** Join an `owner` path into one composite key, segment-encoded so it's unambiguous. */
32
+ function ownerKeyOf(owner, principal) {
33
+ return owner(principal).map(encodeURIComponent).join("/");
34
+ }
35
+ export function makeStorageAdapter(db, s, opts) {
36
+ const ownerKey = (p) => ownerKeyOf(opts.owner, p);
37
+ const rowToChat = (r) => ({
38
+ id: r.id,
39
+ owner: r.owner,
40
+ agent: r.agent,
41
+ title: r.title ?? undefined,
42
+ kind: r.kind,
43
+ createdAt: r.createdAt,
44
+ updatedAt: r.updatedAt,
45
+ });
46
+ const rowToRun = (r) => ({
47
+ id: r.id,
48
+ chatId: r.chatId,
49
+ agent: r.agent,
50
+ status: r.status,
51
+ identity: r.identity ?? undefined,
52
+ leaseOwner: r.leaseOwner,
53
+ leaseExpiresAt: r.leaseExpiresAt,
54
+ fencingToken: r.fencingToken,
55
+ heartbeatAt: r.heartbeatAt,
56
+ attempt: r.attempt,
57
+ usageInputTokens: r.usageInputTokens ?? undefined,
58
+ usageOutputTokens: r.usageOutputTokens ?? undefined,
59
+ usageCacheReadTokens: r.usageCacheReadTokens ?? undefined,
60
+ usageCacheWriteTokens: r.usageCacheWriteTokens ?? undefined,
61
+ costTotal: r.costTotal ?? undefined,
62
+ kind: r.kind,
63
+ toolsHash: r.toolsHash,
64
+ error: r.error,
65
+ startedAt: r.startedAt,
66
+ endedAt: r.endedAt,
67
+ });
68
+ const rowToSchedule = (r) => ({
69
+ id: r.id,
70
+ owner: r.owner,
71
+ agent: r.agent,
72
+ identity: r.identity ?? undefined,
73
+ cron: r.cron,
74
+ timezone: r.timezone ?? undefined,
75
+ prompt: r.prompt,
76
+ delivery: r.delivery ?? undefined,
77
+ nextRunAt: r.nextRunAt,
78
+ lastRunAt: r.lastRunAt,
79
+ onParked: (r.onParked ?? undefined),
80
+ lastChatId: r.lastChatId,
81
+ enabled: r.enabled === 1,
82
+ leaseOwner: r.leaseOwner,
83
+ leaseExpiresAt: r.leaseExpiresAt,
84
+ createdAt: r.createdAt,
85
+ });
86
+ async function getChat(principal, id) {
87
+ const rows = await db
88
+ .select()
89
+ .from(s.chats)
90
+ .where(and(eq(s.chats.id, id), eq(s.chats.owner, ownerKey(principal))));
91
+ return rows[0] ? rowToChat(rows[0]) : null;
92
+ }
93
+ /** The instant a live active run stops counting as live (lease, or T1 stale timeout). */
94
+ const liveUntil = sql `coalesce(${s.runs.leaseExpiresAt}, ${s.runs.startedAt} + ${STALE_RUN_MS})`;
95
+ /**
96
+ * One active run per chat, self-healing: an active run whose lease (or T1
97
+ * stale window) has expired is superseded — marked errored, fencing token
98
+ * bumped so its worker's late writes are refused — before a new run opens.
99
+ * A crashed turn therefore never blocks its chat; the next message moves the
100
+ * conversation on, the same rule as a new message closing a pending approval.
101
+ */
102
+ const supersedeStaleQuery = (chatId, now, exec = db) => exec
103
+ .update(s.runs)
104
+ .set({
105
+ status: "errored",
106
+ error: "superseded: lease expired",
107
+ endedAt: now,
108
+ leaseOwner: null,
109
+ fencingToken: sql `coalesce(${s.runs.fencingToken}, 0) + 1`,
110
+ })
111
+ .where(and(eq(s.runs.chatId, chatId), eq(s.runs.status, "active"), lt(liveUntil, now)));
112
+ async function supersedeStale(exec, chatId, now) {
113
+ await supersedeStaleQuery(chatId, now, exec);
114
+ }
115
+ /** One message upsert (seq computed in-statement) as a query, for batching. */
116
+ const messageInsert = (chatId, m, exec = db) => exec
117
+ .insert(s.messages)
118
+ .values({
119
+ id: m.id,
120
+ chatId,
121
+ runId: null,
122
+ seq: sql `(select coalesce(max(${s.messages.seq}), -1) + 1 from ${s.messages} where ${s.messages.chatId} = ${chatId})`,
123
+ role: m.role,
124
+ parts: m.parts,
125
+ metadata: m.metadata ?? null,
126
+ createdAt: m.metadata?.createdAt ?? Date.now(),
127
+ })
128
+ // Existing message (same chat + id) → update content only; seq is
129
+ // preserved. Conflict target is the composite PK — a same-id row in
130
+ // ANOTHER chat is a different row, never overwritten from here.
131
+ .onConflictDoUpdate({
132
+ target: [s.messages.chatId, s.messages.id],
133
+ set: { parts: m.parts, metadata: m.metadata ?? null },
134
+ });
135
+ /**
136
+ * Insert a run row. A LIVE active run in the chat trips the partial unique
137
+ * index → a placeholder `ChatBusyError` (retryAfterMs 0). The caller fills
138
+ * in the lease's remaining time OUTSIDE the transaction, because on Postgres
139
+ * a failed statement aborts the transaction and nothing can be read in it.
140
+ */
141
+ async function insertRun(exec, row) {
142
+ try {
143
+ const got = await exec.insert(s.runs).values(row).returning();
144
+ return got[0];
145
+ }
146
+ catch (error) {
147
+ if (!isUniqueViolation(error))
148
+ throw error;
149
+ throw new ChatBusyError(String(row.chatId), 0);
150
+ }
151
+ }
152
+ /** The busy refusal with the live run's remaining time, computed on the main connection. */
153
+ async function busyError(chatId, now) {
154
+ const live = await db
155
+ .select({ until: liveUntil })
156
+ .from(s.runs)
157
+ .where(and(eq(s.runs.chatId, chatId), eq(s.runs.status, "active")))
158
+ .limit(1);
159
+ const until = live[0] ? Number(live[0].until) : now;
160
+ return new ChatBusyError(chatId, Math.max(1, until - now));
161
+ }
162
+ /** `insertRun` for the non-transactional entry points: turn the placeholder into the real refusal. */
163
+ async function openRunRow(row, chatId, now) {
164
+ await supersedeStale(db, chatId, now);
165
+ try {
166
+ return await insertRun(db, row);
167
+ }
168
+ catch (error) {
169
+ if (error instanceof ChatBusyError)
170
+ throw await busyError(chatId, now);
171
+ throw error;
172
+ }
173
+ }
174
+ const runRow = (principal, input, now) => ({
175
+ id: newId("run"),
176
+ chatId: input.chatId,
177
+ agent: input.agent,
178
+ status: "active",
179
+ identity: principal,
180
+ kind: input.kind,
181
+ startedAt: now,
182
+ ...(input.lease
183
+ ? {
184
+ leaseOwner: input.lease.owner,
185
+ leaseExpiresAt: now + input.lease.ttlMs,
186
+ fencingToken: 1,
187
+ heartbeatAt: now,
188
+ attempt: 1,
189
+ }
190
+ : {}),
191
+ });
192
+ /** Append messages on `exec` (db or tx): seq computed inside each INSERT, upsert by (chat, id), touch the chat. */
193
+ async function appendMessagesWith(exec, chatId, msgs) {
194
+ for (const m of msgs)
195
+ await messageInsert(chatId, m, exec);
196
+ // Chat activity: keep `updatedAt` fresh so `listChats` orders by it.
197
+ await exec.update(s.chats).set({ updatedAt: Date.now() }).where(eq(s.chats.id, chatId));
198
+ }
199
+ return {
200
+ async createChat(principal, input) {
201
+ const now = Date.now();
202
+ const row = {
203
+ id: input.id ?? newId("chat"),
204
+ owner: ownerKey(principal),
205
+ agent: input.agent,
206
+ title: input.title ?? null,
207
+ kind: input.kind ?? "user",
208
+ createdAt: now,
209
+ updatedAt: now,
210
+ };
211
+ try {
212
+ await db.insert(s.chats).values(row);
213
+ }
214
+ catch (error) {
215
+ // A client-supplied id can collide with a chat the caller doesn't own
216
+ // (the scoped getChat missed, so the caller fell through to create).
217
+ // Surface a typed conflict the server layer can map to a 409.
218
+ if (isUniqueViolation(error))
219
+ throw new ChatConflictError(row.id);
220
+ throw error;
221
+ }
222
+ return rowToChat(row);
223
+ },
224
+ getChat,
225
+ async listChats(principal, opts) {
226
+ // No kind → all chats (back-compatible); kind → only that kind.
227
+ const scope = eq(s.chats.owner, ownerKey(principal));
228
+ // The latest run's status per chat, as one correlated subquery over
229
+ // latch_runs_chat_idx — NOT a per-chat run scan in the caller. Latest
230
+ // only: a continuation opens a new run, so a superseded pause stops
231
+ // reporting `awaiting_input` the moment the conversation moves on.
232
+ // Explicitly aliased raw SQL: drizzle renders `${s.chats.id}`
233
+ // UNQUALIFIED inside a select-field subquery, where it resolves to the
234
+ // runs table's own `id` and the correlation silently never matches.
235
+ // `id desc` breaks started_at ties (ms precision) deterministically —
236
+ // an arbitrary but STABLE pick, so the projection can't flap between
237
+ // reads or disagree across dialects.
238
+ const lastRunStatus = sql `(select r.status from ${sql.raw(getTableName(s.runs))} r where r.chat_id = ${sql.raw(getTableName(s.chats))}.id order by r.started_at desc, r.id desc limit 1)`;
239
+ const rows = await db
240
+ .select({ ...getTableColumns(s.chats), lastRunStatus })
241
+ .from(s.chats)
242
+ .where(opts?.kind !== undefined
243
+ ? and(scope, eq(s.chats.kind, opts.kind))
244
+ : scope)
245
+ .orderBy(sql `${s.chats.updatedAt} desc`)
246
+ .limit(opts?.limit ?? 100);
247
+ return rows.map((r) => ({
248
+ ...rowToChat(r),
249
+ ...(r.lastRunStatus ? { lastRunStatus: r.lastRunStatus } : {}),
250
+ }));
251
+ },
252
+ async loadMessages(principal, chatId) {
253
+ // Scope check first — a chat the caller doesn't own returns nothing.
254
+ const chat = await getChat(principal, chatId);
255
+ if (!chat)
256
+ return [];
257
+ const rows = await db
258
+ .select()
259
+ .from(s.messages)
260
+ .where(eq(s.messages.chatId, chatId))
261
+ .orderBy(asc(s.messages.seq));
262
+ return rows.map((r) => ({
263
+ id: r.id,
264
+ role: r.role,
265
+ parts: r.parts,
266
+ metadata: (r.metadata ?? undefined),
267
+ }));
268
+ },
269
+ async appendMessages(chatId, msgs) {
270
+ if (msgs.length === 0)
271
+ return;
272
+ // The next seq is computed INSIDE each INSERT (a single statement), so
273
+ // two concurrent appenders can't both read the same max(seq) and then
274
+ // write colliding rows — the statement is atomic, and the UNIQUE
275
+ // (chat_id, seq) index backstops it. `withTx` is the dialect's batch
276
+ // boundary: a real transaction where the driver is async (Postgres,
277
+ // libsql), sequential statements on synchronous better-sqlite3.
278
+ await opts.withTx((tx) => appendMessagesWith(tx, chatId, msgs));
279
+ },
280
+ /**
281
+ * Run + first message in ONE transaction: a busy chat persists nothing, and
282
+ * a crash can't leave a run without its message. The busy placeholder from
283
+ * `insertRun` rolls the transaction back; the real refusal (with the live
284
+ * lease's remaining time) is built on the main connection afterwards.
285
+ */
286
+ async openTurn(principal, input) {
287
+ const now = Date.now();
288
+ const row = runRow(principal, input, now);
289
+ try {
290
+ if (opts.batch) {
291
+ // The statements are independent (the run id is minted here), so a
292
+ // batch is a transaction without an interactive connection.
293
+ const results = await opts.batch([
294
+ supersedeStaleQuery(input.chatId, now),
295
+ db.insert(s.runs).values(row).returning(),
296
+ ...input.messages.map((m) => messageInsert(input.chatId, m)),
297
+ db.update(s.chats).set({ updatedAt: now }).where(eq(s.chats.id, input.chatId)),
298
+ ]);
299
+ return rowToRun(results[1][0]);
300
+ }
301
+ if (opts.syncTx) {
302
+ const got = opts.syncTx((tx) => {
303
+ supersedeStaleQuery(input.chatId, now, tx).run();
304
+ const inserted = tx.insert(s.runs).values(row).returning().get();
305
+ for (const m of input.messages)
306
+ messageInsert(input.chatId, m, tx).run();
307
+ tx.update(s.chats).set({ updatedAt: now }).where(eq(s.chats.id, input.chatId)).run();
308
+ return inserted;
309
+ });
310
+ return rowToRun(got);
311
+ }
312
+ // Real transaction (Postgres). An adapter that is neither batch- nor
313
+ // sync-capable falls through to `withTx`, whose atomicity is its own.
314
+ const inserted = await opts.withTx(async (tx) => {
315
+ await supersedeStale(tx, input.chatId, now);
316
+ const got = await insertRun(tx, row);
317
+ await appendMessagesWith(tx, input.chatId, input.messages);
318
+ return got;
319
+ });
320
+ return rowToRun(inserted);
321
+ }
322
+ catch (error) {
323
+ if (error instanceof ChatBusyError || isUniqueViolation(error)) {
324
+ throw await busyError(input.chatId, now);
325
+ }
326
+ throw error;
327
+ }
328
+ },
329
+ async createRun(principal, input) {
330
+ const now = Date.now();
331
+ return rowToRun(await openRunRow(runRow(principal, input, now), input.chatId, now));
332
+ },
333
+ async claimRun(input) {
334
+ const now = Date.now();
335
+ const row = runRow(input.principal, { chatId: input.chatId, agent: input.agent, lease: { owner: input.owner, ttlMs: input.ttlMs } }, now);
336
+ return rowToRun(await openRunRow(row, input.chatId, now));
337
+ },
338
+ async heartbeatRun(id, owner, ttlMs, fencingToken) {
339
+ const now = Date.now();
340
+ const updated = await db
341
+ .update(s.runs)
342
+ .set({ leaseExpiresAt: now + ttlMs, heartbeatAt: now })
343
+ .where(and(eq(s.runs.id, id), eq(s.runs.leaseOwner, owner),
344
+ // Fenced: a stale holder whose run was reaped + re-claimed (owner
345
+ // may match again, token was bumped) can't resurrect the lease.
346
+ eq(s.runs.fencingToken, fencingToken), eq(s.runs.status, "active")))
347
+ .returning({ id: s.runs.id });
348
+ return updated.length > 0;
349
+ },
350
+ async reclaimRun(id, owner, ttlMs) {
351
+ const now = Date.now();
352
+ let updated;
353
+ try {
354
+ updated = await db
355
+ .update(s.runs)
356
+ .set({
357
+ status: "active",
358
+ leaseOwner: owner,
359
+ leaseExpiresAt: now + ttlMs,
360
+ heartbeatAt: now,
361
+ error: null,
362
+ endedAt: null,
363
+ fencingToken: sql `coalesce(${s.runs.fencingToken}, 0) + 1`,
364
+ attempt: sql `coalesce(${s.runs.attempt}, 1) + 1`,
365
+ })
366
+ .where(and(eq(s.runs.id, id), ne(s.runs.status, "completed"),
367
+ // Only runs that WERE leased and whose lease has expired. A
368
+ // never-leased live (T1) run has leaseExpiresAt NULL and must not
369
+ // be seizable; a reaped run keeps its (expired) leaseExpiresAt
370
+ // even though the reaper cleared leaseOwner, so it still matches.
371
+ isNotNull(s.runs.leaseExpiresAt), lt(s.runs.leaseExpiresAt, now)))
372
+ .returning();
373
+ }
374
+ catch (error) {
375
+ // The chat moved on: a fresh message superseded this crashed turn and
376
+ // opened a newer active run (one active per chat). Resuming the old one
377
+ // would interleave — it stays errored, and nobody owns it.
378
+ if (isUniqueViolation(error))
379
+ return null;
380
+ throw error;
381
+ }
382
+ return updated[0] ? rowToRun(updated[0]) : null;
383
+ },
384
+ async updateRun(id, patch, guard) {
385
+ const set = Object.fromEntries(Object.entries(patch).filter(([k, v]) => v !== undefined && k !== "id"));
386
+ if (Object.keys(set).length === 0)
387
+ return true;
388
+ const where = guard
389
+ ? and(eq(s.runs.id, id), eq(s.runs.leaseOwner, guard.owner), eq(s.runs.fencingToken, guard.fencingToken))
390
+ : eq(s.runs.id, id);
391
+ const updated = await db
392
+ .update(s.runs)
393
+ .set(set)
394
+ .where(where)
395
+ .returning({ id: s.runs.id });
396
+ return updated.length > 0;
397
+ },
398
+ async reapExpiredRuns(now, opts) {
399
+ const reaped = await db
400
+ .update(s.runs)
401
+ .set({
402
+ status: "errored",
403
+ error: opts?.error ?? "lease expired",
404
+ endedAt: now,
405
+ leaseOwner: null,
406
+ fencingToken: sql `${s.runs.fencingToken} + 1`,
407
+ })
408
+ .where(and(eq(s.runs.status, "active"), lt(s.runs.leaseExpiresAt, now)))
409
+ .returning();
410
+ return reaped.map(rowToRun);
411
+ },
412
+ async getRun(id) {
413
+ const rows = await db
414
+ .select()
415
+ .from(s.runs)
416
+ .where(eq(s.runs.id, id));
417
+ return rows[0] ? rowToRun(rows[0]) : null;
418
+ },
419
+ async listRuns(principal, opts) {
420
+ const rows = await db
421
+ .select({ run: s.runs })
422
+ .from(s.runs)
423
+ .innerJoin(s.chats, eq(s.runs.chatId, s.chats.id))
424
+ .where(eq(s.chats.owner, ownerKey(principal)))
425
+ .orderBy(sql `${s.runs.startedAt} desc`)
426
+ .limit(opts?.limit ?? 100);
427
+ return rows.map((r) => rowToRun(r.run));
428
+ },
429
+ async recordUsage(principal, input) {
430
+ await db.insert(s.usage).values({
431
+ id: newId("use"),
432
+ owner: ownerKey(principal),
433
+ runId: input.runId,
434
+ model: input.model,
435
+ inputTokens: input.inputTokens,
436
+ outputTokens: input.outputTokens,
437
+ cacheReadTokens: input.cacheReadTokens,
438
+ cacheWriteTokens: input.cacheWriteTokens,
439
+ cost: input.cost,
440
+ createdAt: Date.now(),
441
+ });
442
+ },
443
+ async createSchedule(principal, input) {
444
+ const now = Date.now();
445
+ const row = {
446
+ id: newId("sch"),
447
+ owner: ownerKey(principal),
448
+ agent: input.agent,
449
+ identity: principal,
450
+ cron: input.cron,
451
+ timezone: input.timezone ?? null,
452
+ prompt: input.prompt,
453
+ delivery: input.delivery ?? null,
454
+ nextRunAt: input.nextRunAt,
455
+ lastRunAt: null,
456
+ onParked: input.onParked ?? null,
457
+ lastChatId: null,
458
+ enabled: 1,
459
+ leaseOwner: null,
460
+ leaseExpiresAt: null,
461
+ createdAt: now,
462
+ };
463
+ const got = await db.insert(s.schedules).values(row).returning();
464
+ return rowToSchedule(got[0]);
465
+ },
466
+ async listSchedules(principal) {
467
+ const rows = await db
468
+ .select()
469
+ .from(s.schedules)
470
+ .where(eq(s.schedules.owner, ownerKey(principal)))
471
+ .orderBy(sql `${s.schedules.createdAt} desc`);
472
+ return rows.map(rowToSchedule);
473
+ },
474
+ async deleteSchedule(principal, id) {
475
+ await db
476
+ .delete(s.schedules)
477
+ .where(and(eq(s.schedules.id, id), eq(s.schedules.owner, ownerKey(principal))));
478
+ },
479
+ async bumpSchedule(principal, id) {
480
+ const armed = await db
481
+ .update(s.schedules)
482
+ .set({ nextRunAt: 0 })
483
+ // Owner-fenced, and `enabled` only: a spent one-shot stays spent rather
484
+ // than being resurrectable by re-arming its clock.
485
+ .where(and(eq(s.schedules.id, id), eq(s.schedules.owner, ownerKey(principal)), eq(s.schedules.enabled, 1)))
486
+ .returning({ id: s.schedules.id });
487
+ return armed.length > 0;
488
+ },
489
+ async claimDueSchedules(now, ttlMs, owner) {
490
+ // Atomic claim: stamp a lease on due, unclaimed/expired rows. NOT
491
+ // exactly-once on its own — the lease is never renewed, so it only
492
+ // serializes claimers within one TTL; the runtime makes the occurrence
493
+ // at-most-once by advancing nextRunAt (completeSchedule) before firing.
494
+ const claimed = await db
495
+ .update(s.schedules)
496
+ .set({ leaseOwner: owner, leaseExpiresAt: now + ttlMs })
497
+ .where(and(eq(s.schedules.enabled, 1), lte(s.schedules.nextRunAt, now), or(isNull(s.schedules.leaseOwner), lt(s.schedules.leaseExpiresAt, now))))
498
+ .returning();
499
+ return claimed.map(rowToSchedule);
500
+ },
501
+ async completeSchedule(id, patch, owner) {
502
+ await db
503
+ .update(s.schedules)
504
+ .set({
505
+ nextRunAt: patch.nextRunAt,
506
+ lastRunAt: patch.lastRunAt,
507
+ enabled: patch.enabled ? 1 : 0,
508
+ leaseOwner: null,
509
+ leaseExpiresAt: null,
510
+ })
511
+ // Fenced by the claim lease: if our lease expired mid-fire and another
512
+ // node re-claimed the schedule, this no-ops instead of clobbering it.
513
+ .where(and(eq(s.schedules.id, id), eq(s.schedules.leaseOwner, owner)));
514
+ },
515
+ async noteScheduleFire(id, patch) {
516
+ // Fenced by the OCCURRENCE (see StorageAdapter): the stamp only lands
517
+ // while last_run_at still holds the value this fire's completeSchedule
518
+ // wrote — a delayed stamp from an older fire no-ops once a newer
519
+ // occurrence has consumed.
520
+ await db
521
+ .update(s.schedules)
522
+ .set({ lastChatId: patch.lastChatId })
523
+ .where(and(eq(s.schedules.id, id), eq(s.schedules.lastRunAt, patch.firedAt)));
524
+ },
525
+ };
526
+ }
527
+ //# sourceMappingURL=adapter.shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.shared.js","sourceRoot":"","sources":["../src/adapter.shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
2
+ import type { PgDatabase } from "drizzle-orm/pg-core";
3
+ import type { LanguageModel } from "ai";
4
+ import type { AgentConfig } from "@intentface/latch-core";
5
+ import type { AgentBuilderStore, AgentRecord, AgentScope } from "@intentface/latch-agent-builder";
6
+ export interface AgentStoreOptions<P> {
7
+ /**
8
+ * Derive the ownership key segments for a principal at a scope — the
9
+ * isolation boundary (e.g. platform: org → [orgId], user → [orgId, userId];
10
+ * a workspace-per-DB host: org → ["workspace"], user → [userId]). Must be
11
+ * server-derived from the authenticated principal, never client input.
12
+ */
13
+ owner: (principal: P, scope: AgentScope) => string[];
14
+ /** Resolve a stored model id to the executable model (host catalog). */
15
+ modelFor: (id: string) => LanguageModel;
16
+ /**
17
+ * Resolve the named authored tools into executable tools for a caller —
18
+ * supplied by hosts with a tool-authoring feature. When omitted, an agent's
19
+ * `authoredTools` are simply not attached.
20
+ */
21
+ loadAuthoredTools?: (principal: P, names: string[], agentScope: AgentScope) => Promise<Record<string, unknown>>;
22
+ /**
23
+ * Decorate the resolved `AgentConfig` with host policy, with the matched
24
+ * RECORD in hand (resolve alone hides it) — e.g. default a baseline
25
+ * toolset, or gate/waive tool approvals off `exec` flags. Runs last;
26
+ * return the (mutated or replaced) config.
27
+ */
28
+ decorateResolve?: (cfg: AgentConfig<P>, record: AgentRecord, principal: P) => AgentConfig<P>;
29
+ }
30
+ /** `AgentBuilderStore` on a Drizzle SQLite database (libsql / better-sqlite3 / Turso). */
31
+ export declare function createSqliteAgentBuilderStore<P>(db: BaseSQLiteDatabase<"sync" | "async", any, any>, opts: AgentStoreOptions<P>): AgentBuilderStore<P>;
32
+ /** `AgentBuilderStore` on a Drizzle Postgres database (node-postgres / postgres-js / PGlite). */
33
+ export declare function createPostgresAgentBuilderStore<P>(db: PgDatabase<any, any, any>, opts: AgentStoreOptions<P>): AgentBuilderStore<P>;
34
+ //# sourceMappingURL=agent-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-store.d.ts","sourceRoot":"","sources":["../src/agent-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,wBAAwB,CAAC;AAErE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAclG,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC;;;;;OAKG;IACH,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,KAAK,MAAM,EAAE,CAAC;IACrD,wEAAwE;IACxE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,aAAa,CAAC;IACxC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAClB,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAChB,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,CAAC,KACT,WAAW,CAAC,CAAC,CAAC,CAAC;CACrB;AAoOD,0FAA0F;AAC1F,wBAAgB,6BAA6B,CAAC,CAAC,EAC7C,EAAE,EAAE,kBAAkB,CAAC,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EAClD,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GACzB,iBAAiB,CAAC,CAAC,CAAC,CA2BtB;AAED,iGAAiG;AACjG,wBAAgB,+BAA+B,CAAC,CAAC,EAC/C,EAAE,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC7B,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GACzB,iBAAiB,CAAC,CAAC,CAAC,CA2BtB"}