negotium 0.1.11 → 0.1.13
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/README.md +11 -2
- package/dist/canonical-mcp-bridge.js +2 -3
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/{chunk-gz12qcf0.js → chunk-a9y2rwxf.js} +2 -2
- package/dist/{chunk-gz12qcf0.js.map → chunk-a9y2rwxf.js.map} +3 -3
- package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
- package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
- package/dist/cron.js +292 -256
- package/dist/cron.js.map +23 -22
- package/dist/hosted-agent.js +3012 -17
- package/dist/hosted-agent.js.map +30 -3
- package/dist/main.js +31323 -36
- package/dist/main.js.map +198 -3
- package/dist/prompts.js +12 -9
- package/dist/prompts.js.map +5 -5
- package/dist/registry.js +10 -6
- package/dist/registry.js.map +3 -3
- package/dist/rollout.js +1 -1
- package/dist/runtime/cron/store.ts +24 -1
- package/dist/runtime/src/application/submit-user-message.ts +3 -0
- package/dist/runtime/src/index.ts +7 -0
- package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
- package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
- package/dist/runtime/src/platform/config.ts +2 -2
- package/dist/runtime/src/platform/mcp-config.ts +13 -0
- package/dist/runtime/src/prompts/builders.ts +20 -6
- package/dist/runtime/src/query/active-rooms.ts +2 -0
- package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
- package/dist/runtime/src/runtime/errors.ts +12 -12
- package/dist/runtime/src/runtime/turn-runner.ts +12 -0
- package/dist/runtime/src/storage/api-messages.ts +7 -5
- package/dist/runtime/src/storage/api-topics.ts +5 -2
- package/dist/runtime/src/storage/forum-db.ts +4 -1
- package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
- package/dist/runtime/src/storage/session-asks.ts +13 -5
- package/dist/runtime/src/storage/storage-contract.ts +54 -0
- package/dist/runtime/src/storage/storage-host.ts +89 -36
- package/dist/runtime/src/storage/storage-public-host.ts +16 -0
- package/dist/runtime/src/storage/storage-public.ts +21 -5
- package/dist/runtime/src/storage/token-stats.ts +1 -1
- package/dist/runtime/src/types/api.ts +2 -0
- package/dist/runtime/src/types.ts +2 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +29 -18
- package/dist/runtime-helpers.js.map +8 -7
- package/dist/storage.js +260 -202
- package/dist/storage.js.map +11 -9
- package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
- package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
- package/dist/types/packages/core/src/storage/api-messages.d.ts +6 -6
- package/dist/types/packages/core/src/storage/api-topics.d.ts +20 -2
- package/dist/types/packages/core/src/storage/forum-db.d.ts +2 -1
- package/dist/types/packages/core/src/storage/session-asks.d.ts +3 -2
- package/dist/types/packages/core/src/storage/storage-contract.d.ts +46 -0
- package/dist/types/packages/core/src/storage/storage-host.d.ts +12 -19
- package/dist/types/packages/core/src/storage/storage-public-host.d.ts +7 -0
- package/dist/types/packages/core/src/storage/storage-public.d.ts +4 -2
- package/dist/types/packages/core/src/types/api.d.ts +2 -0
- package/dist/types/packages/core/src/types.d.ts +2 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/types/packages/module-cron/src/store.d.ts +22 -2
- package/dist/vault.js +2 -2
- package/dist/vault.js.map +3 -3
- package/package.json +1 -1
- package/dist/chunk-01xcc856.js +0 -149
- package/dist/chunk-01xcc856.js.map +0 -10
- package/dist/chunk-1a6kv9vt.js +0 -118
- package/dist/chunk-1a6kv9vt.js.map +0 -10
- package/dist/chunk-1b62d730.js +0 -117
- package/dist/chunk-1b62d730.js.map +0 -10
- package/dist/chunk-1k7t7bnx.js +0 -97
- package/dist/chunk-1k7t7bnx.js.map +0 -10
- package/dist/chunk-28apmz4r.js +0 -431
- package/dist/chunk-28apmz4r.js.map +0 -11
- package/dist/chunk-2fvydfkx.js +0 -141
- package/dist/chunk-2fvydfkx.js.map +0 -10
- package/dist/chunk-41ygvg5k.js +0 -2387
- package/dist/chunk-41ygvg5k.js.map +0 -26
- package/dist/chunk-4q966ttx.js +0 -371
- package/dist/chunk-4q966ttx.js.map +0 -11
- package/dist/chunk-51rcsavw.js +0 -1712
- package/dist/chunk-51rcsavw.js.map +0 -18
- package/dist/chunk-59d0shyj.js +0 -103
- package/dist/chunk-59d0shyj.js.map +0 -10
- package/dist/chunk-5fzgvn79.js +0 -3536
- package/dist/chunk-5fzgvn79.js.map +0 -20
- package/dist/chunk-61px0717.js +0 -153
- package/dist/chunk-61px0717.js.map +0 -11
- package/dist/chunk-66y0hr8c.js +0 -2136
- package/dist/chunk-66y0hr8c.js.map +0 -29
- package/dist/chunk-69k45zg8.js +0 -250
- package/dist/chunk-69k45zg8.js.map +0 -11
- package/dist/chunk-6ah5farg.js +0 -130
- package/dist/chunk-6ah5farg.js.map +0 -10
- package/dist/chunk-6d4fmea5.js +0 -117
- package/dist/chunk-6d4fmea5.js.map +0 -12
- package/dist/chunk-8cahx7xc.js +0 -46
- package/dist/chunk-8cahx7xc.js.map +0 -10
- package/dist/chunk-8f20fk4n.js +0 -252
- package/dist/chunk-8f20fk4n.js.map +0 -10
- package/dist/chunk-91ckrvk8.js +0 -318
- package/dist/chunk-91ckrvk8.js.map +0 -10
- package/dist/chunk-93krf6ng.js +0 -3069
- package/dist/chunk-93krf6ng.js.map +0 -32
- package/dist/chunk-9qx1t77a.js +0 -214
- package/dist/chunk-9qx1t77a.js.map +0 -10
- package/dist/chunk-beqhdr9w.js +0 -589
- package/dist/chunk-beqhdr9w.js.map +0 -11
- package/dist/chunk-bftftsgq.js +0 -1637
- package/dist/chunk-bftftsgq.js.map +0 -15
- package/dist/chunk-c500xe9z.js +0 -33
- package/dist/chunk-c500xe9z.js.map +0 -10
- package/dist/chunk-cjsnkvq2.js +0 -23
- package/dist/chunk-cjsnkvq2.js.map +0 -10
- package/dist/chunk-cxa7yghg.js +0 -577
- package/dist/chunk-cxa7yghg.js.map +0 -14
- package/dist/chunk-edb07sjp.js +0 -567
- package/dist/chunk-edb07sjp.js.map +0 -14
- package/dist/chunk-f361dwba.js +0 -589
- package/dist/chunk-f361dwba.js.map +0 -11
- package/dist/chunk-f5xgprg1.js +0 -59
- package/dist/chunk-f5xgprg1.js.map +0 -10
- package/dist/chunk-ffefbd3r.js +0 -17
- package/dist/chunk-ffefbd3r.js.map +0 -10
- package/dist/chunk-fswhzdf5.js +0 -64
- package/dist/chunk-fswhzdf5.js.map +0 -10
- package/dist/chunk-g144wdrs.js +0 -2907
- package/dist/chunk-g144wdrs.js.map +0 -24
- package/dist/chunk-h980hb2n.js +0 -512
- package/dist/chunk-h980hb2n.js.map +0 -13
- package/dist/chunk-h9vbhhgr.js +0 -1337
- package/dist/chunk-h9vbhhgr.js.map +0 -16
- package/dist/chunk-hwy3n31w.js +0 -21
- package/dist/chunk-hwy3n31w.js.map +0 -9
- package/dist/chunk-jtrk0khr.js +0 -108
- package/dist/chunk-jtrk0khr.js.map +0 -10
- package/dist/chunk-jzz91jwh.js +0 -70
- package/dist/chunk-jzz91jwh.js.map +0 -10
- package/dist/chunk-m9e3tbr8.js +0 -708
- package/dist/chunk-m9e3tbr8.js.map +0 -14
- package/dist/chunk-mh5mexsf.js +0 -147
- package/dist/chunk-mh5mexsf.js.map +0 -11
- package/dist/chunk-npd8n03v.js +0 -2152
- package/dist/chunk-npd8n03v.js.map +0 -15
- package/dist/chunk-pg1azh6n.js +0 -2
- package/dist/chunk-pg1azh6n.js.map +0 -9
- package/dist/chunk-qwy57177.js +0 -237
- package/dist/chunk-qwy57177.js.map +0 -11
- package/dist/chunk-r31q21h5.js +0 -53
- package/dist/chunk-r31q21h5.js.map +0 -10
- package/dist/chunk-rbvctv1n.js +0 -366
- package/dist/chunk-rbvctv1n.js.map +0 -10
- package/dist/chunk-sa874j5c.js +0 -9
- package/dist/chunk-sa874j5c.js.map +0 -10
- package/dist/chunk-sctcs5zb.js +0 -281
- package/dist/chunk-sctcs5zb.js.map +0 -10
- package/dist/chunk-tsstrcfc.js +0 -122
- package/dist/chunk-tsstrcfc.js.map +0 -10
- package/dist/chunk-wk2qf31s.js +0 -58
- package/dist/chunk-wk2qf31s.js.map +0 -10
- package/dist/chunk-wx7ag4dd.js +0 -2936
- package/dist/chunk-wx7ag4dd.js.map +0 -20
- package/dist/chunk-znx1fpfd.js +0 -61
- package/dist/chunk-znx1fpfd.js.map +0 -10
package/dist/storage.js
CHANGED
|
@@ -228,6 +228,8 @@ if (isBun) {
|
|
|
228
228
|
// ../../packages/core/src/storage/storage-host.ts
|
|
229
229
|
var configuredHost = {};
|
|
230
230
|
var fallbackDatabase = null;
|
|
231
|
+
var fallbackDatabasePath = null;
|
|
232
|
+
var storageHostFrames = [];
|
|
231
233
|
var schemaInitializers = [];
|
|
232
234
|
var initializedSchemas = new WeakMap;
|
|
233
235
|
var initializingDatabases = new WeakSet;
|
|
@@ -252,7 +254,7 @@ function defaultSessionAsksDir() {
|
|
|
252
254
|
return join(runDir, "session-asks");
|
|
253
255
|
}
|
|
254
256
|
function defaultSessionsDatabasePath() {
|
|
255
|
-
return envPath("SESSIONS_DB_PATH", join(
|
|
257
|
+
return envPath("SESSIONS_DB_PATH", join(resolveStorageDataDir(), "sessions.db"));
|
|
256
258
|
}
|
|
257
259
|
function initializeDatabase(database) {
|
|
258
260
|
database.exec("PRAGMA journal_mode = WAL");
|
|
@@ -264,11 +266,14 @@ function initializeDatabase(database) {
|
|
|
264
266
|
} catch {}
|
|
265
267
|
}
|
|
266
268
|
function defaultDatabase() {
|
|
267
|
-
if (fallbackDatabase)
|
|
268
|
-
return fallbackDatabase;
|
|
269
269
|
const path = defaultSessionsDatabasePath();
|
|
270
|
+
if (fallbackDatabase && fallbackDatabasePath === path)
|
|
271
|
+
return fallbackDatabase;
|
|
272
|
+
if (fallbackDatabase)
|
|
273
|
+
fallbackDatabase.close();
|
|
270
274
|
mkdirSync2(dirname2(path), { recursive: true });
|
|
271
275
|
fallbackDatabase = new Database(path, { create: true });
|
|
276
|
+
fallbackDatabasePath = path;
|
|
272
277
|
initializeDatabase(fallbackDatabase);
|
|
273
278
|
return fallbackDatabase;
|
|
274
279
|
}
|
|
@@ -288,27 +293,62 @@ function resolveStorageWorkspaceDir() {
|
|
|
288
293
|
return configuredHost.workspaceDir ?? defaultWorkspaceDir();
|
|
289
294
|
}
|
|
290
295
|
function resolveStorageSharedWikiDir() {
|
|
291
|
-
return join(resolveStorageWorkspaceDir(), "wiki");
|
|
296
|
+
return configuredHost.sharedWikiDir ?? join(resolveStorageWorkspaceDir(), "wiki");
|
|
292
297
|
}
|
|
293
298
|
function resolveStorageUsersLogDir() {
|
|
294
|
-
return join(resolveStorageDataDir(), "users");
|
|
299
|
+
return configuredHost.usersLogDir ?? join(resolveStorageDataDir(), "users");
|
|
300
|
+
}
|
|
301
|
+
var STORAGE_PATH_KEYS = [
|
|
302
|
+
"dataDir",
|
|
303
|
+
"logDir",
|
|
304
|
+
"sessionAsksDir",
|
|
305
|
+
"workspaceDir",
|
|
306
|
+
"sharedWikiDir",
|
|
307
|
+
"usersLogDir"
|
|
308
|
+
];
|
|
309
|
+
function normalizeStorageHostPatch(options) {
|
|
310
|
+
const patch = {};
|
|
311
|
+
if (options.database !== undefined)
|
|
312
|
+
patch.database = options.database;
|
|
313
|
+
for (const key of STORAGE_PATH_KEYS) {
|
|
314
|
+
const value = options[key];
|
|
315
|
+
if (value === undefined)
|
|
316
|
+
continue;
|
|
317
|
+
if (!value.trim())
|
|
318
|
+
throw new TypeError(`${key} must not be empty`);
|
|
319
|
+
patch[key] = resolve(value);
|
|
320
|
+
}
|
|
321
|
+
return Object.freeze(patch);
|
|
322
|
+
}
|
|
323
|
+
function refreshConfiguredHost() {
|
|
324
|
+
configuredHost = Object.freeze(Object.assign({}, ...storageHostFrames.filter((frame) => frame.active).map((frame) => frame.patch)));
|
|
295
325
|
}
|
|
296
326
|
function configureStorageHost(options) {
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
327
|
+
const frame = { active: true, patch: normalizeStorageHostPatch(options) };
|
|
328
|
+
storageHostFrames.push(frame);
|
|
329
|
+
refreshConfiguredHost();
|
|
300
330
|
return () => {
|
|
301
|
-
if (
|
|
331
|
+
if (!frame.active)
|
|
302
332
|
return;
|
|
303
|
-
|
|
304
|
-
|
|
333
|
+
frame.active = false;
|
|
334
|
+
const index = storageHostFrames.indexOf(frame);
|
|
335
|
+
if (index >= 0)
|
|
336
|
+
storageHostFrames.splice(index, 1);
|
|
337
|
+
refreshConfiguredHost();
|
|
305
338
|
};
|
|
306
339
|
}
|
|
340
|
+
function resetStorageHost() {
|
|
341
|
+
for (const frame of storageHostFrames)
|
|
342
|
+
frame.active = false;
|
|
343
|
+
storageHostFrames.length = 0;
|
|
344
|
+
refreshConfiguredHost();
|
|
345
|
+
}
|
|
307
346
|
function closeStorageDatabase() {
|
|
308
|
-
if (
|
|
347
|
+
if (!fallbackDatabase)
|
|
309
348
|
return;
|
|
310
349
|
fallbackDatabase.close();
|
|
311
350
|
fallbackDatabase = null;
|
|
351
|
+
fallbackDatabasePath = null;
|
|
312
352
|
}
|
|
313
353
|
function registerStorageSchemaInitializer(initialize, priority = 100) {
|
|
314
354
|
schemaInitializers.push({ initialize, priority });
|
|
@@ -339,7 +379,7 @@ function ensureStorageSchemas(database = resolveStorageDatabase()) {
|
|
|
339
379
|
initializingDatabases.delete(database);
|
|
340
380
|
}
|
|
341
381
|
}
|
|
342
|
-
var
|
|
382
|
+
var internalStorageDatabase = new Proxy({}, {
|
|
343
383
|
get(_target, property) {
|
|
344
384
|
const database = resolveStorageDatabase();
|
|
345
385
|
ensureStorageSchemas(database);
|
|
@@ -352,6 +392,7 @@ var storageDatabase = new Proxy({}, {
|
|
|
352
392
|
return Reflect.set(database, property, value, database);
|
|
353
393
|
}
|
|
354
394
|
});
|
|
395
|
+
var storageDatabase = internalStorageDatabase;
|
|
355
396
|
|
|
356
397
|
// ../../packages/core/src/storage/activity-log.ts
|
|
357
398
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
@@ -487,8 +528,13 @@ __export(exports_api_messages, {
|
|
|
487
528
|
appendApiMessage: () => appendApiMessage,
|
|
488
529
|
anonymizeApiMessages: () => anonymizeApiMessages
|
|
489
530
|
});
|
|
531
|
+
|
|
532
|
+
// ../../packages/core/src/storage/forum-db.ts
|
|
533
|
+
var db = internalStorageDatabase;
|
|
534
|
+
|
|
535
|
+
// ../../packages/core/src/storage/api-messages.ts
|
|
490
536
|
function initializeApiMessagesSchema() {
|
|
491
|
-
|
|
537
|
+
db.exec(`
|
|
492
538
|
CREATE TABLE IF NOT EXISTS api_messages (
|
|
493
539
|
id TEXT PRIMARY KEY,
|
|
494
540
|
topic_id TEXT NOT NULL,
|
|
@@ -512,34 +558,34 @@ function initializeApiMessagesSchema() {
|
|
|
512
558
|
)
|
|
513
559
|
`);
|
|
514
560
|
try {
|
|
515
|
-
|
|
561
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN source_adapter TEXT");
|
|
516
562
|
} catch {}
|
|
517
563
|
try {
|
|
518
|
-
|
|
564
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0");
|
|
519
565
|
} catch {}
|
|
520
566
|
try {
|
|
521
|
-
|
|
567
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN edited_at TEXT");
|
|
522
568
|
} catch {}
|
|
523
569
|
try {
|
|
524
|
-
|
|
570
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN reactions TEXT");
|
|
525
571
|
} catch {}
|
|
526
572
|
try {
|
|
527
|
-
|
|
573
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN kind TEXT");
|
|
528
574
|
} catch {}
|
|
529
575
|
try {
|
|
530
|
-
|
|
576
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN ask_user_question TEXT");
|
|
531
577
|
} catch {}
|
|
532
578
|
try {
|
|
533
|
-
|
|
579
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN mentions TEXT");
|
|
534
580
|
} catch {}
|
|
535
581
|
try {
|
|
536
|
-
|
|
582
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN thread_root_id TEXT");
|
|
537
583
|
} catch {}
|
|
538
584
|
try {
|
|
539
|
-
|
|
585
|
+
db.exec("ALTER TABLE api_messages ADD COLUMN subagent_card TEXT");
|
|
540
586
|
} catch {}
|
|
541
|
-
|
|
542
|
-
|
|
587
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_topic ON api_messages(topic_id)");
|
|
588
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_thread_root ON api_messages(thread_root_id)");
|
|
543
589
|
}
|
|
544
590
|
registerStorageSchemaInitializer(initializeApiMessagesSchema, 30);
|
|
545
591
|
var appendHooks = new Set;
|
|
@@ -598,14 +644,14 @@ function appendApiMessage(msg, options = {}) {
|
|
|
598
644
|
const notify = options.notify ?? true;
|
|
599
645
|
const updateTopicLastMessageAt = options.updateTopicLastMessageAt ?? true;
|
|
600
646
|
let inserted = false;
|
|
601
|
-
|
|
602
|
-
const result =
|
|
647
|
+
db.transaction(() => {
|
|
648
|
+
const result = db.query(`INSERT INTO api_messages
|
|
603
649
|
(id, topic_id, parent_id, author_id, source_adapter, text, query_id, agent_type, model, attachments, usage, deleted, edited_at, reactions, kind, ask_user_question, subagent_card, mentions, thread_root_id, created_at)
|
|
604
650
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
605
651
|
ON CONFLICT(id) DO NOTHING`).run(msg.id, msg.topicId, msg.parentId ?? null, msg.authorId, msg.sourceAdapter ?? null, msg.text, msg.queryId ?? null, msg.agentType ?? null, msg.model ?? null, msg.attachments ? JSON.stringify(msg.attachments) : null, msg.usage ? JSON.stringify(msg.usage) : null, msg.deleted ? 1 : 0, msg.editedAt ?? null, msg.reactions?.length ? JSON.stringify(msg.reactions) : null, msg.kind ?? null, msg.askUserQuestion ? JSON.stringify(msg.askUserQuestion) : null, msg.subagentCard ? JSON.stringify(msg.subagentCard) : null, msg.mentions?.length ? JSON.stringify(msg.mentions) : null, msg.threadRootId ?? null, msg.createdAt);
|
|
606
652
|
inserted = Number(result.changes ?? 0) > 0;
|
|
607
653
|
if (inserted && updateTopicLastMessageAt && !msg.deleted) {
|
|
608
|
-
|
|
654
|
+
db.query(`UPDATE api_topics
|
|
609
655
|
SET last_message_at = CASE
|
|
610
656
|
WHEN last_message_at IS NULL OR last_message_at < ? THEN ?
|
|
611
657
|
ELSE last_message_at
|
|
@@ -617,15 +663,15 @@ function appendApiMessage(msg, options = {}) {
|
|
|
617
663
|
emitApiMessageAppended(msg);
|
|
618
664
|
}
|
|
619
665
|
function getApiMessage(topicId, messageId) {
|
|
620
|
-
const row =
|
|
666
|
+
const row = db.query("SELECT * FROM api_messages WHERE topic_id = ? AND id = ?").get(topicId, messageId);
|
|
621
667
|
return row ? rowToDto(row) : null;
|
|
622
668
|
}
|
|
623
669
|
function topicHasAttachmentFileId(topicId, fileId) {
|
|
624
|
-
const rows =
|
|
670
|
+
const rows = db.query("SELECT attachments FROM api_messages WHERE topic_id = ? AND deleted = 0 AND attachments IS NOT NULL").all(topicId);
|
|
625
671
|
return rows.some((row) => attachmentListHasFileId(row.attachments, fileId));
|
|
626
672
|
}
|
|
627
673
|
function updateApiMessageText(topicId, messageId, text, editedAt = new Date().toISOString()) {
|
|
628
|
-
const res =
|
|
674
|
+
const res = db.query(`UPDATE api_messages
|
|
629
675
|
SET text = ?, edited_at = ?
|
|
630
676
|
WHERE topic_id = ? AND id = ? AND deleted = 0`).run(text, editedAt, topicId, messageId);
|
|
631
677
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -633,7 +679,7 @@ function updateApiMessageText(topicId, messageId, text, editedAt = new Date().to
|
|
|
633
679
|
return getApiMessage(topicId, messageId);
|
|
634
680
|
}
|
|
635
681
|
function updateApiMessageUsage(topicId, messageId, usage) {
|
|
636
|
-
const res =
|
|
682
|
+
const res = db.query(`UPDATE api_messages
|
|
637
683
|
SET usage = ?
|
|
638
684
|
WHERE topic_id = ? AND id = ? AND deleted = 0`).run(JSON.stringify(usage), topicId, messageId);
|
|
639
685
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -641,7 +687,7 @@ function updateApiMessageUsage(topicId, messageId, usage) {
|
|
|
641
687
|
return getApiMessage(topicId, messageId);
|
|
642
688
|
}
|
|
643
689
|
function updateApiMessageAskUserQuestion(topicId, messageId, askUserQuestion, editedAt = new Date().toISOString()) {
|
|
644
|
-
const res =
|
|
690
|
+
const res = db.query(`UPDATE api_messages
|
|
645
691
|
SET ask_user_question = ?, edited_at = ?
|
|
646
692
|
WHERE topic_id = ? AND id = ? AND deleted = 0 AND kind = 'ask_user_question'`).run(JSON.stringify(askUserQuestion), editedAt, topicId, messageId);
|
|
647
693
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -649,7 +695,7 @@ function updateApiMessageAskUserQuestion(topicId, messageId, askUserQuestion, ed
|
|
|
649
695
|
return getApiMessage(topicId, messageId);
|
|
650
696
|
}
|
|
651
697
|
function updateApiMessageSubagentCard(topicId, messageId, subagentCard, editedAt = new Date().toISOString()) {
|
|
652
|
-
const res =
|
|
698
|
+
const res = db.query(`UPDATE api_messages
|
|
653
699
|
SET subagent_card = ?, edited_at = ?
|
|
654
700
|
WHERE topic_id = ? AND id = ? AND deleted = 0 AND kind = 'subagent'`).run(JSON.stringify(subagentCard), editedAt, topicId, messageId);
|
|
655
701
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -657,11 +703,11 @@ function updateApiMessageSubagentCard(topicId, messageId, subagentCard, editedAt
|
|
|
657
703
|
return getApiMessage(topicId, messageId);
|
|
658
704
|
}
|
|
659
705
|
function listApiMessagesByKind(kind) {
|
|
660
|
-
const rows =
|
|
706
|
+
const rows = db.query("SELECT * FROM api_messages WHERE kind = ? AND deleted = 0").all(kind);
|
|
661
707
|
return rows.map(rowToDto);
|
|
662
708
|
}
|
|
663
709
|
function setApiMessageReactions(topicId, messageId, reactions) {
|
|
664
|
-
const res =
|
|
710
|
+
const res = db.query(`UPDATE api_messages
|
|
665
711
|
SET reactions = ?
|
|
666
712
|
WHERE topic_id = ? AND id = ? AND deleted = 0`).run(reactions.length ? JSON.stringify(reactions) : null, topicId, messageId);
|
|
667
713
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -669,7 +715,7 @@ function setApiMessageReactions(topicId, messageId, reactions) {
|
|
|
669
715
|
return getApiMessage(topicId, messageId);
|
|
670
716
|
}
|
|
671
717
|
function softDeleteApiMessage(topicId, messageId) {
|
|
672
|
-
const res =
|
|
718
|
+
const res = db.query(`UPDATE api_messages
|
|
673
719
|
SET deleted = 1, text = ''
|
|
674
720
|
WHERE topic_id = ? AND id = ? AND deleted = 0`).run(topicId, messageId);
|
|
675
721
|
if (Number(res.changes ?? 0) === 0)
|
|
@@ -680,14 +726,14 @@ function listApiMessages(topicId, options) {
|
|
|
680
726
|
const limit = Math.max(1, Math.min(options?.limit ?? 50, 200));
|
|
681
727
|
let anchorRowid = null;
|
|
682
728
|
if (options?.cursor) {
|
|
683
|
-
const cur =
|
|
729
|
+
const cur = db.query("SELECT rowid AS rowid FROM api_messages WHERE topic_id = ? AND id = ?").get(topicId, options.cursor);
|
|
684
730
|
if (cur)
|
|
685
731
|
anchorRowid = cur.rowid;
|
|
686
732
|
}
|
|
687
|
-
const rows = anchorRowid !== null ?
|
|
733
|
+
const rows = anchorRowid !== null ? db.query(`SELECT *, rowid AS rowid FROM api_messages
|
|
688
734
|
WHERE topic_id = ? AND deleted = 0 AND thread_root_id IS NULL AND rowid < ?
|
|
689
735
|
ORDER BY rowid DESC
|
|
690
|
-
LIMIT ?`).all(topicId, anchorRowid, limit + 1) :
|
|
736
|
+
LIMIT ?`).all(topicId, anchorRowid, limit + 1) : db.query(`SELECT *, rowid AS rowid FROM api_messages
|
|
691
737
|
WHERE topic_id = ? AND deleted = 0 AND thread_root_id IS NULL
|
|
692
738
|
ORDER BY rowid DESC
|
|
693
739
|
LIMIT ?`).all(topicId, limit + 1);
|
|
@@ -715,7 +761,7 @@ function getThreadSummaries(rootIds) {
|
|
|
715
761
|
const ids = [...new Set(rootIds)].filter(Boolean);
|
|
716
762
|
if (ids.length === 0)
|
|
717
763
|
return out;
|
|
718
|
-
const rows =
|
|
764
|
+
const rows = db.query(`SELECT thread_root_id AS rootId, COUNT(*) AS replyCount, MAX(created_at) AS lastReplyAt
|
|
719
765
|
FROM api_messages
|
|
720
766
|
WHERE thread_root_id IN (${ids.map(() => "?").join(",")}) AND deleted = 0
|
|
721
767
|
GROUP BY thread_root_id`).all(...ids);
|
|
@@ -726,14 +772,14 @@ function getThreadSummaries(rootIds) {
|
|
|
726
772
|
}
|
|
727
773
|
function listThreadMessages(topicId, rootId) {
|
|
728
774
|
const root = getApiMessage(topicId, rootId);
|
|
729
|
-
const rows =
|
|
775
|
+
const rows = db.query(`SELECT *, rowid AS rowid FROM api_messages
|
|
730
776
|
WHERE topic_id = ? AND thread_root_id = ? AND deleted = 0
|
|
731
777
|
ORDER BY rowid ASC
|
|
732
778
|
LIMIT 200`).all(topicId, rootId);
|
|
733
779
|
return { root, replies: rows.map(rowToDto) };
|
|
734
780
|
}
|
|
735
781
|
function findRecentUserMessage(topicId, authorId, text, maxAgeMs) {
|
|
736
|
-
const row =
|
|
782
|
+
const row = db.query(`SELECT * FROM api_messages
|
|
737
783
|
WHERE topic_id = ? AND author_id = ? AND text = ?
|
|
738
784
|
AND deleted = 0
|
|
739
785
|
ORDER BY rowid DESC
|
|
@@ -750,7 +796,7 @@ function getLastMessagePreviews(topicIds) {
|
|
|
750
796
|
if (uniqueTopicIds && uniqueTopicIds.length === 0)
|
|
751
797
|
return new Map;
|
|
752
798
|
const topicFilter = uniqueTopicIds ? `AND topic_id IN (${uniqueTopicIds.map(() => "?").join(",")})` : "";
|
|
753
|
-
const rows =
|
|
799
|
+
const rows = db.query(`SELECT m.topic_id AS topic_id, m.text AS text
|
|
754
800
|
FROM api_messages m
|
|
755
801
|
JOIN (
|
|
756
802
|
SELECT topic_id, MAX(rowid) AS mx FROM api_messages
|
|
@@ -767,19 +813,19 @@ function getLastMessagePreviews(topicIds) {
|
|
|
767
813
|
return out;
|
|
768
814
|
}
|
|
769
815
|
function deleteMessagesForTopic(topicId) {
|
|
770
|
-
const res =
|
|
816
|
+
const res = db.query("DELETE FROM api_messages WHERE topic_id = ?").run(topicId);
|
|
771
817
|
return Number(res.changes ?? 0);
|
|
772
818
|
}
|
|
773
819
|
function anonymizeApiMessages(userId) {
|
|
774
|
-
|
|
820
|
+
db.query("UPDATE api_messages SET author_id = 'deleted-user' WHERE author_id = ?").run(userId);
|
|
775
821
|
}
|
|
776
822
|
function listTopicIdsForAttachment(fileId) {
|
|
777
823
|
const needle = `%"${fileId.replace(/[\\%_]/g, (char) => `\\${char}`)}"%`;
|
|
778
|
-
const rows =
|
|
824
|
+
const rows = db.query("SELECT DISTINCT topic_id FROM api_messages WHERE attachments LIKE ? ESCAPE '\\'").all(needle);
|
|
779
825
|
return rows.map((row) => row.topic_id);
|
|
780
826
|
}
|
|
781
827
|
function copyMessagesForTopic(sourceTopicId, targetTopicId) {
|
|
782
|
-
const rows =
|
|
828
|
+
const rows = db.query("SELECT * FROM api_messages WHERE topic_id = ? AND deleted = 0 ORDER BY rowid ASC").all(sourceTopicId);
|
|
783
829
|
if (rows.length === 0)
|
|
784
830
|
return 0;
|
|
785
831
|
const idMap = new Map(rows.map((r) => [r.id, crypto.randomUUID()]));
|
|
@@ -800,10 +846,10 @@ function copyMessagesForTopic(sourceTopicId, targetTopicId) {
|
|
|
800
846
|
return copied;
|
|
801
847
|
}
|
|
802
848
|
function getAllMessagesForTopic(topicId) {
|
|
803
|
-
return
|
|
849
|
+
return db.query("SELECT *, rowid AS rowid FROM api_messages WHERE topic_id = ? AND deleted = 0 ORDER BY rowid ASC").all(topicId);
|
|
804
850
|
}
|
|
805
851
|
function getMessagesForTopicAfterRowid(topicId, afterRowid) {
|
|
806
|
-
return
|
|
852
|
+
return db.query("SELECT *, rowid AS rowid FROM api_messages WHERE topic_id = ? AND rowid > ? AND deleted = 0 ORDER BY rowid ASC").all(topicId, afterRowid);
|
|
807
853
|
}
|
|
808
854
|
// ../../packages/core/src/storage/api-topic-brief.ts
|
|
809
855
|
var exports_api_topic_brief = {};
|
|
@@ -835,7 +881,7 @@ function rowToBrief(r) {
|
|
|
835
881
|
};
|
|
836
882
|
}
|
|
837
883
|
function getTopicBrief(topicId) {
|
|
838
|
-
const row =
|
|
884
|
+
const row = db.query("SELECT topic_id, brief_md, latest_summary_md, summary_date, updated_at FROM api_topic_brief WHERE topic_id = ?").get(topicId);
|
|
839
885
|
if (!row)
|
|
840
886
|
return null;
|
|
841
887
|
return rowToBrief(row);
|
|
@@ -852,7 +898,7 @@ function setTopicBrief(topicId, fields) {
|
|
|
852
898
|
const briefMd = fields.briefMd !== undefined ? fields.briefMd : existing?.briefMd ?? "";
|
|
853
899
|
const latestSummaryMd = fields.latestSummaryMd !== undefined ? fields.latestSummaryMd : existing?.latestSummaryMd ?? null;
|
|
854
900
|
const summaryDate = fields.summaryDate !== undefined ? fields.summaryDate : existing?.summaryDate ?? null;
|
|
855
|
-
|
|
901
|
+
db.query(`INSERT INTO api_topic_brief
|
|
856
902
|
(topic_id, brief_md, latest_summary_md, summary_date, updated_at)
|
|
857
903
|
VALUES (?, ?, ?, ?, datetime('now'))
|
|
858
904
|
ON CONFLICT(topic_id) DO UPDATE SET
|
|
@@ -863,10 +909,10 @@ function setTopicBrief(topicId, fields) {
|
|
|
863
909
|
return getTopicBrief(topicId);
|
|
864
910
|
}
|
|
865
911
|
function deleteTopicBrief(topicId) {
|
|
866
|
-
|
|
912
|
+
db.query("DELETE FROM api_topic_brief WHERE topic_id = ?").run(topicId);
|
|
867
913
|
}
|
|
868
914
|
function listTopicBriefs() {
|
|
869
|
-
const rows =
|
|
915
|
+
const rows = db.query("SELECT topic_id, brief_md, latest_summary_md, summary_date, updated_at FROM api_topic_brief ORDER BY updated_at DESC").all();
|
|
870
916
|
return rows.map(rowToBrief);
|
|
871
917
|
}
|
|
872
918
|
// ../../packages/core/src/storage/api-topic-config.ts
|
|
@@ -877,11 +923,11 @@ __export(exports_api_topic_config, {
|
|
|
877
923
|
deleteApiTopicConfig: () => deleteApiTopicConfig
|
|
878
924
|
});
|
|
879
925
|
function tableColumns(table) {
|
|
880
|
-
const rows =
|
|
926
|
+
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
881
927
|
return new Set(rows.map((row) => row.name));
|
|
882
928
|
}
|
|
883
929
|
function createCanonicalConfigTable(name = "api_topic_config") {
|
|
884
|
-
|
|
930
|
+
db.exec(`
|
|
885
931
|
CREATE TABLE IF NOT EXISTS ${name} (
|
|
886
932
|
topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,
|
|
887
933
|
model TEXT,
|
|
@@ -901,7 +947,7 @@ function initializeApiTopicConfigSchema() {
|
|
|
901
947
|
const topicColumns = tableColumns("api_topics");
|
|
902
948
|
const agentColumn = topicColumns.has("agent") ? "agent" : topicColumns.has("runtime_agent") ? "runtime_agent" : null;
|
|
903
949
|
if (agentColumn && existingConfigColumns.has("agent")) {
|
|
904
|
-
|
|
950
|
+
db.exec(`UPDATE api_topics
|
|
905
951
|
SET ${agentColumn} = (
|
|
906
952
|
SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
|
|
907
953
|
)
|
|
@@ -911,15 +957,15 @@ function initializeApiTopicConfigSchema() {
|
|
|
911
957
|
WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
|
|
912
958
|
)`);
|
|
913
959
|
}
|
|
914
|
-
const previousForeignKeys =
|
|
915
|
-
|
|
960
|
+
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
961
|
+
db.exec("PRAGMA foreign_keys = OFF");
|
|
916
962
|
try {
|
|
917
963
|
const agentLockSource = existingConfigColumns.has("runtime_locked") ? "runtime_locked" : existingConfigColumns.has("agent_pinned") ? "agent_pinned" : "0";
|
|
918
964
|
const modelLockSource = existingConfigColumns.has("model_locked") ? "model_locked" : existingConfigColumns.has("model_pinned") ? "model_pinned" : "0";
|
|
919
965
|
const effortLockSource = existingConfigColumns.has("effort_locked") ? "effort_locked" : existingConfigColumns.has("effort_pinned") ? "effort_pinned" : "0";
|
|
920
|
-
|
|
966
|
+
db.transaction(() => {
|
|
921
967
|
createCanonicalConfigTable("api_topic_config_next");
|
|
922
|
-
|
|
968
|
+
db.exec(`
|
|
923
969
|
INSERT INTO api_topic_config_next
|
|
924
970
|
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
925
971
|
SELECT
|
|
@@ -933,11 +979,11 @@ function initializeApiTopicConfigSchema() {
|
|
|
933
979
|
FROM api_topic_config
|
|
934
980
|
WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
|
|
935
981
|
`);
|
|
936
|
-
|
|
937
|
-
|
|
982
|
+
db.exec("DROP TABLE api_topic_config");
|
|
983
|
+
db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
|
|
938
984
|
})();
|
|
939
985
|
} finally {
|
|
940
|
-
|
|
986
|
+
db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
941
987
|
}
|
|
942
988
|
} else {
|
|
943
989
|
createCanonicalConfigTable();
|
|
@@ -966,14 +1012,14 @@ function rowToConfig(r) {
|
|
|
966
1012
|
return cfg;
|
|
967
1013
|
}
|
|
968
1014
|
function getApiTopicConfig(topicId) {
|
|
969
|
-
const row =
|
|
1015
|
+
const row = db.query("SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?").get(topicId);
|
|
970
1016
|
if (!row)
|
|
971
1017
|
return;
|
|
972
1018
|
const config = rowToConfig(row);
|
|
973
1019
|
return Object.keys(config).length > 0 ? config : undefined;
|
|
974
1020
|
}
|
|
975
1021
|
function setApiTopicConfig(topicId, config) {
|
|
976
|
-
|
|
1022
|
+
db.query(`INSERT INTO api_topic_config
|
|
977
1023
|
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
978
1024
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
979
1025
|
ON CONFLICT(topic_id) DO UPDATE SET
|
|
@@ -985,7 +1031,7 @@ function setApiTopicConfig(topicId, config) {
|
|
|
985
1031
|
effort_locked = excluded.effort_locked`).run(topicId, config.model ?? null, config.effort ?? null, config.mcp ? JSON.stringify(config.mcp) : null, config.agentLocked ? 1 : 0, config.modelLocked ? 1 : 0, config.effortLocked ? 1 : 0);
|
|
986
1032
|
}
|
|
987
1033
|
function deleteApiTopicConfig(topicId) {
|
|
988
|
-
|
|
1034
|
+
db.query("DELETE FROM api_topic_config WHERE topic_id = ?").run(topicId);
|
|
989
1035
|
}
|
|
990
1036
|
// ../../packages/core/src/storage/api-topics.ts
|
|
991
1037
|
var exports_api_topics = {};
|
|
@@ -1032,18 +1078,18 @@ var GENERAL_TOPIC_ID = "general";
|
|
|
1032
1078
|
// ../../packages/core/src/storage/api-topics.ts
|
|
1033
1079
|
var DEFAULT_AGENT_ROOM_AGENT = "maestro";
|
|
1034
1080
|
function tableColumns2(table) {
|
|
1035
|
-
const rows =
|
|
1081
|
+
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
1036
1082
|
return new Set(rows.map((row) => row.name));
|
|
1037
1083
|
}
|
|
1038
1084
|
function setApiTopicAgent(topicId, agent, defaults) {
|
|
1039
1085
|
if (!defaults) {
|
|
1040
|
-
|
|
1086
|
+
db.query("UPDATE api_topics SET agent = ? WHERE id = ?").run(agent, topicId);
|
|
1041
1087
|
return;
|
|
1042
1088
|
}
|
|
1043
|
-
|
|
1089
|
+
db.query("UPDATE api_topics SET agent = ?, base_model = ?, base_effort = ? WHERE id = ?").run(agent, defaults.model, defaults.effort ?? null, topicId);
|
|
1044
1090
|
}
|
|
1045
1091
|
function initializeApiTopicsSchema() {
|
|
1046
|
-
|
|
1092
|
+
db.exec(`
|
|
1047
1093
|
CREATE TABLE IF NOT EXISTS api_topics (
|
|
1048
1094
|
id TEXT PRIMARY KEY,
|
|
1049
1095
|
title TEXT NOT NULL,
|
|
@@ -1065,56 +1111,56 @@ function initializeApiTopicsSchema() {
|
|
|
1065
1111
|
const needsCanonicalTopicRebuild = legacyTopicSchema || !initialTopicColumns.has("agent");
|
|
1066
1112
|
if (legacyTopicSchema) {
|
|
1067
1113
|
try {
|
|
1068
|
-
|
|
1114
|
+
db.exec("ALTER TABLE api_topics RENAME COLUMN default_agent TO agent");
|
|
1069
1115
|
} catch {}
|
|
1070
1116
|
try {
|
|
1071
|
-
|
|
1117
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN ai_mention INTEGER NOT NULL DEFAULT 0");
|
|
1072
1118
|
} catch {}
|
|
1073
1119
|
try {
|
|
1074
|
-
|
|
1120
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN parent_topic_id TEXT");
|
|
1075
1121
|
} catch {}
|
|
1076
1122
|
try {
|
|
1077
|
-
|
|
1123
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN is_fork INTEGER NOT NULL DEFAULT 0");
|
|
1078
1124
|
} catch {}
|
|
1079
1125
|
try {
|
|
1080
|
-
|
|
1126
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN is_subagent INTEGER NOT NULL DEFAULT 0");
|
|
1081
1127
|
} catch {}
|
|
1082
1128
|
try {
|
|
1083
|
-
|
|
1129
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN session_id TEXT");
|
|
1084
1130
|
} catch {}
|
|
1085
1131
|
try {
|
|
1086
|
-
|
|
1132
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN kind TEXT NOT NULL DEFAULT 'channel'");
|
|
1087
1133
|
} catch {}
|
|
1088
1134
|
try {
|
|
1089
|
-
|
|
1135
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN ai_mode TEXT");
|
|
1090
1136
|
} catch {}
|
|
1091
|
-
|
|
1137
|
+
db.exec(`
|
|
1092
1138
|
CREATE TABLE IF NOT EXISTS api_schema_migrations (
|
|
1093
1139
|
key TEXT PRIMARY KEY,
|
|
1094
1140
|
applied_at TEXT NOT NULL
|
|
1095
1141
|
)
|
|
1096
1142
|
`);
|
|
1097
1143
|
const ALWAYS_RESPOND_MIGRATION = "api_topics_ai_invited_default_always_respond_20260623";
|
|
1098
|
-
const alwaysRespondMigration =
|
|
1144
|
+
const alwaysRespondMigration = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(ALWAYS_RESPOND_MIGRATION);
|
|
1099
1145
|
if (!alwaysRespondMigration) {
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1146
|
+
db.transaction(() => {
|
|
1147
|
+
db.query("UPDATE api_topics SET ai_mention = 0 WHERE agent IS NOT NULL").run();
|
|
1148
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(ALWAYS_RESPOND_MIGRATION, new Date().toISOString());
|
|
1103
1149
|
})();
|
|
1104
1150
|
}
|
|
1105
1151
|
const GENERAL_AGENT_KIND_MIGRATION = "api_topics_general_agent_kind_20260704";
|
|
1106
|
-
const generalAgentKindMigration =
|
|
1152
|
+
const generalAgentKindMigration = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(GENERAL_AGENT_KIND_MIGRATION);
|
|
1107
1153
|
if (!generalAgentKindMigration) {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1154
|
+
db.transaction(() => {
|
|
1155
|
+
db.query("UPDATE api_topics SET kind = 'agent', ai_mention = 0 WHERE id = ?").run(GENERAL_TOPIC_ID);
|
|
1156
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(GENERAL_AGENT_KIND_MIGRATION, new Date().toISOString());
|
|
1111
1157
|
})();
|
|
1112
1158
|
}
|
|
1113
1159
|
const AI_MODE_MIGRATION = "api_topics_ai_mode_20260704";
|
|
1114
|
-
const aiModeMigration =
|
|
1160
|
+
const aiModeMigration = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(AI_MODE_MIGRATION);
|
|
1115
1161
|
if (!aiModeMigration) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1162
|
+
db.transaction(() => {
|
|
1163
|
+
db.query(`UPDATE api_topics
|
|
1118
1164
|
SET
|
|
1119
1165
|
kind = CASE
|
|
1120
1166
|
WHEN id = ? THEN 'agent'
|
|
@@ -1130,20 +1176,20 @@ function initializeApiTopicsSchema() {
|
|
|
1130
1176
|
WHEN ai_mention != 0 THEN 'mention'
|
|
1131
1177
|
ELSE 'always'
|
|
1132
1178
|
END`).run(GENERAL_TOPIC_ID, GENERAL_TOPIC_ID);
|
|
1133
|
-
|
|
1179
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(AI_MODE_MIGRATION, new Date().toISOString());
|
|
1134
1180
|
})();
|
|
1135
1181
|
}
|
|
1136
1182
|
const GENERAL_MANAGER_KIND_MIGRATION = "api_topics_general_manager_kind_20260704";
|
|
1137
|
-
const generalManagerKindMigration =
|
|
1183
|
+
const generalManagerKindMigration = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(GENERAL_MANAGER_KIND_MIGRATION);
|
|
1138
1184
|
if (!generalManagerKindMigration) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1185
|
+
db.transaction(() => {
|
|
1186
|
+
db.query("UPDATE api_topics SET kind = 'manager', ai_mention = 0, ai_mode = 'always' WHERE id = ?").run(GENERAL_TOPIC_ID);
|
|
1187
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(GENERAL_MANAGER_KIND_MIGRATION, new Date().toISOString());
|
|
1142
1188
|
})();
|
|
1143
1189
|
}
|
|
1144
1190
|
}
|
|
1145
1191
|
function createCanonicalTopicsTable(name) {
|
|
1146
|
-
|
|
1192
|
+
db.exec(`
|
|
1147
1193
|
CREATE TABLE IF NOT EXISTS ${name} (
|
|
1148
1194
|
id TEXT PRIMARY KEY,
|
|
1149
1195
|
title TEXT NOT NULL,
|
|
@@ -1172,7 +1218,7 @@ function initializeApiTopicsSchema() {
|
|
|
1172
1218
|
`);
|
|
1173
1219
|
}
|
|
1174
1220
|
function createTopicMembersTable() {
|
|
1175
|
-
|
|
1221
|
+
db.exec(`
|
|
1176
1222
|
CREATE TABLE IF NOT EXISTS topic_members (
|
|
1177
1223
|
topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,
|
|
1178
1224
|
user_id TEXT NOT NULL,
|
|
@@ -1180,17 +1226,17 @@ function initializeApiTopicsSchema() {
|
|
|
1180
1226
|
PRIMARY KEY (topic_id, user_id)
|
|
1181
1227
|
)
|
|
1182
1228
|
`);
|
|
1183
|
-
|
|
1229
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_topic_members_user ON topic_members(user_id)");
|
|
1184
1230
|
}
|
|
1185
1231
|
if (needsCanonicalTopicRebuild) {
|
|
1186
|
-
const legacyRows =
|
|
1187
|
-
const existingMemberRows = tableColumns2("topic_members").has("topic_id") ?
|
|
1232
|
+
const legacyRows = db.query("SELECT * FROM api_topics").all();
|
|
1233
|
+
const existingMemberRows = tableColumns2("topic_members").has("topic_id") ? db.query("SELECT topic_id, user_id, role FROM topic_members").all() : [];
|
|
1188
1234
|
const configColumns = tableColumns2("api_topic_config");
|
|
1189
|
-
const legacyAgentOverrides = configColumns.has("agent") ? new Map(
|
|
1190
|
-
const previousForeignKeys =
|
|
1191
|
-
|
|
1235
|
+
const legacyAgentOverrides = configColumns.has("agent") ? new Map(db.query("SELECT topic_id, agent FROM api_topic_config WHERE agent IS NOT NULL").all().map((row) => [row.topic_id, row.agent])) : new Map;
|
|
1236
|
+
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
1237
|
+
db.exec("PRAGMA foreign_keys = OFF");
|
|
1192
1238
|
try {
|
|
1193
|
-
|
|
1239
|
+
db.transaction(() => {
|
|
1194
1240
|
createCanonicalTopicsTable("api_topics_next");
|
|
1195
1241
|
for (const row of legacyRows) {
|
|
1196
1242
|
const selectedAgent = legacyAgentOverrides.get(String(row.id)) ?? row.agent ?? row.runtime_agent ?? row.default_agent ?? undefined;
|
|
@@ -1203,18 +1249,18 @@ function initializeApiTopicsSchema() {
|
|
|
1203
1249
|
});
|
|
1204
1250
|
const legacyBaseModel = row.base_model ?? row.default_model;
|
|
1205
1251
|
const legacyBaseEffort = row.base_effort ?? row.default_effort;
|
|
1206
|
-
|
|
1252
|
+
db.query(`INSERT INTO api_topics_next
|
|
1207
1253
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
1208
1254
|
created_at,last_message_at,parent_topic_id,is_fork,is_subagent,visibility,access_mode,session_id)
|
|
1209
1255
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(String(row.id), String(row.title), normalized.kind, typeof row.description === "string" ? row.description : null, normalized.agent ?? null, typeof legacyBaseModel === "string" ? legacyBaseModel : null, typeof legacyBaseEffort === "string" ? legacyBaseEffort : null, normalized.aiMode, String(row.created_at), typeof row.last_message_at === "string" ? row.last_message_at : null, typeof row.parent_topic_id === "string" ? row.parent_topic_id : null, Number(row.is_fork ?? 0) !== 0 ? 1 : 0, Number(row.is_subagent ?? 0) !== 0 ? 1 : 0, row.visibility === "hidden" ? "hidden" : "visible", row.access_mode === "shared" ? "shared" : "private", typeof row.session_id === "string" ? row.session_id : null);
|
|
1210
1256
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1257
|
+
db.exec("DROP TABLE IF EXISTS topic_members");
|
|
1258
|
+
db.exec("DROP TABLE api_topics");
|
|
1259
|
+
db.exec("ALTER TABLE api_topics_next RENAME TO api_topics");
|
|
1214
1260
|
createTopicMembersTable();
|
|
1215
1261
|
if (existingMemberRows.length > 0) {
|
|
1216
1262
|
for (const member of existingMemberRows) {
|
|
1217
|
-
|
|
1263
|
+
db.query("INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(member.topic_id, member.user_id, member.role === "owner" ? "owner" : "member");
|
|
1218
1264
|
}
|
|
1219
1265
|
} else {
|
|
1220
1266
|
for (const row of legacyRows) {
|
|
@@ -1229,31 +1275,31 @@ function initializeApiTopicsSchema() {
|
|
|
1229
1275
|
for (const participant of participants) {
|
|
1230
1276
|
if (!participant?.userId)
|
|
1231
1277
|
continue;
|
|
1232
|
-
|
|
1278
|
+
db.query("INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(String(row.id), participant.userId, participant.role === "owner" ? "owner" : "member");
|
|
1233
1279
|
}
|
|
1234
1280
|
}
|
|
1235
1281
|
}
|
|
1236
1282
|
})();
|
|
1237
1283
|
} finally {
|
|
1238
|
-
|
|
1284
|
+
db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
1239
1285
|
}
|
|
1240
1286
|
} else {
|
|
1241
1287
|
createCanonicalTopicsTable("api_topics");
|
|
1242
1288
|
createTopicMembersTable();
|
|
1243
1289
|
}
|
|
1244
1290
|
if (!tableColumns2("api_topics").has("visibility")) {
|
|
1245
|
-
|
|
1291
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'");
|
|
1246
1292
|
}
|
|
1247
1293
|
if (!tableColumns2("api_topics").has("access_mode")) {
|
|
1248
|
-
|
|
1294
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN access_mode TEXT NOT NULL DEFAULT 'private'");
|
|
1249
1295
|
}
|
|
1250
1296
|
if (!tableColumns2("api_topics").has("browser_profile")) {
|
|
1251
|
-
|
|
1297
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'");
|
|
1252
1298
|
}
|
|
1253
1299
|
if (!tableColumns2("api_topics").has("browser_profile_owner")) {
|
|
1254
|
-
|
|
1300
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile_owner TEXT");
|
|
1255
1301
|
}
|
|
1256
|
-
|
|
1302
|
+
db.exec(`
|
|
1257
1303
|
UPDATE api_topics
|
|
1258
1304
|
SET browser_profile_owner = (
|
|
1259
1305
|
SELECT m.user_id FROM topic_members m
|
|
@@ -1263,17 +1309,18 @@ function initializeApiTopicsSchema() {
|
|
|
1263
1309
|
)
|
|
1264
1310
|
WHERE browser_profile_owner IS NULL
|
|
1265
1311
|
`);
|
|
1312
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_api_topics_last_message ON api_topics(last_message_at DESC)");
|
|
1266
1313
|
}
|
|
1267
1314
|
registerStorageSchemaInitializer(initializeApiTopicsSchema, 20);
|
|
1268
1315
|
function shortSessionId(sessionId) {
|
|
1269
1316
|
return sessionId ? sessionId.slice(0, 8) : null;
|
|
1270
1317
|
}
|
|
1271
1318
|
function getTopicParticipants(topicId) {
|
|
1272
|
-
return
|
|
1319
|
+
return db.query("SELECT user_id, role FROM topic_members WHERE topic_id = ? ORDER BY rowid").all(topicId).map((row) => ({ userId: row.user_id, role: row.role }));
|
|
1273
1320
|
}
|
|
1274
1321
|
function getAllTopicParticipants() {
|
|
1275
1322
|
const grouped = new Map;
|
|
1276
|
-
const rows =
|
|
1323
|
+
const rows = db.query("SELECT topic_id, user_id, role FROM topic_members ORDER BY rowid").all();
|
|
1277
1324
|
for (const row of rows) {
|
|
1278
1325
|
const participants = grouped.get(row.topic_id) ?? [];
|
|
1279
1326
|
participants.push({ userId: row.user_id, role: row.role });
|
|
@@ -1387,8 +1434,8 @@ function upsertTopic(t) {
|
|
|
1387
1434
|
aiMode: normalizeAiMode(t.aiMode),
|
|
1388
1435
|
aiMention: t.aiMention
|
|
1389
1436
|
});
|
|
1390
|
-
|
|
1391
|
-
|
|
1437
|
+
db.transaction(() => {
|
|
1438
|
+
db.query(`INSERT INTO api_topics
|
|
1392
1439
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
1393
1440
|
created_at,last_message_at,parent_topic_id,is_fork,is_subagent,visibility,access_mode)
|
|
1394
1441
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
|
@@ -1407,29 +1454,29 @@ function upsertTopic(t) {
|
|
|
1407
1454
|
is_subagent = excluded.is_subagent,
|
|
1408
1455
|
visibility = excluded.visibility,
|
|
1409
1456
|
access_mode = excluded.access_mode`).run(t.id, t.title, normalized.kind, t.description ?? null, normalized.agent ?? null, t.defaultModel ?? null, t.defaultEffort ?? null, normalized.aiMode, t.createdAt, t.lastMessageAt ?? null, t.parentTopicId ?? null, t.isFork ? 1 : 0, t.isSubagent ? 1 : 0, normalizeTopicVisibility(t.visibility), normalizeTopicAccessMode(t.accessMode));
|
|
1410
|
-
|
|
1457
|
+
db.query("DELETE FROM topic_members WHERE topic_id = ?").run(t.id);
|
|
1411
1458
|
for (const participant of t.participants) {
|
|
1412
|
-
|
|
1459
|
+
db.query("INSERT INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(t.id, participant.userId, participant.role);
|
|
1413
1460
|
}
|
|
1414
1461
|
const initialBrowserProfileOwner = t.participants.find((participant) => participant.role === "owner")?.userId;
|
|
1415
1462
|
if (initialBrowserProfileOwner) {
|
|
1416
|
-
|
|
1463
|
+
db.query(`UPDATE api_topics
|
|
1417
1464
|
SET browser_profile_owner = COALESCE(browser_profile_owner, ?)
|
|
1418
1465
|
WHERE id = ?`).run(initialBrowserProfileOwner, t.id);
|
|
1419
1466
|
}
|
|
1420
1467
|
})();
|
|
1421
1468
|
}
|
|
1422
1469
|
function listTopics() {
|
|
1423
|
-
const rows =
|
|
1470
|
+
const rows = db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
1424
1471
|
const participants = getAllTopicParticipants();
|
|
1425
1472
|
return rows.map((row) => rowToDto2(row, participants.get(row.id) ?? []));
|
|
1426
1473
|
}
|
|
1427
1474
|
function getTopic(id) {
|
|
1428
|
-
const r =
|
|
1475
|
+
const r = db.query("SELECT * FROM api_topics WHERE id = ?").get(id);
|
|
1429
1476
|
return r ? rowToDto2(r) : null;
|
|
1430
1477
|
}
|
|
1431
1478
|
function getManagerTopicForUser(userId) {
|
|
1432
|
-
const row =
|
|
1479
|
+
const row = db.query(`SELECT t.* FROM api_topics t
|
|
1433
1480
|
JOIN topic_members m ON m.topic_id = t.id
|
|
1434
1481
|
WHERE t.kind = 'manager'
|
|
1435
1482
|
AND t.id != ?
|
|
@@ -1454,18 +1501,18 @@ function getTopicMemoryOrigin(id) {
|
|
|
1454
1501
|
return current;
|
|
1455
1502
|
}
|
|
1456
1503
|
function getTopicByName(title) {
|
|
1457
|
-
const r =
|
|
1504
|
+
const r = db.query("SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?)").get(title);
|
|
1458
1505
|
return r ? rowToDto2(r) : null;
|
|
1459
1506
|
}
|
|
1460
1507
|
function getTopicByNameAndKind(title, kind) {
|
|
1461
|
-
const r =
|
|
1508
|
+
const r = db.query("SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?) AND kind = ?").get(title, kind);
|
|
1462
1509
|
return r ? rowToDto2(r) : null;
|
|
1463
1510
|
}
|
|
1464
1511
|
function findTopicTitleConflict(title, kind, opts = {}) {
|
|
1465
1512
|
const wanted = normalizedTitle(title);
|
|
1466
1513
|
const generalTitleRequested = wanted === normalizedTitle(GENERAL_TOPIC_ID);
|
|
1467
1514
|
if (generalTitleRequested && opts.excludeTopicId !== GENERAL_TOPIC_ID) {
|
|
1468
|
-
const general =
|
|
1515
|
+
const general = db.query("SELECT * FROM api_topics WHERE id = ?").get(GENERAL_TOPIC_ID);
|
|
1469
1516
|
if (general)
|
|
1470
1517
|
return rowToDto2(general);
|
|
1471
1518
|
}
|
|
@@ -1480,7 +1527,7 @@ function findTopicTitleConflict(title, kind, opts = {}) {
|
|
|
1480
1527
|
params.push(opts.excludeTopicId);
|
|
1481
1528
|
}
|
|
1482
1529
|
sql += " LIMIT 1";
|
|
1483
|
-
const row =
|
|
1530
|
+
const row = db.query(sql).get(...params);
|
|
1484
1531
|
return row ? rowToDto2(row) : null;
|
|
1485
1532
|
}
|
|
1486
1533
|
function getTopicByNameForUser(title, userId) {
|
|
@@ -1488,7 +1535,7 @@ function getTopicByNameForUser(title, userId) {
|
|
|
1488
1535
|
const qualified = /^(agent|channel|manager):(.+)$/i.exec(trimmed);
|
|
1489
1536
|
const requestedKind = qualified ? normalizeTopicKind(qualified[1]?.toLowerCase()) : null;
|
|
1490
1537
|
const requestedTitle = qualified ? qualified[2].trim() : trimmed;
|
|
1491
|
-
const rows =
|
|
1538
|
+
const rows = db.query(`SELECT t.* FROM api_topics t
|
|
1492
1539
|
WHERE LOWER(t.title) = LOWER(?)
|
|
1493
1540
|
AND t.id != ?
|
|
1494
1541
|
AND t.visibility != 'hidden'
|
|
@@ -1500,7 +1547,7 @@ function getTopicByNameForUser(title, userId) {
|
|
|
1500
1547
|
}
|
|
1501
1548
|
function setTopicSessionId(topicId, sessionId, context = {}) {
|
|
1502
1549
|
const previous = getTopicSessionId(topicId);
|
|
1503
|
-
const result =
|
|
1550
|
+
const result = db.query("UPDATE api_topics SET session_id = ? WHERE id = ?").run(sessionId, topicId);
|
|
1504
1551
|
const changes = Number(result.changes ?? 0);
|
|
1505
1552
|
const logContext = {
|
|
1506
1553
|
topicId,
|
|
@@ -1520,7 +1567,7 @@ function setTopicSessionId(topicId, sessionId, context = {}) {
|
|
|
1520
1567
|
}
|
|
1521
1568
|
function clearTopicSessionId(topicId, reason = "unspecified") {
|
|
1522
1569
|
const previous = getTopicSessionId(topicId);
|
|
1523
|
-
const result =
|
|
1570
|
+
const result = db.query("UPDATE api_topics SET session_id = NULL WHERE id = ?").run(topicId);
|
|
1524
1571
|
const changes = Number(result.changes ?? 0);
|
|
1525
1572
|
const logContext = { topicId, previousSessionId: shortSessionId(previous), reason };
|
|
1526
1573
|
if (changes === 0) {
|
|
@@ -1532,35 +1579,35 @@ function clearTopicSessionId(topicId, reason = "unspecified") {
|
|
|
1532
1579
|
}
|
|
1533
1580
|
}
|
|
1534
1581
|
function getTopicSessionId(topicId) {
|
|
1535
|
-
const r =
|
|
1582
|
+
const r = db.query("SELECT session_id FROM api_topics WHERE id = ?").get(topicId);
|
|
1536
1583
|
return r?.session_id ?? null;
|
|
1537
1584
|
}
|
|
1538
1585
|
function deleteTopic(id, options = {}) {
|
|
1539
|
-
const r =
|
|
1586
|
+
const r = db.query("SELECT id, kind FROM api_topics WHERE id = ?").get(id);
|
|
1540
1587
|
if (!r)
|
|
1541
1588
|
return false;
|
|
1542
1589
|
if (id === GENERAL_TOPIC_ID || r.kind === "manager" && !options.allowManager)
|
|
1543
1590
|
return false;
|
|
1544
|
-
|
|
1591
|
+
db.query("DELETE FROM api_topics WHERE id = ?").run(id);
|
|
1545
1592
|
return true;
|
|
1546
1593
|
}
|
|
1547
1594
|
function reparentTopicChildren(deletedTopicId, replacementParentTopicId) {
|
|
1548
|
-
const rows =
|
|
1595
|
+
const rows = db.query("SELECT id FROM api_topics WHERE parent_topic_id = ?").all(deletedTopicId);
|
|
1549
1596
|
if (rows.length === 0)
|
|
1550
1597
|
return [];
|
|
1551
|
-
|
|
1598
|
+
db.query("UPDATE api_topics SET parent_topic_id = ? WHERE parent_topic_id = ?").run(replacementParentTopicId, deletedTopicId);
|
|
1552
1599
|
return rows.map((row) => row.id);
|
|
1553
1600
|
}
|
|
1554
1601
|
function addParticipantToDB(topicId, userId, role) {
|
|
1555
|
-
if (!
|
|
1602
|
+
if (!db.query("SELECT 1 FROM api_topics WHERE id = ?").get(topicId))
|
|
1556
1603
|
return false;
|
|
1557
|
-
|
|
1604
|
+
db.query("INSERT OR IGNORE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(topicId, userId, role);
|
|
1558
1605
|
return true;
|
|
1559
1606
|
}
|
|
1560
1607
|
function removeParticipantFromDB(topicId, userId) {
|
|
1561
|
-
if (!
|
|
1608
|
+
if (!db.query("SELECT 1 FROM api_topics WHERE id = ?").get(topicId))
|
|
1562
1609
|
return false;
|
|
1563
|
-
|
|
1610
|
+
db.query("DELETE FROM topic_members WHERE topic_id = ? AND user_id = ?").run(topicId, userId);
|
|
1564
1611
|
return true;
|
|
1565
1612
|
}
|
|
1566
1613
|
// ../../packages/core/src/storage/app-settings.ts
|
|
@@ -1778,7 +1825,7 @@ function errMsg(e, fallback) {
|
|
|
1778
1825
|
|
|
1779
1826
|
// ../../packages/core/src/storage/forum/schema.ts
|
|
1780
1827
|
function initializeForumSchema() {
|
|
1781
|
-
|
|
1828
|
+
db.exec(`
|
|
1782
1829
|
CREATE TABLE IF NOT EXISTS users (
|
|
1783
1830
|
id TEXT PRIMARY KEY,
|
|
1784
1831
|
dm_session_id TEXT,
|
|
@@ -1807,7 +1854,7 @@ function initializeForumSchema() {
|
|
|
1807
1854
|
`);
|
|
1808
1855
|
function tryMigrate(sql, expectedMsg) {
|
|
1809
1856
|
try {
|
|
1810
|
-
|
|
1857
|
+
db.exec(sql);
|
|
1811
1858
|
} catch (e) {
|
|
1812
1859
|
if (expectedMsg && errMsg(e).includes(expectedMsg))
|
|
1813
1860
|
return;
|
|
@@ -1826,10 +1873,10 @@ function initializeForumSchema() {
|
|
|
1826
1873
|
return String(value);
|
|
1827
1874
|
}
|
|
1828
1875
|
function columnExists(table, column) {
|
|
1829
|
-
return
|
|
1876
|
+
return db.query(`PRAGMA table_info(${table})`).all().some((c) => c.name === column);
|
|
1830
1877
|
}
|
|
1831
1878
|
function tableSql(table) {
|
|
1832
|
-
return
|
|
1879
|
+
return db.query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?").get(table)?.sql ?? null;
|
|
1833
1880
|
}
|
|
1834
1881
|
function dropColumnIfExists(table, column) {
|
|
1835
1882
|
if (columnExists(table, column)) {
|
|
@@ -1840,7 +1887,7 @@ function initializeForumSchema() {
|
|
|
1840
1887
|
const sql = tableSql("topics");
|
|
1841
1888
|
if (!sql)
|
|
1842
1889
|
return false;
|
|
1843
|
-
const cols =
|
|
1890
|
+
const cols = db.query("PRAGMA table_info(topics)").all();
|
|
1844
1891
|
const names = new Set(cols.map((c) => c.name));
|
|
1845
1892
|
return names.has("forum_group_id") || names.has("system_prompt_extra") || names.has("model") || names.has("effort") || names.has("model_pinned") || names.has("effort_pinned") || names.has("memory_files") || names.has("memory_summary") || names.has("privacy_mode") || names.has("advisor_enabled") || names.has("agent_settings") || !/PRIMARY KEY \(\s*user_id\s*,\s*name\s*\)/i.test(sql);
|
|
1846
1893
|
}
|
|
@@ -1854,11 +1901,11 @@ function initializeForumSchema() {
|
|
|
1854
1901
|
function rebuildTopicsTableIfNeeded() {
|
|
1855
1902
|
if (!topicTableNeedsRebuild())
|
|
1856
1903
|
return;
|
|
1857
|
-
const cols =
|
|
1904
|
+
const cols = db.query("PRAGMA table_info(topics)").all();
|
|
1858
1905
|
const has = new Set(cols.map((c) => c.name));
|
|
1859
1906
|
const pick = (row, column, fallback = null) => has.has(column) ? row[column] ?? fallback : fallback;
|
|
1860
1907
|
const descriptionFor = (row) => pick(row, "description", pick(row, "system_prompt_extra", null));
|
|
1861
|
-
const rows =
|
|
1908
|
+
const rows = db.query("SELECT rowid AS __rowid, * FROM topics").all().sort((a, b) => {
|
|
1862
1909
|
const aCreated = String(pick(a, "created_at", ""));
|
|
1863
1910
|
const bCreated = String(pick(b, "created_at", ""));
|
|
1864
1911
|
const byDate = bCreated.localeCompare(aCreated);
|
|
@@ -1866,12 +1913,12 @@ function initializeForumSchema() {
|
|
|
1866
1913
|
return byDate;
|
|
1867
1914
|
return Number(b.__rowid ?? 0) - Number(a.__rowid ?? 0);
|
|
1868
1915
|
});
|
|
1869
|
-
const previousForeignKeys =
|
|
1870
|
-
|
|
1916
|
+
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
1917
|
+
db.exec("PRAGMA foreign_keys = OFF");
|
|
1871
1918
|
try {
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1919
|
+
db.transaction(() => {
|
|
1920
|
+
db.exec("DROP TABLE IF EXISTS topics_new");
|
|
1921
|
+
db.exec(`
|
|
1875
1922
|
CREATE TABLE topics_new (
|
|
1876
1923
|
user_id TEXT NOT NULL REFERENCES users(id),
|
|
1877
1924
|
name TEXT NOT NULL,
|
|
@@ -1890,7 +1937,7 @@ function initializeForumSchema() {
|
|
|
1890
1937
|
UNIQUE (user_id, message_thread_id)
|
|
1891
1938
|
)
|
|
1892
1939
|
`);
|
|
1893
|
-
const insert =
|
|
1940
|
+
const insert = db.query(`
|
|
1894
1941
|
INSERT OR IGNORE INTO topics_new
|
|
1895
1942
|
(user_id, name, message_thread_id, session_id, created_at, description,
|
|
1896
1943
|
fork_origin, agent, mcp_enabled, mcp_extra, last_shown_model,
|
|
@@ -1904,13 +1951,13 @@ function initializeForumSchema() {
|
|
|
1904
1951
|
if (Number(result.changes ?? 0) > 0)
|
|
1905
1952
|
inserted += 1;
|
|
1906
1953
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1954
|
+
db.exec("DROP TABLE topics");
|
|
1955
|
+
db.exec("ALTER TABLE topics_new RENAME TO topics");
|
|
1956
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_topics_lookup ON topics(user_id, message_thread_id)");
|
|
1910
1957
|
logger.info({ migrated: inserted, skippedConflicts: rows.length - inserted }, "topics schema migrated to current user-scoped schema");
|
|
1911
1958
|
})();
|
|
1912
1959
|
} finally {
|
|
1913
|
-
|
|
1960
|
+
db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
1914
1961
|
}
|
|
1915
1962
|
}
|
|
1916
1963
|
rebuildTopicsTableIfNeeded();
|
|
@@ -1974,14 +2021,14 @@ function flushSessionCache() {
|
|
|
1974
2021
|
|
|
1975
2022
|
// ../../packages/core/src/storage/forum/agent-settings.ts
|
|
1976
2023
|
function getTopicAgent(userId, topicName) {
|
|
1977
|
-
const row =
|
|
2024
|
+
const row = db.query("SELECT agent FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
1978
2025
|
const value = row?.agent;
|
|
1979
2026
|
if (!isAgentKind(value))
|
|
1980
2027
|
throw new Error(`Invalid agent in DB: ${value}`);
|
|
1981
2028
|
return value;
|
|
1982
2029
|
}
|
|
1983
2030
|
function setTopicAgent(userId, topicName, agent) {
|
|
1984
|
-
const result =
|
|
2031
|
+
const result = db.query("UPDATE topics SET agent = ? WHERE user_id = ? AND name = ?").run(agent, String(userId), topicName);
|
|
1985
2032
|
return result.changes > 0;
|
|
1986
2033
|
}
|
|
1987
2034
|
// ../../packages/core/src/storage/forum/repository.ts
|
|
@@ -1997,10 +2044,10 @@ function defaultSessionAgent() {
|
|
|
1997
2044
|
return "maestro";
|
|
1998
2045
|
}
|
|
1999
2046
|
function getUserConfig(userId) {
|
|
2000
|
-
const user =
|
|
2047
|
+
const user = db.query("SELECT * FROM users WHERE id = ?").get(String(userId));
|
|
2001
2048
|
if (!user)
|
|
2002
2049
|
return null;
|
|
2003
|
-
const topicRows =
|
|
2050
|
+
const topicRows = db.query("SELECT * FROM topics WHERE user_id = ?").all(String(userId));
|
|
2004
2051
|
const topics = {};
|
|
2005
2052
|
for (const row of topicRows)
|
|
2006
2053
|
topics[row.name] = rowToTopic(row);
|
|
@@ -2011,45 +2058,45 @@ function getUserConfig(userId) {
|
|
|
2011
2058
|
};
|
|
2012
2059
|
}
|
|
2013
2060
|
function getTopicByName2(userId, name) {
|
|
2014
|
-
const row =
|
|
2061
|
+
const row = db.query("SELECT * FROM topics WHERE user_id = ? AND name = ?").get(String(userId), name);
|
|
2015
2062
|
return row ? rowToTopic(row) : null;
|
|
2016
2063
|
}
|
|
2017
2064
|
function findUserByThread(threadId) {
|
|
2018
|
-
const row =
|
|
2065
|
+
const row = db.query("SELECT * FROM topics WHERE message_thread_id = ?").get(threadId);
|
|
2019
2066
|
if (!row)
|
|
2020
2067
|
return null;
|
|
2021
2068
|
return { userId: Number(row.user_id), topic: rowToTopic(row) };
|
|
2022
2069
|
}
|
|
2023
2070
|
function getSessionForTopic(userId, topicName) {
|
|
2024
|
-
const row =
|
|
2071
|
+
const row = db.query("SELECT session_id FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
2025
2072
|
return row?.session_id || null;
|
|
2026
2073
|
}
|
|
2027
2074
|
function getTopicNames(userId) {
|
|
2028
|
-
const rows =
|
|
2075
|
+
const rows = db.query("SELECT name FROM topics WHERE user_id = ?").all(String(userId));
|
|
2029
2076
|
return rows.map((r) => r.name);
|
|
2030
2077
|
}
|
|
2031
2078
|
function getAllTopics(userId) {
|
|
2032
|
-
const rows =
|
|
2079
|
+
const rows = db.query("SELECT * FROM topics WHERE user_id = ?").all(String(userId));
|
|
2033
2080
|
return rows.map(rowToTopic);
|
|
2034
2081
|
}
|
|
2035
2082
|
function getAllUserIds() {
|
|
2036
|
-
const rows =
|
|
2083
|
+
const rows = db.query("SELECT id FROM users").all();
|
|
2037
2084
|
return rows.map((r) => Number(r.id)).filter((n) => !Number.isNaN(n));
|
|
2038
2085
|
}
|
|
2039
2086
|
function getCommunicateThreadId(userId) {
|
|
2040
|
-
const row =
|
|
2087
|
+
const row = db.query("SELECT communicate_thread_id FROM users WHERE id = ?").get(String(userId));
|
|
2041
2088
|
return row?.communicate_thread_id ?? null;
|
|
2042
2089
|
}
|
|
2043
2090
|
function getDmSessionId(userId) {
|
|
2044
|
-
const row =
|
|
2091
|
+
const row = db.query("SELECT dm_session_id FROM users WHERE id = ?").get(String(userId));
|
|
2045
2092
|
return row?.dm_session_id ?? null;
|
|
2046
2093
|
}
|
|
2047
2094
|
function getTopicDescription(userId, topicName) {
|
|
2048
|
-
const row =
|
|
2095
|
+
const row = db.query("SELECT description FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
2049
2096
|
return row?.description || null;
|
|
2050
2097
|
}
|
|
2051
2098
|
function getTopicMcpConfig(userId, topicName) {
|
|
2052
|
-
const row =
|
|
2099
|
+
const row = db.query("SELECT mcp_enabled, mcp_extra FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
2053
2100
|
let enabled = null;
|
|
2054
2101
|
let extra = {};
|
|
2055
2102
|
try {
|
|
@@ -2071,8 +2118,8 @@ function addTopic(userId, name, messageThreadId, sessionId, createdAt) {
|
|
|
2071
2118
|
logger.warn({ name }, "addTopic: refusing reserved __ prefix");
|
|
2072
2119
|
return false;
|
|
2073
2120
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2121
|
+
db.query("INSERT OR IGNORE INTO users (id) VALUES (?)").run(String(userId));
|
|
2122
|
+
db.query(`
|
|
2076
2123
|
INSERT INTO topics (user_id, name, message_thread_id, session_id, created_at, agent)
|
|
2077
2124
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
2078
2125
|
ON CONFLICT(user_id, name) DO UPDATE SET
|
|
@@ -2087,59 +2134,59 @@ function renameTopic(userId, oldName, newName) {
|
|
|
2087
2134
|
return { ok: true };
|
|
2088
2135
|
if (getTopicByName2(userId, newName))
|
|
2089
2136
|
return { ok: false, reason: "name_taken" };
|
|
2090
|
-
const result =
|
|
2137
|
+
const result = db.prepare("UPDATE topics SET name = ? WHERE user_id = ? AND name = ?").run(newName, String(userId), oldName);
|
|
2091
2138
|
if (result.changes === 0)
|
|
2092
2139
|
return { ok: false, reason: "not_found" };
|
|
2093
2140
|
return { ok: true };
|
|
2094
2141
|
}
|
|
2095
2142
|
function removeTopic(userId, name) {
|
|
2096
|
-
|
|
2143
|
+
db.query("DELETE FROM topics WHERE user_id = ? AND name = ?").run(String(userId), name);
|
|
2097
2144
|
}
|
|
2098
2145
|
function setSessionForTopic(userId, topicName, sessionId) {
|
|
2099
|
-
|
|
2146
|
+
db.query("UPDATE topics SET session_id = ? WHERE user_id = ? AND name = ?").run(sessionId, String(userId), topicName);
|
|
2100
2147
|
}
|
|
2101
2148
|
function clearSessionForTopic(userId, topicName) {
|
|
2102
|
-
|
|
2149
|
+
db.query("UPDATE topics SET session_id = NULL WHERE user_id = ? AND name = ?").run(String(userId), topicName);
|
|
2103
2150
|
}
|
|
2104
2151
|
function setDmSessionId(userId, sessionId) {
|
|
2105
|
-
|
|
2152
|
+
db.query(`
|
|
2106
2153
|
INSERT INTO users (id, dm_session_id) VALUES (?, ?)
|
|
2107
2154
|
ON CONFLICT(id) DO UPDATE SET dm_session_id = excluded.dm_session_id
|
|
2108
2155
|
`).run(String(userId), sessionId);
|
|
2109
2156
|
}
|
|
2110
2157
|
function clearDmSessionId(userId) {
|
|
2111
|
-
|
|
2158
|
+
db.query("UPDATE users SET dm_session_id = NULL WHERE id = ?").run(String(userId));
|
|
2112
2159
|
}
|
|
2113
2160
|
function setTopicDescription(userId, topicName, description) {
|
|
2114
|
-
const result =
|
|
2161
|
+
const result = db.query("UPDATE topics SET description = ? WHERE user_id = ? AND name = ?").run(description, String(userId), topicName);
|
|
2115
2162
|
return result.changes > 0;
|
|
2116
2163
|
}
|
|
2117
2164
|
function getLastShownConfig(userId, topicName) {
|
|
2118
|
-
const row =
|
|
2165
|
+
const row = db.query("SELECT last_shown_agent, last_shown_model, last_shown_effort FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
2119
2166
|
if (!row)
|
|
2120
2167
|
return null;
|
|
2121
2168
|
const agent = row.last_shown_agent && isAgentKind(row.last_shown_agent) ? row.last_shown_agent : null;
|
|
2122
2169
|
return { agent, model: row.last_shown_model, effort: row.last_shown_effort };
|
|
2123
2170
|
}
|
|
2124
2171
|
function setLastShownConfig(userId, topicName, agent, model, effort) {
|
|
2125
|
-
const result =
|
|
2172
|
+
const result = db.query("UPDATE topics SET last_shown_agent = ?, last_shown_model = ?, last_shown_effort = ? WHERE user_id = ? AND name = ?").run(agent, model, effort ?? null, String(userId), topicName);
|
|
2126
2173
|
return result.changes > 0;
|
|
2127
2174
|
}
|
|
2128
2175
|
function setTopicForkOrigin(userId, topicName, origin) {
|
|
2129
|
-
const result =
|
|
2176
|
+
const result = db.query("UPDATE topics SET fork_origin = ? WHERE user_id = ? AND name = ?").run(origin, String(userId), topicName);
|
|
2130
2177
|
return result.changes > 0;
|
|
2131
2178
|
}
|
|
2132
2179
|
function updateTopicThreadId(userId, topicName, newThreadId) {
|
|
2133
|
-
const result =
|
|
2180
|
+
const result = db.query("UPDATE topics SET message_thread_id = ? WHERE user_id = ? AND name = ?").run(newThreadId, String(userId), topicName);
|
|
2134
2181
|
return result.changes > 0;
|
|
2135
2182
|
}
|
|
2136
2183
|
function setTopicMcpEnabled(userId, topicName, enabled) {
|
|
2137
2184
|
const value = enabled !== null ? JSON.stringify(enabled) : null;
|
|
2138
|
-
const result =
|
|
2185
|
+
const result = db.query("UPDATE topics SET mcp_enabled = ? WHERE user_id = ? AND name = ?").run(value, String(userId), topicName);
|
|
2139
2186
|
return result.changes > 0;
|
|
2140
2187
|
}
|
|
2141
2188
|
function setTopicMcpExtra(userId, topicName, extra) {
|
|
2142
|
-
const result =
|
|
2189
|
+
const result = db.query("UPDATE topics SET mcp_extra = ? WHERE user_id = ? AND name = ?").run(JSON.stringify(extra), String(userId), topicName);
|
|
2143
2190
|
return result.changes > 0;
|
|
2144
2191
|
}
|
|
2145
2192
|
// ../../packages/core/src/storage/session-asks.ts
|
|
@@ -2170,7 +2217,7 @@ import { dirname as dirname5, join as join5 } from "path";
|
|
|
2170
2217
|
var PENDING_ASK_TTL_MS = 15 * 60 * 1000;
|
|
2171
2218
|
function pendingAskDir(userId) {
|
|
2172
2219
|
const rawUserId = String(userId);
|
|
2173
|
-
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) ? rawUserId : `sha256-${createHash("sha256").update(rawUserId).digest("hex")}`;
|
|
2220
|
+
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash("sha256").update(rawUserId).digest("hex")}`;
|
|
2174
2221
|
return join5(resolveStorageSessionAsksDir(), safeUserId);
|
|
2175
2222
|
}
|
|
2176
2223
|
var ASK_FILENAME_PREFIX = "v3-";
|
|
@@ -2231,6 +2278,12 @@ function readPendingAskFile(path, fallback) {
|
|
|
2231
2278
|
const parsed = JSON.parse(raw);
|
|
2232
2279
|
if (!parsed.requestId || !parsed.from || !parsed.to)
|
|
2233
2280
|
return null;
|
|
2281
|
+
if (parsed.userId !== undefined && String(parsed.userId) !== String(fallback.userId))
|
|
2282
|
+
return null;
|
|
2283
|
+
if (fallback.from && parsed.from !== fallback.from)
|
|
2284
|
+
return null;
|
|
2285
|
+
if (fallback.to && parsed.to !== fallback.to)
|
|
2286
|
+
return null;
|
|
2234
2287
|
const now = new Date().toISOString();
|
|
2235
2288
|
return {
|
|
2236
2289
|
userId: fallback.userId,
|
|
@@ -2498,6 +2551,10 @@ function describePendingAskState(state) {
|
|
|
2498
2551
|
return "\uC751\uB2F5\uC744 \uC774 \uC138\uC158\uC5D0 \uC8FC\uC785 \uC911";
|
|
2499
2552
|
}
|
|
2500
2553
|
}
|
|
2554
|
+
// ../../packages/core/src/storage/storage-public-host.ts
|
|
2555
|
+
var configureStorageHost2 = configureStorageHost;
|
|
2556
|
+
var resetStorageHost2 = resetStorageHost;
|
|
2557
|
+
var db2 = storageDatabase;
|
|
2501
2558
|
// ../../packages/core/src/storage/tasks.ts
|
|
2502
2559
|
var exports_tasks = {};
|
|
2503
2560
|
__export(exports_tasks, {
|
|
@@ -2666,7 +2723,7 @@ function emptyBucket() {
|
|
|
2666
2723
|
}
|
|
2667
2724
|
function tokenStatsFileId(userId) {
|
|
2668
2725
|
const rawUserId = String(userId);
|
|
2669
|
-
return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) ? rawUserId : `sha256-${createHash2("sha256").update(rawUserId).digest("hex")}`;
|
|
2726
|
+
return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash2("sha256").update(rawUserId).digest("hex")}`;
|
|
2670
2727
|
}
|
|
2671
2728
|
function queriesPath(userId) {
|
|
2672
2729
|
const fileId = tokenStatsFileId(userId);
|
|
@@ -2900,7 +2957,7 @@ registerStorageSchemaInitializer((database) => {
|
|
|
2900
2957
|
`);
|
|
2901
2958
|
}, 30);
|
|
2902
2959
|
function getTopicArchiveState(topicId) {
|
|
2903
|
-
const row =
|
|
2960
|
+
const row = db.query("SELECT * FROM api_topic_archive_state WHERE topic_id = ?").get(topicId);
|
|
2904
2961
|
if (!row)
|
|
2905
2962
|
return null;
|
|
2906
2963
|
return {
|
|
@@ -2911,7 +2968,7 @@ function getTopicArchiveState(topicId) {
|
|
|
2911
2968
|
};
|
|
2912
2969
|
}
|
|
2913
2970
|
function setTopicArchiveState(topicId, lastArchivedRowid, lastArchivePath) {
|
|
2914
|
-
|
|
2971
|
+
db.query(`INSERT INTO api_topic_archive_state (topic_id, last_archived_rowid, last_archive_path, updated_at)
|
|
2915
2972
|
VALUES (?, ?, ?, ?)
|
|
2916
2973
|
ON CONFLICT(topic_id) DO UPDATE SET
|
|
2917
2974
|
last_archived_rowid = excluded.last_archived_rowid,
|
|
@@ -2919,7 +2976,7 @@ function setTopicArchiveState(topicId, lastArchivedRowid, lastArchivePath) {
|
|
|
2919
2976
|
updated_at = excluded.updated_at`).run(topicId, lastArchivedRowid, lastArchivePath ?? null, new Date().toISOString());
|
|
2920
2977
|
}
|
|
2921
2978
|
function deleteTopicArchiveState(topicId) {
|
|
2922
|
-
return
|
|
2979
|
+
return db.query("DELETE FROM api_topic_archive_state WHERE topic_id = ?").run(topicId).changes > 0;
|
|
2923
2980
|
}
|
|
2924
2981
|
// ../../packages/core/src/storage/topic-settings.ts
|
|
2925
2982
|
var exports_topic_settings = {};
|
|
@@ -2937,13 +2994,13 @@ function toTopicAgentSwitchState(row) {
|
|
|
2937
2994
|
};
|
|
2938
2995
|
}
|
|
2939
2996
|
function getTopicAgentSwitchState(userId, topicName) {
|
|
2940
|
-
const row =
|
|
2997
|
+
const row = db.query("SELECT name, agent FROM topics WHERE user_id = ? AND name = ?").get(String(userId), topicName);
|
|
2941
2998
|
return row ? toTopicAgentSwitchState(row) : null;
|
|
2942
2999
|
}
|
|
2943
3000
|
function setTopicAgentAndSession(opts) {
|
|
2944
3001
|
const { userId, topicName, agent, sessionId } = opts;
|
|
2945
|
-
|
|
2946
|
-
const r =
|
|
3002
|
+
db.transaction(() => {
|
|
3003
|
+
const r = db.query("UPDATE topics SET agent = ?, session_id = ? WHERE user_id = ? AND name = ?").run(agent, sessionId, String(userId), topicName);
|
|
2947
3004
|
if (r.changes === 0) {
|
|
2948
3005
|
throw new Error(`setTopicAgentAndSession: row missing for ${userId}/${topicName}`);
|
|
2949
3006
|
}
|
|
@@ -2952,8 +3009,8 @@ function setTopicAgentAndSession(opts) {
|
|
|
2952
3009
|
function setTopicAgentAndClearSession(opts) {
|
|
2953
3010
|
const { userId, topicName, agent } = opts;
|
|
2954
3011
|
let changed = false;
|
|
2955
|
-
|
|
2956
|
-
const r =
|
|
3012
|
+
db.transaction(() => {
|
|
3013
|
+
const r = db.query("UPDATE topics SET agent = ?, session_id = NULL WHERE user_id = ? AND name = ?").run(agent, String(userId), topicName);
|
|
2957
3014
|
changed = r.changes > 0;
|
|
2958
3015
|
})();
|
|
2959
3016
|
return changed;
|
|
@@ -3039,6 +3096,7 @@ export {
|
|
|
3039
3096
|
exports_session_asks as sessionAsks,
|
|
3040
3097
|
rotateOldLogs,
|
|
3041
3098
|
resolveTopicBrief,
|
|
3099
|
+
resetStorageHost2 as resetStorageHost,
|
|
3042
3100
|
replaceConversationStrict,
|
|
3043
3101
|
reparentTopicChildren,
|
|
3044
3102
|
renderTaskList,
|
|
@@ -3121,12 +3179,12 @@ export {
|
|
|
3121
3179
|
deletePendingAsksForTopic,
|
|
3122
3180
|
deleteMessagesForTopic,
|
|
3123
3181
|
deleteApiTopicConfig,
|
|
3124
|
-
|
|
3182
|
+
db2 as db,
|
|
3125
3183
|
createTasks,
|
|
3126
3184
|
createPendingAsk,
|
|
3127
3185
|
copyMessagesForTopic,
|
|
3128
3186
|
exports_conversations as conversations,
|
|
3129
|
-
configureStorageHost,
|
|
3187
|
+
configureStorageHost2 as configureStorageHost,
|
|
3130
3188
|
cloneConversationLog,
|
|
3131
3189
|
clearTopicSessionId,
|
|
3132
3190
|
clearSessionForTopic,
|
|
@@ -3153,4 +3211,4 @@ export {
|
|
|
3153
3211
|
DEFAULT_AI_NAME
|
|
3154
3212
|
};
|
|
3155
3213
|
|
|
3156
|
-
//# debugId=
|
|
3214
|
+
//# debugId=2E4BC25D01BF122564756E2164756E21
|