@voltagent/libsql 1.0.14 → 1.1.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 +2183 -0
- package/dist/edge.js.map +1 -0
- package/dist/edge.mjs +2155 -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 +209 -340
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +208 -343
- 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 +12 -2
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,7 +332,7 @@ 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)
|
|
335
|
+
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
369
336
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
370
337
|
args: [
|
|
371
338
|
conversationId,
|
|
@@ -375,15 +342,11 @@ var LibSQLMemoryAdapter = class {
|
|
|
375
342
|
safeStringify(message.parts),
|
|
376
343
|
message.metadata ? safeStringify(message.metadata) : null,
|
|
377
344
|
2,
|
|
378
|
-
// format_version
|
|
379
345
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
380
346
|
]
|
|
381
347
|
});
|
|
382
348
|
}, "add message");
|
|
383
349
|
}
|
|
384
|
-
/**
|
|
385
|
-
* Add multiple messages
|
|
386
|
-
*/
|
|
387
350
|
async addMessages(messages, userId, conversationId) {
|
|
388
351
|
await this.initialize();
|
|
389
352
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -395,7 +358,7 @@ var LibSQLMemoryAdapter = class {
|
|
|
395
358
|
await this.executeWithRetry(async () => {
|
|
396
359
|
await this.client.batch(
|
|
397
360
|
messages.map((message) => ({
|
|
398
|
-
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
361
|
+
sql: `INSERT INTO ${messagesTable} (conversation_id, message_id, user_id, role, parts, metadata, format_version, created_at)
|
|
399
362
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
400
363
|
args: [
|
|
401
364
|
conversationId,
|
|
@@ -405,7 +368,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
405
368
|
safeStringify(message.parts),
|
|
406
369
|
message.metadata ? safeStringify(message.metadata) : null,
|
|
407
370
|
2,
|
|
408
|
-
// format_version
|
|
409
371
|
now
|
|
410
372
|
]
|
|
411
373
|
}))
|
|
@@ -478,9 +440,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
478
440
|
);
|
|
479
441
|
}, "save conversation steps");
|
|
480
442
|
}
|
|
481
|
-
/**
|
|
482
|
-
* Get messages with optional filtering
|
|
483
|
-
*/
|
|
484
443
|
async getMessages(userId, conversationId, options) {
|
|
485
444
|
await this.initialize();
|
|
486
445
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -588,9 +547,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
588
547
|
createdAt: row.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
589
548
|
}));
|
|
590
549
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Clear messages for a user
|
|
593
|
-
*/
|
|
594
550
|
async clearMessages(userId, conversationId) {
|
|
595
551
|
await this.initialize();
|
|
596
552
|
const messagesTable = `${this.tablePrefix}_messages`;
|
|
@@ -625,9 +581,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
625
581
|
// ============================================================================
|
|
626
582
|
// Conversation Operations
|
|
627
583
|
// ============================================================================
|
|
628
|
-
/**
|
|
629
|
-
* Create a new conversation
|
|
630
|
-
*/
|
|
631
584
|
async createConversation(input) {
|
|
632
585
|
await this.initialize();
|
|
633
586
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -638,7 +591,7 @@ var LibSQLMemoryAdapter = class {
|
|
|
638
591
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
639
592
|
await this.executeWithRetry(async () => {
|
|
640
593
|
await this.client.execute({
|
|
641
|
-
sql: `INSERT INTO ${conversationsTable} (id, resource_id, user_id, title, metadata, created_at, updated_at)
|
|
594
|
+
sql: `INSERT INTO ${conversationsTable} (id, resource_id, user_id, title, metadata, created_at, updated_at)
|
|
642
595
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
643
596
|
args: [
|
|
644
597
|
input.id,
|
|
@@ -661,9 +614,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
661
614
|
updatedAt: now
|
|
662
615
|
};
|
|
663
616
|
}
|
|
664
|
-
/**
|
|
665
|
-
* Get a conversation by ID
|
|
666
|
-
*/
|
|
667
617
|
async getConversation(id) {
|
|
668
618
|
await this.initialize();
|
|
669
619
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -685,9 +635,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
685
635
|
updatedAt: row.updated_at
|
|
686
636
|
};
|
|
687
637
|
}
|
|
688
|
-
/**
|
|
689
|
-
* Get conversations by resource ID
|
|
690
|
-
*/
|
|
691
638
|
async getConversations(resourceId) {
|
|
692
639
|
await this.initialize();
|
|
693
640
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -705,15 +652,9 @@ var LibSQLMemoryAdapter = class {
|
|
|
705
652
|
updatedAt: row.updated_at
|
|
706
653
|
}));
|
|
707
654
|
}
|
|
708
|
-
/**
|
|
709
|
-
* Get conversations by user ID
|
|
710
|
-
*/
|
|
711
655
|
async getConversationsByUserId(userId, options) {
|
|
712
656
|
return this.queryConversations({ ...options, userId });
|
|
713
657
|
}
|
|
714
|
-
/**
|
|
715
|
-
* Query conversations with filters
|
|
716
|
-
*/
|
|
717
658
|
async queryConversations(options) {
|
|
718
659
|
await this.initialize();
|
|
719
660
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -749,9 +690,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
749
690
|
updatedAt: row.updated_at
|
|
750
691
|
}));
|
|
751
692
|
}
|
|
752
|
-
/**
|
|
753
|
-
* Update a conversation
|
|
754
|
-
*/
|
|
755
693
|
async updateConversation(id, updates) {
|
|
756
694
|
await this.initialize();
|
|
757
695
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -785,9 +723,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
785
723
|
}
|
|
786
724
|
return updated;
|
|
787
725
|
}
|
|
788
|
-
/**
|
|
789
|
-
* Delete a conversation
|
|
790
|
-
*/
|
|
791
726
|
async deleteConversation(id) {
|
|
792
727
|
await this.initialize();
|
|
793
728
|
const conversationsTable = `${this.tablePrefix}_conversations`;
|
|
@@ -799,9 +734,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
799
734
|
// ============================================================================
|
|
800
735
|
// Working Memory Operations
|
|
801
736
|
// ============================================================================
|
|
802
|
-
/**
|
|
803
|
-
* Get working memory
|
|
804
|
-
*/
|
|
805
737
|
async getWorkingMemory(params) {
|
|
806
738
|
await this.initialize();
|
|
807
739
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -821,9 +753,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
821
753
|
}
|
|
822
754
|
return null;
|
|
823
755
|
}
|
|
824
|
-
/**
|
|
825
|
-
* Set working memory
|
|
826
|
-
*/
|
|
827
756
|
async setWorkingMemory(params) {
|
|
828
757
|
await this.initialize();
|
|
829
758
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -857,9 +786,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
857
786
|
}
|
|
858
787
|
}
|
|
859
788
|
}
|
|
860
|
-
/**
|
|
861
|
-
* Delete working memory
|
|
862
|
-
*/
|
|
863
789
|
async deleteWorkingMemory(params) {
|
|
864
790
|
await this.initialize();
|
|
865
791
|
if (params.scope === "conversation" && params.conversationId) {
|
|
@@ -891,9 +817,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
891
817
|
// ============================================================================
|
|
892
818
|
// Workflow State Operations
|
|
893
819
|
// ============================================================================
|
|
894
|
-
/**
|
|
895
|
-
* Get workflow state by execution ID
|
|
896
|
-
*/
|
|
897
820
|
async getWorkflowState(executionId) {
|
|
898
821
|
await this.initialize();
|
|
899
822
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -921,9 +844,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
921
844
|
updatedAt: new Date(row.updated_at)
|
|
922
845
|
};
|
|
923
846
|
}
|
|
924
|
-
/**
|
|
925
|
-
* Query workflow states with optional filters
|
|
926
|
-
*/
|
|
927
847
|
async queryWorkflowRuns(query) {
|
|
928
848
|
await this.initialize();
|
|
929
849
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -978,9 +898,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
978
898
|
updatedAt: new Date(row.updated_at)
|
|
979
899
|
}));
|
|
980
900
|
}
|
|
981
|
-
/**
|
|
982
|
-
* Set workflow state
|
|
983
|
-
*/
|
|
984
901
|
async setWorkflowState(executionId, state) {
|
|
985
902
|
await this.initialize();
|
|
986
903
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -1005,9 +922,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
1005
922
|
]
|
|
1006
923
|
});
|
|
1007
924
|
}
|
|
1008
|
-
/**
|
|
1009
|
-
* Update workflow state
|
|
1010
|
-
*/
|
|
1011
925
|
async updateWorkflowState(executionId, updates) {
|
|
1012
926
|
await this.initialize();
|
|
1013
927
|
const existing = await this.getWorkflowState(executionId);
|
|
@@ -1021,9 +935,6 @@ var LibSQLMemoryAdapter = class {
|
|
|
1021
935
|
};
|
|
1022
936
|
await this.setWorkflowState(executionId, updated);
|
|
1023
937
|
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Get suspended workflow states for a workflow
|
|
1026
|
-
*/
|
|
1027
938
|
async getSuspendedWorkflowStates(workflowId) {
|
|
1028
939
|
await this.initialize();
|
|
1029
940
|
const workflowStatesTable = `${this.tablePrefix}_workflow_states`;
|
|
@@ -1047,23 +958,46 @@ var LibSQLMemoryAdapter = class {
|
|
|
1047
958
|
updatedAt: new Date(row.updated_at)
|
|
1048
959
|
}));
|
|
1049
960
|
}
|
|
1050
|
-
/**
|
|
1051
|
-
* Close database connection
|
|
1052
|
-
*/
|
|
1053
961
|
async close() {
|
|
1054
962
|
this.logger.debug("Closing LibSQL Memory adapter");
|
|
1055
963
|
}
|
|
1056
964
|
};
|
|
1057
965
|
|
|
966
|
+
// src/memory-v2-adapter.ts
|
|
967
|
+
var LibSQLMemoryAdapter = class extends LibSQLMemoryCore {
|
|
968
|
+
static {
|
|
969
|
+
__name(this, "LibSQLMemoryAdapter");
|
|
970
|
+
}
|
|
971
|
+
constructor(options = {}) {
|
|
972
|
+
const url = options.url ?? "file:./.voltagent/memory.db";
|
|
973
|
+
const logger = options.logger || AgentRegistry.getInstance().getGlobalLogger() || createPinoLogger({ name: "libsql-memory" });
|
|
974
|
+
if (url.startsWith("file:")) {
|
|
975
|
+
const dbPath = url.replace("file:", "");
|
|
976
|
+
const dbDir = path.dirname(dbPath);
|
|
977
|
+
if (dbDir && dbDir !== "." && !fs.existsSync(dbDir)) {
|
|
978
|
+
fs.mkdirSync(dbDir, { recursive: true });
|
|
979
|
+
logger.debug(`Created database directory: ${dbDir}`);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
const client = createClient({
|
|
983
|
+
url,
|
|
984
|
+
authToken: options.authToken
|
|
985
|
+
});
|
|
986
|
+
super(client, url, options, logger);
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
|
|
1058
990
|
// src/observability-adapter.ts
|
|
1059
991
|
import { existsSync, mkdirSync } from "fs";
|
|
1060
992
|
import { dirname } from "path";
|
|
1061
993
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1062
|
-
import { safeStringify as safeStringify2 } from "@voltagent/internal/utils";
|
|
1063
994
|
import { createPinoLogger as createPinoLogger2 } from "@voltagent/logger";
|
|
1064
|
-
|
|
995
|
+
|
|
996
|
+
// src/observability-core.ts
|
|
997
|
+
import { safeStringify as safeStringify2 } from "@voltagent/internal/utils";
|
|
998
|
+
var LibSQLObservabilityCore = class {
|
|
1065
999
|
static {
|
|
1066
|
-
__name(this, "
|
|
1000
|
+
__name(this, "LibSQLObservabilityCore");
|
|
1067
1001
|
}
|
|
1068
1002
|
client;
|
|
1069
1003
|
tablePrefix;
|
|
@@ -1071,47 +1005,24 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1071
1005
|
logger;
|
|
1072
1006
|
initialized;
|
|
1073
1007
|
maxSpansPerQuery;
|
|
1074
|
-
constructor(options
|
|
1075
|
-
this.
|
|
1008
|
+
constructor(client, options, logger) {
|
|
1009
|
+
this.client = client;
|
|
1010
|
+
this.logger = logger;
|
|
1076
1011
|
this.tablePrefix = options.tablePrefix || "observability";
|
|
1077
1012
|
this.debug = options.debug || false;
|
|
1078
1013
|
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,
|
|
1014
|
+
this.debugLog("LibSQL observability adapter core initialized", {
|
|
1098
1015
|
tablePrefix: this.tablePrefix,
|
|
1099
1016
|
debug: this.debug,
|
|
1100
1017
|
maxSpansPerQuery: this.maxSpansPerQuery
|
|
1101
1018
|
});
|
|
1102
1019
|
this.initialized = this.initializeDatabase();
|
|
1103
1020
|
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Log a debug message if debug is enabled
|
|
1106
|
-
*/
|
|
1107
1021
|
debugLog(message, data) {
|
|
1108
1022
|
if (this.debug) {
|
|
1109
1023
|
this.logger.debug(`${message}`, data || "");
|
|
1110
1024
|
}
|
|
1111
1025
|
}
|
|
1112
|
-
/**
|
|
1113
|
-
* Initialize database tables for observability
|
|
1114
|
-
*/
|
|
1115
1026
|
async initializeDatabase() {
|
|
1116
1027
|
try {
|
|
1117
1028
|
await this.client.execute(`
|
|
@@ -1138,27 +1049,27 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1138
1049
|
)
|
|
1139
1050
|
`);
|
|
1140
1051
|
await this.client.execute(`
|
|
1141
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_trace_id
|
|
1052
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_trace_id
|
|
1142
1053
|
ON ${this.tablePrefix}_spans(trace_id)
|
|
1143
1054
|
`);
|
|
1144
1055
|
await this.client.execute(`
|
|
1145
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_parent_span_id
|
|
1056
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_parent_span_id
|
|
1146
1057
|
ON ${this.tablePrefix}_spans(parent_span_id)
|
|
1147
1058
|
`);
|
|
1148
1059
|
await this.client.execute(`
|
|
1149
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_start_time
|
|
1060
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_start_time
|
|
1150
1061
|
ON ${this.tablePrefix}_spans(start_time)
|
|
1151
1062
|
`);
|
|
1152
1063
|
await this.client.execute(`
|
|
1153
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_name
|
|
1064
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_name
|
|
1154
1065
|
ON ${this.tablePrefix}_spans(name)
|
|
1155
1066
|
`);
|
|
1156
1067
|
await this.client.execute(`
|
|
1157
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_id
|
|
1068
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_id
|
|
1158
1069
|
ON ${this.tablePrefix}_spans(entity_id)
|
|
1159
1070
|
`);
|
|
1160
1071
|
await this.client.execute(`
|
|
1161
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_type
|
|
1072
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_spans_entity_type
|
|
1162
1073
|
ON ${this.tablePrefix}_spans(entity_type)
|
|
1163
1074
|
`);
|
|
1164
1075
|
await this.client.execute(`
|
|
@@ -1175,15 +1086,15 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1175
1086
|
)
|
|
1176
1087
|
`);
|
|
1177
1088
|
await this.client.execute(`
|
|
1178
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_start_time
|
|
1089
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_start_time
|
|
1179
1090
|
ON ${this.tablePrefix}_traces(start_time DESC)
|
|
1180
1091
|
`);
|
|
1181
1092
|
await this.client.execute(`
|
|
1182
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_id
|
|
1093
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_id
|
|
1183
1094
|
ON ${this.tablePrefix}_traces(entity_id)
|
|
1184
1095
|
`);
|
|
1185
1096
|
await this.client.execute(`
|
|
1186
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_type
|
|
1097
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_traces_entity_type
|
|
1187
1098
|
ON ${this.tablePrefix}_traces(entity_type)
|
|
1188
1099
|
`);
|
|
1189
1100
|
await this.client.execute(`
|
|
@@ -1203,19 +1114,19 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1203
1114
|
)
|
|
1204
1115
|
`);
|
|
1205
1116
|
await this.client.execute(`
|
|
1206
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_trace_id
|
|
1117
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_trace_id
|
|
1207
1118
|
ON ${this.tablePrefix}_logs(trace_id)
|
|
1208
1119
|
`);
|
|
1209
1120
|
await this.client.execute(`
|
|
1210
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_span_id
|
|
1121
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_span_id
|
|
1211
1122
|
ON ${this.tablePrefix}_logs(span_id)
|
|
1212
1123
|
`);
|
|
1213
1124
|
await this.client.execute(`
|
|
1214
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_timestamp
|
|
1125
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_timestamp
|
|
1215
1126
|
ON ${this.tablePrefix}_logs(timestamp DESC)
|
|
1216
1127
|
`);
|
|
1217
1128
|
await this.client.execute(`
|
|
1218
|
-
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_severity
|
|
1129
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tablePrefix}_logs_severity
|
|
1219
1130
|
ON ${this.tablePrefix}_logs(severity_number)
|
|
1220
1131
|
`);
|
|
1221
1132
|
this.debugLog("Database tables initialized successfully");
|
|
@@ -1224,22 +1135,15 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1224
1135
|
throw error;
|
|
1225
1136
|
}
|
|
1226
1137
|
}
|
|
1227
|
-
/**
|
|
1228
|
-
* Ensure database is initialized before operations
|
|
1229
|
-
*/
|
|
1230
1138
|
async ensureInitialized() {
|
|
1231
1139
|
await this.initialized;
|
|
1232
1140
|
}
|
|
1233
|
-
/**
|
|
1234
|
-
* Add a span to the database
|
|
1235
|
-
*/
|
|
1236
1141
|
async addSpan(span) {
|
|
1237
1142
|
await this.ensureInitialized();
|
|
1238
1143
|
try {
|
|
1239
1144
|
const entityId = span.attributes?.["entity.id"] || null;
|
|
1240
1145
|
const entityType = span.attributes?.["entity.type"] || null;
|
|
1241
1146
|
await this.client.batch([
|
|
1242
|
-
// Insert the span with entity columns
|
|
1243
1147
|
{
|
|
1244
1148
|
sql: `
|
|
1245
1149
|
INSERT INTO ${this.tablePrefix}_spans (
|
|
@@ -1270,7 +1174,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1270
1174
|
span.instrumentationScope ? safeStringify2(span.instrumentationScope) : null
|
|
1271
1175
|
]
|
|
1272
1176
|
},
|
|
1273
|
-
// Update or insert trace metadata with entity columns
|
|
1274
1177
|
{
|
|
1275
1178
|
sql: `
|
|
1276
1179
|
INSERT INTO ${this.tablePrefix}_traces (
|
|
@@ -1287,7 +1190,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1287
1190
|
args: [
|
|
1288
1191
|
span.traceId,
|
|
1289
1192
|
span.parentSpanId ? null : span.spanId,
|
|
1290
|
-
// Root span if no parent
|
|
1291
1193
|
entityId,
|
|
1292
1194
|
entityType,
|
|
1293
1195
|
span.startTime,
|
|
@@ -1304,9 +1206,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1304
1206
|
throw error;
|
|
1305
1207
|
}
|
|
1306
1208
|
}
|
|
1307
|
-
/**
|
|
1308
|
-
* Update an existing span
|
|
1309
|
-
*/
|
|
1310
1209
|
async updateSpan(spanId, updates) {
|
|
1311
1210
|
await this.ensureInitialized();
|
|
1312
1211
|
try {
|
|
@@ -1343,7 +1242,7 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1343
1242
|
args.push(spanId);
|
|
1344
1243
|
await this.client.execute({
|
|
1345
1244
|
sql: `
|
|
1346
|
-
UPDATE ${this.tablePrefix}_spans
|
|
1245
|
+
UPDATE ${this.tablePrefix}_spans
|
|
1347
1246
|
SET ${setClauses.join(", ")}
|
|
1348
1247
|
WHERE span_id = ?
|
|
1349
1248
|
`,
|
|
@@ -1369,32 +1268,22 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1369
1268
|
throw error;
|
|
1370
1269
|
}
|
|
1371
1270
|
}
|
|
1372
|
-
/**
|
|
1373
|
-
* Get a span by ID
|
|
1374
|
-
*/
|
|
1375
1271
|
async getSpan(spanId) {
|
|
1376
1272
|
await this.ensureInitialized();
|
|
1377
1273
|
try {
|
|
1378
1274
|
const result = await this.client.execute({
|
|
1379
|
-
sql: `
|
|
1380
|
-
SELECT * FROM ${this.tablePrefix}_spans
|
|
1381
|
-
WHERE span_id = ?
|
|
1382
|
-
`,
|
|
1275
|
+
sql: `SELECT * FROM ${this.tablePrefix}_spans WHERE span_id = ?`,
|
|
1383
1276
|
args: [spanId]
|
|
1384
1277
|
});
|
|
1385
1278
|
if (result.rows.length === 0) {
|
|
1386
1279
|
return null;
|
|
1387
1280
|
}
|
|
1388
|
-
|
|
1389
|
-
return this.rowToSpan(row);
|
|
1281
|
+
return this.rowToSpan(result.rows[0]);
|
|
1390
1282
|
} catch (error) {
|
|
1391
1283
|
this.logger.error("Failed to get span", { error, spanId });
|
|
1392
1284
|
throw error;
|
|
1393
1285
|
}
|
|
1394
1286
|
}
|
|
1395
|
-
/**
|
|
1396
|
-
* Get all spans in a trace
|
|
1397
|
-
*/
|
|
1398
1287
|
async getTrace(traceId) {
|
|
1399
1288
|
await this.ensureInitialized();
|
|
1400
1289
|
try {
|
|
@@ -1413,9 +1302,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1413
1302
|
throw error;
|
|
1414
1303
|
}
|
|
1415
1304
|
}
|
|
1416
|
-
/**
|
|
1417
|
-
* List all traces with optional entity filter
|
|
1418
|
-
*/
|
|
1419
1305
|
async listTraces(limit = 100, offset = 0, filter) {
|
|
1420
1306
|
await this.ensureInitialized();
|
|
1421
1307
|
try {
|
|
@@ -1453,52 +1339,36 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1453
1339
|
throw error;
|
|
1454
1340
|
}
|
|
1455
1341
|
}
|
|
1456
|
-
/**
|
|
1457
|
-
* Delete old spans
|
|
1458
|
-
*/
|
|
1459
1342
|
async deleteOldSpans(beforeTimestamp) {
|
|
1460
1343
|
await this.ensureInitialized();
|
|
1461
1344
|
try {
|
|
1462
1345
|
const beforeDate = new Date(beforeTimestamp).toISOString();
|
|
1463
1346
|
const tracesResult = await this.client.execute({
|
|
1464
|
-
sql: `
|
|
1465
|
-
SELECT DISTINCT trace_id FROM ${this.tablePrefix}_spans
|
|
1466
|
-
WHERE start_time < ?
|
|
1467
|
-
`,
|
|
1347
|
+
sql: `SELECT DISTINCT trace_id FROM ${this.tablePrefix}_spans WHERE start_time < ?`,
|
|
1468
1348
|
args: [beforeDate]
|
|
1469
1349
|
});
|
|
1470
1350
|
const affectedTraceIds = tracesResult.rows.map((row) => row.trace_id);
|
|
1471
1351
|
const deleteResult = await this.client.execute({
|
|
1472
|
-
sql: `
|
|
1473
|
-
DELETE FROM ${this.tablePrefix}_spans
|
|
1474
|
-
WHERE start_time < ?
|
|
1475
|
-
`,
|
|
1352
|
+
sql: `DELETE FROM ${this.tablePrefix}_spans WHERE start_time < ?`,
|
|
1476
1353
|
args: [beforeDate]
|
|
1477
1354
|
});
|
|
1478
1355
|
if (affectedTraceIds.length > 0) {
|
|
1479
1356
|
for (const traceId of affectedTraceIds) {
|
|
1480
1357
|
const countResult = await this.client.execute({
|
|
1481
|
-
sql: `
|
|
1482
|
-
SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans
|
|
1483
|
-
WHERE trace_id = ?
|
|
1484
|
-
`,
|
|
1358
|
+
sql: `SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans WHERE trace_id = ?`,
|
|
1485
1359
|
args: [traceId]
|
|
1486
1360
|
});
|
|
1487
1361
|
const count = countResult.rows[0].count;
|
|
1488
1362
|
if (count === 0) {
|
|
1489
1363
|
await this.client.execute({
|
|
1490
|
-
sql: `
|
|
1491
|
-
DELETE FROM ${this.tablePrefix}_traces
|
|
1492
|
-
WHERE trace_id = ?
|
|
1493
|
-
`,
|
|
1364
|
+
sql: `DELETE FROM ${this.tablePrefix}_traces WHERE trace_id = ?`,
|
|
1494
1365
|
args: [traceId]
|
|
1495
1366
|
});
|
|
1496
1367
|
} else {
|
|
1497
1368
|
await this.client.execute({
|
|
1498
1369
|
sql: `
|
|
1499
1370
|
UPDATE ${this.tablePrefix}_traces
|
|
1500
|
-
SET span_count = ?,
|
|
1501
|
-
updated_at = CURRENT_TIMESTAMP
|
|
1371
|
+
SET span_count = ?, updated_at = CURRENT_TIMESTAMP
|
|
1502
1372
|
WHERE trace_id = ?
|
|
1503
1373
|
`,
|
|
1504
1374
|
args: [count, traceId]
|
|
@@ -1514,9 +1384,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1514
1384
|
throw error;
|
|
1515
1385
|
}
|
|
1516
1386
|
}
|
|
1517
|
-
/**
|
|
1518
|
-
* Clear all spans, traces, and logs
|
|
1519
|
-
*/
|
|
1520
1387
|
async clear() {
|
|
1521
1388
|
await this.ensureInitialized();
|
|
1522
1389
|
try {
|
|
@@ -1531,9 +1398,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1531
1398
|
throw error;
|
|
1532
1399
|
}
|
|
1533
1400
|
}
|
|
1534
|
-
/**
|
|
1535
|
-
* Convert a database row to an ObservabilitySpan
|
|
1536
|
-
*/
|
|
1537
1401
|
rowToSpan(row) {
|
|
1538
1402
|
const span = {
|
|
1539
1403
|
traceId: row.trace_id,
|
|
@@ -1579,9 +1443,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1579
1443
|
}
|
|
1580
1444
|
return span;
|
|
1581
1445
|
}
|
|
1582
|
-
/**
|
|
1583
|
-
* Get statistics about stored spans
|
|
1584
|
-
*/
|
|
1585
1446
|
async getStats() {
|
|
1586
1447
|
await this.ensureInitialized();
|
|
1587
1448
|
try {
|
|
@@ -1589,9 +1450,7 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1589
1450
|
this.client.execute(`SELECT COUNT(*) as count FROM ${this.tablePrefix}_spans`),
|
|
1590
1451
|
this.client.execute(`SELECT COUNT(*) as count FROM ${this.tablePrefix}_traces`),
|
|
1591
1452
|
this.client.execute(`
|
|
1592
|
-
SELECT
|
|
1593
|
-
MIN(start_time) as oldest,
|
|
1594
|
-
MAX(start_time) as newest
|
|
1453
|
+
SELECT MIN(start_time) as oldest, MAX(start_time) as newest
|
|
1595
1454
|
FROM ${this.tablePrefix}_spans
|
|
1596
1455
|
`)
|
|
1597
1456
|
]);
|
|
@@ -1611,9 +1470,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1611
1470
|
throw error;
|
|
1612
1471
|
}
|
|
1613
1472
|
}
|
|
1614
|
-
/**
|
|
1615
|
-
* Save a log record to the database
|
|
1616
|
-
*/
|
|
1617
1473
|
async saveLogRecord(logRecord) {
|
|
1618
1474
|
await this.ensureInitialized();
|
|
1619
1475
|
try {
|
|
@@ -1668,9 +1524,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1668
1524
|
throw error;
|
|
1669
1525
|
}
|
|
1670
1526
|
}
|
|
1671
|
-
/**
|
|
1672
|
-
* Get logs by trace ID
|
|
1673
|
-
*/
|
|
1674
1527
|
async getLogsByTraceId(traceId) {
|
|
1675
1528
|
await this.ensureInitialized();
|
|
1676
1529
|
try {
|
|
@@ -1689,9 +1542,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1689
1542
|
throw error;
|
|
1690
1543
|
}
|
|
1691
1544
|
}
|
|
1692
|
-
/**
|
|
1693
|
-
* Get logs by span ID
|
|
1694
|
-
*/
|
|
1695
1545
|
async getLogsBySpanId(spanId) {
|
|
1696
1546
|
await this.ensureInitialized();
|
|
1697
1547
|
try {
|
|
@@ -1710,9 +1560,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1710
1560
|
throw error;
|
|
1711
1561
|
}
|
|
1712
1562
|
}
|
|
1713
|
-
/**
|
|
1714
|
-
* Query logs with flexible filtering
|
|
1715
|
-
*/
|
|
1716
1563
|
async queryLogs(filter) {
|
|
1717
1564
|
await this.ensureInitialized();
|
|
1718
1565
|
try {
|
|
@@ -1781,18 +1628,12 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1781
1628
|
throw error;
|
|
1782
1629
|
}
|
|
1783
1630
|
}
|
|
1784
|
-
/**
|
|
1785
|
-
* Delete old logs
|
|
1786
|
-
*/
|
|
1787
1631
|
async deleteOldLogs(beforeTimestamp) {
|
|
1788
1632
|
await this.ensureInitialized();
|
|
1789
1633
|
try {
|
|
1790
1634
|
const beforeDate = new Date(beforeTimestamp).toISOString();
|
|
1791
1635
|
const result = await this.client.execute({
|
|
1792
|
-
sql: `
|
|
1793
|
-
DELETE FROM ${this.tablePrefix}_logs
|
|
1794
|
-
WHERE timestamp < ?
|
|
1795
|
-
`,
|
|
1636
|
+
sql: `DELETE FROM ${this.tablePrefix}_logs WHERE timestamp < ?`,
|
|
1796
1637
|
args: [beforeDate]
|
|
1797
1638
|
});
|
|
1798
1639
|
const deletedCount = result.rowsAffected || 0;
|
|
@@ -1803,9 +1644,6 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1803
1644
|
throw error;
|
|
1804
1645
|
}
|
|
1805
1646
|
}
|
|
1806
|
-
/**
|
|
1807
|
-
* Convert a database row to an ObservabilityLogRecord
|
|
1808
|
-
*/
|
|
1809
1647
|
rowToLogRecord(row) {
|
|
1810
1648
|
const log = {
|
|
1811
1649
|
timestamp: row.timestamp,
|
|
@@ -1872,26 +1710,55 @@ var LibSQLObservabilityAdapter = class {
|
|
|
1872
1710
|
description: "Persists spans and logs to a LibSQL/Turso database for long-term retention."
|
|
1873
1711
|
};
|
|
1874
1712
|
}
|
|
1875
|
-
/**
|
|
1876
|
-
* Close the database connection
|
|
1877
|
-
*/
|
|
1878
1713
|
async close() {
|
|
1879
1714
|
this.debugLog("LibSQL observability adapter closed");
|
|
1880
1715
|
}
|
|
1881
1716
|
};
|
|
1882
1717
|
|
|
1718
|
+
// src/observability-adapter.ts
|
|
1719
|
+
var LibSQLObservabilityAdapter = class extends LibSQLObservabilityCore {
|
|
1720
|
+
static {
|
|
1721
|
+
__name(this, "LibSQLObservabilityAdapter");
|
|
1722
|
+
}
|
|
1723
|
+
constructor(options = {}) {
|
|
1724
|
+
const url = options.url || "file:./.voltagent/observability.db";
|
|
1725
|
+
const logger = options.logger || createPinoLogger2({ name: "libsql-observability" });
|
|
1726
|
+
if (url.startsWith("file:") && !url.includes(":memory:")) {
|
|
1727
|
+
const filePath = url.substring(5);
|
|
1728
|
+
const dir = dirname(filePath);
|
|
1729
|
+
if (dir && dir !== "." && !existsSync(dir)) {
|
|
1730
|
+
try {
|
|
1731
|
+
mkdirSync(dir, { recursive: true });
|
|
1732
|
+
if (options.debug) {
|
|
1733
|
+
logger.debug("Created directory for database", { dir });
|
|
1734
|
+
}
|
|
1735
|
+
} catch (error) {
|
|
1736
|
+
logger.warn("Failed to create directory for database", { dir, error });
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
const client = createClient2({
|
|
1741
|
+
url,
|
|
1742
|
+
authToken: options.authToken
|
|
1743
|
+
});
|
|
1744
|
+
super(client, options, logger);
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
|
|
1883
1748
|
// src/vector-adapter.ts
|
|
1884
1749
|
import fs2 from "fs";
|
|
1885
1750
|
import path2 from "path";
|
|
1886
1751
|
import { createClient as createClient3 } from "@libsql/client";
|
|
1752
|
+
import { createPinoLogger as createPinoLogger3 } from "@voltagent/logger";
|
|
1753
|
+
|
|
1754
|
+
// src/vector-core.ts
|
|
1887
1755
|
import {
|
|
1888
1756
|
cosineSimilarity
|
|
1889
1757
|
} from "@voltagent/core";
|
|
1890
1758
|
import { safeStringify as safeStringify3 } from "@voltagent/internal";
|
|
1891
|
-
|
|
1892
|
-
var LibSQLVectorAdapter = class {
|
|
1759
|
+
var LibSQLVectorCore = class {
|
|
1893
1760
|
static {
|
|
1894
|
-
__name(this, "
|
|
1761
|
+
__name(this, "LibSQLVectorCore");
|
|
1895
1762
|
}
|
|
1896
1763
|
client;
|
|
1897
1764
|
tablePrefix;
|
|
@@ -1902,11 +1769,11 @@ var LibSQLVectorAdapter = class {
|
|
|
1902
1769
|
logger;
|
|
1903
1770
|
maxRetries;
|
|
1904
1771
|
retryDelayMs;
|
|
1905
|
-
url;
|
|
1906
1772
|
initialized = false;
|
|
1907
1773
|
vectorCache;
|
|
1908
1774
|
dimensions = null;
|
|
1909
|
-
constructor(options
|
|
1775
|
+
constructor(client, options, logger) {
|
|
1776
|
+
this.client = client;
|
|
1910
1777
|
this.tablePrefix = options.tablePrefix ?? "voltagent";
|
|
1911
1778
|
this.maxVectorDimensions = options.maxVectorDimensions ?? 1536;
|
|
1912
1779
|
this.cacheSize = options.cacheSize ?? 100;
|
|
@@ -1914,28 +1781,32 @@ var LibSQLVectorAdapter = class {
|
|
|
1914
1781
|
this.maxRetries = options.maxRetries ?? 3;
|
|
1915
1782
|
this.retryDelayMs = options.retryDelayMs ?? 100;
|
|
1916
1783
|
this.debug = options.debug ?? false;
|
|
1917
|
-
this.logger =
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1784
|
+
this.logger = logger;
|
|
1785
|
+
this.vectorCache = /* @__PURE__ */ new Map();
|
|
1786
|
+
}
|
|
1787
|
+
/**
|
|
1788
|
+
* Serialize a vector to binary format
|
|
1789
|
+
* Uses ArrayBuffer/DataView for cross-platform compatibility
|
|
1790
|
+
*/
|
|
1791
|
+
serializeVector(vector) {
|
|
1792
|
+
const buffer = new ArrayBuffer(vector.length * 4);
|
|
1793
|
+
const view = new DataView(buffer);
|
|
1794
|
+
for (let i = 0; i < vector.length; i++) {
|
|
1795
|
+
view.setFloat32(i * 4, vector[i], true);
|
|
1926
1796
|
}
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1797
|
+
return new Uint8Array(buffer);
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Deserialize a vector from binary format
|
|
1801
|
+
*/
|
|
1802
|
+
deserializeVector(data) {
|
|
1803
|
+
const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
1804
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1805
|
+
const vector = [];
|
|
1806
|
+
for (let i = 0; i < bytes.length; i += 4) {
|
|
1807
|
+
vector.push(view.getFloat32(i, true));
|
|
1933
1808
|
}
|
|
1934
|
-
|
|
1935
|
-
url: this.url,
|
|
1936
|
-
authToken: options.authToken
|
|
1937
|
-
});
|
|
1938
|
-
this.vectorCache = /* @__PURE__ */ new Map();
|
|
1809
|
+
return vector;
|
|
1939
1810
|
}
|
|
1940
1811
|
/**
|
|
1941
1812
|
* Initialize the database schema
|
|
@@ -1944,8 +1815,7 @@ var LibSQLVectorAdapter = class {
|
|
|
1944
1815
|
if (this.initialized) return;
|
|
1945
1816
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
1946
1817
|
try {
|
|
1947
|
-
await this.client.
|
|
1948
|
-
BEGIN;
|
|
1818
|
+
await this.client.execute(`
|
|
1949
1819
|
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
1950
1820
|
id TEXT PRIMARY KEY,
|
|
1951
1821
|
vector BLOB NOT NULL,
|
|
@@ -1954,11 +1824,14 @@ var LibSQLVectorAdapter = class {
|
|
|
1954
1824
|
content TEXT,
|
|
1955
1825
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1956
1826
|
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;
|
|
1827
|
+
)
|
|
1961
1828
|
`);
|
|
1829
|
+
await this.client.execute(
|
|
1830
|
+
`CREATE INDEX IF NOT EXISTS idx_${tableName}_created ON ${tableName}(created_at)`
|
|
1831
|
+
);
|
|
1832
|
+
await this.client.execute(
|
|
1833
|
+
`CREATE INDEX IF NOT EXISTS idx_${tableName}_dimensions ON ${tableName}(dimensions)`
|
|
1834
|
+
);
|
|
1962
1835
|
this.initialized = true;
|
|
1963
1836
|
this.logger.debug("Vector adapter initialized");
|
|
1964
1837
|
} catch (error) {
|
|
@@ -1966,34 +1839,6 @@ var LibSQLVectorAdapter = class {
|
|
|
1966
1839
|
throw error;
|
|
1967
1840
|
}
|
|
1968
1841
|
}
|
|
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
1842
|
/**
|
|
1998
1843
|
* Execute a database operation with retries
|
|
1999
1844
|
*/
|
|
@@ -2015,9 +1860,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2015
1860
|
this.logger.error(`Operation failed after ${this.maxRetries} attempts: ${context}`, lastError);
|
|
2016
1861
|
throw lastError;
|
|
2017
1862
|
}
|
|
2018
|
-
/**
|
|
2019
|
-
* Store a vector with associated metadata
|
|
2020
|
-
*/
|
|
2021
1863
|
async store(id, vector, metadata) {
|
|
2022
1864
|
await this.initialize();
|
|
2023
1865
|
if (!Array.isArray(vector) || vector.length === 0) {
|
|
@@ -2041,7 +1883,7 @@ var LibSQLVectorAdapter = class {
|
|
|
2041
1883
|
await this.executeWithRetry(async () => {
|
|
2042
1884
|
await this.client.execute({
|
|
2043
1885
|
sql: `
|
|
2044
|
-
INSERT OR REPLACE INTO ${tableName}
|
|
1886
|
+
INSERT OR REPLACE INTO ${tableName}
|
|
2045
1887
|
(id, vector, dimensions, metadata, updated_at)
|
|
2046
1888
|
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
2047
1889
|
`,
|
|
@@ -2055,9 +1897,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2055
1897
|
this.vectorCache.set(id, { id, vector, metadata });
|
|
2056
1898
|
this.logger.debug(`Vector stored: ${id} (${vector.length} dimensions)`);
|
|
2057
1899
|
}
|
|
2058
|
-
/**
|
|
2059
|
-
* Store multiple vectors in batch
|
|
2060
|
-
*/
|
|
2061
1900
|
async storeBatch(items) {
|
|
2062
1901
|
await this.initialize();
|
|
2063
1902
|
if (items.length === 0) return;
|
|
@@ -2090,9 +1929,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2090
1929
|
this.logger.debug(`Batch of ${batch.length} vectors stored`);
|
|
2091
1930
|
}
|
|
2092
1931
|
}
|
|
2093
|
-
/**
|
|
2094
|
-
* Search for similar vectors using cosine similarity
|
|
2095
|
-
*/
|
|
2096
1932
|
async search(queryVector, options) {
|
|
2097
1933
|
await this.initialize();
|
|
2098
1934
|
const { limit = 10, threshold = 0, filter } = options || {};
|
|
@@ -2133,16 +1969,12 @@ var LibSQLVectorAdapter = class {
|
|
|
2133
1969
|
content,
|
|
2134
1970
|
score,
|
|
2135
1971
|
distance: 1 - similarity
|
|
2136
|
-
// Convert to distance metric
|
|
2137
1972
|
});
|
|
2138
1973
|
}
|
|
2139
1974
|
}
|
|
2140
1975
|
searchResults.sort((a, b) => b.score - a.score);
|
|
2141
1976
|
return searchResults.slice(0, limit);
|
|
2142
1977
|
}
|
|
2143
|
-
/**
|
|
2144
|
-
* Check if metadata matches the filter criteria
|
|
2145
|
-
*/
|
|
2146
1978
|
matchesFilter(metadata, filter) {
|
|
2147
1979
|
if (!metadata) {
|
|
2148
1980
|
return false;
|
|
@@ -2154,9 +1986,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2154
1986
|
}
|
|
2155
1987
|
return true;
|
|
2156
1988
|
}
|
|
2157
|
-
/**
|
|
2158
|
-
* Delete a vector by ID
|
|
2159
|
-
*/
|
|
2160
1989
|
async delete(id) {
|
|
2161
1990
|
await this.initialize();
|
|
2162
1991
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2169,9 +1998,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2169
1998
|
this.vectorCache.delete(id);
|
|
2170
1999
|
this.logger.debug(`Vector deleted: ${id}`);
|
|
2171
2000
|
}
|
|
2172
|
-
/**
|
|
2173
|
-
* Delete multiple vectors by IDs
|
|
2174
|
-
*/
|
|
2175
2001
|
async deleteBatch(ids) {
|
|
2176
2002
|
await this.initialize();
|
|
2177
2003
|
if (ids.length === 0) return;
|
|
@@ -2191,9 +2017,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2191
2017
|
this.logger.debug(`Batch of ${batch.length} vectors deleted`);
|
|
2192
2018
|
}
|
|
2193
2019
|
}
|
|
2194
|
-
/**
|
|
2195
|
-
* Clear all vectors
|
|
2196
|
-
*/
|
|
2197
2020
|
async clear() {
|
|
2198
2021
|
await this.initialize();
|
|
2199
2022
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2204,9 +2027,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2204
2027
|
this.dimensions = null;
|
|
2205
2028
|
this.logger.debug("All vectors cleared");
|
|
2206
2029
|
}
|
|
2207
|
-
/**
|
|
2208
|
-
* Get total count of stored vectors
|
|
2209
|
-
*/
|
|
2210
2030
|
async count() {
|
|
2211
2031
|
await this.initialize();
|
|
2212
2032
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2219,9 +2039,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2219
2039
|
if (typeof raw === "string") return Number.parseInt(raw, 10) || 0;
|
|
2220
2040
|
return raw ?? 0;
|
|
2221
2041
|
}
|
|
2222
|
-
/**
|
|
2223
|
-
* Get a specific vector by ID
|
|
2224
|
-
*/
|
|
2225
2042
|
async get(id) {
|
|
2226
2043
|
await this.initialize();
|
|
2227
2044
|
if (this.vectorCache.has(id)) {
|
|
@@ -2230,7 +2047,6 @@ var LibSQLVectorAdapter = class {
|
|
|
2230
2047
|
return {
|
|
2231
2048
|
...cached,
|
|
2232
2049
|
vector: [...cached.vector],
|
|
2233
|
-
// Return a copy
|
|
2234
2050
|
metadata: cached.metadata ? { ...cached.metadata } : void 0
|
|
2235
2051
|
};
|
|
2236
2052
|
}
|
|
@@ -2265,20 +2081,10 @@ var LibSQLVectorAdapter = class {
|
|
|
2265
2081
|
this.vectorCache.set(id, item);
|
|
2266
2082
|
return item;
|
|
2267
2083
|
}
|
|
2268
|
-
/**
|
|
2269
|
-
* Close the database connection
|
|
2270
|
-
*/
|
|
2271
2084
|
async close() {
|
|
2272
2085
|
this.vectorCache.clear();
|
|
2273
2086
|
this.logger.debug("Vector adapter closed");
|
|
2274
|
-
try {
|
|
2275
|
-
this.client?.close?.();
|
|
2276
|
-
} catch {
|
|
2277
|
-
}
|
|
2278
2087
|
}
|
|
2279
|
-
/**
|
|
2280
|
-
* Get statistics about the vector table and cache
|
|
2281
|
-
*/
|
|
2282
2088
|
async getStats() {
|
|
2283
2089
|
await this.initialize();
|
|
2284
2090
|
const tableName = `${this.tablePrefix}_vectors`;
|
|
@@ -2289,12 +2095,11 @@ var LibSQLVectorAdapter = class {
|
|
|
2289
2095
|
),
|
|
2290
2096
|
"getStats count"
|
|
2291
2097
|
),
|
|
2292
|
-
// Approximate table size by summing blob/text lengths
|
|
2293
2098
|
this.executeWithRetry(
|
|
2294
2099
|
async () => await this.client.execute({
|
|
2295
|
-
sql: `SELECT
|
|
2296
|
-
COALESCE(SUM(LENGTH(id)),0) +
|
|
2297
|
-
COALESCE(SUM(LENGTH(vector)),0) +
|
|
2100
|
+
sql: `SELECT
|
|
2101
|
+
COALESCE(SUM(LENGTH(id)),0) +
|
|
2102
|
+
COALESCE(SUM(LENGTH(vector)),0) +
|
|
2298
2103
|
COALESCE(SUM(LENGTH(metadata)),0) +
|
|
2299
2104
|
COALESCE(SUM(LENGTH(content)),0) AS size
|
|
2300
2105
|
FROM ${tableName}`
|
|
@@ -2316,6 +2121,66 @@ var LibSQLVectorAdapter = class {
|
|
|
2316
2121
|
};
|
|
2317
2122
|
}
|
|
2318
2123
|
};
|
|
2124
|
+
|
|
2125
|
+
// src/vector-adapter.ts
|
|
2126
|
+
var LibSQLVectorAdapter = class extends LibSQLVectorCore {
|
|
2127
|
+
static {
|
|
2128
|
+
__name(this, "LibSQLVectorAdapter");
|
|
2129
|
+
}
|
|
2130
|
+
constructor(options = {}) {
|
|
2131
|
+
const logger = options.logger ?? createPinoLogger3({
|
|
2132
|
+
name: "libsql-vector-adapter",
|
|
2133
|
+
level: options.debug ? "debug" : "info"
|
|
2134
|
+
});
|
|
2135
|
+
const requestedUrl = options.url ?? "file:./.voltagent/memory.db";
|
|
2136
|
+
let url;
|
|
2137
|
+
if (requestedUrl === ":memory:" || requestedUrl === "file::memory:" || requestedUrl.startsWith("file::memory:")) {
|
|
2138
|
+
url = ":memory:";
|
|
2139
|
+
} else {
|
|
2140
|
+
url = requestedUrl;
|
|
2141
|
+
}
|
|
2142
|
+
if (url.startsWith("file:") && !url.startsWith("file::memory:")) {
|
|
2143
|
+
const dbPath = url.replace("file:", "");
|
|
2144
|
+
const dbDir = path2.dirname(dbPath);
|
|
2145
|
+
if (!fs2.existsSync(dbDir)) {
|
|
2146
|
+
fs2.mkdirSync(dbDir, { recursive: true });
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
const client = createClient3({
|
|
2150
|
+
url,
|
|
2151
|
+
authToken: options.authToken
|
|
2152
|
+
});
|
|
2153
|
+
super(client, options, logger);
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Override to use Buffer for more efficient serialization in Node.js
|
|
2157
|
+
*/
|
|
2158
|
+
serializeVector(vector) {
|
|
2159
|
+
const buffer = Buffer.allocUnsafe(vector.length * 4);
|
|
2160
|
+
for (let i = 0; i < vector.length; i++) {
|
|
2161
|
+
buffer.writeFloatLE(vector[i], i * 4);
|
|
2162
|
+
}
|
|
2163
|
+
return buffer;
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Override to use Buffer for more efficient deserialization in Node.js
|
|
2167
|
+
*/
|
|
2168
|
+
deserializeVector(data) {
|
|
2169
|
+
let buffer;
|
|
2170
|
+
if (data instanceof Buffer) {
|
|
2171
|
+
buffer = data;
|
|
2172
|
+
} else if (data instanceof ArrayBuffer) {
|
|
2173
|
+
buffer = Buffer.from(data);
|
|
2174
|
+
} else {
|
|
2175
|
+
buffer = Buffer.from(data);
|
|
2176
|
+
}
|
|
2177
|
+
const vector = [];
|
|
2178
|
+
for (let i = 0; i < buffer.length; i += 4) {
|
|
2179
|
+
vector.push(buffer.readFloatLE(i));
|
|
2180
|
+
}
|
|
2181
|
+
return vector;
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2319
2184
|
export {
|
|
2320
2185
|
LibSQLMemoryAdapter,
|
|
2321
2186
|
LibSQLObservabilityAdapter,
|