@ai-setting/roy-agent-core 1.5.89 → 1.5.90
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/dist/env/agent/index.js +3 -3
- package/dist/env/event-source/index.js +8 -4
- package/dist/env/index.js +9 -9
- package/dist/env/llm/index.js +4 -2
- package/dist/env/session/index.js +3 -3
- package/dist/env/session/storage/index.js +2 -2
- package/dist/env/task/plugins/index.js +1 -1
- package/dist/env/workflow/engine/index.js +2 -2
- package/dist/env/workflow/index.js +3 -3
- package/dist/env/workflow/nodes/index.js +1 -1
- package/dist/index.js +119 -14
- package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-0r4ndyn9.js} +119 -7
- package/dist/shared/@ai-setting/{roy-agent-core-fvfc7f6v.js → roy-agent-core-2c8eraxq.js} +62 -8
- package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-5ykms33a.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-fgpnv7dt.js → roy-agent-core-8zjntsbb.js} +71 -28
- package/dist/shared/@ai-setting/{roy-agent-core-vneyghpg.js → roy-agent-core-ddq5hcp5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qhhxx2x2.js → roy-agent-core-ds5f75pg.js} +2 -1
- package/dist/shared/@ai-setting/{roy-agent-core-3f6k060j.js → roy-agent-core-j0107ww1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-2q7cshpm.js → roy-agent-core-m683wd1n.js} +283 -15
- package/dist/shared/@ai-setting/{roy-agent-core-qbq3jgrn.js → roy-agent-core-rkz8r2sx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-txwf64pd.js} +70 -0
- package/dist/shared/@ai-setting/{roy-agent-core-m3dkyprg.js → roy-agent-core-w0kb72ve.js} +7 -2
- package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-z240ts1r.js} +27 -3
- package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-zky9jse4.js} +163 -3
- package/package.json +1 -1
- /package/dist/shared/@ai-setting/{roy-agent-core-4f3976cd.js → roy-agent-core-k5hxvaf0.js} +0 -0
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SessionMessageConverter
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-txwf64pd.js";
|
|
4
|
+
import {
|
|
5
|
+
createLogger,
|
|
6
|
+
init_logger
|
|
7
|
+
} from "./roy-agent-core-shme7set.js";
|
|
4
8
|
import {
|
|
5
9
|
__require
|
|
6
10
|
} from "./roy-agent-core-fs0mn2jk.js";
|
|
7
11
|
|
|
12
|
+
// src/env/session/session-store.ts
|
|
13
|
+
class BaseSessionStore {
|
|
14
|
+
async addMessages(sessionId, messages) {
|
|
15
|
+
if (messages.length === 0)
|
|
16
|
+
return [];
|
|
17
|
+
const ids = [];
|
|
18
|
+
for (const msg of messages) {
|
|
19
|
+
ids.push(await this.addMessage(sessionId, msg));
|
|
20
|
+
}
|
|
21
|
+
return ids;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
// src/env/session/storage/memory.ts
|
|
9
26
|
import { randomUUID } from "crypto";
|
|
10
27
|
function generateSessionId() {
|
|
@@ -14,7 +31,7 @@ function generateMessageId() {
|
|
|
14
31
|
return `msg_${randomUUID()}`;
|
|
15
32
|
}
|
|
16
33
|
|
|
17
|
-
class MemorySessionStore {
|
|
34
|
+
class MemorySessionStore extends BaseSessionStore {
|
|
18
35
|
sessions = new Map;
|
|
19
36
|
messages = new Map;
|
|
20
37
|
checkpoints = new Map;
|
|
@@ -138,6 +155,40 @@ class MemorySessionStore {
|
|
|
138
155
|
session.updatedAt = Date.now();
|
|
139
156
|
return msg.id;
|
|
140
157
|
}
|
|
158
|
+
async addMessages(sessionId, messages) {
|
|
159
|
+
if (messages.length === 0) {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
const session = this.sessions.get(sessionId);
|
|
163
|
+
if (!session) {
|
|
164
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
165
|
+
}
|
|
166
|
+
const sessionMessages = this.messages.get(sessionId) ?? [];
|
|
167
|
+
const ids = [];
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
for (const message of messages) {
|
|
170
|
+
const rawMessage = {
|
|
171
|
+
sessionID: sessionId,
|
|
172
|
+
role: message.role,
|
|
173
|
+
content: message.content,
|
|
174
|
+
parts: message.parts,
|
|
175
|
+
metadata: message.metadata
|
|
176
|
+
};
|
|
177
|
+
const msg = this.messageConverter.migrateMessage(rawMessage);
|
|
178
|
+
msg.id = generateMessageId();
|
|
179
|
+
msg.timestamp = now;
|
|
180
|
+
sessionMessages.push(msg);
|
|
181
|
+
ids.push(msg.id);
|
|
182
|
+
}
|
|
183
|
+
this.messages.set(sessionId, sessionMessages);
|
|
184
|
+
session.messageCount = sessionMessages.filter((m) => !m.isArchived).length;
|
|
185
|
+
session.metadata = {
|
|
186
|
+
...session.metadata,
|
|
187
|
+
messageCount: session.messageCount
|
|
188
|
+
};
|
|
189
|
+
session.updatedAt = now;
|
|
190
|
+
return ids;
|
|
191
|
+
}
|
|
141
192
|
async updateMessage(sessionId, messageId, updates) {
|
|
142
193
|
const sessionMessages = this.messages.get(sessionId);
|
|
143
194
|
if (!sessionMessages) {
|
|
@@ -371,6 +422,8 @@ class MemorySessionStore {
|
|
|
371
422
|
// src/env/session/storage/sqlite.ts
|
|
372
423
|
import { join } from "path";
|
|
373
424
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
425
|
+
init_logger();
|
|
426
|
+
var logger = createLogger("session:storage:sqlite");
|
|
374
427
|
function getDatabaseClass() {
|
|
375
428
|
if (typeof Bun !== "undefined") {
|
|
376
429
|
const { Database } = __require("bun:sqlite");
|
|
@@ -379,6 +432,17 @@ function getDatabaseClass() {
|
|
|
379
432
|
return __require("better-sqlite3");
|
|
380
433
|
}
|
|
381
434
|
}
|
|
435
|
+
function isSqliteBusyError(err) {
|
|
436
|
+
if (err == null)
|
|
437
|
+
return false;
|
|
438
|
+
const e = err;
|
|
439
|
+
if (typeof e.code === "string" && /^SQLITE_(BUSY|LOCKED)$/i.test(e.code))
|
|
440
|
+
return true;
|
|
441
|
+
if (typeof e.errno === "number" && (e.errno === 5 || e.errno === 6))
|
|
442
|
+
return true;
|
|
443
|
+
const msg = e.message ?? "";
|
|
444
|
+
return /SQLiteError:\s+(database is locked|database table is locked)/i.test(msg);
|
|
445
|
+
}
|
|
382
446
|
function createCompatibleDatabase(path) {
|
|
383
447
|
const Database = getDatabaseClass();
|
|
384
448
|
const db = new Database(path);
|
|
@@ -407,7 +471,7 @@ function getDefaultSessionDbPath() {
|
|
|
407
471
|
return join(getDefaultDataDir(), "roy-agent", "sessions.db");
|
|
408
472
|
}
|
|
409
473
|
|
|
410
|
-
class SQLiteSessionStore {
|
|
474
|
+
class SQLiteSessionStore extends BaseSessionStore {
|
|
411
475
|
db = null;
|
|
412
476
|
dbPath;
|
|
413
477
|
initialized = false;
|
|
@@ -416,6 +480,7 @@ class SQLiteSessionStore {
|
|
|
416
480
|
checkpointsCache = new Map;
|
|
417
481
|
messageConverter = new SessionMessageConverter;
|
|
418
482
|
constructor(dbPath) {
|
|
483
|
+
super();
|
|
419
484
|
this.dbPath = dbPath || getDefaultSessionDbPath();
|
|
420
485
|
}
|
|
421
486
|
async initialize() {
|
|
@@ -430,6 +495,10 @@ class SQLiteSessionStore {
|
|
|
430
495
|
}
|
|
431
496
|
}
|
|
432
497
|
this.db = createCompatibleDatabase(this.dbPath);
|
|
498
|
+
this.applyPragma("PRAGMA journal_mode = WAL");
|
|
499
|
+
this.applyPragma("PRAGMA busy_timeout = 5000");
|
|
500
|
+
this.applyPragma("PRAGMA synchronous = NORMAL");
|
|
501
|
+
this.applyPragma("PRAGMA wal_autocheckpoint = 1000");
|
|
433
502
|
this.db.run(`
|
|
434
503
|
CREATE TABLE IF NOT EXISTS session (
|
|
435
504
|
id TEXT PRIMARY KEY,
|
|
@@ -611,6 +680,90 @@ class SQLiteSessionStore {
|
|
|
611
680
|
this.sessionsCache.set(sessionId, session);
|
|
612
681
|
return msg.id;
|
|
613
682
|
}
|
|
683
|
+
async addMessages(sessionId, messages) {
|
|
684
|
+
if (messages.length === 0) {
|
|
685
|
+
return [];
|
|
686
|
+
}
|
|
687
|
+
const BATCH_BACKOFFS_MS = [50, 100, 200];
|
|
688
|
+
let lastError = undefined;
|
|
689
|
+
for (let attempt = 0;attempt <= BATCH_BACKOFFS_MS.length; attempt++) {
|
|
690
|
+
try {
|
|
691
|
+
return await this.addMessagesOnce(sessionId, messages);
|
|
692
|
+
} catch (err) {
|
|
693
|
+
if (!isSqliteBusyError(err) || attempt === BATCH_BACKOFFS_MS.length) {
|
|
694
|
+
this.messagesCache.delete(sessionId);
|
|
695
|
+
this.sessionsCache.delete(sessionId);
|
|
696
|
+
lastError = err;
|
|
697
|
+
if (!isSqliteBusyError(err))
|
|
698
|
+
throw err;
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
await new Promise((resolve) => setTimeout(resolve, BATCH_BACKOFFS_MS[attempt]));
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
throw lastError;
|
|
705
|
+
}
|
|
706
|
+
async addMessagesOnce(sessionId, messages) {
|
|
707
|
+
await this.initialize();
|
|
708
|
+
const session = await this.get(sessionId);
|
|
709
|
+
if (!session) {
|
|
710
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
711
|
+
}
|
|
712
|
+
const now = Date.now();
|
|
713
|
+
const ids = [];
|
|
714
|
+
const insertStmt = this.db.prepare(`
|
|
715
|
+
INSERT INTO message (id, session_id, role, content, timestamp, parts, metadata)
|
|
716
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
717
|
+
`);
|
|
718
|
+
const sessionUpdateStmt = this.db.prepare(`
|
|
719
|
+
UPDATE session SET message_count = ?, metadata = ?, updated_at = ? WHERE id = ?
|
|
720
|
+
`);
|
|
721
|
+
this.db.run("BEGIN");
|
|
722
|
+
try {
|
|
723
|
+
for (const message of messages) {
|
|
724
|
+
const id = generateMessageId2();
|
|
725
|
+
ids.push(id);
|
|
726
|
+
insertStmt.run(id, sessionId, message.role, message.content, now, message.parts ? JSON.stringify(message.parts) : null, message.metadata ? JSON.stringify(message.metadata) : null);
|
|
727
|
+
}
|
|
728
|
+
const countResult = this.db.prepare("SELECT COUNT(*) as count FROM message WHERE session_id = ? AND is_archived = 0").get(sessionId);
|
|
729
|
+
const newCount = countResult?.count ?? 0;
|
|
730
|
+
session.messageCount = newCount;
|
|
731
|
+
session.updatedAt = now;
|
|
732
|
+
session.metadata = {
|
|
733
|
+
...session.metadata ?? {},
|
|
734
|
+
messageCount: newCount
|
|
735
|
+
};
|
|
736
|
+
sessionUpdateStmt.run(newCount, JSON.stringify(session.metadata), now, sessionId);
|
|
737
|
+
this.db.run("COMMIT");
|
|
738
|
+
} catch (err) {
|
|
739
|
+
try {
|
|
740
|
+
this.db.run("ROLLBACK");
|
|
741
|
+
} catch {}
|
|
742
|
+
throw err;
|
|
743
|
+
}
|
|
744
|
+
try {
|
|
745
|
+
const cached = this.messagesCache.get(sessionId) ?? [];
|
|
746
|
+
for (let i = 0;i < messages.length; i++) {
|
|
747
|
+
const message = messages[i];
|
|
748
|
+
cached.push({
|
|
749
|
+
id: ids[i],
|
|
750
|
+
sessionID: sessionId,
|
|
751
|
+
role: message.role,
|
|
752
|
+
content: message.content,
|
|
753
|
+
timestamp: now,
|
|
754
|
+
parts: message.parts,
|
|
755
|
+
metadata: message.metadata
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
this.messagesCache.set(sessionId, cached);
|
|
759
|
+
this.sessionsCache.set(sessionId, session);
|
|
760
|
+
} catch (cacheErr) {
|
|
761
|
+
logger.warn(`[SQLiteSessionStore] cache update failed after commit; invalidating: ${cacheErr}`);
|
|
762
|
+
this.messagesCache.delete(sessionId);
|
|
763
|
+
this.sessionsCache.delete(sessionId);
|
|
764
|
+
}
|
|
765
|
+
return ids;
|
|
766
|
+
}
|
|
614
767
|
async updateMessage(sessionId, messageId, updates) {
|
|
615
768
|
await this.initialize();
|
|
616
769
|
const row = this.db.prepare("SELECT id FROM message WHERE id = ? AND session_id = ?").get(messageId, sessionId);
|
|
@@ -679,6 +832,13 @@ class SQLiteSessionStore {
|
|
|
679
832
|
const rows = this.db.prepare(sql).all(...params);
|
|
680
833
|
return rows.map((row) => this.rowToMessage(row));
|
|
681
834
|
}
|
|
835
|
+
applyPragma(pragmaSql) {
|
|
836
|
+
this.db.run(pragmaSql);
|
|
837
|
+
const readback = this.db.prepare(pragmaSql.split("=")[0].trim()).get();
|
|
838
|
+
const key = Object.keys(readback ?? {})[0];
|
|
839
|
+
const actual = key ? readback[key] : undefined;
|
|
840
|
+
logger.info(`[SQLiteSessionStore] Applied ${pragmaSql} → ${actual}`);
|
|
841
|
+
}
|
|
682
842
|
async getMessageCount(sessionId, includeArchived = false) {
|
|
683
843
|
await this.initialize();
|
|
684
844
|
let sql = "SELECT COUNT(*) as count FROM message WHERE session_id = ?";
|
package/package.json
CHANGED
|
File without changes
|