@witqq/agent-sdk 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/{types-CqvUAYxt.d.ts → agent-C6H2CgJA.d.cts} +139 -102
  2. package/dist/{types-CqvUAYxt.d.cts → agent-F7oB6eKp.d.ts} +139 -102
  3. package/dist/auth/index.cjs +72 -1
  4. package/dist/auth/index.cjs.map +1 -1
  5. package/dist/auth/index.d.cts +21 -154
  6. package/dist/auth/index.d.ts +21 -154
  7. package/dist/auth/index.js +72 -1
  8. package/dist/auth/index.js.map +1 -1
  9. package/dist/backends/claude.cjs +480 -261
  10. package/dist/backends/claude.cjs.map +1 -1
  11. package/dist/backends/claude.d.cts +3 -1
  12. package/dist/backends/claude.d.ts +3 -1
  13. package/dist/backends/claude.js +480 -261
  14. package/dist/backends/claude.js.map +1 -1
  15. package/dist/backends/copilot.cjs +337 -112
  16. package/dist/backends/copilot.cjs.map +1 -1
  17. package/dist/backends/copilot.d.cts +12 -4
  18. package/dist/backends/copilot.d.ts +12 -4
  19. package/dist/backends/copilot.js +337 -112
  20. package/dist/backends/copilot.js.map +1 -1
  21. package/dist/backends/mock-llm.cjs +719 -0
  22. package/dist/backends/mock-llm.cjs.map +1 -0
  23. package/dist/backends/mock-llm.d.cts +37 -0
  24. package/dist/backends/mock-llm.d.ts +37 -0
  25. package/dist/backends/mock-llm.js +717 -0
  26. package/dist/backends/mock-llm.js.map +1 -0
  27. package/dist/backends/vercel-ai.cjs +301 -61
  28. package/dist/backends/vercel-ai.cjs.map +1 -1
  29. package/dist/backends/vercel-ai.d.cts +3 -1
  30. package/dist/backends/vercel-ai.d.ts +3 -1
  31. package/dist/backends/vercel-ai.js +301 -61
  32. package/dist/backends/vercel-ai.js.map +1 -1
  33. package/dist/backends-Cno0gZjy.d.cts +114 -0
  34. package/dist/backends-Cno0gZjy.d.ts +114 -0
  35. package/dist/chat/accumulator.cjs +1 -1
  36. package/dist/chat/accumulator.cjs.map +1 -1
  37. package/dist/chat/accumulator.d.cts +5 -2
  38. package/dist/chat/accumulator.d.ts +5 -2
  39. package/dist/chat/accumulator.js +1 -1
  40. package/dist/chat/accumulator.js.map +1 -1
  41. package/dist/chat/backends.cjs +1084 -821
  42. package/dist/chat/backends.cjs.map +1 -1
  43. package/dist/chat/backends.d.cts +10 -6
  44. package/dist/chat/backends.d.ts +10 -6
  45. package/dist/chat/backends.js +1082 -800
  46. package/dist/chat/backends.js.map +1 -1
  47. package/dist/chat/context.cjs +50 -0
  48. package/dist/chat/context.cjs.map +1 -1
  49. package/dist/chat/context.d.cts +27 -3
  50. package/dist/chat/context.d.ts +27 -3
  51. package/dist/chat/context.js +50 -0
  52. package/dist/chat/context.js.map +1 -1
  53. package/dist/chat/core.cjs +60 -27
  54. package/dist/chat/core.cjs.map +1 -1
  55. package/dist/chat/core.d.cts +41 -382
  56. package/dist/chat/core.d.ts +41 -382
  57. package/dist/chat/core.js +58 -28
  58. package/dist/chat/core.js.map +1 -1
  59. package/dist/chat/errors.cjs +48 -26
  60. package/dist/chat/errors.cjs.map +1 -1
  61. package/dist/chat/errors.d.cts +6 -31
  62. package/dist/chat/errors.d.ts +6 -31
  63. package/dist/chat/errors.js +48 -25
  64. package/dist/chat/errors.js.map +1 -1
  65. package/dist/chat/events.cjs.map +1 -1
  66. package/dist/chat/events.d.cts +6 -2
  67. package/dist/chat/events.d.ts +6 -2
  68. package/dist/chat/events.js.map +1 -1
  69. package/dist/chat/index.cjs +1612 -1125
  70. package/dist/chat/index.cjs.map +1 -1
  71. package/dist/chat/index.d.cts +35 -10
  72. package/dist/chat/index.d.ts +35 -10
  73. package/dist/chat/index.js +1600 -1097
  74. package/dist/chat/index.js.map +1 -1
  75. package/dist/chat/react/theme.css +2517 -0
  76. package/dist/chat/react.cjs +2212 -1158
  77. package/dist/chat/react.cjs.map +1 -1
  78. package/dist/chat/react.d.cts +665 -122
  79. package/dist/chat/react.d.ts +665 -122
  80. package/dist/chat/react.js +2191 -1156
  81. package/dist/chat/react.js.map +1 -1
  82. package/dist/chat/runtime.cjs +405 -186
  83. package/dist/chat/runtime.cjs.map +1 -1
  84. package/dist/chat/runtime.d.cts +92 -28
  85. package/dist/chat/runtime.d.ts +92 -28
  86. package/dist/chat/runtime.js +405 -186
  87. package/dist/chat/runtime.js.map +1 -1
  88. package/dist/chat/server.cjs +2247 -212
  89. package/dist/chat/server.cjs.map +1 -1
  90. package/dist/chat/server.d.cts +451 -90
  91. package/dist/chat/server.d.ts +451 -90
  92. package/dist/chat/server.js +2234 -213
  93. package/dist/chat/server.js.map +1 -1
  94. package/dist/chat/sessions.cjs +64 -66
  95. package/dist/chat/sessions.cjs.map +1 -1
  96. package/dist/chat/sessions.d.cts +37 -118
  97. package/dist/chat/sessions.d.ts +37 -118
  98. package/dist/chat/sessions.js +65 -67
  99. package/dist/chat/sessions.js.map +1 -1
  100. package/dist/chat/sqlite.cjs +536 -0
  101. package/dist/chat/sqlite.cjs.map +1 -0
  102. package/dist/chat/sqlite.d.cts +164 -0
  103. package/dist/chat/sqlite.d.ts +164 -0
  104. package/dist/chat/sqlite.js +527 -0
  105. package/dist/chat/sqlite.js.map +1 -0
  106. package/dist/chat/state.cjs +14 -1
  107. package/dist/chat/state.cjs.map +1 -1
  108. package/dist/chat/state.d.cts +5 -2
  109. package/dist/chat/state.d.ts +5 -2
  110. package/dist/chat/state.js +14 -1
  111. package/dist/chat/state.js.map +1 -1
  112. package/dist/chat/storage.cjs +58 -33
  113. package/dist/chat/storage.cjs.map +1 -1
  114. package/dist/chat/storage.d.cts +18 -8
  115. package/dist/chat/storage.d.ts +18 -8
  116. package/dist/chat/storage.js +59 -34
  117. package/dist/chat/storage.js.map +1 -1
  118. package/dist/errors-C-so0M4t.d.cts +33 -0
  119. package/dist/errors-C-so0M4t.d.ts +33 -0
  120. package/dist/errors-CmVvczxZ.d.cts +28 -0
  121. package/dist/errors-CmVvczxZ.d.ts +28 -0
  122. package/dist/{in-process-transport-C2oPTYs6.d.ts → in-process-transport-7EIit9Xk.d.ts} +72 -33
  123. package/dist/{in-process-transport-DG-w5G6k.d.cts → in-process-transport-Ct9YcX8I.d.cts} +72 -33
  124. package/dist/index.cjs +354 -60
  125. package/dist/index.cjs.map +1 -1
  126. package/dist/index.d.cts +294 -123
  127. package/dist/index.d.ts +294 -123
  128. package/dist/index.js +347 -60
  129. package/dist/index.js.map +1 -1
  130. package/dist/provider-types-PTSlRPNB.d.cts +39 -0
  131. package/dist/provider-types-PTSlRPNB.d.ts +39 -0
  132. package/dist/refresh-manager-B81PpYBr.d.cts +153 -0
  133. package/dist/refresh-manager-Dlv_iNZi.d.ts +153 -0
  134. package/dist/testing.cjs +1107 -0
  135. package/dist/testing.cjs.map +1 -0
  136. package/dist/testing.d.cts +144 -0
  137. package/dist/testing.d.ts +144 -0
  138. package/dist/testing.js +1101 -0
  139. package/dist/testing.js.map +1 -0
  140. package/dist/token-store-CSUBgYwn.d.ts +48 -0
  141. package/dist/token-store-CuC4hB9Z.d.cts +48 -0
  142. package/dist/{transport-DX1Nhm4N.d.cts → transport-DLWCN18G.d.cts} +5 -4
  143. package/dist/{transport-D1OaUgRk.d.ts → transport-DsuS-GeM.d.ts} +5 -4
  144. package/dist/{types-CGF7AEX1.d.cts → types-4vbcmPTp.d.cts} +4 -2
  145. package/dist/{types-Bh5AhqD-.d.ts → types-BxggH0Yh.d.ts} +4 -2
  146. package/dist/types-DgtI1hzh.d.ts +364 -0
  147. package/dist/types-DkSXALKg.d.cts +364 -0
  148. package/package.json +41 -5
  149. package/LICENSE +0 -21
  150. package/README.md +0 -948
  151. package/dist/errors-BDLbNu9w.d.cts +0 -13
  152. package/dist/errors-BDLbNu9w.d.ts +0 -13
  153. package/dist/types-DLZzlJxt.d.ts +0 -39
  154. package/dist/types-tE0CXwBl.d.cts +0 -39
