@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.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/adapter.d.ts +18 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +33 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapter.pg.d.ts +10 -0
- package/dist/adapter.pg.d.ts.map +1 -0
- package/dist/adapter.pg.js +18 -0
- package/dist/adapter.pg.js.map +1 -0
- package/dist/adapter.shared.d.ts +55 -0
- package/dist/adapter.shared.d.ts.map +1 -0
- package/dist/adapter.shared.js +527 -0
- package/dist/adapter.shared.js.map +1 -0
- package/dist/agent-store.d.ts +34 -0
- package/dist/agent-store.d.ts.map +1 -0
- package/dist/agent-store.js +236 -0
- package/dist/agent-store.js.map +1 -0
- package/dist/agent-store.smoke.d.ts +2 -0
- package/dist/agent-store.smoke.d.ts.map +1 -0
- package/dist/agent-store.smoke.js +77 -0
- package/dist/agent-store.smoke.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/limit-store.d.ts +5 -0
- package/dist/limit-store.d.ts.map +1 -0
- package/dist/limit-store.js +7 -0
- package/dist/limit-store.js.map +1 -0
- package/dist/limit-store.pg.d.ts +5 -0
- package/dist/limit-store.pg.d.ts.map +1 -0
- package/dist/limit-store.pg.js +7 -0
- package/dist/limit-store.pg.js.map +1 -0
- package/dist/limit-store.shared.d.ts +14 -0
- package/dist/limit-store.shared.d.ts.map +1 -0
- package/dist/limit-store.shared.js +60 -0
- package/dist/limit-store.shared.js.map +1 -0
- package/dist/limit-store.smoke.shared.d.ts +7 -0
- package/dist/limit-store.smoke.shared.d.ts.map +1 -0
- package/dist/limit-store.smoke.shared.js +33 -0
- package/dist/limit-store.smoke.shared.js.map +1 -0
- package/dist/memory-job-store.d.ts +5 -0
- package/dist/memory-job-store.d.ts.map +1 -0
- package/dist/memory-job-store.js +7 -0
- package/dist/memory-job-store.js.map +1 -0
- package/dist/memory-job-store.pg.d.ts +5 -0
- package/dist/memory-job-store.pg.d.ts.map +1 -0
- package/dist/memory-job-store.pg.js +7 -0
- package/dist/memory-job-store.pg.js.map +1 -0
- package/dist/memory-job-store.shared.d.ts +23 -0
- package/dist/memory-job-store.shared.d.ts.map +1 -0
- package/dist/memory-job-store.shared.js +294 -0
- package/dist/memory-job-store.shared.js.map +1 -0
- package/dist/memory-job-store.smoke.shared.d.ts +18 -0
- package/dist/memory-job-store.smoke.shared.d.ts.map +1 -0
- package/dist/memory-job-store.smoke.shared.js +149 -0
- package/dist/memory-job-store.smoke.shared.js.map +1 -0
- package/dist/migrate.d.ts +10 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +202 -0
- package/dist/migrate.js.map +1 -0
- package/dist/migrate.pg.d.ts +3 -0
- package/dist/migrate.pg.d.ts.map +1 -0
- package/dist/migrate.pg.js +120 -0
- package/dist/migrate.pg.js.map +1 -0
- package/dist/run-lease.smoke.shared.d.ts +13 -0
- package/dist/run-lease.smoke.shared.d.ts.map +1 -0
- package/dist/run-lease.smoke.shared.js +65 -0
- package/dist/run-lease.smoke.shared.js.map +1 -0
- package/dist/schedule.smoke.shared.d.ts +16 -0
- package/dist/schedule.smoke.shared.d.ts.map +1 -0
- package/dist/schedule.smoke.shared.js +104 -0
- package/dist/schedule.smoke.shared.js.map +1 -0
- package/dist/schema.d.ts +2348 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +225 -0
- package/dist/schema.js.map +1 -0
- package/dist/schema.pg.d.ts +2215 -0
- package/dist/schema.pg.d.ts.map +1 -0
- package/dist/schema.pg.js +197 -0
- package/dist/schema.pg.js.map +1 -0
- package/dist/secret-store.d.ts +11 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +11 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/secret-store.pg.d.ts +6 -0
- package/dist/secret-store.pg.d.ts.map +1 -0
- package/dist/secret-store.pg.js +7 -0
- package/dist/secret-store.pg.js.map +1 -0
- package/dist/secret-store.shared.d.ts +25 -0
- package/dist/secret-store.shared.d.ts.map +1 -0
- package/dist/secret-store.shared.js +67 -0
- package/dist/secret-store.shared.js.map +1 -0
- package/dist/smoke.d.ts +2 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +108 -0
- package/dist/smoke.js.map +1 -0
- package/dist/smoke.pg.d.ts +2 -0
- package/dist/smoke.pg.d.ts.map +1 -0
- package/dist/smoke.pg.js +107 -0
- package/dist/smoke.pg.js.map +1 -0
- 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"}
|