@voltagent/libsql 1.0.14 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/edge.d.mts +111 -0
- package/dist/edge.d.ts +111 -0
- package/dist/edge.js +2195 -0
- package/dist/edge.js.map +1 -0
- package/dist/edge.mjs +2167 -0
- package/dist/edge.mjs.map +1 -0
- package/dist/index.d.mts +24 -391
- package/dist/index.d.ts +24 -391
- package/dist/index.js +223 -342
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +222 -345
- package/dist/index.mjs.map +1 -1
- package/dist/vector-core-CKn8FNVK.d.mts +274 -0
- package/dist/vector-core-CKn8FNVK.d.ts +274 -0
- package/package.json +23 -8
package/dist/index.mjs
CHANGED
|
@@ -5,16 +5,15 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { createClient } from "@libsql/client";
|
|
8
|
-
import {
|
|
9
|
-
AgentRegistry,
|
|
10
|
-
ConversationAlreadyExistsError,
|
|
11
|
-
ConversationNotFoundError
|
|
12
|
-
} from "@voltagent/core";
|
|
13
|
-
import { safeStringify } from "@voltagent/internal";
|
|
8
|
+
import { AgentRegistry } from "@voltagent/core";
|
|
14
9
|
import { createPinoLogger } from "@voltagent/logger";
|
|
15
|
-
|
|
10
|
+
|
|
11
|
+
// src/memory-core.ts
|
|
12
|
+
import { ConversationAlreadyExistsError, ConversationNotFoundError } from "@voltagent/core";
|
|
13
|
+
import { safeStringify } from "@voltagent/internal";
|
|
14
|
+
var LibSQLMemoryCore = class {
|
|
16
15
|
static {
|
|
17
|
-
__name(this, "
|
|
16
|
+
__name(this, "LibSQLMemoryCore");
|
|
18
17
|
}
|
|
19
18
|
client;
|
|
20
19
|
tablePrefix;
|
|
@@ -23,25 +22,14 @@ var LibSQLMemoryAdapter = class {
|
|
|
23
22
|
maxRetries;
|
|
24
23
|
retryDelayMs;
|
|
25
24
|
url;
|
|
26
|
-
constructor(options
|
|
25
|
+
constructor(client, url, options, logger) {
|
|
26
|
+
this.client = client;
|
|
27
|
+
this.url = url;
|
|
27
28
|
this.tablePrefix = options.tablePrefix ?? "voltagent_memory";
|
|
28
29
|
this.maxRetries = options.maxRetries ?? 3;
|
|
29
30
|
this.retryDelayMs = options.retryDelayMs ?? 100;
|
|
30
|
-
this.logger =
|
|
31
|
-
this.
|
|
32
|
-
if (this.url.startsWith("file:")) {
|
|
33
|
-
const dbPath = this.url.replace("file:", "");
|
|
34
|
-
const dbDir = path.dirname(dbPath);
|
|
35
|
-
if (dbDir && dbDir !== "." && !fs.existsSync(dbDir)) {
|
|
36
|
-
fs.mkdirSync(dbDir, { recursive: true });
|
|
37
|
-
this.logger.debug(`Created database directory: ${dbDir}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
this.client = createClient({
|
|
41
|
-
url: this.url,
|
|
42
|
-
authToken: options.authToken
|
|
43
|
-
});
|
|
44
|
-
this.logger.debug("LibSQL Memory adapter initialized", { url: this.url });
|
|
31
|
+
this.logger = logger;
|
|
32
|
+
this.logger.debug("LibSQL Memory adapter core initialized", { url: this.url });
|
|
45
33
|
}
|
|
46
34
|
/**
|
|
47
35
|
* Execute a database operation with retry logic
|
|
@@ -104,14 +92,12 @@ var LibSQLMemoryAdapter = class {
|
|
|
104
92
|
this.logger.debug("Applied PRAGMA settings for better concurrency");
|
|
105
93
|
await this.executeWithRetry(async () => {
|
|
106
94
|
await this.client.batch([
|
|
107
|
-
// Create users table (for user-level working memory)
|
|
108
95
|
`CREATE TABLE IF NOT EXISTS ${usersTable} (
|
|
109
96
|
id TEXT PRIMARY KEY,
|
|
110
97
|
metadata TEXT,
|
|
111
98
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
112
99
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
113
100
|
)`,
|
|
114
|
-
// Create conversations table (matching existing structure)
|
|
115
101
|
`CREATE TABLE IF NOT EXISTS ${conversationsTable} (
|
|
116
102
|
id TEXT PRIMARY KEY,
|
|
117
103
|
resource_id TEXT NOT NULL,
|
|
@@ -121,7 +107,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
121
107
|
created_at TEXT NOT NULL,
|
|
122
108
|
updated_at TEXT NOT NULL
|
|
123
109
|
)`,
|
|
124
|
-
// Create messages table (matching existing structure)
|
|
125
110
|
`CREATE TABLE IF NOT EXISTS ${messagesTable} (
|
|
126
111
|
conversation_id TEXT NOT NULL,
|
|
127
112
|
message_id TEXT NOT NULL,
|
|
@@ -133,7 +118,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
133
118
|
created_at TEXT NOT NULL,
|
|
134
119
|
PRIMARY KEY (conversation_id, message_id)
|
|
135
120
|
)`,
|
|
136
|
-
// Create workflow states table
|
|
137
121
|
`CREATE TABLE IF NOT EXISTS ${workflowStatesTable} (
|
|
138
122
|
id TEXT PRIMARY KEY,
|
|
139
123
|
workflow_id TEXT NOT NULL,
|
|
@@ -149,7 +133,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
149
133
|
created_at TEXT NOT NULL,
|
|
150
134
|
updated_at TEXT NOT NULL
|
|
151
135
|
)`,
|
|
152
|
-
// Create conversation steps table
|
|
153
136
|
`CREATE TABLE IF NOT EXISTS ${stepsTable} (
|
|
154
137
|
id TEXT PRIMARY KEY,
|
|
155
138
|
conversation_id TEXT NOT NULL,
|
|
@@ -169,7 +152,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
169
152
|
created_at TEXT NOT NULL,
|
|
170
153
|
FOREIGN KEY (conversation_id) REFERENCES ${conversationsTable}(id) ON DELETE CASCADE
|
|
171
154
|
)`,
|
|
172
|
-
// Create indexes for better performance
|
|
173
155
|
`CREATE INDEX IF NOT EXISTS idx_${conversationsTable}_user_id ON ${conversationsTable}(user_id)`,
|
|
174
156
|
`CREATE INDEX IF NOT EXISTS idx_${conversationsTable}_resource_id ON ${conversationsTable}(resource_id)`,
|
|
175
157
|
`CREATE INDEX IF NOT EXISTS idx_${messagesTable}_conversation_id ON ${messagesTable}(conversation_id)`,
|
|
@@ -186,10 +168,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
186
168
|
this.initialized = true;
|
|
187
169
|
this.logger.debug("Database schema initialized");
|
|
188
170
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Add new columns to messages table for V2 format if they don't exist
|
|
191
|
-
* This allows existing tables to support both old and new message formats
|
|
192
|
-
*/
|
|
193
171
|
async addV2ColumnsToMessagesTable() {
|
|
194
172
|
const messagesTableName = `${this.tablePrefix}_messages`;
|
|
195
173
|
try {
|
|
@@ -262,10 +240,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
262
240
|
} catch (_) {
|
|
263
241
|
}
|
|
264
242
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Migrate default user_id values in messages table
|
|
267
|
-
* Updates messages with user_id='default' to use the actual user_id from their conversation
|
|
268
|
-
*/
|
|
269
243
|
async migrateDefaultUserIds() {
|
|
270
244
|
const messagesTableName = `${this.tablePrefix}_messages`;
|
|
271
245
|
const conversationsTableName = `${this.tablePrefix}_conversations`;
|
|
@@ -283,14 +257,14 @@ var LibSQLMemoryAdapter = class {
|
|
|
283
257
|
const result = await this.client.execute({
|
|
284
258
|
sql: `UPDATE ${messagesTableName}
|
|
285
259
|
SET user_id = (
|
|
286
|
-
SELECT c.user_id
|
|
287
|
-
FROM ${conversationsTableName} c
|
|
260
|
+
SELECT c.user_id
|
|
261
|
+
FROM ${conversationsTableName} c
|
|
288
262
|
WHERE c.id = ${messagesTableName}.conversation_id
|
|
289
263
|
)
|
|
290
264
|
WHERE user_id = 'default'
|
|
291
265
|
AND EXISTS (
|
|
292
|
-
SELECT 1
|
|
293
|
-
FROM ${conversationsTableName} c
|
|
266
|
+
SELECT 1
|
|
267
|
+
FROM ${conversationsTableName} c
|
|
294
268
|
WHERE c.id = ${messagesTableName}.conversation_id
|
|
295
269
|
)`,
|
|
296
270
|
args: []
|
|
@@ -314,10 +288,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
314
288
|
this.logger.error("Failed to migrate default user_ids", error);
|
|
315
289
|
}
|
|
316
290
|
}
|
|
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
291
|
async addWorkflowStateColumns() {
|
|
322
292
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
323
293
|
try {
|
|
@@ -353,9 +323,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
353
323
|
// ============================================================================
|
|
354
324
|
// Message Operations
|
|
355
325
|
// ============================================================================
|
|
356
|
-
/**
|
|
357
|
-
* Add a single message
|
|
358
|
-
*/
|
|
359
326
|
async addMessage(message, userId, conversationId) {
|
|
360
327
|
await this.initialize();
|
|
361
328
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -365,8 +332,14 @@ var LibSQLMemoryAdapter = class {
|
|
|
365
332
|
}
|
|
366
333
|
await this.executeWithRetry(async () => {
|
|
367
334
|
await this.client.execute({
|
|
368
|
-
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
369
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
335
|
+
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
336
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
337
|
+
ON CONFLICT(conversation_id, message_id) DO UPDATE SET
|
|
338
|
+
user_id = excluded.user_id,
|
|
339
|
+
role = excluded.role,
|
|
340
|
+
parts = excluded.parts,
|
|
341
|
+
metadata = excluded.metadata,
|
|
342
|
+
format_version = excluded.format_version`,
|
|
370
343
|
args: [
|
|
371
344
|
conversationId,
|
|
372
345
|
message.id,
|
|
@@ -375,15 +348,11 @@ var LibSQLMemoryAdapter = class {
|
|
|
375
348
|
safeStringify(message.parts),
|
|
376
349
|
message.metadata ? safeStringify(message.metadata) : null,
|
|
377
350
|
2,
|
|
378
|
-
// format_version
|
|
379
351
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
380
352
|
]
|
|
381
353
|
});
|
|
382
354
|
}, "add message");
|
|
383
355
|
}
|
|
384
|
-
/**
|
|
385
|
-
* Add multiple messages
|
|
386
|
-
*/
|
|
387
356
|
async addMessages(messages, userId, conversationId) {
|
|
388
357
|
await this.initialize();
|
|
389
358
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -395,8 +364,14 @@ var LibSQLMemoryAdapter = class {
|
|
|
395
364
|
await this.executeWithRetry(async () => {
|
|
396
365
|
await this.client.batch(
|
|
397
366
|
messages.map((message) => ({
|
|
398
|
-
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
399
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
367
|
+
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
368
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
369
|
+
ON CONFLICT(conversation_id, message_id) DO UPDATE SET
|
|
370
|
+
user_id = excluded.user_id,
|
|
371
|
+
role = excluded.role,
|
|
372
|
+
parts = excluded.parts,
|
|
373
|
+
metadata = excluded.metadata,
|
|
374
|
+
format_version = excluded.format_version`,
|
|
400
375
|
args: [
|
|
401
376
|
conversationId,
|
|
402
377
|
message.id,
|
|
@@ -405,7 +380,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
405
380
|
safeStringify(message.parts),
|
|
406
381
|
message.metadata ? safeStringify(message.metadata) : null,
|
|
407
382
|
2,
|
|
408
|
-
// format_version
|
|
409
383
|
now
|
|
410
384
|
]
|
|
411
385
|
}))
|
|
@@ -478,9 +452,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
478
452
|
);
|
|
479
453
|
}, "save conversation steps");
|
|
480
454
|
}
|
|
481
|
-
/**
|
|
482
|
-
* Get messages with optional filtering
|
|
483
|
-
*/
|
|
484
455
|
async getMessages(userId, conversationId, options) {
|
|
485
456
|
await this.initialize();
|
|
486
457
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -588,9 +559,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
588
559
|
createdAt: row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
589
560
|
}));
|
|
590
561
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Clear messages for a user
|
|
593
|
-
*/
|
|
594
562
|
async clearMessages(userId, conversationId) {
|
|
595
563
|
await this.initialize();
|
|
596
564
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -625,9 +593,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
625
593
|
// ============================================================================
|
|
626
594
|
// Conversation Operations
|
|
627
595
|
// ============================================================================
|
|
628
|
-
/**
|
|
629
|
-
* Create a new conversation
|
|
630
|
-
*/
|
|
631
596
|
async createConversation(input) {
|
|
632
597
|
await this.initialize();
|
|
633
598
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -638,7 +603,7 @@ var LibSQLMemoryAdapter = class {
|
|
|
638
603
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
639
604
|
await this.executeWithRetry(async () => {
|
|
640
605
|
await this.client.execute({
|
|
641
|
-
sql: `INSERT INTO ${conversationsTable} (id, resource_id, user_id, title, metadata, created_at, updated_at)
|
|
606
|
+
sql: `INSERT INTO ${conversationsTable} (id, resource_id, user_id, title, metadata, created_at, updated_at)
|
|
642
607
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
643
608
|
args: [
|
|
644
609
|
input.id,
|
|
@@ -661,9 +626,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
661
626
|
updatedAt: now
|
|
662
627
|
};
|
|
663
628
|
}
|
|
664
|
-
/**
|
|
665
|
-
* Get a conversation by ID
|
|
666
|
-
*/
|
|
667
629
|
async getConversation(id) {
|
|
668
630
|
await this.initialize();
|
|
669
631
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -685,9 +647,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
685
647
|
updatedAt: row.updated_at
|
|
686
648
|
};
|
|
687
649
|
}
|
|
688
|
-
/**
|
|
689
|
-
* Get conversations by resource ID
|
|
690
|
-
*/
|
|
691
650
|
async getConversations(resourceId) {
|
|
692
651
|
await this.initialize();
|
|
693
652
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -705,15 +664,9 @@ var LibSQLMemoryAdapter = class {
|
|
|
705
664
|
updatedAt: row.updated_at
|
|
706
665
|
}));
|
|
707
666
|
}
|
|
708
|
-
/**
|
|
709
|
-
* Get conversations by user ID
|
|
710
|
-
*/
|
|
711
667
|
async getConversationsByUserId(userId, options) {
|
|
712
668
|
return this.queryConversations({ ...options, userId });
|
|
713
669
|
}
|
|
714
|
-
/**
|
|
715
|
-
* Query conversations with filters
|
|
716
|
-
*/
|
|
717
670
|
async queryConversations(options) {
|
|
718
671
|
await this.initialize();
|
|
719
672
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -749,9 +702,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
749
702
|
updatedAt: row.updated_at
|
|
750
703
|
}));
|
|
751
704
|
}
|
|
752
|
-
/**
|
|
753
|
-
* Update a conversation
|
|
754
|
-
*/
|
|
755
705
|
async updateConversation(id, updates) {
|
|
756
706
|
await this.initialize();
|
|
757
707
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -785,9 +735,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
785
735
|
}
|
|
786
736
|
return updated;
|
|
787
737
|
}
|
|
788
|
-
/**
|
|
789
|
-
* Delete a conversation
|
|
790
|
-
*/
|
|
791
738
|
async deleteConversation(id) {
|
|
792
739
|
await this.initialize();
|
|
793
740
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -799,9 +746,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
799
746
|
// ============================================================================
|
|
800
747
|
// Working Memory Operations
|
|
801
748
|
// ============================================================================
|
|
802
|
-
/**
|
|
803
|
-
* Get working memory
|
|
804
|
-
*/
|
|
805
749
|
async getWorkingMemory(params) {
|
|
806
750
|
await this.initialize();
|
|
807
751
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -821,9 +765,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
821
765
|
}
|
|
822
766
|
return null;
|
|
823
767
|
}
|
|
824
|
-
/**
|
|
825
|
-
* Set working memory
|
|
826
|
-
*/
|
|
827
768
|
async setWorkingMemory(params) {
|
|
828
769
|
await this.initialize();
|
|
829
770
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -857,9 +798,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
857
798
|
}
|
|
858
799
|
}
|
|
859
800
|
}
|
|
860
|
-
/**
|
|
861
|
-
* Delete working memory
|
|
862
|
-
*/
|
|
863
801
|
async deleteWorkingMemory(params) {
|
|
864
802
|
await this.initialize();
|
|
865
803
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -891,9 +829,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
891
829
|
// ============================================================================
|
|
892
830
|
// Workflow State Operations
|
|
893
831
|
// ============================================================================
|
|
894
|
-
/**
|
|
895
|
-
* Get workflow state by execution ID
|
|
896
|
-
*/
|
|
897
832
|
async getWorkflowState(executionId) {
|
|
898
833
|
await this.initialize();
|
|
899
834
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -921,9 +856,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
921
856
|
updatedAt: new Date(row.updated_at)
|
|
922
857
|
};
|
|
923
858
|
}
|
|
924
|
-
/**
|
|
925
|
-
* Query workflow states with optional filters
|
|
926
|
-
*/
|
|
927
859
|
async queryWorkflowRuns(query) {
|
|
928
860
|
await this.initialize();
|
|
929
861
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -978,9 +910,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
978
910
|
updatedAt: new Date(row.updated_at)
|
|
979
911
|
}));
|
|
980
912
|
}
|
|
981
|
-
/**
|
|
982
|
-
* Set workflow state
|
|
983
|
-
*/
|
|
984
913
|
async setWorkflowState(executionId, state) {
|
|
985
914
|
await this.initialize();
|
|
986
915
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -1005,9 +934,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
1005
934
|
]
|
|
1006
935
|
});
|
|
1007
936
|
}
|
|
1008
|
-
/**
|
|
1009
|
-
* Update workflow state
|
|
1010
|
-
*/
|
|
1011
937
|
async updateWorkflowState(executionId, updates) {
|
|
1012
938
|
await this.initialize();
|
|
1013
939
|
const existing = await this.getWorkflowState(executionId);
|
|
@@ -1021,9 +947,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
1021
947
|
};
|
|
1022
948
|
await this.setWorkflowState(executionId, updated);
|
|
1023
949
|
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Get suspended workflow states for a workflow
|
|
1026
|
-
*/
|
|
1027
950
|
async getSuspendedWorkflowStates(workflowId) {
|
|
1028
951
|
await this.initialize();
|
|
1029
952
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -1047,23 +970,46 @@ var LibSQLMemoryAdapter = class {
|
|
|
1047
970
|
updatedAt: new Date(row.updated_at)
|
|
1048
971
|
}));
|
|
1049
972
|
}
|
|
1050
|
-
/**
|
|
1051
|
-
* Close database connection
|
|
1052
|
-
*/
|
|
1053
973
|
async close() {
|
|
1054
974
|
this.logger.debug("Closing LibSQL Memory adapter");
|
|
1055
975
|
}
|
|
1056
976
|
};
|
|
1057
977
|
|
|
978
|
+
// src/memory-v2-adapter.ts
|
|
979
|
+
var LibSQLMemoryAdapter = class extends LibSQLMemoryCore {
|
|
980
|
+
static {
|
|
981
|
+
__name(this, "LibSQLMemoryAdapter");
|
|
982
|
+
}
|
|
983
|
+
constructor(options = {}) {
|
|
984
|
+
const url = options.url ?? "file:./.voltagent/memory.db";
|
|
985
|
+
const logger = options.logger || AgentRegistry.getInstance().getGlobalLogger() || createPinoLogger({ name: "libsql-memory" });
|
|
986
|
+
if (url.startsWith("file:")) {
|
|
987
|
+
const dbPath = url.replace("file:", "");
|
|
988
|
+
const dbDir = path.dirname(dbPath);
|
|
989
|
+
if (dbDir && dbDir !== "." && !fs.existsSync(dbDir)) {
|
|
990
|
+
fs.mkdirSync(dbDir, { recursive: true });
|
|
991
|
+
logger.debug(`Created database directory: ${dbDir}`);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
const client = createClient({
|
|
995
|
+
url,
|
|
996
|
+
authToken: options.authToken
|
|
997
|
+
});
|
|
998
|
+
super(client, url, options, logger);
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1058
1002
|
// src/observability-adapter.ts
|
|
1059
1003
|
import { existsSync, mkdirSync } from "fs";
|
|
1060
1004
|
import { dirname } from "path";
|
|
1061
1005
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1062
|
-
import { safeStringify as safeStringify2 } from "@voltagent/internal/utils";
|
|
1063
1006
|
import { createPinoLogger as createPinoLogger2 } from "@voltagent/logger";
|
|
1064
|
-
|
|
1007
|
+
|
|
1008
|
+
// src/observability-core.ts
|
|
1009
|
+
import { safeStringify as safeStringify2 } from "@voltagent/internal/utils";
|
|
1010
|
+
var LibSQLObservabilityCore = class {
|
|
1065
1011
|
static {
|
|
1066
|
-
__name(this, "
|
|
1012
|
+
__name(this, "LibSQLObservabilityCore");
|
|
1067
1013
|
}
|
|
1068
1014
|
client;
|
|
1069
1015
|
tablePrefix;
|
|
@@ -1071,47 +1017,24 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1071
1017
|
logger;
|
|
1072
1018
|
initialized;
|
|
1073
1019
|
maxSpansPerQuery;
|
|
1074
|
-
constructor(options
|
|
1075
|
-
this.
|
|
1020
|
+
constructor(client, options, logger) {
|
|
1021
|
+
this.client = client;
|
|
1022
|
+
this.logger = logger;
|
|
1076
1023
|
this.tablePrefix = options.tablePrefix || "observability";
|
|
1077
1024
|
this.debug = options.debug || false;
|
|
1078
1025
|
this.maxSpansPerQuery = options.maxSpansPerQuery || 1e3;
|
|
1079
|
-
|
|
1080
|
-
if (url.startsWith("file:") && !url.includes(":memory:")) {
|
|
1081
|
-
const filePath = url.substring(5);
|
|
1082
|
-
const dir = dirname(filePath);
|
|
1083
|
-
if (dir && dir !== "." && !existsSync(dir)) {
|
|
1084
|
-
try {
|
|
1085
|
-
mkdirSync(dir, { recursive: true });
|
|
1086
|
-
this.debugLog("Created directory for database", { dir });
|
|
1087
|
-
} catch (error) {
|
|
1088
|
-
this.logger.warn("Failed to create directory for database", { dir, error });
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
this.client = createClient2({
|
|
1093
|
-
url,
|
|
1094
|
-
authToken: options.authToken
|
|
1095
|
-
});
|
|
1096
|
-
this.debugLog("LibSQL observability adapter initialized with options", {
|
|
1097
|
-
url,
|
|
1026
|
+
this.debugLog("LibSQL observability adapter core initialized", {
|
|
1098
1027
|
tablePrefix: this.tablePrefix,
|
|
1099
1028
|
debug: this.debug,
|
|
1100
1029
|
maxSpansPerQuery: this.maxSpansPerQuery
|
|
1101
1030
|
});
|
|
1102
1031
|
this.initialized = this.initializeDatabase();
|
|
1103
1032
|
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Log a debug message if debug is enabled
|
|
1106
|
-
*/
|
|
1107
1033
|
debugLog(message, data) {
|
|
1108
1034
|
if (this.debug) {
|
|
1109
1035
|
this.logger.debug(`${message}`, data || "");
|
|
1110
1036
|
}
|
|
1111
1037
|
}
|
|
1112
|
-
/**
|
|
1113
|
-
* Initialize database tables for observability
|
|
1114
|
-
*/
|
|
1115
1038
|
async initializeDatabase() {
|
|
1116
1039
|
try {
|
|
1117
1040
|
await this.client.execute(`
|
|
@@ -1138,27 +1061,27 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1138
1061
|
)
|
|
1139
1062
|
`);
|
|
1140
1063
|
await this.client.execute(`
|
|
1141
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_trace_id
|
|
1064
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_trace_id
|
|
1142
1065
|
ON ${this.tablePrefix}_spans(trace_id)
|
|
1143
1066
|
`);
|
|
1144
1067
|
await this.client.execute(`
|
|
1145
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_parent_span_id
|
|
1068
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_parent_span_id
|
|
1146
1069
|
ON ${this.tablePrefix}_spans(parent_span_id)
|
|
1147
1070
|
`);
|
|
1148
1071
|
await this.client.execute(`
|
|
1149
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_start_time
|
|
1072
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_start_time
|
|
1150
1073
|
ON ${this.tablePrefix}_spans(start_time)
|
|
1151
1074
|
`);
|
|
1152
1075
|
await this.client.execute(`
|
|
1153
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_name
|
|
1076
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_name
|
|
1154
1077
|
ON ${this.tablePrefix}_spans(name)
|
|
1155
1078
|
`);
|
|
1156
1079
|
await this.client.execute(`
|
|
1157
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_id
|
|
1080
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_id
|
|
1158
1081
|
ON ${this.tablePrefix}_spans(entity_id)
|
|
1159
1082
|
`);
|
|
1160
1083
|
await this.client.execute(`
|
|
1161
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_type
|
|
1084
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_type
|
|
1162
1085
|
ON ${this.tablePrefix}_spans(entity_type)
|
|
1163
1086
|
`);
|
|
1164
1087
|
await this.client.execute(`
|
|
@@ -1175,15 +1098,15 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1175
1098
|
)
|
|
1176
1099
|
`);
|
|
1177
1100
|
await this.client.execute(`
|
|
1178
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_start_time
|
|
1101
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_start_time
|
|
1179
1102
|
ON ${this.tablePrefix}_traces(start_time DESC)
|
|
1180
1103
|
`);
|
|
1181
1104
|
await this.client.execute(`
|
|
1182
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_id
|
|
1105
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_id
|
|
1183
1106
|
ON ${this.tablePrefix}_traces(entity_id)
|
|
1184
1107
|
`);
|
|
1185
1108
|
await this.client.execute(`
|
|
1186
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_type
|
|
1109
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_type
|
|
1187
1110
|
ON ${this.tablePrefix}_traces(entity_type)
|
|
1188
1111
|
`);
|
|
1189
1112
|
await this.client.execute(`
|
|
@@ -1203,19 +1126,19 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1203
1126
|
)
|
|
1204
1127
|
`);
|
|
1205
1128
|
await this.client.execute(`
|
|
1206
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_trace_id
|
|
1129
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_trace_id
|
|
1207
1130
|
ON ${this.tablePrefix}_logs(trace_id)
|
|
1208
1131
|
`);
|
|
1209
1132
|
await this.client.execute(`
|
|
1210
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_span_id
|
|
1133
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_span_id
|
|
1211
1134
|
ON ${this.tablePrefix}_logs(span_id)
|
|
1212
1135
|
`);
|
|
1213
1136
|
await this.client.execute(`
|
|
1214
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_timestamp
|
|
1137
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_timestamp
|
|
1215
1138
|
ON ${this.tablePrefix}_logs(timestamp DESC)
|
|
1216
1139
|
`);
|
|
1217
1140
|
await this.client.execute(`
|
|
1218
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_severity
|
|
1141
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_severity
|
|
1219
1142
|
ON ${this.tablePrefix}_logs(severity_number)
|
|
1220
1143
|
`);
|
|
1221
1144
|
this.debugLog("Database tables initialized successfully");
|
|
@@ -1224,22 +1147,15 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1224
1147
|
throw error;
|
|
1225
1148
|
}
|
|
1226
1149
|
}
|
|
1227
|
-
/**
|
|
1228
|
-
* Ensure database is initialized before operations
|
|
1229
|
-
*/
|
|
1230
1150
|
async ensureInitialized() {
|
|
1231
1151
|
await this.initialized;
|
|
1232
1152
|
}
|
|
1233
|
-
/**
|
|
1234
|
-
* Add a span to the database
|
|
1235
|
-
*/
|
|
1236
1153
|
async addSpan(span) {
|
|
1237
1154
|
await this.ensureInitialized();
|
|
1238
1155
|
try {
|
|
1239
1156
|
const entityId = span.attributes?.["entity.id"] || null;
|
|
1240
1157
|
const entityType = span.attributes?.["entity.type"] || null;
|
|
1241
1158
|
await this.client.batch([
|
|
1242
|
-
// Insert the span with entity columns
|
|
1243
1159
|
{
|
|
1244
1160
|
sql: `
|
|
1245
1161
|
INSERT INTO ${this.tablePrefix}_spans (
|
|
@@ -1270,7 +1186,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1270
1186
|
span.instrumentationScope ? safeStringify2(span.instrumentationScope) : null
|
|
1271
1187
|
]
|
|
1272
1188
|
},
|
|
1273
|
-
// Update or insert trace metadata with entity columns
|
|
1274
1189
|
{
|
|
1275
1190
|
sql: `
|
|
1276
1191
|
INSERT INTO ${this.tablePrefix}_traces (
|
|
@@ -1287,7 +1202,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1287
1202
|
args: [
|
|
1288
1203
|
span.traceId,
|
|
1289
1204
|
span.parentSpanId ? null : span.spanId,
|
|
1290
|
-
// Root span if no parent
|
|
1291
1205
|
entityId,
|
|
1292
1206
|
entityType,
|
|
1293
1207
|
span.startTime,
|
|
@@ -1304,9 +1218,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1304
1218
|
throw error;
|
|
1305
1219
|
}
|
|
1306
1220
|
}
|
|
1307
|
-
/**
|
|
1308
|
-
* Update an existing span
|
|
1309
|
-
*/
|
|
1310
1221
|
async updateSpan(spanId, updates) {
|
|
1311
1222
|
await this.ensureInitialized();
|
|
1312
1223
|
try {
|
|
@@ -1343,7 +1254,7 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1343
1254
|
args.push(spanId);
|
|
1344
1255
|
await this.client.execute({
|
|
1345
1256
|
sql: `
|
|
1346
|
-
UPDATE ${this.tablePrefix}_spans
|
|
1257
|
+
UPDATE ${this.tablePrefix}_spans
|
|
1347
1258
|
SET ${setClauses.join(", ")}
|
|
1348
1259
|
WHERE span_id = ?
|
|
1349
1260
|
`,
|
|
@@ -1369,32 +1280,22 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1369
1280
|
throw error;
|
|
1370
1281
|
}
|
|
1371
1282
|
}
|
|
1372
|
-
/**
|
|
1373
|
-
* Get a span by ID
|
|
1374
|
-
*/
|
|
1375
1283
|
async getSpan(spanId) {
|
|
1376
1284
|
await this.ensureInitialized();
|
|
1377
1285
|
try {
|
|
1378
1286
|
const result = await this.client.execute({
|
|
1379
|
-
sql: `
|
|
1380
|
-
SELECT * FROM ${this.tablePrefix}_spans
|
|
1381
|
-
WHERE span_id = ?
|
|
1382
|
-
`,
|
|
1287
|
+
sql: `SELECT * FROM ${this.tablePrefix}_spans WHERE span_id = ?`,
|
|
1383
1288
|
args: [spanId]
|
|
1384
1289
|
});
|
|
1385
1290
|
if (result.rows.length === 0) {
|
|
1386
1291
|
return null;
|
|
1387
1292
|
}
|
|
1388
|
-
|
|
1389
|
-
return this.rowToSpan(row);
|
|
1293
|
+
return this.rowToSpan(result.rows[0]);
|
|
1390
1294
|
} catch (error) {
|
|
1391
1295
|
this.logger.error("Failed to get span", { error, spanId });
|
|
1392
1296
|
throw error;
|
|
1393
1297
|
}
|
|
1394
1298
|
}
|
|
1395
|
-
/**
|
|
1396
|
-
* Get all spans in a trace
|
|
1397
|
-
*/
|
|
1398
1299
|
async getTrace(traceId) {
|
|
1399
1300
|
await this.ensureInitialized();
|
|
1400
1301
|
try {
|
|
@@ -1413,9 +1314,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1413
1314
|
throw error;
|
|
1414
1315
|
}
|
|
1415
1316
|
}
|
|
1416
|
-
/**
|
|
1417
|
-
* List all traces with optional entity filter
|
|
1418
|
-
*/
|
|
1419
1317
|
async listTraces(limit = 100, offset = 0, filter) {
|
|
1420
1318
|
await this.ensureInitialized();
|
|
1421
1319
|
try {
|
|
@@ -1453,52 +1351,36 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1453
1351
|
throw error;
|
|
1454
1352
|
}
|
|
1455
1353
|
}
|
|
1456
|
-
/**
|
|
1457
|
-
* Delete old spans
|
|
1458
|
-
*/
|
|
1459
1354
|
async deleteOldSpans(beforeTimestamp) {
|
|
1460
1355
|
await this.ensureInitialized();
|
|
1461
1356
|
try {
|
|
1462
1357
|
const beforeDate = new Date(beforeTimestamp).toISOString();
|
|
1463
1358
|
const tracesResult = await this.client.execute({
|
|
1464
|
-
sql: `
|
|
1465
|
-
SELECT DISTINCT trace_id FROM ${this.tablePrefix}_spans
|
|
1466
|
-
WHERE start_time < ?
|
|
1467
|
-
`,
|
|
1359
|
+
sql: `SELECT DISTINCT trace_id FROM ${this.tablePrefix}_spans WHERE start_time < ?`,
|
|
1468
1360
|
args: [beforeDate]
|
|
1469
1361
|
});
|
|
1470
1362
|
const affectedTraceIds = tracesResult.rows.map((row) => row.trace_id);
|
|
1471
1363
|
const deleteResult = await this.client.execute({
|
|
1472
|
-
sql: `
|
|
1473
|
-
DELETE FROM ${this.tablePrefix}_spans
|
|
1474
|
-
WHERE start_time < ?
|
|
1475
|
-
`,
|
|
1364
|
+
sql: `DELETE FROM ${this.tablePrefix}_spans WHERE start_time < ?`,
|
|
1476
1365
|
args: [beforeDate]
|
|
1477
1366
|
});
|
|
1478
1367
|
if (affectedTraceIds.length > 0) {
|
|
1479
1368
|
for (const traceId of affectedTraceIds) {
|
|
1480
1369
|
const countResult = await this.client.execute({
|
|
1481
|
-
sql: `
|
|
1482
|
-
SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans
|
|
1483
|
-
WHERE trace_id = ?
|
|
1484
|
-
`,
|
|
1370
|
+
sql: `SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans WHERE trace_id = ?`,
|
|
1485
1371
|
args: [traceId]
|
|
1486
1372
|
});
|
|
1487
1373
|
const count = countResult.rows[0].count;
|
|
1488
1374
|
if (count === 0) {
|
|
1489
1375
|
await this.client.execute({
|
|
1490
|
-
sql: `
|
|
1491
|
-
DELETE FROM ${this.tablePrefix}_traces
|
|
1492
|
-
WHERE trace_id = ?
|
|
1493
|
-
`,
|
|
1376
|
+
sql: `DELETE FROM ${this.tablePrefix}_traces WHERE trace_id = ?`,
|
|
1494
1377
|
args: [traceId]
|
|
1495
1378
|
});
|
|
1496
1379
|
} else {
|
|
1497
1380
|
await this.client.execute({
|
|
1498
1381
|
sql: `
|
|
1499
1382
|
UPDATE ${this.tablePrefix}_traces
|
|
1500
|
-
SET span_count = ?,
|
|
1501
|
-
updated_at = CURRENT_TIMESTAMP
|
|
1383
|
+
SET span_count = ?, updated_at = CURRENT_TIMESTAMP
|
|
1502
1384
|
WHERE trace_id = ?
|
|
1503
1385
|
`,
|
|
1504
1386
|
args: [count, traceId]
|
|
@@ -1514,9 +1396,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1514
1396
|
throw error;
|
|
1515
1397
|
}
|
|
1516
1398
|
}
|
|
1517
|
-
/**
|
|
1518
|
-
* Clear all spans, traces, and logs
|
|
1519
|
-
*/
|
|
1520
1399
|
async clear() {
|
|
1521
1400
|
await this.ensureInitialized();
|
|
1522
1401
|
try {
|
|
@@ -1531,9 +1410,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1531
1410
|
throw error;
|
|
1532
1411
|
}
|
|
1533
1412
|
}
|
|
1534
|
-
/**
|
|
1535
|
-
* Convert a database row to an ObservabilitySpan
|
|
1536
|
-
*/
|
|
1537
1413
|
rowToSpan(row) {
|
|
1538
1414
|
const span = {
|
|
1539
1415
|
traceId: row.trace_id,
|
|
@@ -1579,9 +1455,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1579
1455
|
}
|
|
1580
1456
|
return span;
|
|
1581
1457
|
}
|
|
1582
|
-
/**
|
|
1583
|
-
* Get statistics about stored spans
|
|
1584
|
-
*/
|
|
1585
1458
|
async getStats() {
|
|
1586
1459
|
await this.ensureInitialized();
|
|
1587
1460
|
try {
|
|
@@ -1589,9 +1462,7 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1589
1462
|
this.client.execute(`SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans`),
|
|
1590
1463
|
this.client.execute(`SELECT COUNT(*) as count FROM ${this.tablePrefix}_traces`),
|
|
1591
1464
|
this.client.execute(`
|
|
1592
|
-
SELECT
|
|
1593
|
-
MIN(start_time) as oldest,
|
|
1594
|
-
MAX(start_time) as newest
|
|
1465
|
+
SELECT MIN(start_time) as oldest, MAX(start_time) as newest
|
|
1595
1466
|
FROM ${this.tablePrefix}_spans
|
|
1596
1467
|
`)
|
|
1597
1468
|
]);
|
|
@@ -1611,9 +1482,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1611
1482
|
throw error;
|
|
1612
1483
|
}
|
|
1613
1484
|
}
|
|
1614
|
-
/**
|
|
1615
|
-
* Save a log record to the database
|
|
1616
|
-
*/
|
|
1617
1485
|
async saveLogRecord(logRecord) {
|
|
1618
1486
|
await this.ensureInitialized();
|
|
1619
1487
|
try {
|
|
@@ -1668,9 +1536,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1668
1536
|
throw error;
|
|
1669
1537
|
}
|
|
1670
1538
|
}
|
|
1671
|
-
/**
|
|
1672
|
-
* Get logs by trace ID
|
|
1673
|
-
*/
|
|
1674
1539
|
async getLogsByTraceId(traceId) {
|
|
1675
1540
|
await this.ensureInitialized();
|
|
1676
1541
|
try {
|
|
@@ -1689,9 +1554,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1689
1554
|
throw error;
|
|
1690
1555
|
}
|
|
1691
1556
|
}
|
|
1692
|
-
/**
|
|
1693
|
-
* Get logs by span ID
|
|
1694
|
-
*/
|
|
1695
1557
|
async getLogsBySpanId(spanId) {
|
|
1696
1558
|
await this.ensureInitialized();
|
|
1697
1559
|
try {
|
|
@@ -1710,9 +1572,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1710
1572
|
throw error;
|
|
1711
1573
|
}
|
|
1712
1574
|
}
|
|
1713
|
-
/**
|
|
1714
|
-
* Query logs with flexible filtering
|
|
1715
|
-
*/
|
|
1716
1575
|
async queryLogs(filter) {
|
|
1717
1576
|
await this.ensureInitialized();
|
|
1718
1577
|
try {
|
|
@@ -1781,18 +1640,12 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1781
1640
|
throw error;
|
|
1782
1641
|
}
|
|
1783
1642
|
}
|
|
1784
|
-
/**
|
|
1785
|
-
* Delete old logs
|
|
1786
|
-
*/
|
|
1787
1643
|
async deleteOldLogs(beforeTimestamp) {
|
|
1788
1644
|
await this.ensureInitialized();
|
|
1789
1645
|
try {
|
|
1790
1646
|
const beforeDate = new Date(beforeTimestamp).toISOString();
|
|
1791
1647
|
const result = await this.client.execute({
|
|
1792
|
-
sql: `
|
|
1793
|
-
DELETE FROM ${this.tablePrefix}_logs
|
|
1794
|
-
WHERE timestamp < ?
|
|
1795
|
-
`,
|
|
1648
|
+
sql: `DELETE FROM ${this.tablePrefix}_logs WHERE timestamp < ?`,
|
|
1796
1649
|
args: [beforeDate]
|
|
1797
1650
|
});
|
|
1798
1651
|
const deletedCount = result.rowsAffected || 0;
|
|
@@ -1803,9 +1656,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1803
1656
|
throw error;
|
|
1804
1657
|
}
|
|
1805
1658
|
}
|
|
1806
|
-
/**
|
|
1807
|
-
* Convert a database row to an ObservabilityLogRecord
|
|
1808
|
-
*/
|
|
1809
1659
|
rowToLogRecord(row) {
|
|
1810
1660
|
const log = {
|
|
1811
1661
|
timestamp: row.timestamp,
|
|
@@ -1872,26 +1722,55 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1872
1722
|
description: "Persists spans and logs to a LibSQL/Turso database for long-term retention."
|
|
1873
1723
|
};
|
|
1874
1724
|
}
|
|
1875
|
-
/**
|
|
1876
|
-
* Close the database connection
|
|
1877
|
-
*/
|
|
1878
1725
|
async close() {
|
|
1879
1726
|
this.debugLog("LibSQL observability adapter closed");
|
|
1880
1727
|
}
|
|
1881
1728
|
};
|
|
1882
1729
|
|
|
1730
|
+
// src/observability-adapter.ts
|
|
1731
|
+
var LibSQLObservabilityAdapter = class extends LibSQLObservabilityCore {
|
|
1732
|
+
static {
|
|
1733
|
+
__name(this, "LibSQLObservabilityAdapter");
|
|
1734
|
+
}
|
|
1735
|
+
constructor(options = {}) {
|
|
1736
|
+
const url = options.url || "file:./.voltagent/observability.db";
|
|
1737
|
+
const logger = options.logger || createPinoLogger2({ name: "libsql-observability" });
|
|
1738
|
+
if (url.startsWith("file:") && !url.includes(":memory:")) {
|
|
1739
|
+
const filePath = url.substring(5);
|
|
1740
|
+
const dir = dirname(filePath);
|
|
1741
|
+
if (dir && dir !== "." && !existsSync(dir)) {
|
|
1742
|
+
try {
|
|
1743
|
+
mkdirSync(dir, { recursive: true });
|
|
1744
|
+
if (options.debug) {
|
|
1745
|
+
logger.debug("Created directory for database", { dir });
|
|
1746
|
+
}
|
|
1747
|
+
} catch (error) {
|
|
1748
|
+
logger.warn("Failed to create directory for database", { dir, error });
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
const client = createClient2({
|
|
1753
|
+
url,
|
|
1754
|
+
authToken: options.authToken
|
|
1755
|
+
});
|
|
1756
|
+
super(client, options, logger);
|
|
1757
|
+
}
|
|
1758
|
+
};
|
|
1759
|
+
|
|
1883
1760
|
// src/vector-adapter.ts
|
|
1884
1761
|
import fs2 from "fs";
|
|
1885
1762
|
import path2 from "path";
|
|
1886
1763
|
import { createClient as createClient3 } from "@libsql/client";
|
|
1764
|
+
import { createPinoLogger as createPinoLogger3 } from "@voltagent/logger";
|
|
1765
|
+
|
|
1766
|
+
// src/vector-core.ts
|
|
1887
1767
|
import {
|
|
1888
1768
|
cosineSimilarity
|
|
1889
1769
|
} from "@voltagent/core";
|
|
1890
1770
|
import { safeStringify as safeStringify3 } from "@voltagent/internal";
|
|
1891
|
-
|
|
1892
|
-
var LibSQLVectorAdapter = class {
|
|
1771
|
+
var LibSQLVectorCore = class {
|
|
1893
1772
|
static {
|
|
1894
|
-
__name(this, "
|
|
1773
|
+
__name(this, "LibSQLVectorCore");
|
|
1895
1774
|
}
|
|
1896
1775
|
client;
|
|
1897
1776
|
tablePrefix;
|
|
@@ -1902,11 +1781,11 @@ var LibSQLVectorAdapter = class {
|
|
|
1902
1781
|
logger;
|
|
1903
1782
|
maxRetries;
|
|
1904
1783
|
retryDelayMs;
|
|
1905
|
-
url;
|
|
1906
1784
|
initialized = false;
|
|
1907
1785
|
vectorCache;
|
|
1908
1786
|
dimensions = null;
|
|
1909
|
-
constructor(options
|
|
1787
|
+
constructor(client, options, logger) {
|
|
1788
|
+
this.client = client;
|
|
1910
1789
|
this.tablePrefix = options.tablePrefix ?? "voltagent";
|
|
1911
1790
|
this.maxVectorDimensions = options.maxVectorDimensions ?? 1536;
|
|
1912
1791
|
this.cacheSize = options.cacheSize ?? 100;
|
|
@@ -1914,28 +1793,32 @@ var LibSQLVectorAdapter = class {
|
|
|
1914
1793
|
this.maxRetries = options.maxRetries ?? 3;
|
|
1915
1794
|
this.retryDelayMs = options.retryDelayMs ?? 100;
|
|
1916
1795
|
this.debug = options.debug ?? false;
|
|
1917
|
-
this.logger =
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1796
|
+
this.logger = logger;
|
|
1797
|
+
this.vectorCache = /* @__PURE__ */ new Map();
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Serialize a vector to binary format
|
|
1801
|
+
* Uses ArrayBuffer/DataView for cross-platform compatibility
|
|
1802
|
+
*/
|
|
1803
|
+
serializeVector(vector) {
|
|
1804
|
+
const buffer = new ArrayBuffer(vector.length * 4);
|
|
1805
|
+
const view = new DataView(buffer);
|
|
1806
|
+
for (let i = 0; i < vector.length; i++) {
|
|
1807
|
+
view.setFloat32(i * 4, vector[i], true);
|
|
1926
1808
|
}
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1809
|
+
return new Uint8Array(buffer);
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Deserialize a vector from binary format
|
|
1813
|
+
*/
|
|
1814
|
+
deserializeVector(data) {
|
|
1815
|
+
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
1816
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1817
|
+
const vector = [];
|
|
1818
|
+
for (let i = 0; i < bytes.length; i += 4) {
|
|
1819
|
+
vector.push(view.getFloat32(i, true));
|
|
1933
1820
|
}
|
|
1934
|
-
|
|
1935
|
-
url: this.url,
|
|
1936
|
-
authToken: options.authToken
|
|
1937
|
-
});
|
|
1938
|
-
this.vectorCache = /* @__PURE__ */ new Map();
|
|
1821
|
+
return vector;
|
|
1939
1822
|
}
|
|
1940
1823
|
/**
|
|
1941
1824
|
* Initialize the database schema
|
|
@@ -1944,8 +1827,7 @@ var LibSQLVectorAdapter = class {
|
|
|
1944
1827
|
if (this.initialized) return;
|
|
1945
1828
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
1946
1829
|
try {
|
|
1947
|
-
await this.client.
|
|
1948
|
-
BEGIN;
|
|
1830
|
+
await this.client.execute(`
|
|
1949
1831
|
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
1950
1832
|
id TEXT PRIMARY KEY,
|
|
1951
1833
|
vector BLOB NOT NULL,
|
|
@@ -1954,11 +1836,14 @@ var LibSQLVectorAdapter = class {
|
|
|
1954
1836
|
content TEXT,
|
|
1955
1837
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1956
1838
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
1957
|
-
)
|
|
1958
|
-
CREATE INDEX IF NOT EXISTS idx_${tableName}_created ON ${tableName}(created_at);
|
|
1959
|
-
CREATE INDEX IF NOT EXISTS idx_${tableName}_dimensions ON ${tableName}(dimensions);
|
|
1960
|
-
COMMIT;
|
|
1839
|
+
)
|
|
1961
1840
|
`);
|
|
1841
|
+
await this.client.execute(
|
|
1842
|
+
`CREATE INDEX IF NOT EXISTS idx_${tableName}_created ON ${tableName}(created_at)`
|
|
1843
|
+
);
|
|
1844
|
+
await this.client.execute(
|
|
1845
|
+
`CREATE INDEX IF NOT EXISTS idx_${tableName}_dimensions ON ${tableName}(dimensions)`
|
|
1846
|
+
);
|
|
1962
1847
|
this.initialized = true;
|
|
1963
1848
|
this.logger.debug("Vector adapter initialized");
|
|
1964
1849
|
} catch (error) {
|
|
@@ -1966,34 +1851,6 @@ var LibSQLVectorAdapter = class {
|
|
|
1966
1851
|
throw error;
|
|
1967
1852
|
}
|
|
1968
1853
|
}
|
|
1969
|
-
/**
|
|
1970
|
-
* Serialize a vector to binary format
|
|
1971
|
-
*/
|
|
1972
|
-
serializeVector(vector) {
|
|
1973
|
-
const buffer = Buffer.allocUnsafe(vector.length * 4);
|
|
1974
|
-
for (let i = 0; i < vector.length; i++) {
|
|
1975
|
-
buffer.writeFloatLE(vector[i], i * 4);
|
|
1976
|
-
}
|
|
1977
|
-
return buffer;
|
|
1978
|
-
}
|
|
1979
|
-
/**
|
|
1980
|
-
* Deserialize a vector from binary format
|
|
1981
|
-
*/
|
|
1982
|
-
deserializeVector(buffer) {
|
|
1983
|
-
let bytes;
|
|
1984
|
-
if (buffer instanceof Buffer) {
|
|
1985
|
-
bytes = buffer;
|
|
1986
|
-
} else if (buffer instanceof ArrayBuffer) {
|
|
1987
|
-
bytes = Buffer.from(buffer);
|
|
1988
|
-
} else {
|
|
1989
|
-
bytes = Buffer.from(buffer);
|
|
1990
|
-
}
|
|
1991
|
-
const vector = [];
|
|
1992
|
-
for (let i = 0; i < bytes.length; i += 4) {
|
|
1993
|
-
vector.push(bytes.readFloatLE(i));
|
|
1994
|
-
}
|
|
1995
|
-
return vector;
|
|
1996
|
-
}
|
|
1997
1854
|
/**
|
|
1998
1855
|
* Execute a database operation with retries
|
|
1999
1856
|
*/
|
|
@@ -2015,9 +1872,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2015
1872
|
this.logger.error(`Operation failed after ${this.maxRetries} attempts: ${context}`, lastError);
|
|
2016
1873
|
throw lastError;
|
|
2017
1874
|
}
|
|
2018
|
-
/**
|
|
2019
|
-
* Store a vector with associated metadata
|
|
2020
|
-
*/
|
|
2021
1875
|
async store(id, vector, metadata) {
|
|
2022
1876
|
await this.initialize();
|
|
2023
1877
|
if (!Array.isArray(vector) || vector.length === 0) {
|
|
@@ -2041,7 +1895,7 @@ var LibSQLVectorAdapter = class {
|
|
|
2041
1895
|
await this.executeWithRetry(async () => {
|
|
2042
1896
|
await this.client.execute({
|
|
2043
1897
|
sql: `
|
|
2044
|
-
INSERT OR REPLACE INTO ${tableName}
|
|
1898
|
+
INSERT OR REPLACE INTO ${tableName}
|
|
2045
1899
|
(id, vector, dimensions, metadata, updated_at)
|
|
2046
1900
|
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
2047
1901
|
`,
|
|
@@ -2055,9 +1909,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2055
1909
|
this.vectorCache.set(id, { id, vector, metadata });
|
|
2056
1910
|
this.logger.debug(`Vector stored: ${id} (${vector.length} dimensions)`);
|
|
2057
1911
|
}
|
|
2058
|
-
/**
|
|
2059
|
-
* Store multiple vectors in batch
|
|
2060
|
-
*/
|
|
2061
1912
|
async storeBatch(items) {
|
|
2062
1913
|
await this.initialize();
|
|
2063
1914
|
if (items.length === 0) return;
|
|
@@ -2090,9 +1941,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2090
1941
|
this.logger.debug(`Batch of ${batch.length} vectors stored`);
|
|
2091
1942
|
}
|
|
2092
1943
|
}
|
|
2093
|
-
/**
|
|
2094
|
-
* Search for similar vectors using cosine similarity
|
|
2095
|
-
*/
|
|
2096
1944
|
async search(queryVector, options) {
|
|
2097
1945
|
await this.initialize();
|
|
2098
1946
|
const { limit = 10, threshold = 0, filter } = options || {};
|
|
@@ -2133,16 +1981,12 @@ var LibSQLVectorAdapter = class {
|
|
|
2133
1981
|
content,
|
|
2134
1982
|
score,
|
|
2135
1983
|
distance: 1 - similarity
|
|
2136
|
-
// Convert to distance metric
|
|
2137
1984
|
});
|
|
2138
1985
|
}
|
|
2139
1986
|
}
|
|
2140
1987
|
searchResults.sort((a, b) => b.score - a.score);
|
|
2141
1988
|
return searchResults.slice(0, limit);
|
|
2142
1989
|
}
|
|
2143
|
-
/**
|
|
2144
|
-
* Check if metadata matches the filter criteria
|
|
2145
|
-
*/
|
|
2146
1990
|
matchesFilter(metadata, filter) {
|
|
2147
1991
|
if (!metadata) {
|
|
2148
1992
|
return false;
|
|
@@ -2154,9 +1998,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2154
1998
|
}
|
|
2155
1999
|
return true;
|
|
2156
2000
|
}
|
|
2157
|
-
/**
|
|
2158
|
-
* Delete a vector by ID
|
|
2159
|
-
*/
|
|
2160
2001
|
async delete(id) {
|
|
2161
2002
|
await this.initialize();
|
|
2162
2003
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2169,9 +2010,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2169
2010
|
this.vectorCache.delete(id);
|
|
2170
2011
|
this.logger.debug(`Vector deleted: ${id}`);
|
|
2171
2012
|
}
|
|
2172
|
-
/**
|
|
2173
|
-
* Delete multiple vectors by IDs
|
|
2174
|
-
*/
|
|
2175
2013
|
async deleteBatch(ids) {
|
|
2176
2014
|
await this.initialize();
|
|
2177
2015
|
if (ids.length === 0) return;
|
|
@@ -2191,9 +2029,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2191
2029
|
this.logger.debug(`Batch of ${batch.length} vectors deleted`);
|
|
2192
2030
|
}
|
|
2193
2031
|
}
|
|
2194
|
-
/**
|
|
2195
|
-
* Clear all vectors
|
|
2196
|
-
*/
|
|
2197
2032
|
async clear() {
|
|
2198
2033
|
await this.initialize();
|
|
2199
2034
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2204,9 +2039,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2204
2039
|
this.dimensions = null;
|
|
2205
2040
|
this.logger.debug("All vectors cleared");
|
|
2206
2041
|
}
|
|
2207
|
-
/**
|
|
2208
|
-
* Get total count of stored vectors
|
|
2209
|
-
*/
|
|
2210
2042
|
async count() {
|
|
2211
2043
|
await this.initialize();
|
|
2212
2044
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2219,9 +2051,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2219
2051
|
if (typeof raw === "string") return Number.parseInt(raw, 10) || 0;
|
|
2220
2052
|
return raw ?? 0;
|
|
2221
2053
|
}
|
|
2222
|
-
/**
|
|
2223
|
-
* Get a specific vector by ID
|
|
2224
|
-
*/
|
|
2225
2054
|
async get(id) {
|
|
2226
2055
|
await this.initialize();
|
|
2227
2056
|
if (this.vectorCache.has(id)) {
|
|
@@ -2230,7 +2059,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2230
2059
|
return {
|
|
2231
2060
|
...cached,
|
|
2232
2061
|
vector: [...cached.vector],
|
|
2233
|
-
// Return a copy
|
|
2234
2062
|
metadata: cached.metadata ? { ...cached.metadata } : void 0
|
|
2235
2063
|
};
|
|
2236
2064
|
}
|
|
@@ -2265,20 +2093,10 @@ var LibSQLVectorAdapter = class {
|
|
|
2265
2093
|
this.vectorCache.set(id, item);
|
|
2266
2094
|
return item;
|
|
2267
2095
|
}
|
|
2268
|
-
/**
|
|
2269
|
-
* Close the database connection
|
|
2270
|
-
*/
|
|
2271
2096
|
async close() {
|
|
2272
2097
|
this.vectorCache.clear();
|
|
2273
2098
|
this.logger.debug("Vector adapter closed");
|
|
2274
|
-
try {
|
|
2275
|
-
this.client?.close?.();
|
|
2276
|
-
} catch {
|
|
2277
|
-
}
|
|
2278
2099
|
}
|
|
2279
|
-
/**
|
|
2280
|
-
* Get statistics about the vector table and cache
|
|
2281
|
-
*/
|
|
2282
2100
|
async getStats() {
|
|
2283
2101
|
await this.initialize();
|
|
2284
2102
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2289,12 +2107,11 @@ var LibSQLVectorAdapter = class {
|
|
|
2289
2107
|
),
|
|
2290
2108
|
"getStats count"
|
|
2291
2109
|
),
|
|
2292
|
-
// Approximate table size by summing blob/text lengths
|
|
2293
2110
|
this.executeWithRetry(
|
|
2294
2111
|
async () => await this.client.execute({
|
|
2295
|
-
sql: `SELECT
|
|
2296
|
-
COALESCE(SUM(LENGTH(id)),0) +
|
|
2297
|
-
COALESCE(SUM(LENGTH(vector)),0) +
|
|
2112
|
+
sql: `SELECT
|
|
2113
|
+
COALESCE(SUM(LENGTH(id)),0) +
|
|
2114
|
+
COALESCE(SUM(LENGTH(vector)),0) +
|
|
2298
2115
|
COALESCE(SUM(LENGTH(metadata)),0) +
|
|
2299
2116
|
COALESCE(SUM(LENGTH(content)),0) AS size
|
|
2300
2117
|
FROM ${tableName}`
|
|
@@ -2316,6 +2133,66 @@ var LibSQLVectorAdapter = class {
|
|
|
2316
2133
|
};
|
|
2317
2134
|
}
|
|
2318
2135
|
};
|
|
2136
|
+
|
|
2137
|
+
// src/vector-adapter.ts
|
|
2138
|
+
var LibSQLVectorAdapter = class extends LibSQLVectorCore {
|
|
2139
|
+
static {
|
|
2140
|
+
__name(this, "LibSQLVectorAdapter");
|
|
2141
|
+
}
|
|
2142
|
+
constructor(options = {}) {
|
|
2143
|
+
const logger = options.logger ?? createPinoLogger3({
|
|
2144
|
+
name: "libsql-vector-adapter",
|
|
2145
|
+
level: options.debug ? "debug" : "info"
|
|
2146
|
+
});
|
|
2147
|
+
const requestedUrl = options.url ?? "file:./.voltagent/memory.db";
|
|
2148
|
+
let url;
|
|
2149
|
+
if (requestedUrl === ":memory:" || requestedUrl === "file::memory:" || requestedUrl.startsWith("file::memory:")) {
|
|
2150
|
+
url = ":memory:";
|
|
2151
|
+
} else {
|
|
2152
|
+
url = requestedUrl;
|
|
2153
|
+
}
|
|
2154
|
+
if (url.startsWith("file:") && !url.startsWith("file::memory:")) {
|
|
2155
|
+
const dbPath = url.replace("file:", "");
|
|
2156
|
+
const dbDir = path2.dirname(dbPath);
|
|
2157
|
+
if (!fs2.existsSync(dbDir)) {
|
|
2158
|
+
fs2.mkdirSync(dbDir, { recursive: true });
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
const client = createClient3({
|
|
2162
|
+
url,
|
|
2163
|
+
authToken: options.authToken
|
|
2164
|
+
});
|
|
2165
|
+
super(client, options, logger);
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Override to use Buffer for more efficient serialization in Node.js
|
|
2169
|
+
*/
|
|
2170
|
+
serializeVector(vector) {
|
|
2171
|
+
const buffer = Buffer.allocUnsafe(vector.length * 4);
|
|
2172
|
+
for (let i = 0; i < vector.length; i++) {
|
|
2173
|
+
buffer.writeFloatLE(vector[i], i * 4);
|
|
2174
|
+
}
|
|
2175
|
+
return buffer;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Override to use Buffer for more efficient deserialization in Node.js
|
|
2179
|
+
*/
|
|
2180
|
+
deserializeVector(data) {
|
|
2181
|
+
let buffer;
|
|
2182
|
+
if (data instanceof Buffer) {
|
|
2183
|
+
buffer = data;
|
|
2184
|
+
} else if (data instanceof ArrayBuffer) {
|
|
2185
|
+
buffer = Buffer.from(data);
|
|
2186
|
+
} else {
|
|
2187
|
+
buffer = Buffer.from(data);
|
|
2188
|
+
}
|
|
2189
|
+
const vector = [];
|
|
2190
|
+
for (let i = 0; i < buffer.length; i += 4) {
|
|
2191
|
+
vector.push(buffer.readFloatLE(i));
|
|
2192
|
+
}
|
|
2193
|
+
return vector;
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2319
2196
|
export {
|
|
2320
2197
|
LibSQLMemoryAdapter,
|
|
2321
2198
|
LibSQLObservabilityAdapter,
|