stitchkit 0.118.0 → 0.119.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/CHANGELOG.md +78 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/contract/client-types.d.ts +6 -3
- package/dist/contract/client-types.d.ts.map +1 -1
- package/dist/contract/define-validation.d.ts.map +1 -1
- package/dist/contract/define.d.ts +18 -12
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/endpoint-capabilities.d.ts +28 -0
- package/dist/contract/endpoint-capabilities.d.ts.map +1 -0
- package/dist/contract/factory.d.ts +49 -19
- package/dist/contract/factory.d.ts.map +1 -1
- package/dist/contract/tool-view.d.ts +1 -1
- package/dist/contract/tool-view.d.ts.map +1 -1
- package/dist/contract/transports.d.ts +5 -0
- package/dist/contract/transports.d.ts.map +1 -0
- package/dist/entrypoints/agent-runtime/coding-tools.js +6 -5
- package/dist/entrypoints/agent-runtime/harness.js +6 -5
- package/dist/entrypoints/agent-runtime/sandbox.js +6 -5
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +9 -8
- package/dist/entrypoints/agent-runtime/sqlite/node.js +9 -8
- package/dist/entrypoints/agent-runtime/testing.js +9 -8
- package/dist/entrypoints/agent-runtime.js +14 -13
- package/dist/entrypoints/application/diagnostic-journal.js +3 -3
- package/dist/entrypoints/application/directory-inbox.js +4 -4
- package/dist/entrypoints/application/opentelemetry.js +1 -1
- package/dist/entrypoints/application.js +5 -5
- package/dist/entrypoints/cli/publish.js +4 -4
- package/dist/entrypoints/cli.js +8 -7
- package/dist/entrypoints/contract.d.ts +1 -1
- package/dist/entrypoints/contract.d.ts.map +1 -1
- package/dist/entrypoints/contract.js +6 -4
- package/dist/entrypoints/files.js +3 -3
- package/dist/entrypoints/geo/contract.d.ts +7 -0
- package/dist/entrypoints/geo/contract.d.ts.map +1 -0
- package/dist/entrypoints/geo/contract.js +6 -0
- package/dist/entrypoints/geo.js +60 -23
- package/dist/entrypoints/http.js +2 -2
- package/dist/entrypoints/index.js +8 -6
- package/dist/entrypoints/live.js +1 -1
- package/dist/entrypoints/node.js +7 -6
- package/dist/entrypoints/primitives.js +1 -1
- package/dist/entrypoints/process/owner-loss.js +1 -1
- package/dist/entrypoints/process.js +3 -3
- package/dist/entrypoints/react.js +1 -1
- package/dist/entrypoints/remote.js +4 -3
- package/dist/entrypoints/server.d.ts +1 -1
- package/dist/entrypoints/server.d.ts.map +1 -1
- package/dist/entrypoints/server.js +42 -27
- package/dist/entrypoints/telegram.js +2 -2
- package/dist/entrypoints/testing.js +7 -6
- package/dist/entrypoints/tools/connections.js +3 -2
- package/dist/entrypoints/tools/contract.js +1 -1
- package/dist/entrypoints/tools/invoker.js +5 -4
- package/dist/entrypoints/tools/mcp.js +7 -6
- package/dist/entrypoints/tools.js +17 -15
- package/dist/entrypoints/tracking/contract.js +5 -3
- package/dist/entrypoints/tracking/performance.js +3 -3
- package/dist/entrypoints/tracking.d.ts +1 -1
- package/dist/entrypoints/tracking.d.ts.map +1 -1
- package/dist/entrypoints/tracking.js +63 -83
- package/dist/entrypoints/xlsx.js +1 -1
- package/dist/geo/index.d.ts +2 -1
- package/dist/geo/index.d.ts.map +1 -1
- package/dist/geo/record.d.ts +8 -0
- package/dist/geo/record.d.ts.map +1 -0
- package/dist/geo/resolver.d.ts +1 -3
- package/dist/geo/resolver.d.ts.map +1 -1
- package/dist/geo/schema.d.ts +44 -0
- package/dist/geo/schema.d.ts.map +1 -0
- package/dist/geo/types.d.ts +2 -13
- package/dist/geo/types.d.ts.map +1 -1
- package/dist/{index-n5sv4z0w.js → index-1k18qzqa.js} +13 -15
- package/dist/{index-tsngj2b5.js → index-2dfvv1jg.js} +206 -206
- package/dist/{index-d9hq291n.js → index-4jpykzvw.js} +70 -81
- package/dist/{index-ghtpfz4z.js → index-57gqaq8b.js} +2 -2
- package/dist/index-69t14s4a.js +39 -0
- package/dist/{index-6p3frkv5.js → index-6a69xzrx.js} +4 -4
- package/dist/{index-dky0dcmf.js → index-72r9k0av.js} +6 -2
- package/dist/{index-vv1sch8a.js → index-8vzh5wpv.js} +13 -8
- package/dist/{index-xx1j310k.js → index-8yxgcyt6.js} +171 -169
- package/dist/{index-p6apg0jg.js → index-9frf01t9.js} +16 -9
- package/dist/{index-q0th8q0z.js → index-9mjrnqxs.js} +1 -3
- package/dist/{index-ega3yz4c.js → index-aqwg2dm5.js} +1 -1
- package/dist/{index-073nw9qr.js → index-ba7are04.js} +524 -522
- package/dist/{index-095ya5hm.js → index-bbvc59gw.js} +13 -11
- package/dist/{index-txg1npmg.js → index-cyxp8rbf.js} +1 -1
- package/dist/index-d3xdyjt6.js +38 -0
- package/dist/{index-n8z3rvzw.js → index-f4njz9j0.js} +3 -5
- package/dist/{index-90p34rts.js → index-fcqj44mb.js} +3 -1
- package/dist/{index-86nbfysb.js → index-ff39f9dr.js} +3 -3
- package/dist/{index-75ns2ybj.js → index-fqd4yqwd.js} +1 -1
- package/dist/{index-nqxrm176.js → index-g444vfz2.js} +1 -1
- package/dist/{index-vwhrnp67.js → index-kz9734jc.js} +3 -3
- package/dist/{index-dr3t5n1v.js → index-nn9qvkww.js} +46 -46
- package/dist/{index-qezhmp51.js → index-nz06qw5a.js} +3 -1
- package/dist/{index-1bx1xv1k.js → index-pfvde2fz.js} +5 -2
- package/dist/{index-s80awwsw.js → index-qch1vcaa.js} +3 -1
- package/dist/{index-cycp3r3e.js → index-rxcgp4b9.js} +2 -2
- package/dist/{index-w7jq3fz9.js → index-s0qjs6ee.js} +1198 -1196
- package/dist/{index-p0rf7sq9.js → index-s20s2mad.js} +209 -209
- package/dist/{index-v6vb5qx8.js → index-s3yxw6kt.js} +1 -1
- package/dist/{index-cqmqyjax.js → index-sa99p98w.js} +1 -1
- package/dist/{index-0gxvns6s.js → index-sba3e6m4.js} +1 -0
- package/dist/{index-f24bdt13.js → index-v1swr26p.js} +3 -1
- package/dist/{index-rhzkndr5.js → index-x4p3kw1p.js} +533 -530
- package/dist/{index-hdjmdwsj.js → index-x8d9fdeg.js} +513 -507
- package/dist/{index-htxh46ej.js → index-ycqhyars.js} +2 -2
- package/dist/{index-9bwcthxw.js → index-yj6saztf.js} +31 -13
- package/dist/{index-tdpmfks8.js → index-ynrf908v.js} +1 -1
- package/dist/{index-f6m4c545.js → index-zrdcmg6j.js} +4 -6
- package/dist/process/bun-child.d.ts +3 -2
- package/dist/process/bun-child.d.ts.map +1 -1
- package/dist/server/contract-method.d.ts.map +1 -1
- package/dist/server/file.d.ts +12 -6
- package/dist/server/file.d.ts.map +1 -1
- package/dist/tools/internal/surface-projector.d.ts.map +1 -1
- package/dist/tools/operations/async-operation-canonical-types.d.ts +1 -1
- package/dist/tracking/attribution.d.ts +21 -25
- package/dist/tracking/attribution.d.ts.map +1 -1
- package/dist/tracking/client-visit.d.ts +5 -7
- package/dist/tracking/client-visit.d.ts.map +1 -1
- package/dist/tracking/client.d.ts +2 -2
- package/dist/tracking/client.d.ts.map +1 -1
- package/dist/tracking/contract.d.ts +1 -1
- package/dist/tracking/host.d.ts +0 -1
- package/dist/tracking/host.d.ts.map +1 -1
- package/dist/tracking/privacy.d.ts +6 -0
- package/dist/tracking/privacy.d.ts.map +1 -1
- package/dist/tracking/schemas.d.ts +2 -2
- package/dist/tracking/schemas.d.ts.map +1 -1
- package/llms/contract.txt +46 -24
- package/llms/geo-contract.txt +23 -0
- package/llms/geo.txt +40 -4
- package/llms/server.2.txt +19 -6
- package/llms/server.5.txt +2 -1
- package/llms/stitchkit.txt +4 -3
- package/llms/testing.txt +3 -3
- package/llms/tools.2.txt +2 -2
- package/llms/tools.3.txt +1 -1
- package/llms/tracking-contract.txt +1 -1
- package/llms/tracking.txt +27 -5
- package/llms/{upgrading-0.105.0-0.118.0.txt → upgrading-0.106.0-0.119.0.txt} +121 -410
- package/llms/upgrading-0.37.0-0.53.0.txt +969 -0
- package/llms/{upgrading-0.44.0-0.62.0.txt → upgrading-0.55.0-0.68.0.txt} +509 -528
- package/llms/{upgrading-0.63.0-0.83.0.txt → upgrading-0.69.0-0.95.0.txt} +506 -509
- package/llms/{upgrading-0.84.0-0.104.0.txt → upgrading-0.96.0-0.105.0.txt} +410 -506
- package/llms/upgrading.txt +5 -5
- package/llms-full.txt +271 -48
- package/llms.txt +11 -10
- package/package.json +23 -19
- package/llms/upgrading-0.37.0-0.44.0.txt +0 -444
|
@@ -10,81 +10,24 @@ import {
|
|
|
10
10
|
AgentAdmissionReceiptSchema2,
|
|
11
11
|
AgentSeedReceiptSchema2,
|
|
12
12
|
AgentHistoryMutationSchema2
|
|
13
|
-
} from "./index-
|
|
14
|
-
import {
|
|
15
|
-
AgentMessageSchema2,
|
|
16
|
-
AgentRunSchema2
|
|
17
|
-
} from "./index-8kzct1d6.js";
|
|
13
|
+
} from "./index-8yxgcyt6.js";
|
|
18
14
|
import {
|
|
19
15
|
appendEventIn,
|
|
20
16
|
ArchiveProjectionSchema,
|
|
21
17
|
createAgentRuntimeStore2
|
|
22
|
-
} from "./index-
|
|
18
|
+
} from "./index-rxcgp4b9.js";
|
|
19
|
+
import {
|
|
20
|
+
AgentMessageSchema2,
|
|
21
|
+
AgentRunSchema2
|
|
22
|
+
} from "./index-8kzct1d6.js";
|
|
23
23
|
import {
|
|
24
24
|
AgentConversationPageSchema2,
|
|
25
25
|
AgentConversationMessagePageSchema2
|
|
26
26
|
} from "./index-kqnd6a85.js";
|
|
27
27
|
|
|
28
|
-
// src/agent-runtime/sqlite-
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
// src/agent-runtime/sqlite-purge.ts
|
|
32
|
-
var OWNED_TABLES = [
|
|
33
|
-
"stitchkit_agent_runtime_spills",
|
|
34
|
-
"stitchkit_agent_runtime_schedules",
|
|
35
|
-
"stitchkit_agent_runtime_projections",
|
|
36
|
-
"stitchkit_agent_runtime_events",
|
|
37
|
-
"stitchkit_agent_runtime_messages",
|
|
38
|
-
"stitchkit_agent_runtime_seeds",
|
|
39
|
-
"stitchkit_agent_runtime_admissions",
|
|
40
|
-
"stitchkit_agent_runtime_runs",
|
|
41
|
-
"stitchkit_agent_runtime_heads"
|
|
42
|
-
];
|
|
43
|
-
function initializeSqliteConversationPurge(database) {
|
|
44
|
-
database.exec(`
|
|
45
|
-
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_purged (
|
|
46
|
-
conversation_id TEXT PRIMARY KEY
|
|
47
|
-
);
|
|
48
|
-
`);
|
|
49
|
-
for (const table of OWNED_TABLES) {
|
|
50
|
-
for (const operation of ["INSERT", "UPDATE"]) {
|
|
51
|
-
database.exec(`
|
|
52
|
-
CREATE TRIGGER IF NOT EXISTS ${table}_purge_${operation.toLowerCase()}
|
|
53
|
-
BEFORE ${operation} ON ${table}
|
|
54
|
-
WHEN EXISTS (
|
|
55
|
-
SELECT 1 FROM stitchkit_agent_runtime_purged WHERE conversation_id = NEW.conversation_id
|
|
56
|
-
)
|
|
57
|
-
BEGIN SELECT RAISE(ABORT, 'Agent conversation has been purged'); END;
|
|
58
|
-
`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function sqliteConversationPurge(database) {
|
|
63
|
-
const table = database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'stitchkit_agent_runtime_purged'").get();
|
|
64
|
-
if (table === null || table === undefined)
|
|
65
|
-
return;
|
|
66
|
-
return {
|
|
67
|
-
async isEmpty(transaction, conversationId) {
|
|
68
|
-
for (const table of OWNED_TABLES) {
|
|
69
|
-
const row = transaction.prepare(`SELECT 1 FROM ${table} WHERE conversation_id = ? LIMIT 1`).get(conversationId);
|
|
70
|
-
if (row !== null && row !== undefined)
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
return transaction.prepare("SELECT 1 FROM stitchkit_agent_runtime_children WHERE parent_conversation_id = ? OR child_conversation_id = ? LIMIT 1").get(conversationId, conversationId) == null;
|
|
74
|
-
},
|
|
75
|
-
async isPurged(transaction, conversationId) {
|
|
76
|
-
const row = transaction.prepare("SELECT conversation_id FROM stitchkit_agent_runtime_purged WHERE conversation_id = ?").get(conversationId);
|
|
77
|
-
return row !== null && row !== undefined;
|
|
78
|
-
},
|
|
79
|
-
async remove(transaction, conversationId) {
|
|
80
|
-
transaction.prepare("INSERT INTO stitchkit_agent_runtime_purged (conversation_id) VALUES (?)").run(conversationId);
|
|
81
|
-
for (const table of OWNED_TABLES) {
|
|
82
|
-
transaction.prepare(`DELETE FROM ${table} WHERE conversation_id = ?`).run(conversationId);
|
|
83
|
-
}
|
|
84
|
-
transaction.prepare("DELETE FROM stitchkit_agent_runtime_children WHERE parent_conversation_id = ? OR child_conversation_id = ?").run(conversationId, conversationId);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
}
|
|
28
|
+
// src/agent-runtime/sqlite-events.ts
|
|
29
|
+
import { createHash } from "node:crypto";
|
|
30
|
+
import { z as z2 } from "zod";
|
|
88
31
|
|
|
89
32
|
// src/agent-runtime/sqlite-rows.ts
|
|
90
33
|
import { z } from "zod";
|
|
@@ -144,424 +87,88 @@ function parseEventRow(value) {
|
|
|
144
87
|
});
|
|
145
88
|
}
|
|
146
89
|
|
|
147
|
-
// src/agent-runtime/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
version: z2.int().nonnegative()
|
|
153
|
-
});
|
|
154
|
-
var PayloadRowSchema = z2.object({
|
|
155
|
-
payload: z2.string(),
|
|
156
|
-
terminal_assistant_payload: z2.string().nullable().optional()
|
|
157
|
-
});
|
|
158
|
-
var HistoryRowSchema = z2.object({
|
|
90
|
+
// src/agent-runtime/sqlite-events.ts
|
|
91
|
+
var ArchiveProjectionRowSchema = z2.object({
|
|
92
|
+
name: z2.string(),
|
|
93
|
+
version: z2.int().positive(),
|
|
94
|
+
upto_seq: z2.int().nonnegative(),
|
|
159
95
|
payload: z2.string(),
|
|
160
|
-
|
|
96
|
+
updated_at: z2.string()
|
|
161
97
|
});
|
|
162
|
-
var
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
98
|
+
var ArchiveSpillRowSchema = z2.object({
|
|
99
|
+
reference_id: z2.string(),
|
|
100
|
+
run_id: z2.string().nullable(),
|
|
101
|
+
tool_call_id: z2.string().nullable(),
|
|
102
|
+
media_type: z2.string(),
|
|
103
|
+
bytes: z2.int().nonnegative(),
|
|
104
|
+
sha256: z2.string(),
|
|
105
|
+
created_at: z2.string(),
|
|
106
|
+
expires_at: z2.string().nullable(),
|
|
107
|
+
authorization_payload: z2.string().nullable(),
|
|
108
|
+
payload: z2.instanceof(Uint8Array)
|
|
168
109
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
id TEXT PRIMARY KEY,
|
|
216
|
-
conversation_id TEXT NOT NULL,
|
|
217
|
-
kind TEXT NOT NULL,
|
|
218
|
-
next_at TEXT NOT NULL,
|
|
219
|
-
interval_ms INTEGER,
|
|
220
|
-
time_zone TEXT,
|
|
221
|
-
input_payload TEXT NOT NULL,
|
|
222
|
-
state TEXT NOT NULL,
|
|
223
|
-
occurrence INTEGER NOT NULL DEFAULT 0 CHECK (occurrence >= 0),
|
|
224
|
-
claim_owner TEXT,
|
|
225
|
-
claim_until TEXT,
|
|
226
|
-
created_at TEXT NOT NULL,
|
|
227
|
-
updated_at TEXT NOT NULL
|
|
228
|
-
);
|
|
229
|
-
CREATE INDEX IF NOT EXISTS stitchkit_agent_runtime_schedules_due
|
|
230
|
-
ON stitchkit_agent_runtime_schedules (state, next_at);
|
|
231
|
-
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_children (
|
|
232
|
-
parent_conversation_id TEXT NOT NULL,
|
|
233
|
-
child_conversation_id TEXT NOT NULL UNIQUE,
|
|
234
|
-
seed_upto_seq INTEGER,
|
|
235
|
-
state TEXT NOT NULL,
|
|
236
|
-
budget_payload TEXT NOT NULL,
|
|
237
|
-
usage_payload TEXT NOT NULL,
|
|
238
|
-
result_reference TEXT,
|
|
239
|
-
created_at TEXT NOT NULL,
|
|
240
|
-
updated_at TEXT NOT NULL,
|
|
241
|
-
PRIMARY KEY (parent_conversation_id, child_conversation_id)
|
|
242
|
-
);
|
|
243
|
-
`);
|
|
244
|
-
try {
|
|
245
|
-
database.exec(`
|
|
246
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS stitchkit_agent_runtime_events_fts
|
|
247
|
-
USING fts5(
|
|
248
|
-
conversation_id UNINDEXED,
|
|
249
|
-
event_seq UNINDEXED,
|
|
250
|
-
occurred_at UNINDEXED,
|
|
251
|
-
body,
|
|
252
|
-
tokenize = 'unicode61 remove_diacritics 2'
|
|
253
|
-
);
|
|
254
|
-
CREATE TRIGGER IF NOT EXISTS stitchkit_agent_runtime_events_fts_insert
|
|
255
|
-
AFTER INSERT ON stitchkit_agent_runtime_events BEGIN
|
|
256
|
-
INSERT INTO stitchkit_agent_runtime_events_fts(
|
|
257
|
-
rowid, conversation_id, event_seq, occurred_at, body
|
|
258
|
-
) VALUES (new.row_id, new.conversation_id, new.seq, new.occurred_at, new.payload);
|
|
259
|
-
END;
|
|
260
|
-
CREATE TRIGGER IF NOT EXISTS stitchkit_agent_runtime_events_fts_delete
|
|
261
|
-
AFTER DELETE ON stitchkit_agent_runtime_events BEGIN
|
|
262
|
-
DELETE FROM stitchkit_agent_runtime_events_fts WHERE rowid = old.row_id;
|
|
263
|
-
END;
|
|
264
|
-
`);
|
|
265
|
-
} catch (error) {
|
|
266
|
-
throw new Error("SQLite agent-runtime requires FTS5 support", { cause: error });
|
|
110
|
+
var sqliteEvents = {
|
|
111
|
+
async append(transaction, rawEvent) {
|
|
112
|
+
const event = rawEvent;
|
|
113
|
+
const last = transaction.prepare("SELECT COALESCE(MAX(seq), 0) AS count FROM stitchkit_agent_runtime_events WHERE conversation_id = ?").get(event.conversationId);
|
|
114
|
+
const seq = CountRowSchema.parse(last).count + 1;
|
|
115
|
+
transaction.prepare(`
|
|
116
|
+
INSERT INTO stitchkit_agent_runtime_events (
|
|
117
|
+
conversation_id, seq, event_id, schema_version, kind, occurred_at, ignorable, payload
|
|
118
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
119
|
+
`).run(event.conversationId, seq, event.eventId, event.schemaVersion, event.kind, event.occurredAt, event.ignorable ? 1 : 0, encodeJson(event.payload));
|
|
120
|
+
return AgentStoreEventEnvelopeSchema2.parse({ ...event, seq });
|
|
121
|
+
},
|
|
122
|
+
async list(transaction, input) {
|
|
123
|
+
const clauses = ["conversation_id = ?"];
|
|
124
|
+
const values = [input.conversationId];
|
|
125
|
+
if (input.fromSeq !== undefined) {
|
|
126
|
+
clauses.push("seq >= ?");
|
|
127
|
+
values.push(input.fromSeq);
|
|
128
|
+
}
|
|
129
|
+
if (input.toSeq !== undefined) {
|
|
130
|
+
clauses.push("seq <= ?");
|
|
131
|
+
values.push(input.toSeq);
|
|
132
|
+
}
|
|
133
|
+
const rows = transaction.prepare(`
|
|
134
|
+
SELECT event_id, conversation_id, seq, schema_version, kind, occurred_at,
|
|
135
|
+
ignorable, payload
|
|
136
|
+
FROM stitchkit_agent_runtime_events
|
|
137
|
+
WHERE ${clauses.join(" AND ")}
|
|
138
|
+
ORDER BY seq ASC LIMIT ?
|
|
139
|
+
`).all(...values, input.limit + 1).map(parseEventRow);
|
|
140
|
+
const hasMore = rows.length > input.limit;
|
|
141
|
+
const items = rows.slice(0, input.limit);
|
|
142
|
+
const lastEvent = items.at(-1);
|
|
143
|
+
return AgentStoreEventPageSchema2.parse({
|
|
144
|
+
items,
|
|
145
|
+
...hasMore && lastEvent ? { nextSeq: lastEvent.seq + 1 } : {}
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
async find(transaction, input) {
|
|
149
|
+
const row = transaction.prepare(`
|
|
150
|
+
SELECT event_id, conversation_id, seq, schema_version, kind, occurred_at,
|
|
151
|
+
ignorable, payload
|
|
152
|
+
FROM stitchkit_agent_runtime_events
|
|
153
|
+
WHERE event_id = ? AND conversation_id = ?
|
|
154
|
+
`).get(input.eventId, input.conversationId);
|
|
155
|
+
return row === null || row === undefined ? undefined : parseEventRow(row);
|
|
267
156
|
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const rows = database.prepare("SELECT payload, active FROM stitchkit_agent_runtime_messages WHERE conversation_id = ? ORDER BY position, rowid").all(conversation.conversation_id).map((row) => {
|
|
278
|
-
const parsed = HistoryRowSchema.parse(row);
|
|
157
|
+
};
|
|
158
|
+
var sqliteArchive = {
|
|
159
|
+
async export(transaction, conversationId) {
|
|
160
|
+
const projections = transaction.prepare(`
|
|
161
|
+
SELECT name, version, upto_seq, payload, updated_at
|
|
162
|
+
FROM stitchkit_agent_runtime_projections
|
|
163
|
+
WHERE conversation_id = ? ORDER BY name
|
|
164
|
+
`).all(conversationId).map((raw) => {
|
|
165
|
+
const row = ArchiveProjectionRowSchema.parse(raw);
|
|
279
166
|
return {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const compacted = rows.filter((row) => !row.active).map((row) => row.message.id);
|
|
286
|
-
const runs = database.prepare("SELECT payload, terminal_assistant_payload FROM stitchkit_agent_runtime_runs WHERE conversation_id = ? ORDER BY created_at, run_id").all(conversation.conversation_id).map((value) => {
|
|
287
|
-
const row = PayloadRowSchema.parse(value);
|
|
288
|
-
return {
|
|
289
|
-
schemaVersion: 1,
|
|
290
|
-
run: AgentRunSchema2.parse(parseJson2(row.payload)),
|
|
291
|
-
...row.terminal_assistant_payload ? {
|
|
292
|
-
terminalAssistant: AgentMessageSchema2.parse(parseJson2(row.terminal_assistant_payload))
|
|
293
|
-
} : {}
|
|
294
|
-
};
|
|
295
|
-
});
|
|
296
|
-
const admissions = database.prepare("SELECT conversation_id, idempotency_key, input_payload, run_id, assistant_message_id FROM stitchkit_agent_runtime_admissions WHERE conversation_id = ? ORDER BY idempotency_key").all(conversation.conversation_id).map((value) => {
|
|
297
|
-
const row = AdmissionRowSchema.parse(value);
|
|
298
|
-
return {
|
|
299
|
-
schemaVersion: 1,
|
|
300
|
-
conversationId: row.conversation_id,
|
|
301
|
-
idempotencyKey: row.idempotency_key,
|
|
302
|
-
input: AgentMessageSchema2.parse(parseJson2(row.input_payload)),
|
|
303
|
-
runId: row.run_id,
|
|
304
|
-
assistantMessageId: row.assistant_message_id
|
|
305
|
-
};
|
|
306
|
-
});
|
|
307
|
-
const asOf = messages.at(-1)?.createdAt ?? runs.at(-1)?.run.createdAt;
|
|
308
|
-
insert.run(conversation.conversation_id, randomUUID(), migratedAt, canonicalAgentJson2({
|
|
309
|
-
migratedAt,
|
|
310
|
-
...asOf !== undefined && { asOf },
|
|
311
|
-
head: {
|
|
312
|
-
schemaVersion: 1,
|
|
313
|
-
conversationId: conversation.conversation_id,
|
|
314
|
-
version: conversation.version
|
|
315
|
-
},
|
|
316
|
-
messages,
|
|
317
|
-
...compacted.length > 0 && { compacted },
|
|
318
|
-
runs,
|
|
319
|
-
admissions
|
|
320
|
-
}));
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
function migrateAgentRuntimeSqliteV1ToV2(database, migratedAt = new Date().toISOString()) {
|
|
324
|
-
createDurableTables(database);
|
|
325
|
-
writeBaselines(database, migratedAt);
|
|
326
|
-
database.prepare("UPDATE stitchkit_agent_runtime_meta SET value = '2' WHERE key = 'schema_version'").run();
|
|
327
|
-
}
|
|
328
|
-
function createAgentRuntimeSqliteV2Tables(database) {
|
|
329
|
-
createDurableTables(database);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// src/agent-runtime/store-migrations/v2-to-v3.ts
|
|
333
|
-
function createAgentRuntimeSqliteV3Tables(database) {
|
|
334
|
-
database.exec(`
|
|
335
|
-
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_seeds (
|
|
336
|
-
conversation_id TEXT NOT NULL,
|
|
337
|
-
seed_key TEXT NOT NULL,
|
|
338
|
-
message_ids TEXT NOT NULL,
|
|
339
|
-
created_at TEXT NOT NULL,
|
|
340
|
-
PRIMARY KEY (conversation_id, seed_key)
|
|
341
|
-
);
|
|
342
|
-
`);
|
|
343
|
-
}
|
|
344
|
-
function migrateAgentRuntimeSqliteV2ToV3(database) {
|
|
345
|
-
createAgentRuntimeSqliteV3Tables(database);
|
|
346
|
-
database.prepare("UPDATE stitchkit_agent_runtime_meta SET value = '3' WHERE key = 'schema_version'").run();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// src/agent-runtime/store-migrations/v3-to-v4.ts
|
|
350
|
-
function migrateAgentRuntimeSqliteV3ToV4(database) {
|
|
351
|
-
database.exec(`
|
|
352
|
-
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN retry_at TEXT;
|
|
353
|
-
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN attempts INTEGER NOT NULL DEFAULT 0;
|
|
354
|
-
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN last_error TEXT;
|
|
355
|
-
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN eligible_at TEXT
|
|
356
|
-
GENERATED ALWAYS AS (MAX(next_at, COALESCE(retry_at, next_at), COALESCE(claim_until, next_at))) VIRTUAL;
|
|
357
|
-
DROP INDEX stitchkit_agent_runtime_schedules_due;
|
|
358
|
-
CREATE INDEX stitchkit_agent_runtime_schedules_due
|
|
359
|
-
ON stitchkit_agent_runtime_schedules (eligible_at, id) WHERE state = 'scheduled';
|
|
360
|
-
UPDATE stitchkit_agent_runtime_meta SET value = '4' WHERE key = 'schema_version';
|
|
361
|
-
`);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// src/agent-runtime/sqlite-schema.ts
|
|
365
|
-
var MetaRowSchema = z3.object({ value: z3.string() });
|
|
366
|
-
var TableRowSchema = z3.object({ name: z3.string() });
|
|
367
|
-
var SCHEMA_VERSION = 4;
|
|
368
|
-
var TABLES = [
|
|
369
|
-
"stitchkit_agent_runtime_heads",
|
|
370
|
-
"stitchkit_agent_runtime_runs",
|
|
371
|
-
"stitchkit_agent_runtime_admissions",
|
|
372
|
-
"stitchkit_agent_runtime_messages",
|
|
373
|
-
"stitchkit_agent_runtime_seeds",
|
|
374
|
-
"stitchkit_agent_runtime_events",
|
|
375
|
-
"stitchkit_agent_runtime_projections",
|
|
376
|
-
"stitchkit_agent_runtime_spills",
|
|
377
|
-
"stitchkit_agent_runtime_schedules",
|
|
378
|
-
"stitchkit_agent_runtime_children"
|
|
379
|
-
];
|
|
380
|
-
function initializeAgentRuntimeSqlite2(database) {
|
|
381
|
-
database.exec("BEGIN IMMEDIATE");
|
|
382
|
-
try {
|
|
383
|
-
const existing = database.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'stitchkit_agent_runtime_%' ORDER BY name`).all().map((row) => TableRowSchema.parse(row).name);
|
|
384
|
-
const hasMeta = existing.includes("stitchkit_agent_runtime_meta");
|
|
385
|
-
if (!hasMeta && existing.length > 0) {
|
|
386
|
-
throw new Error("Refusing an unversioned partial Stitchkit agent-runtime SQLite schema");
|
|
387
|
-
}
|
|
388
|
-
database.exec(`
|
|
389
|
-
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_meta (
|
|
390
|
-
key TEXT PRIMARY KEY,
|
|
391
|
-
value TEXT NOT NULL
|
|
392
|
-
);
|
|
393
|
-
`);
|
|
394
|
-
const versionRow = database.prepare("SELECT value FROM stitchkit_agent_runtime_meta WHERE key = 'schema_version'").get();
|
|
395
|
-
if (!missing(versionRow)) {
|
|
396
|
-
const version = Number(MetaRowSchema.parse(versionRow).value);
|
|
397
|
-
if (version === 1) {
|
|
398
|
-
migrateAgentRuntimeSqliteV1ToV2(database);
|
|
399
|
-
migrateAgentRuntimeSqliteV2ToV3(database);
|
|
400
|
-
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
401
|
-
initializeSqliteConversationPurge(database);
|
|
402
|
-
database.exec("COMMIT");
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
if (version === 2) {
|
|
406
|
-
migrateAgentRuntimeSqliteV2ToV3(database);
|
|
407
|
-
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
408
|
-
initializeSqliteConversationPurge(database);
|
|
409
|
-
database.exec("COMMIT");
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
if (version === 3) {
|
|
413
|
-
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
414
|
-
initializeSqliteConversationPurge(database);
|
|
415
|
-
database.exec("COMMIT");
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
418
|
-
if (version !== SCHEMA_VERSION) {
|
|
419
|
-
throw new Error(`Unsupported Stitchkit agent-runtime SQLite schema version ${version}; expected ${SCHEMA_VERSION}`);
|
|
420
|
-
}
|
|
421
|
-
const missingTables = TABLES.filter((table) => !existing.includes(table));
|
|
422
|
-
if (missingTables.length > 0) {
|
|
423
|
-
throw new Error(`Refusing a partial Stitchkit agent-runtime SQLite schema; missing ${missingTables.join(", ")}`);
|
|
424
|
-
}
|
|
425
|
-
initializeSqliteConversationPurge(database);
|
|
426
|
-
database.exec("COMMIT");
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
if (existing.some((table) => table !== "stitchkit_agent_runtime_meta")) {
|
|
430
|
-
throw new Error("Refusing an unversioned partial Stitchkit agent-runtime SQLite schema");
|
|
431
|
-
}
|
|
432
|
-
database.exec(`
|
|
433
|
-
CREATE TABLE stitchkit_agent_runtime_heads (
|
|
434
|
-
conversation_id TEXT PRIMARY KEY,
|
|
435
|
-
version INTEGER NOT NULL CHECK (version >= 0)
|
|
436
|
-
);
|
|
437
|
-
CREATE TABLE stitchkit_agent_runtime_runs (
|
|
438
|
-
conversation_id TEXT NOT NULL,
|
|
439
|
-
run_id TEXT NOT NULL,
|
|
440
|
-
assistant_message_id TEXT NOT NULL,
|
|
441
|
-
state TEXT NOT NULL,
|
|
442
|
-
created_at TEXT NOT NULL,
|
|
443
|
-
payload TEXT NOT NULL,
|
|
444
|
-
terminal_assistant_payload TEXT,
|
|
445
|
-
PRIMARY KEY (conversation_id, run_id),
|
|
446
|
-
UNIQUE (conversation_id, assistant_message_id)
|
|
447
|
-
);
|
|
448
|
-
CREATE INDEX stitchkit_agent_runtime_recoverable
|
|
449
|
-
ON stitchkit_agent_runtime_runs (state, conversation_id, run_id);
|
|
450
|
-
CREATE TABLE stitchkit_agent_runtime_admissions (
|
|
451
|
-
conversation_id TEXT NOT NULL,
|
|
452
|
-
idempotency_key TEXT NOT NULL,
|
|
453
|
-
input_message_id TEXT NOT NULL,
|
|
454
|
-
run_id TEXT NOT NULL,
|
|
455
|
-
assistant_message_id TEXT NOT NULL,
|
|
456
|
-
input_payload TEXT NOT NULL,
|
|
457
|
-
PRIMARY KEY (conversation_id, idempotency_key),
|
|
458
|
-
UNIQUE (conversation_id, input_message_id)
|
|
459
|
-
);
|
|
460
|
-
CREATE TABLE stitchkit_agent_runtime_messages (
|
|
461
|
-
conversation_id TEXT NOT NULL,
|
|
462
|
-
id TEXT NOT NULL,
|
|
463
|
-
position INTEGER NOT NULL CHECK (position >= 0),
|
|
464
|
-
active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0, 1)),
|
|
465
|
-
payload TEXT NOT NULL,
|
|
466
|
-
PRIMARY KEY (conversation_id, id)
|
|
467
|
-
);
|
|
468
|
-
`);
|
|
469
|
-
createAgentRuntimeSqliteV2Tables(database);
|
|
470
|
-
createAgentRuntimeSqliteV3Tables(database);
|
|
471
|
-
database.prepare("INSERT INTO stitchkit_agent_runtime_meta (key, value) VALUES ('schema_version', '3')").run();
|
|
472
|
-
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
473
|
-
initializeSqliteConversationPurge(database);
|
|
474
|
-
database.exec("COMMIT");
|
|
475
|
-
} catch (error) {
|
|
476
|
-
database.exec("ROLLBACK");
|
|
477
|
-
throw error;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// src/agent-runtime/sqlite-events.ts
|
|
482
|
-
import { createHash } from "node:crypto";
|
|
483
|
-
import { z as z4 } from "zod";
|
|
484
|
-
var ArchiveProjectionRowSchema = z4.object({
|
|
485
|
-
name: z4.string(),
|
|
486
|
-
version: z4.int().positive(),
|
|
487
|
-
upto_seq: z4.int().nonnegative(),
|
|
488
|
-
payload: z4.string(),
|
|
489
|
-
updated_at: z4.string()
|
|
490
|
-
});
|
|
491
|
-
var ArchiveSpillRowSchema = z4.object({
|
|
492
|
-
reference_id: z4.string(),
|
|
493
|
-
run_id: z4.string().nullable(),
|
|
494
|
-
tool_call_id: z4.string().nullable(),
|
|
495
|
-
media_type: z4.string(),
|
|
496
|
-
bytes: z4.int().nonnegative(),
|
|
497
|
-
sha256: z4.string(),
|
|
498
|
-
created_at: z4.string(),
|
|
499
|
-
expires_at: z4.string().nullable(),
|
|
500
|
-
authorization_payload: z4.string().nullable(),
|
|
501
|
-
payload: z4.instanceof(Uint8Array)
|
|
502
|
-
});
|
|
503
|
-
var sqliteEvents = {
|
|
504
|
-
async append(transaction, rawEvent) {
|
|
505
|
-
const event = rawEvent;
|
|
506
|
-
const last = transaction.prepare("SELECT COALESCE(MAX(seq), 0) AS count FROM stitchkit_agent_runtime_events WHERE conversation_id = ?").get(event.conversationId);
|
|
507
|
-
const seq = CountRowSchema.parse(last).count + 1;
|
|
508
|
-
transaction.prepare(`
|
|
509
|
-
INSERT INTO stitchkit_agent_runtime_events (
|
|
510
|
-
conversation_id, seq, event_id, schema_version, kind, occurred_at, ignorable, payload
|
|
511
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
512
|
-
`).run(event.conversationId, seq, event.eventId, event.schemaVersion, event.kind, event.occurredAt, event.ignorable ? 1 : 0, encodeJson(event.payload));
|
|
513
|
-
return AgentStoreEventEnvelopeSchema2.parse({ ...event, seq });
|
|
514
|
-
},
|
|
515
|
-
async list(transaction, input) {
|
|
516
|
-
const clauses = ["conversation_id = ?"];
|
|
517
|
-
const values = [input.conversationId];
|
|
518
|
-
if (input.fromSeq !== undefined) {
|
|
519
|
-
clauses.push("seq >= ?");
|
|
520
|
-
values.push(input.fromSeq);
|
|
521
|
-
}
|
|
522
|
-
if (input.toSeq !== undefined) {
|
|
523
|
-
clauses.push("seq <= ?");
|
|
524
|
-
values.push(input.toSeq);
|
|
525
|
-
}
|
|
526
|
-
const rows = transaction.prepare(`
|
|
527
|
-
SELECT event_id, conversation_id, seq, schema_version, kind, occurred_at,
|
|
528
|
-
ignorable, payload
|
|
529
|
-
FROM stitchkit_agent_runtime_events
|
|
530
|
-
WHERE ${clauses.join(" AND ")}
|
|
531
|
-
ORDER BY seq ASC LIMIT ?
|
|
532
|
-
`).all(...values, input.limit + 1).map(parseEventRow);
|
|
533
|
-
const hasMore = rows.length > input.limit;
|
|
534
|
-
const items = rows.slice(0, input.limit);
|
|
535
|
-
const lastEvent = items.at(-1);
|
|
536
|
-
return AgentStoreEventPageSchema2.parse({
|
|
537
|
-
items,
|
|
538
|
-
...hasMore && lastEvent ? { nextSeq: lastEvent.seq + 1 } : {}
|
|
539
|
-
});
|
|
540
|
-
},
|
|
541
|
-
async find(transaction, input) {
|
|
542
|
-
const row = transaction.prepare(`
|
|
543
|
-
SELECT event_id, conversation_id, seq, schema_version, kind, occurred_at,
|
|
544
|
-
ignorable, payload
|
|
545
|
-
FROM stitchkit_agent_runtime_events
|
|
546
|
-
WHERE event_id = ? AND conversation_id = ?
|
|
547
|
-
`).get(input.eventId, input.conversationId);
|
|
548
|
-
return row === null || row === undefined ? undefined : parseEventRow(row);
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
var sqliteArchive = {
|
|
552
|
-
async export(transaction, conversationId) {
|
|
553
|
-
const projections = transaction.prepare(`
|
|
554
|
-
SELECT name, version, upto_seq, payload, updated_at
|
|
555
|
-
FROM stitchkit_agent_runtime_projections
|
|
556
|
-
WHERE conversation_id = ? ORDER BY name
|
|
557
|
-
`).all(conversationId).map((raw) => {
|
|
558
|
-
const row = ArchiveProjectionRowSchema.parse(raw);
|
|
559
|
-
return {
|
|
560
|
-
name: row.name,
|
|
561
|
-
version: row.version,
|
|
562
|
-
uptoSeq: row.upto_seq,
|
|
563
|
-
value: z4.json().parse(parseJson(row.payload)),
|
|
564
|
-
updatedAt: row.updated_at
|
|
167
|
+
name: row.name,
|
|
168
|
+
version: row.version,
|
|
169
|
+
uptoSeq: row.upto_seq,
|
|
170
|
+
value: z2.json().parse(parseJson(row.payload)),
|
|
171
|
+
updatedAt: row.updated_at
|
|
565
172
|
};
|
|
566
173
|
});
|
|
567
174
|
const spills = transaction.prepare(`
|
|
@@ -581,7 +188,7 @@ var sqliteArchive = {
|
|
|
581
188
|
createdAt: row.created_at,
|
|
582
189
|
...row.expires_at && { expiresAt: row.expires_at },
|
|
583
190
|
...row.authorization_payload && {
|
|
584
|
-
authorization:
|
|
191
|
+
authorization: z2.json().parse(parseJson(row.authorization_payload))
|
|
585
192
|
},
|
|
586
193
|
base64: Buffer.from(row.payload).toString("base64")
|
|
587
194
|
};
|
|
@@ -601,17 +208,17 @@ var sqliteArchive = {
|
|
|
601
208
|
`).run(archive.conversationId, projection.name, projection.version, projection.uptoSeq, encodeJson(projection.value), projection.updatedAt);
|
|
602
209
|
}
|
|
603
210
|
for (const raw of archive.spills) {
|
|
604
|
-
const spill =
|
|
605
|
-
reference:
|
|
606
|
-
runId:
|
|
607
|
-
toolCallId:
|
|
608
|
-
mediaType:
|
|
609
|
-
bytes:
|
|
610
|
-
sha256:
|
|
611
|
-
createdAt:
|
|
612
|
-
expiresAt:
|
|
613
|
-
authorization:
|
|
614
|
-
base64:
|
|
211
|
+
const spill = z2.object({
|
|
212
|
+
reference: z2.string(),
|
|
213
|
+
runId: z2.string().optional(),
|
|
214
|
+
toolCallId: z2.string().optional(),
|
|
215
|
+
mediaType: z2.string(),
|
|
216
|
+
bytes: z2.int().nonnegative(),
|
|
217
|
+
sha256: z2.string(),
|
|
218
|
+
createdAt: z2.string(),
|
|
219
|
+
expiresAt: z2.string().optional(),
|
|
220
|
+
authorization: z2.json().optional(),
|
|
221
|
+
base64: z2.string()
|
|
615
222
|
}).strict().parse(raw);
|
|
616
223
|
const payload = Buffer.from(spill.base64, "base64");
|
|
617
224
|
if (payload.byteLength !== spill.bytes) {
|
|
@@ -740,21 +347,21 @@ var sqliteHistory = {
|
|
|
740
347
|
};
|
|
741
348
|
|
|
742
349
|
// src/agent-runtime/sqlite-ledger.ts
|
|
743
|
-
import { z as
|
|
744
|
-
var
|
|
745
|
-
conversation_id:
|
|
746
|
-
idempotency_key:
|
|
747
|
-
input_payload:
|
|
748
|
-
run_id:
|
|
749
|
-
assistant_message_id:
|
|
350
|
+
import { z as z3 } from "zod";
|
|
351
|
+
var AdmissionRowSchema = z3.object({
|
|
352
|
+
conversation_id: z3.string(),
|
|
353
|
+
idempotency_key: z3.string(),
|
|
354
|
+
input_payload: z3.string(),
|
|
355
|
+
run_id: z3.string(),
|
|
356
|
+
assistant_message_id: z3.string()
|
|
750
357
|
});
|
|
751
|
-
var SeedRowSchema =
|
|
752
|
-
conversation_id:
|
|
753
|
-
seed_key:
|
|
754
|
-
message_ids:
|
|
358
|
+
var SeedRowSchema = z3.object({
|
|
359
|
+
conversation_id: z3.string(),
|
|
360
|
+
seed_key: z3.string(),
|
|
361
|
+
message_ids: z3.string()
|
|
755
362
|
});
|
|
756
363
|
function parseAdmissionRow(value) {
|
|
757
|
-
const row =
|
|
364
|
+
const row = AdmissionRowSchema.parse(value);
|
|
758
365
|
return AgentAdmissionReceiptSchema2.parse({
|
|
759
366
|
schemaVersion: 1,
|
|
760
367
|
conversationId: row.conversation_id,
|
|
@@ -879,7 +486,7 @@ var sqliteSeeds = {
|
|
|
879
486
|
schemaVersion: 1,
|
|
880
487
|
conversationId: row.conversation_id,
|
|
881
488
|
seedKey: row.seed_key,
|
|
882
|
-
messageIds:
|
|
489
|
+
messageIds: z3.array(z3.string().min(1)).parse(parseJson(row.message_ids))
|
|
883
490
|
});
|
|
884
491
|
},
|
|
885
492
|
async create(transaction, rawReceipt) {
|
|
@@ -892,8 +499,66 @@ var sqliteSeeds = {
|
|
|
892
499
|
}
|
|
893
500
|
};
|
|
894
501
|
|
|
502
|
+
// src/agent-runtime/sqlite-purge.ts
|
|
503
|
+
var OWNED_TABLES = [
|
|
504
|
+
"stitchkit_agent_runtime_spills",
|
|
505
|
+
"stitchkit_agent_runtime_schedules",
|
|
506
|
+
"stitchkit_agent_runtime_projections",
|
|
507
|
+
"stitchkit_agent_runtime_events",
|
|
508
|
+
"stitchkit_agent_runtime_messages",
|
|
509
|
+
"stitchkit_agent_runtime_seeds",
|
|
510
|
+
"stitchkit_agent_runtime_admissions",
|
|
511
|
+
"stitchkit_agent_runtime_runs",
|
|
512
|
+
"stitchkit_agent_runtime_heads"
|
|
513
|
+
];
|
|
514
|
+
function initializeSqliteConversationPurge(database) {
|
|
515
|
+
database.exec(`
|
|
516
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_purged (
|
|
517
|
+
conversation_id TEXT PRIMARY KEY
|
|
518
|
+
);
|
|
519
|
+
`);
|
|
520
|
+
for (const table of OWNED_TABLES) {
|
|
521
|
+
for (const operation of ["INSERT", "UPDATE"]) {
|
|
522
|
+
database.exec(`
|
|
523
|
+
CREATE TRIGGER IF NOT EXISTS ${table}_purge_${operation.toLowerCase()}
|
|
524
|
+
BEFORE ${operation} ON ${table}
|
|
525
|
+
WHEN EXISTS (
|
|
526
|
+
SELECT 1 FROM stitchkit_agent_runtime_purged WHERE conversation_id = NEW.conversation_id
|
|
527
|
+
)
|
|
528
|
+
BEGIN SELECT RAISE(ABORT, 'Agent conversation has been purged'); END;
|
|
529
|
+
`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
function sqliteConversationPurge(database) {
|
|
534
|
+
const table = database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'stitchkit_agent_runtime_purged'").get();
|
|
535
|
+
if (table === null || table === undefined)
|
|
536
|
+
return;
|
|
537
|
+
return {
|
|
538
|
+
async isEmpty(transaction, conversationId) {
|
|
539
|
+
for (const table of OWNED_TABLES) {
|
|
540
|
+
const row = transaction.prepare(`SELECT 1 FROM ${table} WHERE conversation_id = ? LIMIT 1`).get(conversationId);
|
|
541
|
+
if (row !== null && row !== undefined)
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
return transaction.prepare("SELECT 1 FROM stitchkit_agent_runtime_children WHERE parent_conversation_id = ? OR child_conversation_id = ? LIMIT 1").get(conversationId, conversationId) == null;
|
|
545
|
+
},
|
|
546
|
+
async isPurged(transaction, conversationId) {
|
|
547
|
+
const row = transaction.prepare("SELECT conversation_id FROM stitchkit_agent_runtime_purged WHERE conversation_id = ?").get(conversationId);
|
|
548
|
+
return row !== null && row !== undefined;
|
|
549
|
+
},
|
|
550
|
+
async remove(transaction, conversationId) {
|
|
551
|
+
transaction.prepare("INSERT INTO stitchkit_agent_runtime_purged (conversation_id) VALUES (?)").run(conversationId);
|
|
552
|
+
for (const table of OWNED_TABLES) {
|
|
553
|
+
transaction.prepare(`DELETE FROM ${table} WHERE conversation_id = ?`).run(conversationId);
|
|
554
|
+
}
|
|
555
|
+
transaction.prepare("DELETE FROM stitchkit_agent_runtime_children WHERE parent_conversation_id = ? OR child_conversation_id = ?").run(conversationId, conversationId);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
|
|
895
560
|
// src/agent-runtime/sqlite-reads.ts
|
|
896
|
-
import { z as
|
|
561
|
+
import { z as z4 } from "zod";
|
|
897
562
|
|
|
898
563
|
// src/agent-runtime/sqlite-transactions.ts
|
|
899
564
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -951,40 +616,40 @@ async function closeSqliteStore(state) {
|
|
|
951
616
|
}
|
|
952
617
|
|
|
953
618
|
// src/agent-runtime/sqlite-reads.ts
|
|
954
|
-
var RecoverableRowSchema =
|
|
955
|
-
conversation_id:
|
|
956
|
-
run_id:
|
|
957
|
-
payload:
|
|
619
|
+
var RecoverableRowSchema = z4.object({
|
|
620
|
+
conversation_id: z4.string(),
|
|
621
|
+
run_id: z4.string(),
|
|
622
|
+
payload: z4.string()
|
|
958
623
|
});
|
|
959
|
-
var ConversationHeadRowSchema =
|
|
960
|
-
conversation_id:
|
|
961
|
-
version:
|
|
624
|
+
var ConversationHeadRowSchema = z4.object({
|
|
625
|
+
conversation_id: z4.string(),
|
|
626
|
+
version: z4.number().int().nonnegative()
|
|
962
627
|
});
|
|
963
|
-
var MessagePageRowSchema =
|
|
964
|
-
row_id:
|
|
965
|
-
position:
|
|
966
|
-
active:
|
|
967
|
-
payload:
|
|
628
|
+
var MessagePageRowSchema = z4.object({
|
|
629
|
+
row_id: z4.number().int().positive(),
|
|
630
|
+
position: z4.number().int().nonnegative(),
|
|
631
|
+
active: z4.union([z4.literal(0), z4.literal(1)]),
|
|
632
|
+
payload: z4.string()
|
|
968
633
|
});
|
|
969
634
|
function recoveryCursor(conversationId, runId) {
|
|
970
635
|
return encodeJson([conversationId, runId]);
|
|
971
636
|
}
|
|
972
637
|
function parseRecoveryCursor(cursor) {
|
|
973
|
-
return
|
|
638
|
+
return z4.tuple([z4.string().min(1), z4.string().min(1)]).parse(parseJson(cursor));
|
|
974
639
|
}
|
|
975
640
|
function conversationCursor(conversationId) {
|
|
976
641
|
return encodeJson([conversationId]);
|
|
977
642
|
}
|
|
978
643
|
function parseConversationCursor(cursor) {
|
|
979
|
-
return
|
|
644
|
+
return z4.tuple([z4.string().min(1)]).parse(parseJson(cursor))[0];
|
|
980
645
|
}
|
|
981
646
|
function messageCursor(position, rowId) {
|
|
982
647
|
return encodeJson([position, rowId]);
|
|
983
648
|
}
|
|
984
649
|
function parseMessageCursor(cursor) {
|
|
985
|
-
const parsed =
|
|
986
|
-
|
|
987
|
-
|
|
650
|
+
const parsed = z4.union([
|
|
651
|
+
z4.tuple([z4.int().nonnegative(), z4.int().positive()]),
|
|
652
|
+
z4.tuple([z4.int().nonnegative()])
|
|
988
653
|
]).parse(parseJson(cursor));
|
|
989
654
|
const [position, rowId] = parsed;
|
|
990
655
|
return { position, ...rowId !== undefined && { rowId } };
|
|
@@ -1109,6 +774,343 @@ function pageSqliteConversationMessages(state, input) {
|
|
|
1109
774
|
});
|
|
1110
775
|
}
|
|
1111
776
|
|
|
777
|
+
// src/agent-runtime/sqlite-schema.ts
|
|
778
|
+
import { z as z6 } from "zod";
|
|
779
|
+
|
|
780
|
+
// src/agent-runtime/store-migrations/v1-to-v2.ts
|
|
781
|
+
import { randomUUID } from "node:crypto";
|
|
782
|
+
import { z as z5 } from "zod";
|
|
783
|
+
var ConversationRowSchema = z5.object({
|
|
784
|
+
conversation_id: z5.string().min(1),
|
|
785
|
+
version: z5.int().nonnegative()
|
|
786
|
+
});
|
|
787
|
+
var PayloadRowSchema = z5.object({
|
|
788
|
+
payload: z5.string(),
|
|
789
|
+
terminal_assistant_payload: z5.string().nullable().optional()
|
|
790
|
+
});
|
|
791
|
+
var HistoryRowSchema = z5.object({
|
|
792
|
+
payload: z5.string(),
|
|
793
|
+
active: z5.union([z5.literal(0), z5.literal(1)])
|
|
794
|
+
});
|
|
795
|
+
var AdmissionRowSchema2 = z5.object({
|
|
796
|
+
conversation_id: z5.string(),
|
|
797
|
+
idempotency_key: z5.string(),
|
|
798
|
+
input_payload: z5.string(),
|
|
799
|
+
run_id: z5.string(),
|
|
800
|
+
assistant_message_id: z5.string()
|
|
801
|
+
});
|
|
802
|
+
function parseJson2(value) {
|
|
803
|
+
return JSON.parse(value);
|
|
804
|
+
}
|
|
805
|
+
function createDurableTables(database) {
|
|
806
|
+
database.exec(`
|
|
807
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_events (
|
|
808
|
+
row_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
809
|
+
conversation_id TEXT NOT NULL,
|
|
810
|
+
seq INTEGER NOT NULL CHECK (seq > 0),
|
|
811
|
+
event_id TEXT NOT NULL UNIQUE,
|
|
812
|
+
schema_version INTEGER NOT NULL CHECK (schema_version > 0),
|
|
813
|
+
kind TEXT NOT NULL,
|
|
814
|
+
occurred_at TEXT NOT NULL,
|
|
815
|
+
ignorable INTEGER NOT NULL DEFAULT 0 CHECK (ignorable IN (0, 1)),
|
|
816
|
+
payload TEXT NOT NULL,
|
|
817
|
+
UNIQUE (conversation_id, seq)
|
|
818
|
+
);
|
|
819
|
+
CREATE INDEX IF NOT EXISTS stitchkit_agent_runtime_events_time
|
|
820
|
+
ON stitchkit_agent_runtime_events (conversation_id, occurred_at, seq);
|
|
821
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_projections (
|
|
822
|
+
conversation_id TEXT NOT NULL,
|
|
823
|
+
name TEXT NOT NULL,
|
|
824
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
825
|
+
upto_seq INTEGER NOT NULL CHECK (upto_seq >= 0),
|
|
826
|
+
payload TEXT NOT NULL,
|
|
827
|
+
updated_at TEXT NOT NULL,
|
|
828
|
+
PRIMARY KEY (conversation_id, name)
|
|
829
|
+
);
|
|
830
|
+
CREATE INDEX IF NOT EXISTS stitchkit_agent_runtime_projection_updates
|
|
831
|
+
ON stitchkit_agent_runtime_projections (name, updated_at, conversation_id);
|
|
832
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_spills (
|
|
833
|
+
reference_id TEXT PRIMARY KEY,
|
|
834
|
+
conversation_id TEXT NOT NULL,
|
|
835
|
+
run_id TEXT,
|
|
836
|
+
tool_call_id TEXT,
|
|
837
|
+
media_type TEXT NOT NULL,
|
|
838
|
+
bytes INTEGER NOT NULL CHECK (bytes >= 0),
|
|
839
|
+
sha256 TEXT NOT NULL,
|
|
840
|
+
created_at TEXT NOT NULL,
|
|
841
|
+
expires_at TEXT,
|
|
842
|
+
authorization_payload TEXT,
|
|
843
|
+
payload BLOB NOT NULL
|
|
844
|
+
);
|
|
845
|
+
CREATE INDEX IF NOT EXISTS stitchkit_agent_runtime_spills_owner
|
|
846
|
+
ON stitchkit_agent_runtime_spills (conversation_id, created_at);
|
|
847
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_schedules (
|
|
848
|
+
id TEXT PRIMARY KEY,
|
|
849
|
+
conversation_id TEXT NOT NULL,
|
|
850
|
+
kind TEXT NOT NULL,
|
|
851
|
+
next_at TEXT NOT NULL,
|
|
852
|
+
interval_ms INTEGER,
|
|
853
|
+
time_zone TEXT,
|
|
854
|
+
input_payload TEXT NOT NULL,
|
|
855
|
+
state TEXT NOT NULL,
|
|
856
|
+
occurrence INTEGER NOT NULL DEFAULT 0 CHECK (occurrence >= 0),
|
|
857
|
+
claim_owner TEXT,
|
|
858
|
+
claim_until TEXT,
|
|
859
|
+
created_at TEXT NOT NULL,
|
|
860
|
+
updated_at TEXT NOT NULL
|
|
861
|
+
);
|
|
862
|
+
CREATE INDEX IF NOT EXISTS stitchkit_agent_runtime_schedules_due
|
|
863
|
+
ON stitchkit_agent_runtime_schedules (state, next_at);
|
|
864
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_children (
|
|
865
|
+
parent_conversation_id TEXT NOT NULL,
|
|
866
|
+
child_conversation_id TEXT NOT NULL UNIQUE,
|
|
867
|
+
seed_upto_seq INTEGER,
|
|
868
|
+
state TEXT NOT NULL,
|
|
869
|
+
budget_payload TEXT NOT NULL,
|
|
870
|
+
usage_payload TEXT NOT NULL,
|
|
871
|
+
result_reference TEXT,
|
|
872
|
+
created_at TEXT NOT NULL,
|
|
873
|
+
updated_at TEXT NOT NULL,
|
|
874
|
+
PRIMARY KEY (parent_conversation_id, child_conversation_id)
|
|
875
|
+
);
|
|
876
|
+
`);
|
|
877
|
+
try {
|
|
878
|
+
database.exec(`
|
|
879
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS stitchkit_agent_runtime_events_fts
|
|
880
|
+
USING fts5(
|
|
881
|
+
conversation_id UNINDEXED,
|
|
882
|
+
event_seq UNINDEXED,
|
|
883
|
+
occurred_at UNINDEXED,
|
|
884
|
+
body,
|
|
885
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
886
|
+
);
|
|
887
|
+
CREATE TRIGGER IF NOT EXISTS stitchkit_agent_runtime_events_fts_insert
|
|
888
|
+
AFTER INSERT ON stitchkit_agent_runtime_events BEGIN
|
|
889
|
+
INSERT INTO stitchkit_agent_runtime_events_fts(
|
|
890
|
+
rowid, conversation_id, event_seq, occurred_at, body
|
|
891
|
+
) VALUES (new.row_id, new.conversation_id, new.seq, new.occurred_at, new.payload);
|
|
892
|
+
END;
|
|
893
|
+
CREATE TRIGGER IF NOT EXISTS stitchkit_agent_runtime_events_fts_delete
|
|
894
|
+
AFTER DELETE ON stitchkit_agent_runtime_events BEGIN
|
|
895
|
+
DELETE FROM stitchkit_agent_runtime_events_fts WHERE rowid = old.row_id;
|
|
896
|
+
END;
|
|
897
|
+
`);
|
|
898
|
+
} catch (error) {
|
|
899
|
+
throw new Error("SQLite agent-runtime requires FTS5 support", { cause: error });
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function writeBaselines(database, migratedAt) {
|
|
903
|
+
const conversations = database.prepare("SELECT conversation_id, version FROM stitchkit_agent_runtime_heads ORDER BY conversation_id").all().map((row) => ConversationRowSchema.parse(row));
|
|
904
|
+
const insert = database.prepare(`
|
|
905
|
+
INSERT INTO stitchkit_agent_runtime_events (
|
|
906
|
+
conversation_id, seq, event_id, schema_version, kind, occurred_at, ignorable, payload
|
|
907
|
+
) VALUES (?, 1, ?, 1, 'runtime/baseline', ?, 0, ?)
|
|
908
|
+
`);
|
|
909
|
+
for (const conversation of conversations) {
|
|
910
|
+
const rows = database.prepare("SELECT payload, active FROM stitchkit_agent_runtime_messages WHERE conversation_id = ? ORDER BY position, rowid").all(conversation.conversation_id).map((row) => {
|
|
911
|
+
const parsed = HistoryRowSchema.parse(row);
|
|
912
|
+
return {
|
|
913
|
+
message: AgentMessageSchema2.parse(parseJson2(parsed.payload)),
|
|
914
|
+
active: parsed.active === 1
|
|
915
|
+
};
|
|
916
|
+
});
|
|
917
|
+
const messages = rows.map((row) => row.message);
|
|
918
|
+
const compacted = rows.filter((row) => !row.active).map((row) => row.message.id);
|
|
919
|
+
const runs = database.prepare("SELECT payload, terminal_assistant_payload FROM stitchkit_agent_runtime_runs WHERE conversation_id = ? ORDER BY created_at, run_id").all(conversation.conversation_id).map((value) => {
|
|
920
|
+
const row = PayloadRowSchema.parse(value);
|
|
921
|
+
return {
|
|
922
|
+
schemaVersion: 1,
|
|
923
|
+
run: AgentRunSchema2.parse(parseJson2(row.payload)),
|
|
924
|
+
...row.terminal_assistant_payload ? {
|
|
925
|
+
terminalAssistant: AgentMessageSchema2.parse(parseJson2(row.terminal_assistant_payload))
|
|
926
|
+
} : {}
|
|
927
|
+
};
|
|
928
|
+
});
|
|
929
|
+
const admissions = database.prepare("SELECT conversation_id, idempotency_key, input_payload, run_id, assistant_message_id FROM stitchkit_agent_runtime_admissions WHERE conversation_id = ? ORDER BY idempotency_key").all(conversation.conversation_id).map((value) => {
|
|
930
|
+
const row = AdmissionRowSchema2.parse(value);
|
|
931
|
+
return {
|
|
932
|
+
schemaVersion: 1,
|
|
933
|
+
conversationId: row.conversation_id,
|
|
934
|
+
idempotencyKey: row.idempotency_key,
|
|
935
|
+
input: AgentMessageSchema2.parse(parseJson2(row.input_payload)),
|
|
936
|
+
runId: row.run_id,
|
|
937
|
+
assistantMessageId: row.assistant_message_id
|
|
938
|
+
};
|
|
939
|
+
});
|
|
940
|
+
const asOf = messages.at(-1)?.createdAt ?? runs.at(-1)?.run.createdAt;
|
|
941
|
+
insert.run(conversation.conversation_id, randomUUID(), migratedAt, canonicalAgentJson2({
|
|
942
|
+
migratedAt,
|
|
943
|
+
...asOf !== undefined && { asOf },
|
|
944
|
+
head: {
|
|
945
|
+
schemaVersion: 1,
|
|
946
|
+
conversationId: conversation.conversation_id,
|
|
947
|
+
version: conversation.version
|
|
948
|
+
},
|
|
949
|
+
messages,
|
|
950
|
+
...compacted.length > 0 && { compacted },
|
|
951
|
+
runs,
|
|
952
|
+
admissions
|
|
953
|
+
}));
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function migrateAgentRuntimeSqliteV1ToV2(database, migratedAt = new Date().toISOString()) {
|
|
957
|
+
createDurableTables(database);
|
|
958
|
+
writeBaselines(database, migratedAt);
|
|
959
|
+
database.prepare("UPDATE stitchkit_agent_runtime_meta SET value = '2' WHERE key = 'schema_version'").run();
|
|
960
|
+
}
|
|
961
|
+
function createAgentRuntimeSqliteV2Tables(database) {
|
|
962
|
+
createDurableTables(database);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// src/agent-runtime/store-migrations/v2-to-v3.ts
|
|
966
|
+
function createAgentRuntimeSqliteV3Tables(database) {
|
|
967
|
+
database.exec(`
|
|
968
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_seeds (
|
|
969
|
+
conversation_id TEXT NOT NULL,
|
|
970
|
+
seed_key TEXT NOT NULL,
|
|
971
|
+
message_ids TEXT NOT NULL,
|
|
972
|
+
created_at TEXT NOT NULL,
|
|
973
|
+
PRIMARY KEY (conversation_id, seed_key)
|
|
974
|
+
);
|
|
975
|
+
`);
|
|
976
|
+
}
|
|
977
|
+
function migrateAgentRuntimeSqliteV2ToV3(database) {
|
|
978
|
+
createAgentRuntimeSqliteV3Tables(database);
|
|
979
|
+
database.prepare("UPDATE stitchkit_agent_runtime_meta SET value = '3' WHERE key = 'schema_version'").run();
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// src/agent-runtime/store-migrations/v3-to-v4.ts
|
|
983
|
+
function migrateAgentRuntimeSqliteV3ToV4(database) {
|
|
984
|
+
database.exec(`
|
|
985
|
+
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN retry_at TEXT;
|
|
986
|
+
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN attempts INTEGER NOT NULL DEFAULT 0;
|
|
987
|
+
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN last_error TEXT;
|
|
988
|
+
ALTER TABLE stitchkit_agent_runtime_schedules ADD COLUMN eligible_at TEXT
|
|
989
|
+
GENERATED ALWAYS AS (MAX(next_at, COALESCE(retry_at, next_at), COALESCE(claim_until, next_at))) VIRTUAL;
|
|
990
|
+
DROP INDEX stitchkit_agent_runtime_schedules_due;
|
|
991
|
+
CREATE INDEX stitchkit_agent_runtime_schedules_due
|
|
992
|
+
ON stitchkit_agent_runtime_schedules (eligible_at, id) WHERE state = 'scheduled';
|
|
993
|
+
UPDATE stitchkit_agent_runtime_meta SET value = '4' WHERE key = 'schema_version';
|
|
994
|
+
`);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// src/agent-runtime/sqlite-schema.ts
|
|
998
|
+
var MetaRowSchema = z6.object({ value: z6.string() });
|
|
999
|
+
var TableRowSchema = z6.object({ name: z6.string() });
|
|
1000
|
+
var SCHEMA_VERSION = 4;
|
|
1001
|
+
var TABLES = [
|
|
1002
|
+
"stitchkit_agent_runtime_heads",
|
|
1003
|
+
"stitchkit_agent_runtime_runs",
|
|
1004
|
+
"stitchkit_agent_runtime_admissions",
|
|
1005
|
+
"stitchkit_agent_runtime_messages",
|
|
1006
|
+
"stitchkit_agent_runtime_seeds",
|
|
1007
|
+
"stitchkit_agent_runtime_events",
|
|
1008
|
+
"stitchkit_agent_runtime_projections",
|
|
1009
|
+
"stitchkit_agent_runtime_spills",
|
|
1010
|
+
"stitchkit_agent_runtime_schedules",
|
|
1011
|
+
"stitchkit_agent_runtime_children"
|
|
1012
|
+
];
|
|
1013
|
+
function initializeAgentRuntimeSqlite2(database) {
|
|
1014
|
+
database.exec("BEGIN IMMEDIATE");
|
|
1015
|
+
try {
|
|
1016
|
+
const existing = database.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'stitchkit_agent_runtime_%' ORDER BY name`).all().map((row) => TableRowSchema.parse(row).name);
|
|
1017
|
+
const hasMeta = existing.includes("stitchkit_agent_runtime_meta");
|
|
1018
|
+
if (!hasMeta && existing.length > 0) {
|
|
1019
|
+
throw new Error("Refusing an unversioned partial Stitchkit agent-runtime SQLite schema");
|
|
1020
|
+
}
|
|
1021
|
+
database.exec(`
|
|
1022
|
+
CREATE TABLE IF NOT EXISTS stitchkit_agent_runtime_meta (
|
|
1023
|
+
key TEXT PRIMARY KEY,
|
|
1024
|
+
value TEXT NOT NULL
|
|
1025
|
+
);
|
|
1026
|
+
`);
|
|
1027
|
+
const versionRow = database.prepare("SELECT value FROM stitchkit_agent_runtime_meta WHERE key = 'schema_version'").get();
|
|
1028
|
+
if (!missing(versionRow)) {
|
|
1029
|
+
const version = Number(MetaRowSchema.parse(versionRow).value);
|
|
1030
|
+
if (version === 1) {
|
|
1031
|
+
migrateAgentRuntimeSqliteV1ToV2(database);
|
|
1032
|
+
migrateAgentRuntimeSqliteV2ToV3(database);
|
|
1033
|
+
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
1034
|
+
initializeSqliteConversationPurge(database);
|
|
1035
|
+
database.exec("COMMIT");
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
if (version === 2) {
|
|
1039
|
+
migrateAgentRuntimeSqliteV2ToV3(database);
|
|
1040
|
+
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
1041
|
+
initializeSqliteConversationPurge(database);
|
|
1042
|
+
database.exec("COMMIT");
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
if (version === 3) {
|
|
1046
|
+
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
1047
|
+
initializeSqliteConversationPurge(database);
|
|
1048
|
+
database.exec("COMMIT");
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
if (version !== SCHEMA_VERSION) {
|
|
1052
|
+
throw new Error(`Unsupported Stitchkit agent-runtime SQLite schema version ${version}; expected ${SCHEMA_VERSION}`);
|
|
1053
|
+
}
|
|
1054
|
+
const missingTables = TABLES.filter((table) => !existing.includes(table));
|
|
1055
|
+
if (missingTables.length > 0) {
|
|
1056
|
+
throw new Error(`Refusing a partial Stitchkit agent-runtime SQLite schema; missing ${missingTables.join(", ")}`);
|
|
1057
|
+
}
|
|
1058
|
+
initializeSqliteConversationPurge(database);
|
|
1059
|
+
database.exec("COMMIT");
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
if (existing.some((table) => table !== "stitchkit_agent_runtime_meta")) {
|
|
1063
|
+
throw new Error("Refusing an unversioned partial Stitchkit agent-runtime SQLite schema");
|
|
1064
|
+
}
|
|
1065
|
+
database.exec(`
|
|
1066
|
+
CREATE TABLE stitchkit_agent_runtime_heads (
|
|
1067
|
+
conversation_id TEXT PRIMARY KEY,
|
|
1068
|
+
version INTEGER NOT NULL CHECK (version >= 0)
|
|
1069
|
+
);
|
|
1070
|
+
CREATE TABLE stitchkit_agent_runtime_runs (
|
|
1071
|
+
conversation_id TEXT NOT NULL,
|
|
1072
|
+
run_id TEXT NOT NULL,
|
|
1073
|
+
assistant_message_id TEXT NOT NULL,
|
|
1074
|
+
state TEXT NOT NULL,
|
|
1075
|
+
created_at TEXT NOT NULL,
|
|
1076
|
+
payload TEXT NOT NULL,
|
|
1077
|
+
terminal_assistant_payload TEXT,
|
|
1078
|
+
PRIMARY KEY (conversation_id, run_id),
|
|
1079
|
+
UNIQUE (conversation_id, assistant_message_id)
|
|
1080
|
+
);
|
|
1081
|
+
CREATE INDEX stitchkit_agent_runtime_recoverable
|
|
1082
|
+
ON stitchkit_agent_runtime_runs (state, conversation_id, run_id);
|
|
1083
|
+
CREATE TABLE stitchkit_agent_runtime_admissions (
|
|
1084
|
+
conversation_id TEXT NOT NULL,
|
|
1085
|
+
idempotency_key TEXT NOT NULL,
|
|
1086
|
+
input_message_id TEXT NOT NULL,
|
|
1087
|
+
run_id TEXT NOT NULL,
|
|
1088
|
+
assistant_message_id TEXT NOT NULL,
|
|
1089
|
+
input_payload TEXT NOT NULL,
|
|
1090
|
+
PRIMARY KEY (conversation_id, idempotency_key),
|
|
1091
|
+
UNIQUE (conversation_id, input_message_id)
|
|
1092
|
+
);
|
|
1093
|
+
CREATE TABLE stitchkit_agent_runtime_messages (
|
|
1094
|
+
conversation_id TEXT NOT NULL,
|
|
1095
|
+
id TEXT NOT NULL,
|
|
1096
|
+
position INTEGER NOT NULL CHECK (position >= 0),
|
|
1097
|
+
active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0, 1)),
|
|
1098
|
+
payload TEXT NOT NULL,
|
|
1099
|
+
PRIMARY KEY (conversation_id, id)
|
|
1100
|
+
);
|
|
1101
|
+
`);
|
|
1102
|
+
createAgentRuntimeSqliteV2Tables(database);
|
|
1103
|
+
createAgentRuntimeSqliteV3Tables(database);
|
|
1104
|
+
database.prepare("INSERT INTO stitchkit_agent_runtime_meta (key, value) VALUES ('schema_version', '3')").run();
|
|
1105
|
+
migrateAgentRuntimeSqliteV3ToV4(database);
|
|
1106
|
+
initializeSqliteConversationPurge(database);
|
|
1107
|
+
database.exec("COMMIT");
|
|
1108
|
+
} catch (error) {
|
|
1109
|
+
database.exec("ROLLBACK");
|
|
1110
|
+
throw error;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1112
1114
|
// src/agent-runtime/sqlite.ts
|
|
1113
1115
|
function createSqliteAgentRuntimeStore2(config) {
|
|
1114
1116
|
const database = config.database;
|