@@ -0,0 +1,527 @@
1
+ import { createRequire } from 'module';
2
+ import 'fs';
3
+ import 'fs/promises';
4
+ import 'path';
5
+
6
+ // src/chat/sqlite/factory.ts
7
+
8
+ // src/chat/types.ts
9
+ function createChatId() {
10
+ return crypto.randomUUID();
11
+ }
12
+
13
+ // src/errors.ts
14
+ var AgentSDKError = class extends Error {
15
+ /** @internal Marker for cross-bundle identity checks */
16
+ _agentSDKError = true;
17
+ /** Machine-readable error code. Prefer values from the ErrorCode enum. */
18
+ code;
19
+ /** Whether this error is safe to retry */
20
+ retryable;
21
+ /** HTTP status code hint for error classification */
22
+ httpStatus;
23
+ constructor(message, options) {
24
+ super(message, options);
25
+ this.name = "AgentSDKError";
26
+ this.code = options?.code;
27
+ this.retryable = options?.retryable ?? false;
28
+ this.httpStatus = options?.httpStatus;
29
+ }
30
+ /** Check if an error is an AgentSDKError (works across bundled copies) */
31
+ static is(error) {
32
+ return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
33
+ }
34
+ };
35
+
36
+ // src/chat/storage.ts
37
+ var StorageError = class extends AgentSDKError {
38
+ /** Machine-readable error code from the unified ErrorCode enum */
39
+ code;
40
+ constructor(message, code) {
41
+ super(message);
42
+ this.name = "StorageError";
43
+ this.code = code;
44
+ }
45
+ };
46
+
47
+ // src/chat/sqlite/session-store.ts
48
+ var CREATE_SESSIONS_TABLE = `
49
+ CREATE TABLE IF NOT EXISTS sessions (
50
+ id TEXT PRIMARY KEY,
51
+ title TEXT,
52
+ config TEXT NOT NULL,
53
+ metadata TEXT NOT NULL,
54
+ status TEXT NOT NULL DEFAULT 'active',
55
+ backend_session_id TEXT,
56
+ created_at TEXT NOT NULL,
57
+ updated_at TEXT NOT NULL
58
+ )
59
+ `;
60
+ var CREATE_MESSAGES_TABLE = `
61
+ CREATE TABLE IF NOT EXISTS messages (
62
+ id TEXT PRIMARY KEY,
63
+ session_id TEXT NOT NULL,
64
+ role TEXT NOT NULL,
65
+ parts TEXT NOT NULL,
66
+ metadata TEXT,
67
+ status TEXT NOT NULL DEFAULT 'complete',
68
+ created_at TEXT NOT NULL,
69
+ updated_at TEXT,
70
+ position INTEGER NOT NULL,
71
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
72
+ )
73
+ `;
74
+ var CREATE_MESSAGES_SESSION_IDX = `
75
+ CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, position)
76
+ `;
77
+ var SQLiteSessionStore = class {
78
+ db;
79
+ constructor(db) {
80
+ this.db = db;
81
+ this.db.exec(CREATE_SESSIONS_TABLE);
82
+ this.db.exec(CREATE_MESSAGES_TABLE);
83
+ this.db.exec(CREATE_MESSAGES_SESSION_IDX);
84
+ }
85
+ async createSession(options = {}) {
86
+ const id = createChatId();
87
+ const now = (/* @__PURE__ */ new Date()).toISOString();
88
+ const config = {
89
+ model: "default",
90
+ backend: "default",
91
+ ...options.config
92
+ };
93
+ const metadata = {
94
+ messageCount: 0,
95
+ totalTokens: 0,
96
+ tags: options.tags,
97
+ custom: options.custom
98
+ };
99
+ this.db.prepare(`
100
+ INSERT INTO sessions (id, title, config, metadata, status, created_at, updated_at)
101
+ VALUES (?, ?, ?, ?, 'active', ?, ?)
102
+ `).run(id, options.title ?? null, JSON.stringify(config), JSON.stringify(metadata), now, now);
103
+ return this.buildSession(id, options.title, config, metadata, "active", now, now, []);
104
+ }
105
+ async getSession(id) {
106
+ const row = this.db.prepare("SELECT * FROM sessions WHERE id = ?").get(id);
107
+ if (!row) return null;
108
+ const messages = this.loadAllMessages(row.id);
109
+ return this.rowToSession(row, messages);
110
+ }
111
+ async listSessions(options) {
112
+ const rows = this.db.prepare("SELECT * FROM sessions ORDER BY updated_at DESC").all();
113
+ let sessions = rows.map((r) => this.rowToSession(r, []));
114
+ if (options?.filter) sessions = sessions.filter(options.filter);
115
+ if (options?.sort) sessions.sort(options.sort);
116
+ if (options?.offset) sessions = sessions.slice(options.offset);
117
+ if (options?.limit) sessions = sessions.slice(0, options.limit);
118
+ return sessions;
119
+ }
120
+ async updateTitle(id, title) {
121
+ const result = this.db.prepare(
122
+ "UPDATE sessions SET title = ?, updated_at = ? WHERE id = ?"
123
+ ).run(title, (/* @__PURE__ */ new Date()).toISOString(), id);
124
+ if (result.changes === 0) throw new StorageError(`Session not found: ${id}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
125
+ }
126
+ async updateConfig(id, config) {
127
+ const row = this.db.prepare("SELECT config FROM sessions WHERE id = ?").get(id);
128
+ if (!row) throw new StorageError(`Session not found: ${id}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
129
+ const merged = { ...JSON.parse(row.config), ...config };
130
+ this.db.prepare(
131
+ "UPDATE sessions SET config = ?, updated_at = ? WHERE id = ?"
132
+ ).run(JSON.stringify(merged), (/* @__PURE__ */ new Date()).toISOString(), id);
133
+ }
134
+ async deleteSession(id) {
135
+ const result = this.db.prepare("DELETE FROM sessions WHERE id = ?").run(id);
136
+ if (result.changes === 0) throw new StorageError(`Session not found: ${id}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
137
+ }
138
+ async appendMessage(sessionId, message) {
139
+ const session = this.db.prepare("SELECT id FROM sessions WHERE id = ?").get(sessionId);
140
+ if (!session) throw new StorageError(`Session not found: ${sessionId}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
141
+ const position = this.getNextPosition(sessionId);
142
+ this.db.prepare(`
143
+ INSERT INTO messages (id, session_id, role, parts, metadata, status, created_at, updated_at, position)
144
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
145
+ `).run(
146
+ message.id,
147
+ sessionId,
148
+ message.role,
149
+ JSON.stringify(message.parts),
150
+ message.metadata ? JSON.stringify(message.metadata) : null,
151
+ message.status,
152
+ message.createdAt,
153
+ message.updatedAt ?? null,
154
+ position
155
+ );
156
+ this.incrementMessageCount(sessionId);
157
+ }
158
+ async saveMessages(sessionId, messages) {
159
+ if (messages.length === 0) return;
160
+ const session = this.db.prepare("SELECT id FROM sessions WHERE id = ?").get(sessionId);
161
+ if (!session) throw new StorageError(`Session not found: ${sessionId}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
162
+ const insertMsg = this.db.prepare(`
163
+ INSERT INTO messages (id, session_id, role, parts, metadata, status, created_at, updated_at, position)
164
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
165
+ `);
166
+ const tx = this.db.transaction(() => {
167
+ let pos = this.getNextPosition(sessionId);
168
+ for (const msg of messages) {
169
+ insertMsg.run(
170
+ msg.id,
171
+ sessionId,
172
+ msg.role,
173
+ JSON.stringify(msg.parts),
174
+ msg.metadata ? JSON.stringify(msg.metadata) : null,
175
+ msg.status,
176
+ msg.createdAt,
177
+ msg.updatedAt ?? null,
178
+ pos++
179
+ );
180
+ }
181
+ this.updateSessionMeta(sessionId, messages.length);
182
+ });
183
+ tx();
184
+ }
185
+ async loadMessages(sessionId, options) {
186
+ const session = this.db.prepare("SELECT id FROM sessions WHERE id = ?").get(sessionId);
187
+ if (!session) throw new StorageError(`Session not found: ${sessionId}`, "STORAGE_NOT_FOUND" /* STORAGE_NOT_FOUND */);
188
+ const total = this.db.prepare(
189
+ "SELECT COUNT(*) as cnt FROM messages WHERE session_id = ?"
190
+ ).get(sessionId).cnt;
191
+ const limit = options?.limit ?? 50;
192
+ const offset = options?.offset ?? 0;
193
+ const rows = this.db.prepare(
194
+ "SELECT * FROM messages WHERE session_id = ? ORDER BY position ASC LIMIT ? OFFSET ?"
195
+ ).all(sessionId, limit, offset);
196
+ return {
197
+ messages: rows.map(rowToMessage),
198
+ total,
199
+ hasMore: offset + limit < total
200
+ };
201
+ }
202
+ async searchSessions(options) {
203
+ const pattern = `%${options.query}%`;
204
+ const limit = options.limit ?? 20;
205
+ const titleMatches = this.db.prepare(
206
+ "SELECT * FROM sessions WHERE title LIKE ? COLLATE NOCASE LIMIT ?"
207
+ ).all(pattern, limit);
208
+ const contentMatches = this.db.prepare(`
209
+ SELECT DISTINCT s.* FROM sessions s
210
+ JOIN messages m ON m.session_id = s.id
211
+ WHERE m.parts LIKE ? COLLATE NOCASE
212
+ LIMIT ?
213
+ `).all(pattern, limit);
214
+ const seen = /* @__PURE__ */ new Set();
215
+ const results = [];
216
+ for (const row of [...titleMatches, ...contentMatches]) {
217
+ if (!seen.has(row.id)) {
218
+ seen.add(row.id);
219
+ results.push(this.rowToSession(row, []));
220
+ }
221
+ }
222
+ return results.slice(0, limit);
223
+ }
224
+ async count() {
225
+ return this.db.prepare("SELECT COUNT(*) as cnt FROM sessions").get().cnt;
226
+ }
227
+ async clear() {
228
+ this.db.exec("DELETE FROM messages");
229
+ this.db.exec("DELETE FROM sessions");
230
+ }
231
+ // ─── Private Helpers ─────────────────────────────────────────
232
+ getNextPosition(sessionId) {
233
+ const result = this.db.prepare(
234
+ "SELECT MAX(position) as maxPos FROM messages WHERE session_id = ?"
235
+ ).get(sessionId);
236
+ return (result.maxPos ?? -1) + 1;
237
+ }
238
+ incrementMessageCount(sessionId) {
239
+ this.db.prepare(`
240
+ UPDATE sessions
241
+ SET metadata = json_set(metadata, '$.messageCount', json_extract(metadata, '$.messageCount') + 1),
242
+ updated_at = ?
243
+ WHERE id = ?
244
+ `).run((/* @__PURE__ */ new Date()).toISOString(), sessionId);
245
+ }
246
+ updateSessionMeta(sessionId, addedCount) {
247
+ this.db.prepare(`
248
+ UPDATE sessions
249
+ SET metadata = json_set(metadata, '$.messageCount', json_extract(metadata, '$.messageCount') + ?),
250
+ updated_at = ?
251
+ WHERE id = ?
252
+ `).run(addedCount, (/* @__PURE__ */ new Date()).toISOString(), sessionId);
253
+ }
254
+ loadAllMessages(sessionId) {
255
+ const rows = this.db.prepare(
256
+ "SELECT * FROM messages WHERE session_id = ? ORDER BY position ASC"
257
+ ).all(sessionId);
258
+ return rows.map(rowToMessage);
259
+ }
260
+ rowToSession(row, messages) {
261
+ return this.buildSession(
262
+ row.id,
263
+ row.title,
264
+ JSON.parse(row.config),
265
+ JSON.parse(row.metadata),
266
+ row.status,
267
+ row.created_at,
268
+ row.updated_at,
269
+ messages
270
+ );
271
+ }
272
+ buildSession(id, title, config, metadata, status, createdAt, updatedAt, messages) {
273
+ return {
274
+ id,
275
+ title: title ?? void 0,
276
+ messages,
277
+ config,
278
+ metadata,
279
+ status,
280
+ createdAt,
281
+ updatedAt
282
+ };
283
+ }
284
+ };
285
+ function rowToMessage(row) {
286
+ return {
287
+ id: row.id,
288
+ role: row.role,
289
+ parts: JSON.parse(row.parts),
290
+ metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
291
+ status: row.status,
292
+ createdAt: row.created_at,
293
+ updatedAt: row.updated_at ?? void 0
294
+ };
295
+ }
296
+
297
+ // src/chat/sqlite/provider-store.ts
298
+ var CREATE_PROVIDERS_TABLE = `
299
+ CREATE TABLE IF NOT EXISTS providers (
300
+ id TEXT PRIMARY KEY,
301
+ backend TEXT NOT NULL,
302
+ model TEXT NOT NULL,
303
+ label TEXT NOT NULL,
304
+ created_at INTEGER NOT NULL
305
+ )
306
+ `;
307
+ var SQLiteProviderStore = class {
308
+ db;
309
+ constructor(db) {
310
+ this.db = db;
311
+ this.db.exec(CREATE_PROVIDERS_TABLE);
312
+ }
313
+ async create(config) {
314
+ this.db.prepare(`
315
+ INSERT INTO providers (id, backend, model, label, created_at)
316
+ VALUES (?, ?, ?, ?, ?)
317
+ `).run(config.id, config.backend, config.model, config.label, config.createdAt);
318
+ }
319
+ async get(id) {
320
+ const row = this.db.prepare("SELECT * FROM providers WHERE id = ?").get(id);
321
+ return row ? rowToProvider(row) : null;
322
+ }
323
+ async update(id, changes) {
324
+ const existing = this.db.prepare("SELECT id FROM providers WHERE id = ?").get(id);
325
+ if (!existing) throw new Error(`Provider "${id}" not found`);
326
+ const sets = [];
327
+ const values = [];
328
+ if (changes.backend !== void 0) {
329
+ sets.push("backend = ?");
330
+ values.push(changes.backend);
331
+ }
332
+ if (changes.model !== void 0) {
333
+ sets.push("model = ?");
334
+ values.push(changes.model);
335
+ }
336
+ if (changes.label !== void 0) {
337
+ sets.push("label = ?");
338
+ values.push(changes.label);
339
+ }
340
+ if (sets.length > 0) {
341
+ values.push(id);
342
+ this.db.prepare(`UPDATE providers SET ${sets.join(", ")} WHERE id = ?`).run(...values);
343
+ }
344
+ }
345
+ async delete(id) {
346
+ this.db.prepare("DELETE FROM providers WHERE id = ?").run(id);
347
+ }
348
+ async list() {
349
+ const rows = this.db.prepare("SELECT * FROM providers ORDER BY created_at ASC").all();
350
+ return rows.map(rowToProvider);
351
+ }
352
+ };
353
+ function rowToProvider(row) {
354
+ return {
355
+ id: row.id,
356
+ backend: row.backend,
357
+ model: row.model,
358
+ label: row.label,
359
+ createdAt: row.created_at
360
+ };
361
+ }
362
+
363
+ // src/chat/sqlite/token-store.ts
364
+ var CREATE_TOKENS_TABLE = `
365
+ CREATE TABLE IF NOT EXISTS tokens (
366
+ provider TEXT PRIMARY KEY,
367
+ token_json TEXT NOT NULL,
368
+ saved_at INTEGER NOT NULL
369
+ )
370
+ `;
371
+ var SQLiteTokenStore = class {
372
+ db;
373
+ constructor(db) {
374
+ this.db = db;
375
+ this.db.exec(CREATE_TOKENS_TABLE);
376
+ }
377
+ async save(provider, token) {
378
+ this.db.prepare(`
379
+ INSERT OR REPLACE INTO tokens (provider, token_json, saved_at)
380
+ VALUES (?, ?, ?)
381
+ `).run(provider, JSON.stringify(token), Date.now());
382
+ }
383
+ async load(provider) {
384
+ const row = this.db.prepare("SELECT token_json FROM tokens WHERE provider = ?").get(provider);
385
+ return row ? JSON.parse(row.token_json) : null;
386
+ }
387
+ async clear(provider) {
388
+ this.db.prepare("DELETE FROM tokens WHERE provider = ?").run(provider);
389
+ }
390
+ async clearAll() {
391
+ this.db.exec("DELETE FROM tokens");
392
+ }
393
+ async list() {
394
+ const rows = this.db.prepare("SELECT provider FROM tokens ORDER BY saved_at ASC").all();
395
+ return rows.map((r) => r.provider);
396
+ }
397
+ };
398
+
399
+ // src/chat/sqlite/migrations.ts
400
+ var CREATE_VERSION_TABLE = `
401
+ CREATE TABLE IF NOT EXISTS schema_version (
402
+ version INTEGER PRIMARY KEY,
403
+ applied_at TEXT NOT NULL,
404
+ description TEXT
405
+ )
406
+ `;
407
+ var migrations = [
408
+ {
409
+ version: 1,
410
+ description: "Initial schema \u2014 sessions, messages, providers, tokens",
411
+ up: (db) => {
412
+ db.exec(`
413
+ CREATE TABLE IF NOT EXISTS sessions (
414
+ id TEXT PRIMARY KEY,
415
+ title TEXT,
416
+ config TEXT NOT NULL,
417
+ metadata TEXT NOT NULL,
418
+ status TEXT NOT NULL DEFAULT 'active',
419
+ backend_session_id TEXT,
420
+ created_at TEXT NOT NULL,
421
+ updated_at TEXT NOT NULL
422
+ )
423
+ `);
424
+ db.exec(`
425
+ CREATE TABLE IF NOT EXISTS messages (
426
+ id TEXT PRIMARY KEY,
427
+ session_id TEXT NOT NULL,
428
+ role TEXT NOT NULL,
429
+ parts TEXT NOT NULL,
430
+ metadata TEXT,
431
+ status TEXT NOT NULL DEFAULT 'complete',
432
+ created_at TEXT NOT NULL,
433
+ updated_at TEXT,
434
+ position INTEGER NOT NULL,
435
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
436
+ )
437
+ `);
438
+ db.exec(`
439
+ CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, position)
440
+ `);
441
+ db.exec(`
442
+ CREATE TABLE IF NOT EXISTS providers (
443
+ id TEXT PRIMARY KEY,
444
+ backend TEXT NOT NULL,
445
+ model TEXT NOT NULL,
446
+ label TEXT NOT NULL,
447
+ created_at INTEGER NOT NULL
448
+ )
449
+ `);
450
+ db.exec(`
451
+ CREATE TABLE IF NOT EXISTS tokens (
452
+ provider TEXT PRIMARY KEY,
453
+ token_json TEXT NOT NULL,
454
+ saved_at INTEGER NOT NULL
455
+ )
456
+ `);
457
+ }
458
+ }
459
+ ];
460
+ function getSchemaVersion(db) {
461
+ db.exec(CREATE_VERSION_TABLE);
462
+ const row = db.prepare("SELECT MAX(version) as v FROM schema_version").get();
463
+ return row?.v ?? 0;
464
+ }
465
+ function runMigrations(db) {
466
+ db.exec(CREATE_VERSION_TABLE);
467
+ let current = getSchemaVersion(db);
468
+ if (current === 0 && tableExists(db, "sessions")) {
469
+ const now = (/* @__PURE__ */ new Date()).toISOString();
470
+ db.prepare("INSERT INTO schema_version (version, applied_at, description) VALUES (?, ?, ?)").run(1, now, "Initial schema (pre-existing database)");
471
+ current = 1;
472
+ }
473
+ const pending = migrations.filter((m) => m.version > current);
474
+ if (pending.length === 0) return;
475
+ for (const migration of pending) {
476
+ const txn = db.transaction(() => {
477
+ migration.up(db);
478
+ const now = (/* @__PURE__ */ new Date()).toISOString();
479
+ db.prepare("INSERT INTO schema_version (version, applied_at, description) VALUES (?, ?, ?)").run(migration.version, now, migration.description);
480
+ });
481
+ txn();
482
+ }
483
+ }
484
+ function tableExists(db, name) {
485
+ const row = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(name);
486
+ return !!row;
487
+ }
488
+
489
+ // src/chat/sqlite/factory.ts
490
+ function createSQLiteStorage(pathOrOptions) {
491
+ let db;
492
+ if (typeof pathOrOptions === "string") {
493
+ db = createDatabase(pathOrOptions);
494
+ } else if (pathOrOptions.db) {
495
+ db = pathOrOptions.db;
496
+ } else {
497
+ db = createDatabase(pathOrOptions.dbPath);
498
+ }
499
+ db.pragma("journal_mode = WAL");
500
+ db.pragma("foreign_keys = ON");
501
+ runMigrations(db);
502
+ return {
503
+ db,
504
+ sessionStore: new SQLiteSessionStore(db),
505
+ providerStore: new SQLiteProviderStore(db),
506
+ tokenStore: new SQLiteTokenStore(db)
507
+ };
508
+ }
509
+ function createDatabase(dbPath) {
510
+ try {
511
+ const esmRequire = createRequire(import.meta.url);
512
+ const BetterSqlite3 = esmRequire("better-sqlite3");
513
+ return new BetterSqlite3(dbPath);
514
+ } catch (err) {
515
+ const message = err instanceof Error ? err.message : String(err);
516
+ if (message.includes("Cannot find module") || message.includes("MODULE_NOT_FOUND")) {
517
+ throw new Error(
518
+ "better-sqlite3 is required for SQLite storage. Install it: npm install better-sqlite3"
519
+ );
520
+ }
521
+ throw err;
522
+ }
523
+ }
524
+
525
+ export { SQLiteProviderStore, SQLiteSessionStore, SQLiteTokenStore, createSQLiteStorage, getSchemaVersion, migrations, runMigrations };
526
+ //# sourceMappingURL=sqlite.js.map
527
+ //# sourceMappingURL=sqlite.js.map