@voltagent/libsql 1.0.9 → 1.0.11
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/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +199 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +199 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -79,6 +79,7 @@ var LibSQLMemoryAdapter = class {
|
|
|
79
79
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
80
80
|
const usersTable = `${this.tablePrefix}_users`;
|
|
81
81
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
82
|
+
const stepsTable = `${this.tablePrefix}_steps`;
|
|
82
83
|
const isMemoryDb = this.url === ":memory:" || this.url.includes("mode=memory");
|
|
83
84
|
if (!isMemoryDb && (this.url.startsWith("file:") || this.url.startsWith("libsql:"))) {
|
|
84
85
|
try {
|
|
@@ -139,11 +140,34 @@ var LibSQLMemoryAdapter = class {
|
|
|
139
140
|
workflow_name TEXT NOT NULL,
|
|
140
141
|
status TEXT NOT NULL,
|
|
141
142
|
suspension TEXT,
|
|
143
|
+
events TEXT,
|
|
144
|
+
output TEXT,
|
|
145
|
+
cancellation TEXT,
|
|
142
146
|
user_id TEXT,
|
|
143
147
|
conversation_id TEXT,
|
|
144
148
|
metadata TEXT,
|
|
145
149
|
created_at TEXT NOT NULL,
|
|
146
150
|
updated_at TEXT NOT NULL
|
|
151
|
+
)`,
|
|
152
|
+
// Create conversation steps table
|
|
153
|
+
`CREATE TABLE IF NOT EXISTS ${stepsTable} (
|
|
154
|
+
id TEXT PRIMARY KEY,
|
|
155
|
+
conversation_id TEXT NOT NULL,
|
|
156
|
+
user_id TEXT NOT NULL,
|
|
157
|
+
agent_id TEXT NOT NULL,
|
|
158
|
+
agent_name TEXT,
|
|
159
|
+
operation_id TEXT,
|
|
160
|
+
step_index INTEGER NOT NULL,
|
|
161
|
+
type TEXT NOT NULL,
|
|
162
|
+
role TEXT NOT NULL,
|
|
163
|
+
content TEXT,
|
|
164
|
+
arguments TEXT,
|
|
165
|
+
result TEXT,
|
|
166
|
+
usage TEXT,
|
|
167
|
+
sub_agent_id TEXT,
|
|
168
|
+
sub_agent_name TEXT,
|
|
169
|
+
created_at TEXT NOT NULL,
|
|
170
|
+
FOREIGN KEY (conversation_id) REFERENCES ${conversationsTable}(id) ON DELETE CASCADE
|
|
147
171
|
)`,
|
|
148
172
|
// Create indexes for better performance
|
|
149
173
|
`CREATE INDEX IF NOT EXISTS idx_${conversationsTable}_user_id ON ${conversationsTable}(user_id)`,
|
|
@@ -151,11 +175,14 @@ var LibSQLMemoryAdapter = class {
|
|
|
151
175
|
`CREATE INDEX IF NOT EXISTS idx_${messagesTable}_conversation_id ON ${messagesTable}(conversation_id)`,
|
|
152
176
|
`CREATE INDEX IF NOT EXISTS idx_${messagesTable}_created_at ON ${messagesTable}(created_at)`,
|
|
153
177
|
`CREATE INDEX IF NOT EXISTS idx_${workflowStatesTable}_workflow_id ON ${workflowStatesTable}(workflow_id)`,
|
|
154
|
-
`CREATE INDEX IF NOT EXISTS idx_${workflowStatesTable}_status ON ${workflowStatesTable}(status)
|
|
178
|
+
`CREATE INDEX IF NOT EXISTS idx_${workflowStatesTable}_status ON ${workflowStatesTable}(status)`,
|
|
179
|
+
`CREATE INDEX IF NOT EXISTS idx_${stepsTable}_conversation ON ${stepsTable}(conversation_id, step_index)`,
|
|
180
|
+
`CREATE INDEX IF NOT EXISTS idx_${stepsTable}_operation ON ${stepsTable}(conversation_id, operation_id)`
|
|
155
181
|
]);
|
|
156
182
|
}, "initialize database schema");
|
|
157
183
|
await this.addV2ColumnsToMessagesTable();
|
|
158
184
|
await this.migrateDefaultUserIds();
|
|
185
|
+
await this.addWorkflowStateColumns();
|
|
159
186
|
this.initialized = true;
|
|
160
187
|
this.logger.debug("Database schema initialized");
|
|
161
188
|
}
|
|
@@ -287,6 +314,42 @@ var LibSQLMemoryAdapter = class {
|
|
|
287
314
|
this.logger.error("Failed to migrate default user_ids", error);
|
|
288
315
|
}
|
|
289
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Add new columns to workflow_states table for event persistence
|
|
319
|
+
* This migration adds support for events, output, and cancellation tracking
|
|
320
|
+
*/
|
|
321
|
+
async addWorkflowStateColumns() {
|
|
322
|
+
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
323
|
+
try {
|
|
324
|
+
const tableInfo = await this.client.execute(`PRAGMA table_info(${workflowStatesTable})`);
|
|
325
|
+
const columns = tableInfo.rows.map((row) => row.name);
|
|
326
|
+
if (!columns.includes("events")) {
|
|
327
|
+
try {
|
|
328
|
+
await this.client.execute(`ALTER TABLE ${workflowStatesTable} ADD COLUMN events TEXT`);
|
|
329
|
+
this.logger.debug("Added 'events' column to workflow_states table");
|
|
330
|
+
} catch (_e) {
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (!columns.includes("output")) {
|
|
334
|
+
try {
|
|
335
|
+
await this.client.execute(`ALTER TABLE ${workflowStatesTable} ADD COLUMN output TEXT`);
|
|
336
|
+
this.logger.debug("Added 'output' column to workflow_states table");
|
|
337
|
+
} catch (_e) {
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (!columns.includes("cancellation")) {
|
|
341
|
+
try {
|
|
342
|
+
await this.client.execute(
|
|
343
|
+
`ALTER TABLE ${workflowStatesTable} ADD COLUMN cancellation TEXT`
|
|
344
|
+
);
|
|
345
|
+
this.logger.debug("Added 'cancellation' column to workflow_states table");
|
|
346
|
+
} catch (_e) {
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
this.logger.warn("Failed to add workflow state columns (non-critical)", error);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
290
353
|
// ============================================================================
|
|
291
354
|
// Message Operations
|
|
292
355
|
// ============================================================================
|
|
@@ -349,6 +412,72 @@ var LibSQLMemoryAdapter = class {
|
|
|
349
412
|
);
|
|
350
413
|
}, "add batch messages");
|
|
351
414
|
}
|
|
415
|
+
async saveConversationSteps(steps) {
|
|
416
|
+
if (steps.length === 0) return;
|
|
417
|
+
await this.initialize();
|
|
418
|
+
const stepsTable = `${this.tablePrefix}_steps`;
|
|
419
|
+
await this.executeWithRetry(async () => {
|
|
420
|
+
await this.client.batch(
|
|
421
|
+
steps.map((step) => {
|
|
422
|
+
const createdAt = step.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
423
|
+
return {
|
|
424
|
+
sql: `INSERT INTO ${stepsTable} (
|
|
425
|
+
id,
|
|
426
|
+
conversation_id,
|
|
427
|
+
user_id,
|
|
428
|
+
agent_id,
|
|
429
|
+
agent_name,
|
|
430
|
+
operation_id,
|
|
431
|
+
step_index,
|
|
432
|
+
type,
|
|
433
|
+
role,
|
|
434
|
+
content,
|
|
435
|
+
arguments,
|
|
436
|
+
result,
|
|
437
|
+
usage,
|
|
438
|
+
sub_agent_id,
|
|
439
|
+
sub_agent_name,
|
|
440
|
+
created_at
|
|
441
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
442
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
443
|
+
conversation_id = excluded.conversation_id,
|
|
444
|
+
user_id = excluded.user_id,
|
|
445
|
+
agent_id = excluded.agent_id,
|
|
446
|
+
agent_name = excluded.agent_name,
|
|
447
|
+
operation_id = excluded.operation_id,
|
|
448
|
+
step_index = excluded.step_index,
|
|
449
|
+
type = excluded.type,
|
|
450
|
+
role = excluded.role,
|
|
451
|
+
content = excluded.content,
|
|
452
|
+
arguments = excluded.arguments,
|
|
453
|
+
result = excluded.result,
|
|
454
|
+
usage = excluded.usage,
|
|
455
|
+
sub_agent_id = excluded.sub_agent_id,
|
|
456
|
+
sub_agent_name = excluded.sub_agent_name,
|
|
457
|
+
created_at = excluded.created_at`,
|
|
458
|
+
args: [
|
|
459
|
+
step.id,
|
|
460
|
+
step.conversationId,
|
|
461
|
+
step.userId,
|
|
462
|
+
step.agentId,
|
|
463
|
+
step.agentName ?? null,
|
|
464
|
+
step.operationId ?? null,
|
|
465
|
+
step.stepIndex,
|
|
466
|
+
step.type,
|
|
467
|
+
step.role,
|
|
468
|
+
step.content ?? null,
|
|
469
|
+
step.arguments ? safeStringify(step.arguments) : null,
|
|
470
|
+
step.result ? safeStringify(step.result) : null,
|
|
471
|
+
step.usage ? safeStringify(step.usage) : null,
|
|
472
|
+
step.subAgentId ?? null,
|
|
473
|
+
step.subAgentName ?? null,
|
|
474
|
+
createdAt
|
|
475
|
+
]
|
|
476
|
+
};
|
|
477
|
+
})
|
|
478
|
+
);
|
|
479
|
+
}, "save conversation steps");
|
|
480
|
+
}
|
|
352
481
|
/**
|
|
353
482
|
* Get messages with optional filtering
|
|
354
483
|
*/
|
|
@@ -410,6 +539,51 @@ var LibSQLMemoryAdapter = class {
|
|
|
410
539
|
};
|
|
411
540
|
});
|
|
412
541
|
}
|
|
542
|
+
async getConversationSteps(userId, conversationId, options) {
|
|
543
|
+
await this.initialize();
|
|
544
|
+
const stepsTable = `${this.tablePrefix}_steps`;
|
|
545
|
+
const limit = options?.limit && options.limit > 0 ? options.limit : void 0;
|
|
546
|
+
let sql = `SELECT * FROM ${stepsTable} WHERE conversation_id = ? AND user_id = ?`;
|
|
547
|
+
const args = [conversationId, userId];
|
|
548
|
+
if (options?.operationId) {
|
|
549
|
+
sql += " AND operation_id = ?";
|
|
550
|
+
args.push(options.operationId);
|
|
551
|
+
}
|
|
552
|
+
sql += " ORDER BY step_index ASC";
|
|
553
|
+
if (limit !== void 0) {
|
|
554
|
+
sql += " LIMIT ?";
|
|
555
|
+
args.push(limit);
|
|
556
|
+
}
|
|
557
|
+
const result = await this.client.execute({ sql, args });
|
|
558
|
+
const parseJsonField = /* @__PURE__ */ __name((value) => {
|
|
559
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
560
|
+
return void 0;
|
|
561
|
+
}
|
|
562
|
+
try {
|
|
563
|
+
return JSON.parse(value);
|
|
564
|
+
} catch {
|
|
565
|
+
return void 0;
|
|
566
|
+
}
|
|
567
|
+
}, "parseJsonField");
|
|
568
|
+
return result.rows.map((row) => ({
|
|
569
|
+
id: row.id,
|
|
570
|
+
conversationId: row.conversation_id,
|
|
571
|
+
userId: row.user_id,
|
|
572
|
+
agentId: row.agent_id,
|
|
573
|
+
agentName: row.agent_name ?? void 0,
|
|
574
|
+
operationId: row.operation_id ?? void 0,
|
|
575
|
+
stepIndex: typeof row.step_index === "number" ? row.step_index : Number(row.step_index ?? 0),
|
|
576
|
+
type: row.type,
|
|
577
|
+
role: row.role,
|
|
578
|
+
content: row.content ?? void 0,
|
|
579
|
+
arguments: parseJsonField(row.arguments),
|
|
580
|
+
result: parseJsonField(row.result),
|
|
581
|
+
usage: parseJsonField(row.usage),
|
|
582
|
+
subAgentId: row.sub_agent_id ?? void 0,
|
|
583
|
+
subAgentName: row.sub_agent_name ?? void 0,
|
|
584
|
+
createdAt: row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
413
587
|
/**
|
|
414
588
|
* Clear messages for a user
|
|
415
589
|
*/
|
|
@@ -417,11 +591,16 @@ var LibSQLMemoryAdapter = class {
|
|
|
417
591
|
await this.initialize();
|
|
418
592
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
419
593
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
594
|
+
const stepsTable = `${this.tablePrefix}_steps`;
|
|
420
595
|
if (conversationId) {
|
|
421
596
|
await this.client.execute({
|
|
422
597
|
sql: `DELETE FROM ${messagesTable} WHERE conversation_id = ? AND user_id = ?`,
|
|
423
598
|
args: [conversationId, userId]
|
|
424
599
|
});
|
|
600
|
+
await this.client.execute({
|
|
601
|
+
sql: `DELETE FROM ${stepsTable} WHERE conversation_id = ? AND user_id = ?`,
|
|
602
|
+
args: [conversationId, userId]
|
|
603
|
+
});
|
|
425
604
|
} else {
|
|
426
605
|
await this.client.execute({
|
|
427
606
|
sql: `DELETE FROM ${messagesTable}
|
|
@@ -430,6 +609,13 @@ var LibSQLMemoryAdapter = class {
|
|
|
430
609
|
)`,
|
|
431
610
|
args: [userId]
|
|
432
611
|
});
|
|
612
|
+
await this.client.execute({
|
|
613
|
+
sql: `DELETE FROM ${stepsTable}
|
|
614
|
+
WHERE conversation_id IN (
|
|
615
|
+
SELECT id FROM ${conversationsTable} WHERE user_id = ?
|
|
616
|
+
)`,
|
|
617
|
+
args: [userId]
|
|
618
|
+
});
|
|
433
619
|
}
|
|
434
620
|
}
|
|
435
621
|
// ============================================================================
|
|
@@ -721,6 +907,9 @@ var LibSQLMemoryAdapter = class {
|
|
|
721
907
|
workflowName: row.workflow_name,
|
|
722
908
|
status: row.status,
|
|
723
909
|
suspension: row.suspension ? JSON.parse(row.suspension) : void 0,
|
|
910
|
+
events: row.events ? JSON.parse(row.events) : void 0,
|
|
911
|
+
output: row.output ? JSON.parse(row.output) : void 0,
|
|
912
|
+
cancellation: row.cancellation ? JSON.parse(row.cancellation) : void 0,
|
|
724
913
|
userId: row.user_id,
|
|
725
914
|
conversationId: row.conversation_id,
|
|
726
915
|
metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
|
|
@@ -735,15 +924,18 @@ var LibSQLMemoryAdapter = class {
|
|
|
735
924
|
await this.initialize();
|
|
736
925
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
737
926
|
await this.client.execute({
|
|
738
|
-
sql: `INSERT OR REPLACE INTO ${workflowStatesTable}
|
|
739
|
-
(id, workflow_id, workflow_name, status, suspension, user_id, conversation_id, metadata, created_at, updated_at)
|
|
740
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
927
|
+
sql: `INSERT OR REPLACE INTO ${workflowStatesTable}
|
|
928
|
+
(id, workflow_id, workflow_name, status, suspension, events, output, cancellation, user_id, conversation_id, metadata, created_at, updated_at)
|
|
929
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
741
930
|
args: [
|
|
742
931
|
executionId,
|
|
743
932
|
state.workflowId,
|
|
744
933
|
state.workflowName,
|
|
745
934
|
state.status,
|
|
746
935
|
state.suspension ? safeStringify(state.suspension) : null,
|
|
936
|
+
state.events ? safeStringify(state.events) : null,
|
|
937
|
+
state.output ? safeStringify(state.output) : null,
|
|
938
|
+
state.cancellation ? safeStringify(state.cancellation) : null,
|
|
747
939
|
state.userId || null,
|
|
748
940
|
state.conversationId || null,
|
|
749
941
|
state.metadata ? safeStringify(state.metadata) : null,
|
|
@@ -784,6 +976,9 @@ var LibSQLMemoryAdapter = class {
|
|
|
784
976
|
workflowName: row.workflow_name,
|
|
785
977
|
status: "suspended",
|
|
786
978
|
suspension: row.suspension ? JSON.parse(row.suspension) : void 0,
|
|
979
|
+
events: row.events ? JSON.parse(row.events) : void 0,
|
|
980
|
+
output: row.output ? JSON.parse(row.output) : void 0,
|
|
981
|
+
cancellation: row.cancellation ? JSON.parse(row.cancellation) : void 0,
|
|
787
982
|
userId: row.user_id,
|
|
788
983
|
conversationId: row.conversation_id,
|
|
789
984
|
metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
|