@elizaos/plugin-sql 1.0.0-beta.3 → 1.0.0-beta.33
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/LICENSE +1 -1
- package/dist/index.js +208 -18
- package/dist/index.js.map +1 -1
- package/dist/migrate.js +6 -1
- package/dist/migrate.js.map +1 -1
- package/package.json +13 -6
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 Shaw Walters
|
|
3
|
+
Copyright (c) 2025 Shaw Walters and elizaOS Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ import { v4 } from "uuid";
|
|
|
34
34
|
// src/schema/embedding.ts
|
|
35
35
|
import { sql as sql6 } from "drizzle-orm";
|
|
36
36
|
import { check as check2, foreignKey as foreignKey2, index as index2, pgTable as pgTable6, uuid as uuid6, vector as vector2 } from "drizzle-orm/pg-core";
|
|
37
|
+
import { VECTOR_DIMS } from "@elizaos/core";
|
|
37
38
|
|
|
38
39
|
// src/schema/memory.ts
|
|
39
40
|
import { relations, sql as sql5 } from "drizzle-orm";
|
|
@@ -232,14 +233,6 @@ var memoryRelations = relations(memoryTable, ({ one }) => ({
|
|
|
232
233
|
}));
|
|
233
234
|
|
|
234
235
|
// src/schema/embedding.ts
|
|
235
|
-
var VECTOR_DIMS = {
|
|
236
|
-
SMALL: 384,
|
|
237
|
-
MEDIUM: 512,
|
|
238
|
-
LARGE: 768,
|
|
239
|
-
XL: 1024,
|
|
240
|
-
XXL: 1536,
|
|
241
|
-
XXXL: 3072
|
|
242
|
-
};
|
|
243
236
|
var DIMENSION_MAP = {
|
|
244
237
|
[VECTOR_DIMS.SMALL]: "dim384",
|
|
245
238
|
[VECTOR_DIMS.MEDIUM]: "dim512",
|
|
@@ -484,9 +477,12 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
484
477
|
const existingAgent = agents.find(
|
|
485
478
|
(a) => a.name === agent.name
|
|
486
479
|
);
|
|
487
|
-
if (
|
|
488
|
-
|
|
480
|
+
if (existingAgent) {
|
|
481
|
+
return existingAgent;
|
|
489
482
|
}
|
|
483
|
+
agent.id = agent.id || v4();
|
|
484
|
+
await this.createAgent(agent);
|
|
485
|
+
return agent;
|
|
490
486
|
}
|
|
491
487
|
/**
|
|
492
488
|
* Asynchronously ensures that the given embedding dimension is valid for the agent.
|
|
@@ -565,10 +561,13 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
565
561
|
async updateAgent(agentId, agent) {
|
|
566
562
|
return this.withDatabase(async () => {
|
|
567
563
|
try {
|
|
568
|
-
if (!
|
|
564
|
+
if (!agentId) {
|
|
569
565
|
throw new Error("Agent ID is required for update");
|
|
570
566
|
}
|
|
571
567
|
await this.db.transaction(async (tx) => {
|
|
568
|
+
if (agent?.settings) {
|
|
569
|
+
agent.settings = await this.mergeAgentSettings(tx, agentId, agent.settings);
|
|
570
|
+
}
|
|
572
571
|
await tx.update(agentTable).set({
|
|
573
572
|
...agent,
|
|
574
573
|
updatedAt: Date.now()
|
|
@@ -588,6 +587,39 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
588
587
|
}
|
|
589
588
|
});
|
|
590
589
|
}
|
|
590
|
+
/**
|
|
591
|
+
* Merges updated agent settings with existing settings in the database,
|
|
592
|
+
* with special handling for nested objects like secrets.
|
|
593
|
+
* @param tx - The database transaction
|
|
594
|
+
* @param agentId - The ID of the agent
|
|
595
|
+
* @param updatedSettings - The settings object with updates
|
|
596
|
+
* @returns The merged settings object
|
|
597
|
+
* @private
|
|
598
|
+
*/
|
|
599
|
+
async mergeAgentSettings(tx, agentId, updatedSettings) {
|
|
600
|
+
const currentAgent = await tx.select({ settings: agentTable.settings }).from(agentTable).where(eq(agentTable.id, agentId)).limit(1);
|
|
601
|
+
if (currentAgent.length === 0 || !currentAgent[0].settings) {
|
|
602
|
+
return updatedSettings;
|
|
603
|
+
}
|
|
604
|
+
const currentSettings = currentAgent[0].settings;
|
|
605
|
+
if (updatedSettings.secrets) {
|
|
606
|
+
const currentSecrets = currentSettings.secrets || {};
|
|
607
|
+
const updatedSecrets = updatedSettings.secrets;
|
|
608
|
+
const mergedSecrets = { ...currentSecrets };
|
|
609
|
+
for (const [key, value] of Object.entries(updatedSecrets)) {
|
|
610
|
+
if (value === null) {
|
|
611
|
+
delete mergedSecrets[key];
|
|
612
|
+
} else {
|
|
613
|
+
mergedSecrets[key] = value;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
updatedSettings.secrets = mergedSecrets;
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
...currentSettings,
|
|
620
|
+
...updatedSettings
|
|
621
|
+
};
|
|
622
|
+
}
|
|
591
623
|
/**
|
|
592
624
|
* Asynchronously deletes an agent with the specified UUID and all related entries.
|
|
593
625
|
*
|
|
@@ -595,11 +627,161 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
595
627
|
* @returns {Promise<boolean>} - A boolean indicating if the deletion was successful.
|
|
596
628
|
*/
|
|
597
629
|
async deleteAgent(agentId) {
|
|
630
|
+
logger.debug(`[DB] Starting deletion of agent with ID: ${agentId}`);
|
|
598
631
|
return this.withDatabase(async () => {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
632
|
+
try {
|
|
633
|
+
logger.debug(`[DB] Beginning database transaction for deleting agent: ${agentId}`);
|
|
634
|
+
const deletePromise = new Promise((resolve, reject) => {
|
|
635
|
+
const timeoutId = setTimeout(() => {
|
|
636
|
+
logger.error(`[DB] Transaction timeout reached for agent deletion: ${agentId}`);
|
|
637
|
+
reject(new Error("Database transaction timeout"));
|
|
638
|
+
}, 3e4);
|
|
639
|
+
this.db.transaction(async (tx) => {
|
|
640
|
+
try {
|
|
641
|
+
logger.debug(`[DB] Fetching entities for agent: ${agentId}`);
|
|
642
|
+
const entities = await tx.select({ entityId: entityTable.id }).from(entityTable).where(eq(entityTable.agentId, agentId));
|
|
643
|
+
const entityIds = entities.map((e) => e.entityId);
|
|
644
|
+
logger.debug(
|
|
645
|
+
`[DB] Found ${entityIds.length} entities to delete for agent ${agentId}`
|
|
646
|
+
);
|
|
647
|
+
logger.debug(`[DB] Fetching rooms for agent: ${agentId}`);
|
|
648
|
+
const rooms = await tx.select({ roomId: roomTable.id }).from(roomTable).where(eq(roomTable.agentId, agentId));
|
|
649
|
+
const roomIds = rooms.map((r) => r.roomId);
|
|
650
|
+
logger.debug(`[DB] Found ${roomIds.length} rooms for agent ${agentId}`);
|
|
651
|
+
logger.debug(
|
|
652
|
+
`[DB] Explicitly deleting ALL logs with matching entityIds and roomIds`
|
|
653
|
+
);
|
|
654
|
+
if (entityIds.length > 0) {
|
|
655
|
+
logger.debug(`[DB] Deleting logs for ${entityIds.length} entities (first batch)`);
|
|
656
|
+
const BATCH_SIZE = 50;
|
|
657
|
+
for (let i = 0; i < entityIds.length; i += BATCH_SIZE) {
|
|
658
|
+
const batch = entityIds.slice(i, i + BATCH_SIZE);
|
|
659
|
+
logger.debug(
|
|
660
|
+
`[DB] Processing entity logs batch ${i / BATCH_SIZE + 1} with ${batch.length} entities`
|
|
661
|
+
);
|
|
662
|
+
await tx.delete(logTable).where(inArray(logTable.entityId, batch));
|
|
663
|
+
}
|
|
664
|
+
logger.debug(`[DB] Entity logs deletion completed successfully`);
|
|
665
|
+
}
|
|
666
|
+
if (roomIds.length > 0) {
|
|
667
|
+
logger.debug(`[DB] Deleting logs for ${roomIds.length} rooms (first batch)`);
|
|
668
|
+
const BATCH_SIZE = 50;
|
|
669
|
+
for (let i = 0; i < roomIds.length; i += BATCH_SIZE) {
|
|
670
|
+
const batch = roomIds.slice(i, i + BATCH_SIZE);
|
|
671
|
+
logger.debug(
|
|
672
|
+
`[DB] Processing room logs batch ${i / BATCH_SIZE + 1} with ${batch.length} rooms`
|
|
673
|
+
);
|
|
674
|
+
await tx.delete(logTable).where(inArray(logTable.roomId, batch));
|
|
675
|
+
}
|
|
676
|
+
logger.debug(`[DB] Room logs deletion completed successfully`);
|
|
677
|
+
}
|
|
678
|
+
let memoryIds = [];
|
|
679
|
+
if (entityIds.length > 0) {
|
|
680
|
+
logger.debug(`[DB] Finding memories belonging to entities`);
|
|
681
|
+
const memories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.entityId, entityIds));
|
|
682
|
+
memoryIds = memories.map((m) => m.id);
|
|
683
|
+
logger.debug(`[DB] Found ${memoryIds.length} memories belonging to entities`);
|
|
684
|
+
}
|
|
685
|
+
logger.debug(`[DB] Finding memories belonging to agent directly`);
|
|
686
|
+
const agentMemories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(eq(memoryTable.agentId, agentId));
|
|
687
|
+
memoryIds = [...memoryIds, ...agentMemories.map((m) => m.id)];
|
|
688
|
+
logger.debug(`[DB] Found total of ${memoryIds.length} memories to delete`);
|
|
689
|
+
if (roomIds.length > 0) {
|
|
690
|
+
logger.debug(`[DB] Finding memories belonging to rooms`);
|
|
691
|
+
const roomMemories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.roomId, roomIds));
|
|
692
|
+
memoryIds = [...memoryIds, ...roomMemories.map((m) => m.id)];
|
|
693
|
+
logger.debug(`[DB] Updated total to ${memoryIds.length} memories to delete`);
|
|
694
|
+
}
|
|
695
|
+
if (memoryIds.length > 0) {
|
|
696
|
+
logger.debug(`[DB] Deleting embeddings for ${memoryIds.length} memories`);
|
|
697
|
+
const BATCH_SIZE = 100;
|
|
698
|
+
for (let i = 0; i < memoryIds.length; i += BATCH_SIZE) {
|
|
699
|
+
const batch = memoryIds.slice(i, i + BATCH_SIZE);
|
|
700
|
+
await tx.delete(embeddingTable).where(inArray(embeddingTable.memoryId, batch));
|
|
701
|
+
}
|
|
702
|
+
logger.debug(`[DB] Embeddings deleted successfully`);
|
|
703
|
+
}
|
|
704
|
+
if (memoryIds.length > 0) {
|
|
705
|
+
logger.debug(`[DB] Deleting ${memoryIds.length} memories`);
|
|
706
|
+
const BATCH_SIZE = 100;
|
|
707
|
+
for (let i = 0; i < memoryIds.length; i += BATCH_SIZE) {
|
|
708
|
+
const batch = memoryIds.slice(i, i + BATCH_SIZE);
|
|
709
|
+
await tx.delete(memoryTable).where(inArray(memoryTable.id, batch));
|
|
710
|
+
}
|
|
711
|
+
logger.debug(`[DB] Memories deleted successfully`);
|
|
712
|
+
}
|
|
713
|
+
if (entityIds.length > 0) {
|
|
714
|
+
logger.debug(`[DB] Deleting components for entities`);
|
|
715
|
+
await tx.delete(componentTable).where(inArray(componentTable.entityId, entityIds));
|
|
716
|
+
logger.debug(`[DB] Components deleted successfully`);
|
|
717
|
+
}
|
|
718
|
+
if (entityIds.length > 0) {
|
|
719
|
+
logger.debug(`[DB] Deleting source entity references in components`);
|
|
720
|
+
await tx.delete(componentTable).where(inArray(componentTable.sourceEntityId, entityIds));
|
|
721
|
+
logger.debug(`[DB] Source entity references deleted successfully`);
|
|
722
|
+
}
|
|
723
|
+
if (roomIds.length > 0) {
|
|
724
|
+
logger.debug(`[DB] Deleting participations for rooms`);
|
|
725
|
+
await tx.delete(participantTable).where(inArray(participantTable.roomId, roomIds));
|
|
726
|
+
logger.debug(`[DB] Participations deleted for rooms`);
|
|
727
|
+
}
|
|
728
|
+
logger.debug(`[DB] Deleting agent participations`);
|
|
729
|
+
await tx.delete(participantTable).where(eq(participantTable.agentId, agentId));
|
|
730
|
+
logger.debug(`[DB] Agent participations deleted`);
|
|
731
|
+
if (roomIds.length > 0) {
|
|
732
|
+
logger.debug(`[DB] Deleting rooms`);
|
|
733
|
+
await tx.delete(roomTable).where(inArray(roomTable.id, roomIds));
|
|
734
|
+
logger.debug(`[DB] Rooms deleted successfully`);
|
|
735
|
+
}
|
|
736
|
+
logger.debug(`[DB] Deleting cache entries`);
|
|
737
|
+
await tx.delete(cacheTable).where(eq(cacheTable.agentId, agentId));
|
|
738
|
+
logger.debug(`[DB] Cache entries deleted successfully`);
|
|
739
|
+
logger.debug(`[DB] Deleting relationships`);
|
|
740
|
+
if (entityIds.length > 0) {
|
|
741
|
+
await tx.delete(relationshipTable).where(inArray(relationshipTable.sourceEntityId, entityIds));
|
|
742
|
+
await tx.delete(relationshipTable).where(inArray(relationshipTable.targetEntityId, entityIds));
|
|
743
|
+
}
|
|
744
|
+
await tx.delete(relationshipTable).where(eq(relationshipTable.agentId, agentId));
|
|
745
|
+
logger.debug(`[DB] Relationships deleted successfully`);
|
|
746
|
+
if (entityIds.length > 0) {
|
|
747
|
+
logger.debug(`[DB] Deleting entities`);
|
|
748
|
+
await tx.delete(entityTable).where(eq(entityTable.agentId, agentId));
|
|
749
|
+
logger.debug(`[DB] Entities deleted successfully`);
|
|
750
|
+
}
|
|
751
|
+
logger.debug(`[DB] Checking for world references`);
|
|
752
|
+
const worlds = await tx.select({ id: worldTable.id }).from(worldTable).where(eq(worldTable.agentId, agentId));
|
|
753
|
+
if (worlds.length > 0) {
|
|
754
|
+
const worldIds = worlds.map((w) => w.id);
|
|
755
|
+
logger.debug(`[DB] Found ${worldIds.length} worlds to delete`);
|
|
756
|
+
await tx.delete(worldTable).where(inArray(worldTable.id, worldIds));
|
|
757
|
+
logger.debug(`[DB] Worlds deleted successfully`);
|
|
758
|
+
} else {
|
|
759
|
+
logger.debug(`[DB] No worlds found for this agent`);
|
|
760
|
+
}
|
|
761
|
+
logger.debug(`[DB] Deleting agent ${agentId}`);
|
|
762
|
+
await tx.delete(agentTable).where(eq(agentTable.id, agentId));
|
|
763
|
+
logger.debug(`[DB] Agent deleted successfully`);
|
|
764
|
+
resolve(true);
|
|
765
|
+
} catch (error) {
|
|
766
|
+
logger.error(`[DB] Error in transaction:`, error);
|
|
767
|
+
reject(error);
|
|
768
|
+
}
|
|
769
|
+
}).catch((transactionError) => {
|
|
770
|
+
clearTimeout(timeoutId);
|
|
771
|
+
reject(transactionError);
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
await deletePromise;
|
|
775
|
+
logger.success(`[DB] Agent ${agentId} successfully deleted`);
|
|
776
|
+
return true;
|
|
777
|
+
} catch (error) {
|
|
778
|
+
logger.error(`[DB] Error in database transaction for agent deletion ${agentId}:`, error);
|
|
779
|
+
if (error instanceof Error) {
|
|
780
|
+
logger.error(`[DB] Error name: ${error.name}, message: ${error.message}`);
|
|
781
|
+
logger.error(`[DB] Error stack: ${error.stack}`);
|
|
782
|
+
}
|
|
783
|
+
throw error;
|
|
784
|
+
}
|
|
603
785
|
});
|
|
604
786
|
}
|
|
605
787
|
/**
|
|
@@ -651,7 +833,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
651
833
|
const result = await this.db.select({
|
|
652
834
|
entity: entityTable,
|
|
653
835
|
components: componentTable
|
|
654
|
-
}).from(entityTable).leftJoin(componentTable, eq(componentTable.entityId, entityTable.id)).where(
|
|
836
|
+
}).from(entityTable).leftJoin(componentTable, eq(componentTable.entityId, entityTable.id)).where(eq(entityTable.id, entityId));
|
|
655
837
|
if (result.length === 0) return null;
|
|
656
838
|
const entity = result[0].entity;
|
|
657
839
|
entity.components = result.filter((row) => row.components).map((row) => row.components);
|
|
@@ -1205,6 +1387,14 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1205
1387
|
embeddingLength: memory.embedding?.length,
|
|
1206
1388
|
contentLength: memory.content?.text?.length
|
|
1207
1389
|
});
|
|
1390
|
+
const memoryId = memory.id ?? v4();
|
|
1391
|
+
const existing = await this.getMemoryById(memoryId);
|
|
1392
|
+
if (existing) {
|
|
1393
|
+
logger.debug("Memory already exists, skipping creation:", {
|
|
1394
|
+
memoryId
|
|
1395
|
+
});
|
|
1396
|
+
return memoryId;
|
|
1397
|
+
}
|
|
1208
1398
|
let isUnique = true;
|
|
1209
1399
|
if (memory.embedding && Array.isArray(memory.embedding)) {
|
|
1210
1400
|
const similarMemories = await this.searchMemoriesByEmbedding(memory.embedding, {
|
|
@@ -1216,7 +1406,6 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1216
1406
|
isUnique = similarMemories.length === 0;
|
|
1217
1407
|
}
|
|
1218
1408
|
const contentToInsert = typeof memory.content === "string" ? JSON.parse(memory.content) : memory.content;
|
|
1219
|
-
const memoryId = memory.id ?? v4();
|
|
1220
1409
|
await this.db.transaction(async (tx) => {
|
|
1221
1410
|
await tx.insert(memoryTable).values([
|
|
1222
1411
|
{
|
|
@@ -1447,6 +1636,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1447
1636
|
async createRoom({
|
|
1448
1637
|
id,
|
|
1449
1638
|
name,
|
|
1639
|
+
agentId,
|
|
1450
1640
|
source,
|
|
1451
1641
|
type,
|
|
1452
1642
|
channelId,
|
|
@@ -1459,7 +1649,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1459
1649
|
await this.db.insert(roomTable).values({
|
|
1460
1650
|
id: newRoomId,
|
|
1461
1651
|
name,
|
|
1462
|
-
agentId
|
|
1652
|
+
agentId,
|
|
1463
1653
|
source,
|
|
1464
1654
|
type,
|
|
1465
1655
|
channelId,
|