@elizaos/plugin-sql 1.0.0-beta.7 → 1.0.0-beta.71
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/README.md +2 -2
- package/dist/{chunk-ROCRMD5N.js → chunk-QOV7MUNF.js} +66 -11
- package/dist/chunk-QOV7MUNF.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +685 -342
- package/dist/index.js.map +1 -1
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +11 -4
- package/dist/migrate.js.map +1 -1
- package/drizzle/extension.sql +4 -0
- package/drizzle/migrations/{20250302132443_init.sql → 0000_snapshot.sql} +28 -25
- package/drizzle/migrations/meta/{20250302132443_snapshot.json → 0000_snapshot.json} +56 -36
- package/drizzle/migrations/meta/_journal.json +2 -2
- package/package.json +15 -7
- package/dist/chunk-ROCRMD5N.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PGliteClientManager,
|
|
3
3
|
PostgresConnectionManager,
|
|
4
|
-
__name
|
|
5
|
-
|
|
4
|
+
__name,
|
|
5
|
+
resolvePgliteDir
|
|
6
|
+
} from "./chunk-QOV7MUNF.js";
|
|
6
7
|
|
|
7
8
|
// src/index.ts
|
|
8
|
-
import * as os from "node:os";
|
|
9
9
|
import { logger as logger4 } from "@elizaos/core";
|
|
10
10
|
|
|
11
11
|
// src/pglite/adapter.ts
|
|
@@ -15,37 +15,28 @@ import { drizzle } from "drizzle-orm/pglite";
|
|
|
15
15
|
// src/base.ts
|
|
16
16
|
import {
|
|
17
17
|
DatabaseAdapter,
|
|
18
|
-
logger
|
|
18
|
+
logger,
|
|
19
|
+
stringToUuid
|
|
19
20
|
} from "@elizaos/core";
|
|
20
|
-
import {
|
|
21
|
-
and,
|
|
22
|
-
cosineDistance,
|
|
23
|
-
count,
|
|
24
|
-
desc,
|
|
25
|
-
eq,
|
|
26
|
-
gte,
|
|
27
|
-
inArray,
|
|
28
|
-
lte,
|
|
29
|
-
or,
|
|
30
|
-
sql as sql12
|
|
31
|
-
} from "drizzle-orm";
|
|
21
|
+
import { and, cosineDistance, count, desc, eq, gte, inArray, lte, or, sql as sql13 } from "drizzle-orm";
|
|
32
22
|
import { v4 } from "uuid";
|
|
33
23
|
|
|
34
24
|
// src/schema/embedding.ts
|
|
35
|
-
import { sql as
|
|
36
|
-
import { check as check2, foreignKey as foreignKey2, index as index2, pgTable as
|
|
25
|
+
import { sql as sql5 } from "drizzle-orm";
|
|
26
|
+
import { check as check2, foreignKey as foreignKey2, index as index2, pgTable as pgTable5, uuid as uuid5, vector as vector2 } from "drizzle-orm/pg-core";
|
|
27
|
+
import { VECTOR_DIMS } from "@elizaos/core";
|
|
37
28
|
|
|
38
29
|
// src/schema/memory.ts
|
|
39
|
-
import { relations, sql as
|
|
30
|
+
import { relations, sql as sql4 } from "drizzle-orm";
|
|
40
31
|
import {
|
|
41
32
|
boolean as boolean2,
|
|
42
33
|
check,
|
|
43
34
|
foreignKey,
|
|
44
35
|
index,
|
|
45
|
-
jsonb as
|
|
46
|
-
pgTable as
|
|
47
|
-
text as
|
|
48
|
-
uuid as
|
|
36
|
+
jsonb as jsonb4,
|
|
37
|
+
pgTable as pgTable4,
|
|
38
|
+
text as text4,
|
|
39
|
+
uuid as uuid4
|
|
49
40
|
} from "drizzle-orm/pg-core";
|
|
50
41
|
|
|
51
42
|
// src/schema/agent.ts
|
|
@@ -86,18 +77,18 @@ var agentTable = pgTable(
|
|
|
86
77
|
createdAt: numberTimestamp("createdAt").default(sql`now()`).notNull(),
|
|
87
78
|
updatedAt: numberTimestamp("updatedAt").default(sql`now()`).notNull(),
|
|
88
79
|
// Character
|
|
89
|
-
name: text("name"),
|
|
80
|
+
name: text("name").notNull(),
|
|
90
81
|
username: text("username"),
|
|
91
|
-
system: text("system"),
|
|
92
|
-
bio: jsonb("bio").$type().
|
|
93
|
-
messageExamples: jsonb("message_examples").$type().default(sql`'[]'::jsonb`),
|
|
94
|
-
postExamples: jsonb("post_examples").$type().default(sql`'[]'::jsonb`),
|
|
95
|
-
topics: jsonb("topics").$type().default(sql`'[]'::jsonb`),
|
|
96
|
-
adjectives: jsonb("adjectives").$type().default(sql`'[]'::jsonb`),
|
|
97
|
-
knowledge: jsonb("knowledge").$type().default(sql`'[]'::jsonb`),
|
|
98
|
-
plugins: jsonb("plugins").$type().default(sql`'[]'::jsonb`),
|
|
99
|
-
settings: jsonb("settings").$type().default(sql`'{}'::jsonb`),
|
|
100
|
-
style: jsonb("style").$type().default(sql`'{}'::jsonb`)
|
|
82
|
+
system: text("system").default(""),
|
|
83
|
+
bio: jsonb("bio").$type().default(sql`'[]'::jsonb`),
|
|
84
|
+
messageExamples: jsonb("message_examples").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
85
|
+
postExamples: jsonb("post_examples").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
86
|
+
topics: jsonb("topics").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
87
|
+
adjectives: jsonb("adjectives").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
88
|
+
knowledge: jsonb("knowledge").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
89
|
+
plugins: jsonb("plugins").$type().default(sql`'[]'::jsonb`).notNull(),
|
|
90
|
+
settings: jsonb("settings").$type().default(sql`'{}'::jsonb`).notNull(),
|
|
91
|
+
style: jsonb("style").$type().default(sql`'{}'::jsonb`).notNull()
|
|
101
92
|
},
|
|
102
93
|
(table) => {
|
|
103
94
|
return {
|
|
@@ -117,8 +108,8 @@ var entityTable = pgTable2(
|
|
|
117
108
|
onDelete: "cascade"
|
|
118
109
|
}),
|
|
119
110
|
createdAt: numberTimestamp("createdAt").default(sql2`now()`).notNull(),
|
|
120
|
-
names: text2("names").array().default(sql2`'{}'::text[]`),
|
|
121
|
-
metadata: jsonb2("metadata").default(sql2`'{}'::jsonb`)
|
|
111
|
+
names: text2("names").array().default(sql2`'{}'::text[]`).notNull(),
|
|
112
|
+
metadata: jsonb2("metadata").default(sql2`'{}'::jsonb`).notNull()
|
|
122
113
|
},
|
|
123
114
|
(table) => {
|
|
124
115
|
return {
|
|
@@ -128,61 +119,54 @@ var entityTable = pgTable2(
|
|
|
128
119
|
);
|
|
129
120
|
|
|
130
121
|
// src/schema/room.ts
|
|
131
|
-
import { sql as sql4 } from "drizzle-orm";
|
|
132
|
-
import { jsonb as jsonb4, pgTable as pgTable4, text as text4, uuid as uuid4 } from "drizzle-orm/pg-core";
|
|
133
|
-
|
|
134
|
-
// src/schema/worldTable.ts
|
|
135
122
|
import { sql as sql3 } from "drizzle-orm";
|
|
136
123
|
import { jsonb as jsonb3, pgTable as pgTable3, text as text3, uuid as uuid3 } from "drizzle-orm/pg-core";
|
|
137
|
-
var
|
|
124
|
+
var roomTable = pgTable3("rooms", {
|
|
138
125
|
id: uuid3("id").notNull().primaryKey().default(sql3`gen_random_uuid()`),
|
|
139
|
-
agentId: uuid3("agentId").
|
|
140
|
-
name: text3("name").notNull(),
|
|
141
|
-
metadata: jsonb3("metadata"),
|
|
142
|
-
serverId: text3("serverId").notNull(),
|
|
143
|
-
createdAt: numberTimestamp("createdAt").default(sql3`now()`).notNull()
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// src/schema/room.ts
|
|
147
|
-
var roomTable = pgTable4("rooms", {
|
|
148
|
-
id: uuid4("id").notNull().primaryKey().default(sql4`gen_random_uuid()`),
|
|
149
|
-
agentId: uuid4("agentId").references(() => agentTable.id, {
|
|
150
|
-
onDelete: "cascade"
|
|
151
|
-
}),
|
|
152
|
-
source: text4("source").notNull(),
|
|
153
|
-
type: text4("type").notNull(),
|
|
154
|
-
serverId: text4("serverId"),
|
|
155
|
-
worldId: uuid4("worldId").references(() => worldTable.id, {
|
|
126
|
+
agentId: uuid3("agentId").references(() => agentTable.id, {
|
|
156
127
|
onDelete: "cascade"
|
|
157
128
|
}),
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
129
|
+
source: text3("source").notNull(),
|
|
130
|
+
type: text3("type").notNull(),
|
|
131
|
+
serverId: text3("serverId"),
|
|
132
|
+
worldId: uuid3("worldId"),
|
|
133
|
+
// no guarantee that world exists, it is optional for now
|
|
134
|
+
// .references(() => worldTable.id, {
|
|
135
|
+
// onDelete: 'cascade',
|
|
136
|
+
// }),
|
|
137
|
+
name: text3("name"),
|
|
138
|
+
metadata: jsonb3("metadata"),
|
|
139
|
+
channelId: text3("channelId"),
|
|
140
|
+
createdAt: numberTimestamp("createdAt").default(sql3`now()`).notNull()
|
|
162
141
|
});
|
|
163
142
|
|
|
164
143
|
// src/schema/memory.ts
|
|
165
|
-
var memoryTable =
|
|
144
|
+
var memoryTable = pgTable4(
|
|
166
145
|
"memories",
|
|
167
146
|
{
|
|
168
|
-
id:
|
|
169
|
-
type:
|
|
170
|
-
createdAt: numberTimestamp("createdAt").default(
|
|
171
|
-
content:
|
|
172
|
-
entityId:
|
|
147
|
+
id: uuid4("id").primaryKey().notNull(),
|
|
148
|
+
type: text4("type").notNull(),
|
|
149
|
+
createdAt: numberTimestamp("createdAt").default(sql4`now()`).notNull(),
|
|
150
|
+
content: jsonb4("content").notNull(),
|
|
151
|
+
entityId: uuid4("entityId").references(() => entityTable.id, {
|
|
173
152
|
onDelete: "cascade"
|
|
174
153
|
}),
|
|
175
|
-
agentId:
|
|
154
|
+
agentId: uuid4("agentId").references(() => agentTable.id, {
|
|
176
155
|
onDelete: "cascade"
|
|
177
|
-
}),
|
|
178
|
-
roomId:
|
|
156
|
+
}).notNull(),
|
|
157
|
+
roomId: uuid4("roomId").references(() => roomTable.id, {
|
|
179
158
|
onDelete: "cascade"
|
|
180
159
|
}),
|
|
160
|
+
worldId: uuid4("worldId"),
|
|
161
|
+
// .references(() => worldTable.id, {
|
|
162
|
+
// onDelete: 'set null',
|
|
163
|
+
// }),
|
|
181
164
|
unique: boolean2("unique").default(true).notNull(),
|
|
182
|
-
metadata:
|
|
165
|
+
metadata: jsonb4("metadata").default({}).notNull()
|
|
183
166
|
},
|
|
184
167
|
(table) => [
|
|
185
168
|
index("idx_memories_type_room").on(table.type, table.roomId),
|
|
169
|
+
index("idx_memories_world_id").on(table.worldId),
|
|
186
170
|
foreignKey({
|
|
187
171
|
name: "fk_room",
|
|
188
172
|
columns: [table.roomId],
|
|
@@ -196,17 +180,22 @@ var memoryTable = pgTable5(
|
|
|
196
180
|
foreignKey({
|
|
197
181
|
name: "fk_agent",
|
|
198
182
|
columns: [table.agentId],
|
|
199
|
-
foreignColumns: [
|
|
183
|
+
foreignColumns: [agentTable.id]
|
|
200
184
|
}).onDelete("cascade"),
|
|
201
|
-
|
|
202
|
-
|
|
185
|
+
// foreignKey({
|
|
186
|
+
// name: 'fk_world',
|
|
187
|
+
// columns: [table.worldId],
|
|
188
|
+
// foreignColumns: [worldTable.id],
|
|
189
|
+
// }).onDelete('set null'),
|
|
190
|
+
index("idx_memories_metadata_type").on(sql4`((metadata->>'type'))`),
|
|
191
|
+
index("idx_memories_document_id").on(sql4`((metadata->>'documentId'))`),
|
|
203
192
|
index("idx_fragments_order").on(
|
|
204
|
-
|
|
205
|
-
|
|
193
|
+
sql4`((metadata->>'documentId'))`,
|
|
194
|
+
sql4`((metadata->>'position'))`
|
|
206
195
|
),
|
|
207
196
|
check(
|
|
208
197
|
"fragment_metadata_check",
|
|
209
|
-
|
|
198
|
+
sql4`
|
|
210
199
|
CASE
|
|
211
200
|
WHEN metadata->>'type' = 'fragment' THEN
|
|
212
201
|
metadata ? 'documentId' AND
|
|
@@ -217,7 +206,7 @@ var memoryTable = pgTable5(
|
|
|
217
206
|
),
|
|
218
207
|
check(
|
|
219
208
|
"document_metadata_check",
|
|
220
|
-
|
|
209
|
+
sql4`
|
|
221
210
|
CASE
|
|
222
211
|
WHEN metadata->>'type' = 'document' THEN
|
|
223
212
|
metadata ? 'timestamp'
|
|
@@ -232,14 +221,6 @@ var memoryRelations = relations(memoryTable, ({ one }) => ({
|
|
|
232
221
|
}));
|
|
233
222
|
|
|
234
223
|
// 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
224
|
var DIMENSION_MAP = {
|
|
244
225
|
[VECTOR_DIMS.SMALL]: "dim384",
|
|
245
226
|
[VECTOR_DIMS.MEDIUM]: "dim512",
|
|
@@ -248,12 +229,12 @@ var DIMENSION_MAP = {
|
|
|
248
229
|
[VECTOR_DIMS.XXL]: "dim1536",
|
|
249
230
|
[VECTOR_DIMS.XXXL]: "dim3072"
|
|
250
231
|
};
|
|
251
|
-
var embeddingTable =
|
|
232
|
+
var embeddingTable = pgTable5(
|
|
252
233
|
"embeddings",
|
|
253
234
|
{
|
|
254
|
-
id:
|
|
255
|
-
memoryId:
|
|
256
|
-
createdAt: numberTimestamp("created_at").default(
|
|
235
|
+
id: uuid5("id").primaryKey().defaultRandom().notNull(),
|
|
236
|
+
memoryId: uuid5("memory_id").references(() => memoryTable.id),
|
|
237
|
+
createdAt: numberTimestamp("created_at").default(sql5`now()`).notNull(),
|
|
257
238
|
dim384: vector2("dim_384", { dimensions: VECTOR_DIMS.SMALL }),
|
|
258
239
|
dim512: vector2("dim_512", { dimensions: VECTOR_DIMS.MEDIUM }),
|
|
259
240
|
dim768: vector2("dim_768", { dimensions: VECTOR_DIMS.LARGE }),
|
|
@@ -262,7 +243,7 @@ var embeddingTable = pgTable6(
|
|
|
262
243
|
dim3072: vector2("dim_3072", { dimensions: VECTOR_DIMS.XXXL })
|
|
263
244
|
},
|
|
264
245
|
(table) => [
|
|
265
|
-
check2("embedding_source_check",
|
|
246
|
+
check2("embedding_source_check", sql5`"memory_id" IS NOT NULL`),
|
|
266
247
|
index2("idx_embedding_memory").on(table.memoryId),
|
|
267
248
|
foreignKey2({
|
|
268
249
|
name: "fk_embedding_memory",
|
|
@@ -273,16 +254,16 @@ var embeddingTable = pgTable6(
|
|
|
273
254
|
);
|
|
274
255
|
|
|
275
256
|
// src/schema/cache.ts
|
|
276
|
-
import { sql as
|
|
277
|
-
import { jsonb as
|
|
278
|
-
var cacheTable =
|
|
257
|
+
import { sql as sql6 } from "drizzle-orm";
|
|
258
|
+
import { jsonb as jsonb5, pgTable as pgTable6, text as text5, unique as unique4, uuid as uuid6 } from "drizzle-orm/pg-core";
|
|
259
|
+
var cacheTable = pgTable6(
|
|
279
260
|
"cache",
|
|
280
261
|
{
|
|
281
|
-
id:
|
|
282
|
-
key:
|
|
283
|
-
agentId:
|
|
284
|
-
value:
|
|
285
|
-
createdAt: numberTimestamp("createdAt").default(
|
|
262
|
+
id: uuid6("id").notNull().primaryKey().default(sql6`gen_random_uuid()`),
|
|
263
|
+
key: text5("key").notNull(),
|
|
264
|
+
agentId: uuid6("agentId").notNull().references(() => agentTable.id, { onDelete: "cascade" }),
|
|
265
|
+
value: jsonb5("value").notNull(),
|
|
266
|
+
createdAt: numberTimestamp("createdAt").default(sql6`now()`).notNull(),
|
|
286
267
|
expiresAt: numberTimestamp("expiresAt")
|
|
287
268
|
},
|
|
288
269
|
(table) => [unique4("cache_key_agent_unique").on(table.key, table.agentId)]
|
|
@@ -291,6 +272,20 @@ var cacheTable = pgTable7(
|
|
|
291
272
|
// src/schema/component.ts
|
|
292
273
|
import { sql as sql8 } from "drizzle-orm";
|
|
293
274
|
import { jsonb as jsonb7, pgTable as pgTable8, text as text7, uuid as uuid8 } from "drizzle-orm/pg-core";
|
|
275
|
+
|
|
276
|
+
// src/schema/world.ts
|
|
277
|
+
import { sql as sql7 } from "drizzle-orm";
|
|
278
|
+
import { jsonb as jsonb6, pgTable as pgTable7, text as text6, uuid as uuid7 } from "drizzle-orm/pg-core";
|
|
279
|
+
var worldTable = pgTable7("worlds", {
|
|
280
|
+
id: uuid7("id").notNull().primaryKey().default(sql7`gen_random_uuid()`),
|
|
281
|
+
agentId: uuid7("agentId").notNull().references(() => agentTable.id, { onDelete: "cascade" }),
|
|
282
|
+
name: text6("name").notNull(),
|
|
283
|
+
metadata: jsonb6("metadata"),
|
|
284
|
+
serverId: text6("serverId").notNull(),
|
|
285
|
+
createdAt: numberTimestamp("createdAt").default(sql7`now()`).notNull()
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// src/schema/component.ts
|
|
294
289
|
var componentTable = pgTable8("components", {
|
|
295
290
|
id: uuid8("id").primaryKey().defaultRandom(),
|
|
296
291
|
entityId: uuid8("entityId").notNull().references(() => entityTable.id, { onDelete: "cascade" }),
|
|
@@ -318,7 +313,7 @@ var logTable = pgTable9(
|
|
|
318
313
|
entityId: uuid9("entityId").notNull().references(() => entityTable.id),
|
|
319
314
|
body: jsonb8("body").notNull(),
|
|
320
315
|
type: text8("type").notNull(),
|
|
321
|
-
roomId: uuid9("roomId").notNull().references(() => roomTable.id)
|
|
316
|
+
roomId: uuid9("roomId").notNull().references(() => roomTable.id, { onDelete: "cascade" })
|
|
322
317
|
},
|
|
323
318
|
(table) => [
|
|
324
319
|
foreignKey3({
|
|
@@ -402,17 +397,19 @@ var relationshipTable = pgTable11(
|
|
|
402
397
|
|
|
403
398
|
// src/schema/tasks.ts
|
|
404
399
|
import { jsonb as jsonb10, pgTable as pgTable12, text as text11, timestamp, uuid as uuid12 } from "drizzle-orm/pg-core";
|
|
400
|
+
import { sql as sql12 } from "drizzle-orm";
|
|
405
401
|
var taskTable = pgTable12("tasks", {
|
|
406
402
|
id: uuid12("id").primaryKey().defaultRandom(),
|
|
407
403
|
name: text11("name").notNull(),
|
|
408
|
-
description: text11("description")
|
|
409
|
-
roomId: uuid12("
|
|
410
|
-
worldId: uuid12("
|
|
404
|
+
description: text11("description"),
|
|
405
|
+
roomId: uuid12("roomId"),
|
|
406
|
+
worldId: uuid12("worldId"),
|
|
407
|
+
entityId: uuid12("entityId"),
|
|
411
408
|
agentId: uuid12("agent_id").notNull(),
|
|
412
|
-
tags: text11("tags").array(),
|
|
413
|
-
metadata: jsonb10("metadata"),
|
|
414
|
-
createdAt: timestamp("created_at").defaultNow(),
|
|
415
|
-
updatedAt: timestamp("updated_at").defaultNow()
|
|
409
|
+
tags: text11("tags").array().default(sql12`'{}'::text[]`),
|
|
410
|
+
metadata: jsonb10("metadata").default(sql12`'{}'::jsonb`),
|
|
411
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
|
|
412
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow()
|
|
416
413
|
});
|
|
417
414
|
|
|
418
415
|
// src/base.ts
|
|
@@ -481,12 +478,17 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
481
478
|
throw new Error("Agent name is required");
|
|
482
479
|
}
|
|
483
480
|
const agents = await this.getAgents();
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
await this.createAgent(agent);
|
|
481
|
+
const existingAgentId = agents.find((a) => a.name === agent.name)?.id;
|
|
482
|
+
if (existingAgentId) {
|
|
483
|
+
const existingAgent = await this.getAgent(existingAgentId);
|
|
484
|
+
return existingAgent;
|
|
489
485
|
}
|
|
486
|
+
const newAgent = {
|
|
487
|
+
...agent,
|
|
488
|
+
id: stringToUuid(agent.name)
|
|
489
|
+
};
|
|
490
|
+
await this.createAgent(newAgent);
|
|
491
|
+
return newAgent;
|
|
490
492
|
}
|
|
491
493
|
/**
|
|
492
494
|
* Asynchronously ensures that the given embedding dimension is valid for the agent.
|
|
@@ -495,15 +497,17 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
495
497
|
* @returns {Promise<void>} - Resolves once the embedding dimension is ensured.
|
|
496
498
|
*/
|
|
497
499
|
async ensureEmbeddingDimension(dimension) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
500
|
+
return this.withDatabase(async () => {
|
|
501
|
+
const existingMemory = await this.db.select({
|
|
502
|
+
embedding: embeddingTable
|
|
503
|
+
}).from(memoryTable).innerJoin(embeddingTable, eq(embeddingTable.memoryId, memoryTable.id)).where(eq(memoryTable.agentId, this.agentId)).limit(1);
|
|
504
|
+
if (existingMemory.length > 0) {
|
|
505
|
+
const usedDimension = Object.entries(DIMENSION_MAP).find(
|
|
506
|
+
([_, colName]) => existingMemory[0].embedding[colName] !== null
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
this.embeddingDimension = DIMENSION_MAP[dimension];
|
|
510
|
+
});
|
|
507
511
|
}
|
|
508
512
|
/**
|
|
509
513
|
* Asynchronously retrieves an agent by their ID from the database.
|
|
@@ -512,20 +516,35 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
512
516
|
*/
|
|
513
517
|
async getAgent(agentId) {
|
|
514
518
|
return this.withDatabase(async () => {
|
|
515
|
-
const
|
|
516
|
-
if (
|
|
517
|
-
|
|
519
|
+
const rows = await this.db.select().from(agentTable).where(eq(agentTable.id, agentId)).limit(1);
|
|
520
|
+
if (rows.length === 0) return null;
|
|
521
|
+
const row = rows[0];
|
|
522
|
+
return {
|
|
523
|
+
...row,
|
|
524
|
+
username: row.username || "",
|
|
525
|
+
id: row.id,
|
|
526
|
+
system: !row.system ? void 0 : row.system,
|
|
527
|
+
bio: !row.bio ? "" : row.bio
|
|
528
|
+
};
|
|
518
529
|
});
|
|
519
530
|
}
|
|
520
531
|
/**
|
|
521
532
|
* Asynchronously retrieves a list of agents from the database.
|
|
522
533
|
*
|
|
523
|
-
* @returns {Promise<Agent[]>} A Promise that resolves to an array of Agent objects.
|
|
534
|
+
* @returns {Promise<Partial<Agent>[]>} A Promise that resolves to an array of Agent objects.
|
|
524
535
|
*/
|
|
525
536
|
async getAgents() {
|
|
526
537
|
return this.withDatabase(async () => {
|
|
527
|
-
const
|
|
528
|
-
|
|
538
|
+
const rows = await this.db.select({
|
|
539
|
+
id: agentTable.id,
|
|
540
|
+
name: agentTable.name,
|
|
541
|
+
bio: agentTable.bio
|
|
542
|
+
}).from(agentTable);
|
|
543
|
+
return rows.map((row) => ({
|
|
544
|
+
...row,
|
|
545
|
+
id: row.id,
|
|
546
|
+
bio: row.bio === null ? "" : row.bio
|
|
547
|
+
}));
|
|
529
548
|
});
|
|
530
549
|
}
|
|
531
550
|
/**
|
|
@@ -565,10 +584,13 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
565
584
|
async updateAgent(agentId, agent) {
|
|
566
585
|
return this.withDatabase(async () => {
|
|
567
586
|
try {
|
|
568
|
-
if (!
|
|
587
|
+
if (!agentId) {
|
|
569
588
|
throw new Error("Agent ID is required for update");
|
|
570
589
|
}
|
|
571
590
|
await this.db.transaction(async (tx) => {
|
|
591
|
+
if (agent?.settings) {
|
|
592
|
+
agent.settings = await this.mergeAgentSettings(tx, agentId, agent.settings);
|
|
593
|
+
}
|
|
572
594
|
await tx.update(agentTable).set({
|
|
573
595
|
...agent,
|
|
574
596
|
updatedAt: Date.now()
|
|
@@ -588,6 +610,54 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
588
610
|
}
|
|
589
611
|
});
|
|
590
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Merges updated agent settings with existing settings in the database,
|
|
615
|
+
* with special handling for nested objects like secrets.
|
|
616
|
+
* @param tx - The database transaction
|
|
617
|
+
* @param agentId - The ID of the agent
|
|
618
|
+
* @param updatedSettings - The settings object with updates
|
|
619
|
+
* @returns The merged settings object
|
|
620
|
+
* @private
|
|
621
|
+
*/
|
|
622
|
+
async mergeAgentSettings(tx, agentId, updatedSettings) {
|
|
623
|
+
const currentAgent = await tx.select({ settings: agentTable.settings }).from(agentTable).where(eq(agentTable.id, agentId)).limit(1);
|
|
624
|
+
const currentSettings = currentAgent.length > 0 && currentAgent[0].settings ? currentAgent[0].settings : {};
|
|
625
|
+
const deepMerge = /* @__PURE__ */ __name((target, source) => {
|
|
626
|
+
if (source === null) {
|
|
627
|
+
return void 0;
|
|
628
|
+
}
|
|
629
|
+
if (Array.isArray(source) || typeof source !== "object") {
|
|
630
|
+
return source;
|
|
631
|
+
}
|
|
632
|
+
const output = typeof target === "object" && target !== null && !Array.isArray(target) ? { ...target } : {};
|
|
633
|
+
let isEmpty = true;
|
|
634
|
+
for (const key of Object.keys(source)) {
|
|
635
|
+
const sourceValue = source[key];
|
|
636
|
+
if (sourceValue === null) {
|
|
637
|
+
delete output[key];
|
|
638
|
+
} else if (typeof sourceValue === "object" && !Array.isArray(sourceValue)) {
|
|
639
|
+
const nestedMergeResult = deepMerge(output[key], sourceValue);
|
|
640
|
+
if (nestedMergeResult === void 0) {
|
|
641
|
+
delete output[key];
|
|
642
|
+
} else {
|
|
643
|
+
output[key] = nestedMergeResult;
|
|
644
|
+
isEmpty = false;
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
output[key] = sourceValue;
|
|
648
|
+
isEmpty = false;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (Object.keys(output).length === 0) {
|
|
652
|
+
if (!(typeof source === "object" && source !== null && Object.keys(source).length === 0)) {
|
|
653
|
+
return void 0;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return output;
|
|
657
|
+
}, "deepMerge");
|
|
658
|
+
const finalSettings = deepMerge(currentSettings, updatedSettings);
|
|
659
|
+
return finalSettings === void 0 ? {} : finalSettings;
|
|
660
|
+
}
|
|
591
661
|
/**
|
|
592
662
|
* Asynchronously deletes an agent with the specified UUID and all related entries.
|
|
593
663
|
*
|
|
@@ -595,11 +665,161 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
595
665
|
* @returns {Promise<boolean>} - A boolean indicating if the deletion was successful.
|
|
596
666
|
*/
|
|
597
667
|
async deleteAgent(agentId) {
|
|
668
|
+
logger.debug(`[DB] Starting deletion of agent with ID: ${agentId}`);
|
|
598
669
|
return this.withDatabase(async () => {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
670
|
+
try {
|
|
671
|
+
logger.debug(`[DB] Beginning database transaction for deleting agent: ${agentId}`);
|
|
672
|
+
const deletePromise = new Promise((resolve, reject) => {
|
|
673
|
+
const timeoutId = setTimeout(() => {
|
|
674
|
+
logger.error(`[DB] Transaction timeout reached for agent deletion: ${agentId}`);
|
|
675
|
+
reject(new Error("Database transaction timeout"));
|
|
676
|
+
}, 3e4);
|
|
677
|
+
this.db.transaction(async (tx) => {
|
|
678
|
+
try {
|
|
679
|
+
logger.debug(`[DB] Fetching entities for agent: ${agentId}`);
|
|
680
|
+
const entities = await tx.select({ entityId: entityTable.id }).from(entityTable).where(eq(entityTable.agentId, agentId));
|
|
681
|
+
const entityIds = entities.map((e) => e.entityId);
|
|
682
|
+
logger.debug(
|
|
683
|
+
`[DB] Found ${entityIds.length} entities to delete for agent ${agentId}`
|
|
684
|
+
);
|
|
685
|
+
logger.debug(`[DB] Fetching rooms for agent: ${agentId}`);
|
|
686
|
+
const rooms = await tx.select({ roomId: roomTable.id }).from(roomTable).where(eq(roomTable.agentId, agentId));
|
|
687
|
+
const roomIds = rooms.map((r) => r.roomId);
|
|
688
|
+
logger.debug(`[DB] Found ${roomIds.length} rooms for agent ${agentId}`);
|
|
689
|
+
logger.debug(
|
|
690
|
+
`[DB] Explicitly deleting ALL logs with matching entityIds and roomIds`
|
|
691
|
+
);
|
|
692
|
+
if (entityIds.length > 0) {
|
|
693
|
+
logger.debug(`[DB] Deleting logs for ${entityIds.length} entities (first batch)`);
|
|
694
|
+
const BATCH_SIZE = 50;
|
|
695
|
+
for (let i = 0; i < entityIds.length; i += BATCH_SIZE) {
|
|
696
|
+
const batch = entityIds.slice(i, i + BATCH_SIZE);
|
|
697
|
+
logger.debug(
|
|
698
|
+
`[DB] Processing entity logs batch ${i / BATCH_SIZE + 1} with ${batch.length} entities`
|
|
699
|
+
);
|
|
700
|
+
await tx.delete(logTable).where(inArray(logTable.entityId, batch));
|
|
701
|
+
}
|
|
702
|
+
logger.debug(`[DB] Entity logs deletion completed successfully`);
|
|
703
|
+
}
|
|
704
|
+
if (roomIds.length > 0) {
|
|
705
|
+
logger.debug(`[DB] Deleting logs for ${roomIds.length} rooms (first batch)`);
|
|
706
|
+
const BATCH_SIZE = 50;
|
|
707
|
+
for (let i = 0; i < roomIds.length; i += BATCH_SIZE) {
|
|
708
|
+
const batch = roomIds.slice(i, i + BATCH_SIZE);
|
|
709
|
+
logger.debug(
|
|
710
|
+
`[DB] Processing room logs batch ${i / BATCH_SIZE + 1} with ${batch.length} rooms`
|
|
711
|
+
);
|
|
712
|
+
await tx.delete(logTable).where(inArray(logTable.roomId, batch));
|
|
713
|
+
}
|
|
714
|
+
logger.debug(`[DB] Room logs deletion completed successfully`);
|
|
715
|
+
}
|
|
716
|
+
let memoryIds = [];
|
|
717
|
+
if (entityIds.length > 0) {
|
|
718
|
+
logger.debug(`[DB] Finding memories belonging to entities`);
|
|
719
|
+
const memories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.entityId, entityIds));
|
|
720
|
+
memoryIds = memories.map((m) => m.id);
|
|
721
|
+
logger.debug(`[DB] Found ${memoryIds.length} memories belonging to entities`);
|
|
722
|
+
}
|
|
723
|
+
logger.debug(`[DB] Finding memories belonging to agent directly`);
|
|
724
|
+
const agentMemories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(eq(memoryTable.agentId, agentId));
|
|
725
|
+
memoryIds = [...memoryIds, ...agentMemories.map((m) => m.id)];
|
|
726
|
+
logger.debug(`[DB] Found total of ${memoryIds.length} memories to delete`);
|
|
727
|
+
if (roomIds.length > 0) {
|
|
728
|
+
logger.debug(`[DB] Finding memories belonging to rooms`);
|
|
729
|
+
const roomMemories = await tx.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.roomId, roomIds));
|
|
730
|
+
memoryIds = [...memoryIds, ...roomMemories.map((m) => m.id)];
|
|
731
|
+
logger.debug(`[DB] Updated total to ${memoryIds.length} memories to delete`);
|
|
732
|
+
}
|
|
733
|
+
if (memoryIds.length > 0) {
|
|
734
|
+
logger.debug(`[DB] Deleting embeddings for ${memoryIds.length} memories`);
|
|
735
|
+
const BATCH_SIZE = 100;
|
|
736
|
+
for (let i = 0; i < memoryIds.length; i += BATCH_SIZE) {
|
|
737
|
+
const batch = memoryIds.slice(i, i + BATCH_SIZE);
|
|
738
|
+
await tx.delete(embeddingTable).where(inArray(embeddingTable.memoryId, batch));
|
|
739
|
+
}
|
|
740
|
+
logger.debug(`[DB] Embeddings deleted successfully`);
|
|
741
|
+
}
|
|
742
|
+
if (memoryIds.length > 0) {
|
|
743
|
+
logger.debug(`[DB] Deleting ${memoryIds.length} memories`);
|
|
744
|
+
const BATCH_SIZE = 100;
|
|
745
|
+
for (let i = 0; i < memoryIds.length; i += BATCH_SIZE) {
|
|
746
|
+
const batch = memoryIds.slice(i, i + BATCH_SIZE);
|
|
747
|
+
await tx.delete(memoryTable).where(inArray(memoryTable.id, batch));
|
|
748
|
+
}
|
|
749
|
+
logger.debug(`[DB] Memories deleted successfully`);
|
|
750
|
+
}
|
|
751
|
+
if (entityIds.length > 0) {
|
|
752
|
+
logger.debug(`[DB] Deleting components for entities`);
|
|
753
|
+
await tx.delete(componentTable).where(inArray(componentTable.entityId, entityIds));
|
|
754
|
+
logger.debug(`[DB] Components deleted successfully`);
|
|
755
|
+
}
|
|
756
|
+
if (entityIds.length > 0) {
|
|
757
|
+
logger.debug(`[DB] Deleting source entity references in components`);
|
|
758
|
+
await tx.delete(componentTable).where(inArray(componentTable.sourceEntityId, entityIds));
|
|
759
|
+
logger.debug(`[DB] Source entity references deleted successfully`);
|
|
760
|
+
}
|
|
761
|
+
if (roomIds.length > 0) {
|
|
762
|
+
logger.debug(`[DB] Deleting participations for rooms`);
|
|
763
|
+
await tx.delete(participantTable).where(inArray(participantTable.roomId, roomIds));
|
|
764
|
+
logger.debug(`[DB] Participations deleted for rooms`);
|
|
765
|
+
}
|
|
766
|
+
logger.debug(`[DB] Deleting agent participations`);
|
|
767
|
+
await tx.delete(participantTable).where(eq(participantTable.agentId, agentId));
|
|
768
|
+
logger.debug(`[DB] Agent participations deleted`);
|
|
769
|
+
if (roomIds.length > 0) {
|
|
770
|
+
logger.debug(`[DB] Deleting rooms`);
|
|
771
|
+
await tx.delete(roomTable).where(inArray(roomTable.id, roomIds));
|
|
772
|
+
logger.debug(`[DB] Rooms deleted successfully`);
|
|
773
|
+
}
|
|
774
|
+
logger.debug(`[DB] Deleting cache entries`);
|
|
775
|
+
await tx.delete(cacheTable).where(eq(cacheTable.agentId, agentId));
|
|
776
|
+
logger.debug(`[DB] Cache entries deleted successfully`);
|
|
777
|
+
logger.debug(`[DB] Deleting relationships`);
|
|
778
|
+
if (entityIds.length > 0) {
|
|
779
|
+
await tx.delete(relationshipTable).where(inArray(relationshipTable.sourceEntityId, entityIds));
|
|
780
|
+
await tx.delete(relationshipTable).where(inArray(relationshipTable.targetEntityId, entityIds));
|
|
781
|
+
}
|
|
782
|
+
await tx.delete(relationshipTable).where(eq(relationshipTable.agentId, agentId));
|
|
783
|
+
logger.debug(`[DB] Relationships deleted successfully`);
|
|
784
|
+
if (entityIds.length > 0) {
|
|
785
|
+
logger.debug(`[DB] Deleting entities`);
|
|
786
|
+
await tx.delete(entityTable).where(eq(entityTable.agentId, agentId));
|
|
787
|
+
logger.debug(`[DB] Entities deleted successfully`);
|
|
788
|
+
}
|
|
789
|
+
logger.debug(`[DB] Checking for world references`);
|
|
790
|
+
const worlds = await tx.select({ id: worldTable.id }).from(worldTable).where(eq(worldTable.agentId, agentId));
|
|
791
|
+
if (worlds.length > 0) {
|
|
792
|
+
const worldIds = worlds.map((w) => w.id);
|
|
793
|
+
logger.debug(`[DB] Found ${worldIds.length} worlds to delete`);
|
|
794
|
+
await tx.delete(worldTable).where(inArray(worldTable.id, worldIds));
|
|
795
|
+
logger.debug(`[DB] Worlds deleted successfully`);
|
|
796
|
+
} else {
|
|
797
|
+
logger.debug(`[DB] No worlds found for this agent`);
|
|
798
|
+
}
|
|
799
|
+
logger.debug(`[DB] Deleting agent ${agentId}`);
|
|
800
|
+
await tx.delete(agentTable).where(eq(agentTable.id, agentId));
|
|
801
|
+
logger.debug(`[DB] Agent deleted successfully`);
|
|
802
|
+
resolve(true);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
logger.error(`[DB] Error in transaction:`, error);
|
|
805
|
+
reject(error);
|
|
806
|
+
}
|
|
807
|
+
}).catch((transactionError) => {
|
|
808
|
+
clearTimeout(timeoutId);
|
|
809
|
+
reject(transactionError);
|
|
810
|
+
});
|
|
811
|
+
});
|
|
812
|
+
await deletePromise;
|
|
813
|
+
logger.success(`[DB] Agent ${agentId} successfully deleted`);
|
|
814
|
+
return true;
|
|
815
|
+
} catch (error) {
|
|
816
|
+
logger.error(`[DB] Error in database transaction for agent deletion ${agentId}:`, error);
|
|
817
|
+
if (error instanceof Error) {
|
|
818
|
+
logger.error(`[DB] Error name: ${error.name}, message: ${error.message}`);
|
|
819
|
+
logger.error(`[DB] Error stack: ${error.stack}`);
|
|
820
|
+
}
|
|
821
|
+
throw error;
|
|
822
|
+
}
|
|
603
823
|
});
|
|
604
824
|
}
|
|
605
825
|
/**
|
|
@@ -642,20 +862,32 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
642
862
|
});
|
|
643
863
|
}
|
|
644
864
|
/**
|
|
645
|
-
* Asynchronously retrieves an entity and its components by entity
|
|
646
|
-
* @param {UUID}
|
|
647
|
-
* @returns {Promise<Entity | null>} A Promise that resolves to the entity with its components if found, null otherwise.
|
|
865
|
+
* Asynchronously retrieves an entity and its components by entity IDs.
|
|
866
|
+
* @param {UUID[]} entityIds - The unique identifiers of the entities to retrieve.
|
|
867
|
+
* @returns {Promise<Entity[] | null>} A Promise that resolves to the entity with its components if found, null otherwise.
|
|
648
868
|
*/
|
|
649
|
-
async
|
|
869
|
+
async getEntityByIds(entityIds) {
|
|
650
870
|
return this.withDatabase(async () => {
|
|
651
871
|
const result = await this.db.select({
|
|
652
872
|
entity: entityTable,
|
|
653
873
|
components: componentTable
|
|
654
|
-
}).from(entityTable).leftJoin(componentTable, eq(componentTable.entityId, entityTable.id)).where(
|
|
874
|
+
}).from(entityTable).leftJoin(componentTable, eq(componentTable.entityId, entityTable.id)).where(inArray(entityTable.id, entityIds));
|
|
655
875
|
if (result.length === 0) return null;
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
|
|
876
|
+
const entities = {};
|
|
877
|
+
const entityComponents = {};
|
|
878
|
+
for (const e of result) {
|
|
879
|
+
const key = e.entity.id;
|
|
880
|
+
entities[key] = e.entity;
|
|
881
|
+
if (entityComponents[key] === void 0) entityComponents[key] = [];
|
|
882
|
+
if (e.components) {
|
|
883
|
+
const componentsArray = Array.isArray(e.components) ? e.components : [e.components];
|
|
884
|
+
entityComponents[key] = [...entityComponents[key], ...componentsArray];
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
for (const k of Object.keys(entityComponents)) {
|
|
888
|
+
entities[k].components = entityComponents[k];
|
|
889
|
+
}
|
|
890
|
+
return Object.values(entities);
|
|
659
891
|
});
|
|
660
892
|
}
|
|
661
893
|
/**
|
|
@@ -684,6 +916,9 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
684
916
|
if (!entitiesByIdMap.has(entityId)) {
|
|
685
917
|
const entity = {
|
|
686
918
|
...row.entity,
|
|
919
|
+
id: entityId,
|
|
920
|
+
agentId: row.entity.agentId,
|
|
921
|
+
metadata: row.entity.metadata,
|
|
687
922
|
components: includeComponents ? [] : void 0
|
|
688
923
|
};
|
|
689
924
|
entitiesByIdMap.set(entityId, entity);
|
|
@@ -702,25 +937,23 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
702
937
|
});
|
|
703
938
|
}
|
|
704
939
|
/**
|
|
705
|
-
* Asynchronously creates
|
|
706
|
-
* @param {Entity}
|
|
940
|
+
* Asynchronously creates new entities in the database.
|
|
941
|
+
* @param {Entity[]} entities - The entity objects to be created.
|
|
707
942
|
* @returns {Promise<boolean>} A Promise that resolves to a boolean indicating the success of the operation.
|
|
708
943
|
*/
|
|
709
|
-
async
|
|
944
|
+
async createEntities(entities) {
|
|
710
945
|
return this.withDatabase(async () => {
|
|
711
946
|
try {
|
|
712
947
|
return await this.db.transaction(async (tx) => {
|
|
713
|
-
await tx.insert(entityTable).values(
|
|
714
|
-
logger.debug("
|
|
715
|
-
entity
|
|
716
|
-
});
|
|
948
|
+
await tx.insert(entityTable).values(entities);
|
|
949
|
+
logger.debug(entities.length, "Entities created successfully");
|
|
717
950
|
return true;
|
|
718
951
|
});
|
|
719
952
|
} catch (error) {
|
|
720
953
|
logger.error("Error creating entity:", {
|
|
721
954
|
error: error instanceof Error ? error.message : String(error),
|
|
722
|
-
entityId:
|
|
723
|
-
name:
|
|
955
|
+
entityId: entities[0].id,
|
|
956
|
+
name: entities[0].metadata?.name
|
|
724
957
|
});
|
|
725
958
|
logger.trace(error);
|
|
726
959
|
return false;
|
|
@@ -738,9 +971,9 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
738
971
|
return false;
|
|
739
972
|
}
|
|
740
973
|
try {
|
|
741
|
-
const
|
|
742
|
-
if (!
|
|
743
|
-
return await this.
|
|
974
|
+
const existingEntities = await this.getEntityByIds([entity.id]);
|
|
975
|
+
if (!existingEntities || !existingEntities.length) {
|
|
976
|
+
return await this.createEntities([entity]);
|
|
744
977
|
}
|
|
745
978
|
return true;
|
|
746
979
|
} catch (error) {
|
|
@@ -771,7 +1004,18 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
771
1004
|
conditions.push(eq(componentTable.sourceEntityId, sourceEntityId));
|
|
772
1005
|
}
|
|
773
1006
|
const result = await this.db.select().from(componentTable).where(and(...conditions));
|
|
774
|
-
|
|
1007
|
+
if (result.length === 0) return null;
|
|
1008
|
+
const component = result[0];
|
|
1009
|
+
return {
|
|
1010
|
+
...component,
|
|
1011
|
+
id: component.id,
|
|
1012
|
+
entityId: component.entityId,
|
|
1013
|
+
agentId: component.agentId,
|
|
1014
|
+
roomId: component.roomId,
|
|
1015
|
+
worldId: component.worldId ?? "",
|
|
1016
|
+
sourceEntityId: component.sourceEntityId ?? "",
|
|
1017
|
+
data: component.data
|
|
1018
|
+
};
|
|
775
1019
|
});
|
|
776
1020
|
}
|
|
777
1021
|
/**
|
|
@@ -796,10 +1040,23 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
796
1040
|
type: componentTable.type,
|
|
797
1041
|
data: componentTable.data,
|
|
798
1042
|
worldId: componentTable.worldId,
|
|
1043
|
+
agentId: componentTable.agentId,
|
|
1044
|
+
roomId: componentTable.roomId,
|
|
799
1045
|
sourceEntityId: componentTable.sourceEntityId,
|
|
800
1046
|
createdAt: componentTable.createdAt
|
|
801
1047
|
}).from(componentTable).where(and(...conditions));
|
|
802
|
-
return
|
|
1048
|
+
if (result.length === 0) return [];
|
|
1049
|
+
const components = result.map((component) => ({
|
|
1050
|
+
...component,
|
|
1051
|
+
id: component.id,
|
|
1052
|
+
entityId: component.entityId,
|
|
1053
|
+
agentId: component.agentId,
|
|
1054
|
+
roomId: component.roomId,
|
|
1055
|
+
worldId: component.worldId ?? "",
|
|
1056
|
+
sourceEntityId: component.sourceEntityId ?? "",
|
|
1057
|
+
data: component.data
|
|
1058
|
+
}));
|
|
1059
|
+
return components;
|
|
803
1060
|
});
|
|
804
1061
|
}
|
|
805
1062
|
/**
|
|
@@ -845,10 +1102,8 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
845
1102
|
* @returns {Promise<Memory[]>} A Promise that resolves to an array of memories.
|
|
846
1103
|
*/
|
|
847
1104
|
async getMemories(params) {
|
|
848
|
-
const { entityId, agentId, roomId, tableName, count: count2, unique: unique7, start, end } = params;
|
|
1105
|
+
const { entityId, agentId, roomId, worldId, tableName, count: count2, unique: unique7, start, end } = params;
|
|
849
1106
|
if (!tableName) throw new Error("tableName is required");
|
|
850
|
-
if (!roomId && !entityId && !agentId)
|
|
851
|
-
throw new Error("roomId, entityId, or agentId is required");
|
|
852
1107
|
return this.withDatabase(async () => {
|
|
853
1108
|
const conditions = [eq(memoryTable.type, tableName)];
|
|
854
1109
|
if (start) {
|
|
@@ -860,6 +1115,9 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
860
1115
|
if (roomId) {
|
|
861
1116
|
conditions.push(eq(memoryTable.roomId, roomId));
|
|
862
1117
|
}
|
|
1118
|
+
if (worldId) {
|
|
1119
|
+
conditions.push(eq(memoryTable.worldId, worldId));
|
|
1120
|
+
}
|
|
863
1121
|
if (end) {
|
|
864
1122
|
conditions.push(lte(memoryTable.createdAt, end));
|
|
865
1123
|
}
|
|
@@ -959,6 +1217,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
959
1217
|
agentId: row.memory.agentId,
|
|
960
1218
|
roomId: row.memory.roomId,
|
|
961
1219
|
unique: row.memory.unique,
|
|
1220
|
+
metadata: row.memory.metadata,
|
|
962
1221
|
embedding: row.embedding ?? void 0
|
|
963
1222
|
};
|
|
964
1223
|
});
|
|
@@ -1008,7 +1267,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1008
1267
|
async getCachedEmbeddings(opts) {
|
|
1009
1268
|
return this.withDatabase(async () => {
|
|
1010
1269
|
try {
|
|
1011
|
-
const results = await this.db.execute(
|
|
1270
|
+
const results = await this.db.execute(sql13`
|
|
1012
1271
|
WITH content_text AS (
|
|
1013
1272
|
SELECT
|
|
1014
1273
|
m.id,
|
|
@@ -1021,7 +1280,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1021
1280
|
AND m.content->>${opts.query_field_sub_name} IS NOT NULL
|
|
1022
1281
|
),
|
|
1023
1282
|
embedded_text AS (
|
|
1024
|
-
SELECT
|
|
1283
|
+
SELECT
|
|
1025
1284
|
ct.content_text,
|
|
1026
1285
|
COALESCE(
|
|
1027
1286
|
e.dim_384,
|
|
@@ -1072,9 +1331,11 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1072
1331
|
async log(params) {
|
|
1073
1332
|
return this.withDatabase(async () => {
|
|
1074
1333
|
try {
|
|
1334
|
+
const sanitizedBody = this.sanitizeJsonObject(params.body);
|
|
1335
|
+
const jsonString = JSON.stringify(sanitizedBody);
|
|
1075
1336
|
await this.db.transaction(async (tx) => {
|
|
1076
1337
|
await tx.insert(logTable).values({
|
|
1077
|
-
body:
|
|
1338
|
+
body: sql13`${jsonString}::jsonb`,
|
|
1078
1339
|
entityId: params.entityId,
|
|
1079
1340
|
roomId: params.roomId,
|
|
1080
1341
|
type: params.type
|
|
@@ -1091,6 +1352,34 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1091
1352
|
}
|
|
1092
1353
|
});
|
|
1093
1354
|
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Sanitizes a JSON object by replacing problematic Unicode escape sequences
|
|
1357
|
+
* that could cause errors during JSON serialization/storage
|
|
1358
|
+
*
|
|
1359
|
+
* @param value - The value to sanitize
|
|
1360
|
+
* @returns The sanitized value
|
|
1361
|
+
*/
|
|
1362
|
+
sanitizeJsonObject(value) {
|
|
1363
|
+
if (value === null || value === void 0) {
|
|
1364
|
+
return value;
|
|
1365
|
+
}
|
|
1366
|
+
if (typeof value === "string") {
|
|
1367
|
+
return value.replace(/\u0000/g, "").replace(/\\(?!["\\/bfnrtu])/g, "\\\\").replace(/\\u(?![0-9a-fA-F]{4})/g, "\\\\u");
|
|
1368
|
+
}
|
|
1369
|
+
if (typeof value === "object") {
|
|
1370
|
+
if (Array.isArray(value)) {
|
|
1371
|
+
return value.map((item) => this.sanitizeJsonObject(item));
|
|
1372
|
+
} else {
|
|
1373
|
+
const result = {};
|
|
1374
|
+
for (const [key, val] of Object.entries(value)) {
|
|
1375
|
+
const sanitizedKey = typeof key === "string" ? key.replace(/\u0000/g, "").replace(/\\u(?![0-9a-fA-F]{4})/g, "\\\\u") : key;
|
|
1376
|
+
result[sanitizedKey] = this.sanitizeJsonObject(val);
|
|
1377
|
+
}
|
|
1378
|
+
return result;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
return value;
|
|
1382
|
+
}
|
|
1094
1383
|
/**
|
|
1095
1384
|
* Asynchronously retrieves logs from the database based on the provided parameters.
|
|
1096
1385
|
* @param {Object} params - The parameters for retrieving logs.
|
|
@@ -1111,7 +1400,16 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1111
1400
|
type ? eq(logTable.type, type) : void 0
|
|
1112
1401
|
)
|
|
1113
1402
|
).orderBy(desc(logTable.createdAt)).limit(count2 ?? 10).offset(offset ?? 0);
|
|
1114
|
-
|
|
1403
|
+
const logs = result.map((log) => ({
|
|
1404
|
+
...log,
|
|
1405
|
+
id: log.id,
|
|
1406
|
+
entityId: log.entityId,
|
|
1407
|
+
roomId: log.roomId,
|
|
1408
|
+
body: log.body,
|
|
1409
|
+
createdAt: new Date(log.createdAt)
|
|
1410
|
+
}));
|
|
1411
|
+
if (logs.length === 0) return [];
|
|
1412
|
+
return logs;
|
|
1115
1413
|
});
|
|
1116
1414
|
}
|
|
1117
1415
|
/**
|
|
@@ -1128,18 +1426,24 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1128
1426
|
* Asynchronously searches for memories in the database based on the provided parameters.
|
|
1129
1427
|
* @param {Object} params - The parameters for searching for memories.
|
|
1130
1428
|
* @param {string} params.tableName - The name of the table to search for memories in.
|
|
1131
|
-
* @param {UUID} params.roomId - The ID of the room to search for memories in.
|
|
1132
1429
|
* @param {number[]} params.embedding - The embedding to search for.
|
|
1133
1430
|
* @param {number} [params.match_threshold] - The threshold for the cosine distance.
|
|
1134
1431
|
* @param {number} [params.count] - The maximum number of memories to retrieve.
|
|
1135
1432
|
* @param {boolean} [params.unique] - Whether to retrieve unique memories only.
|
|
1433
|
+
* @param {string} [params.query] - Optional query string for potential reranking.
|
|
1434
|
+
* @param {UUID} [params.roomId] - Optional room ID to filter by.
|
|
1435
|
+
* @param {UUID} [params.worldId] - Optional world ID to filter by.
|
|
1436
|
+
* @param {UUID} [params.entityId] - Optional entity ID to filter by.
|
|
1136
1437
|
* @returns {Promise<Memory[]>} A Promise that resolves to an array of memories.
|
|
1137
1438
|
*/
|
|
1138
1439
|
async searchMemories(params) {
|
|
1139
1440
|
return await this.searchMemoriesByEmbedding(params.embedding, {
|
|
1140
1441
|
match_threshold: params.match_threshold,
|
|
1141
1442
|
count: params.count,
|
|
1443
|
+
// Pass direct scope fields down
|
|
1142
1444
|
roomId: params.roomId,
|
|
1445
|
+
worldId: params.worldId,
|
|
1446
|
+
entityId: params.entityId,
|
|
1143
1447
|
unique: params.unique,
|
|
1144
1448
|
tableName: params.tableName
|
|
1145
1449
|
});
|
|
@@ -1150,7 +1454,9 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1150
1454
|
* @param {Object} params - The parameters for searching for memories.
|
|
1151
1455
|
* @param {number} [params.match_threshold] - The threshold for the cosine distance.
|
|
1152
1456
|
* @param {number} [params.count] - The maximum number of memories to retrieve.
|
|
1153
|
-
* @param {UUID} [params.roomId] -
|
|
1457
|
+
* @param {UUID} [params.roomId] - Optional room ID to filter by.
|
|
1458
|
+
* @param {UUID} [params.worldId] - Optional world ID to filter by.
|
|
1459
|
+
* @param {UUID} [params.entityId] - Optional entity ID to filter by.
|
|
1154
1460
|
* @param {boolean} [params.unique] - Whether to retrieve unique memories only.
|
|
1155
1461
|
* @param {string} [params.tableName] - The name of the table to search for memories in.
|
|
1156
1462
|
* @returns {Promise<Memory[]>} A Promise that resolves to an array of memories.
|
|
@@ -1158,7 +1464,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1158
1464
|
async searchMemoriesByEmbedding(embedding, params) {
|
|
1159
1465
|
return this.withDatabase(async () => {
|
|
1160
1466
|
const cleanVector = embedding.map((n) => Number.isFinite(n) ? Number(n.toFixed(6)) : 0);
|
|
1161
|
-
const similarity =
|
|
1467
|
+
const similarity = sql13`1 - (${cosineDistance(
|
|
1162
1468
|
embeddingTable[this.embeddingDimension],
|
|
1163
1469
|
cleanVector
|
|
1164
1470
|
)})`;
|
|
@@ -1170,6 +1476,12 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1170
1476
|
if (params.roomId) {
|
|
1171
1477
|
conditions.push(eq(memoryTable.roomId, params.roomId));
|
|
1172
1478
|
}
|
|
1479
|
+
if (params.worldId) {
|
|
1480
|
+
conditions.push(eq(memoryTable.worldId, params.worldId));
|
|
1481
|
+
}
|
|
1482
|
+
if (params.entityId) {
|
|
1483
|
+
conditions.push(eq(memoryTable.entityId, params.entityId));
|
|
1484
|
+
}
|
|
1173
1485
|
if (params.match_threshold) {
|
|
1174
1486
|
conditions.push(gte(similarity, params.match_threshold));
|
|
1175
1487
|
}
|
|
@@ -1186,6 +1498,8 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1186
1498
|
entityId: row.memory.entityId,
|
|
1187
1499
|
agentId: row.memory.agentId,
|
|
1188
1500
|
roomId: row.memory.roomId,
|
|
1501
|
+
worldId: row.memory.worldId,
|
|
1502
|
+
// Include worldId
|
|
1189
1503
|
unique: row.memory.unique,
|
|
1190
1504
|
metadata: row.memory.metadata,
|
|
1191
1505
|
embedding: row.embedding ?? void 0,
|
|
@@ -1205,28 +1519,40 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1205
1519
|
embeddingLength: memory.embedding?.length,
|
|
1206
1520
|
contentLength: memory.content?.text?.length
|
|
1207
1521
|
});
|
|
1522
|
+
const memoryId = memory.id ?? v4();
|
|
1523
|
+
const existing = await this.getMemoryById(memoryId);
|
|
1524
|
+
if (existing) {
|
|
1525
|
+
logger.debug("Memory already exists, skipping creation:", {
|
|
1526
|
+
memoryId
|
|
1527
|
+
});
|
|
1528
|
+
return memoryId;
|
|
1529
|
+
}
|
|
1208
1530
|
let isUnique = true;
|
|
1209
1531
|
if (memory.embedding && Array.isArray(memory.embedding)) {
|
|
1210
1532
|
const similarMemories = await this.searchMemoriesByEmbedding(memory.embedding, {
|
|
1211
1533
|
tableName,
|
|
1534
|
+
// Use the scope fields from the memory object for similarity check
|
|
1212
1535
|
roomId: memory.roomId,
|
|
1536
|
+
worldId: memory.worldId,
|
|
1537
|
+
entityId: memory.entityId,
|
|
1213
1538
|
match_threshold: 0.95,
|
|
1214
1539
|
count: 1
|
|
1215
1540
|
});
|
|
1216
1541
|
isUnique = similarMemories.length === 0;
|
|
1217
1542
|
}
|
|
1218
1543
|
const contentToInsert = typeof memory.content === "string" ? JSON.parse(memory.content) : memory.content;
|
|
1219
|
-
const memoryId = memory.id ?? v4();
|
|
1220
1544
|
await this.db.transaction(async (tx) => {
|
|
1221
1545
|
await tx.insert(memoryTable).values([
|
|
1222
1546
|
{
|
|
1223
1547
|
id: memoryId,
|
|
1224
1548
|
type: tableName,
|
|
1225
|
-
content:
|
|
1226
|
-
metadata:
|
|
1549
|
+
content: sql13`${contentToInsert}::jsonb`,
|
|
1550
|
+
metadata: sql13`${memory.metadata || {}}::jsonb`,
|
|
1227
1551
|
entityId: memory.entityId,
|
|
1228
1552
|
roomId: memory.roomId,
|
|
1229
|
-
|
|
1553
|
+
worldId: memory.worldId,
|
|
1554
|
+
// Include worldId
|
|
1555
|
+
agentId: this.agentId,
|
|
1230
1556
|
unique: memory.unique ?? isUnique,
|
|
1231
1557
|
createdAt: memory.createdAt
|
|
1232
1558
|
}
|
|
@@ -1262,12 +1588,12 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1262
1588
|
if (memory.content) {
|
|
1263
1589
|
const contentToUpdate = typeof memory.content === "string" ? JSON.parse(memory.content) : memory.content;
|
|
1264
1590
|
await tx.update(memoryTable).set({
|
|
1265
|
-
content:
|
|
1266
|
-
...memory.metadata && { metadata:
|
|
1591
|
+
content: sql13`${contentToUpdate}::jsonb`,
|
|
1592
|
+
...memory.metadata && { metadata: sql13`${memory.metadata}::jsonb` }
|
|
1267
1593
|
}).where(eq(memoryTable.id, memory.id));
|
|
1268
1594
|
} else if (memory.metadata) {
|
|
1269
1595
|
await tx.update(memoryTable).set({
|
|
1270
|
-
metadata:
|
|
1596
|
+
metadata: sql13`${memory.metadata}::jsonb`
|
|
1271
1597
|
}).where(eq(memoryTable.id, memory.id));
|
|
1272
1598
|
}
|
|
1273
1599
|
if (memory.embedding && Array.isArray(memory.embedding)) {
|
|
@@ -1349,10 +1675,10 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1349
1675
|
const fragments = await tx.select({ id: memoryTable.id }).from(memoryTable).where(
|
|
1350
1676
|
and(
|
|
1351
1677
|
eq(memoryTable.agentId, this.agentId),
|
|
1352
|
-
|
|
1678
|
+
sql13`${memoryTable.metadata}->>'documentId' = ${documentId}`
|
|
1353
1679
|
)
|
|
1354
1680
|
);
|
|
1355
|
-
return fragments;
|
|
1681
|
+
return fragments.map((f) => ({ id: f.id }));
|
|
1356
1682
|
}
|
|
1357
1683
|
/**
|
|
1358
1684
|
* Asynchronously deletes all memories from the database based on the provided parameters.
|
|
@@ -1363,21 +1689,21 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1363
1689
|
async deleteAllMemories(roomId, tableName) {
|
|
1364
1690
|
return this.withDatabase(async () => {
|
|
1365
1691
|
await this.db.transaction(async (tx) => {
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
memoryIds.map((m) => m.id)
|
|
1372
|
-
)
|
|
1373
|
-
);
|
|
1374
|
-
await tx.delete(memoryTable).where(and(eq(memoryTable.roomId, roomId), eq(memoryTable.type, tableName)));
|
|
1692
|
+
const rows = await tx.select({ id: memoryTable.id }).from(memoryTable).where(and(eq(memoryTable.roomId, roomId), eq(memoryTable.type, tableName)));
|
|
1693
|
+
const ids = rows.map((r) => r.id);
|
|
1694
|
+
logger.debug("[deleteAllMemories] memory IDs to delete:", { roomId, tableName, ids });
|
|
1695
|
+
if (ids.length === 0) {
|
|
1696
|
+
return;
|
|
1375
1697
|
}
|
|
1698
|
+
await Promise.all(
|
|
1699
|
+
ids.map(async (memoryId) => {
|
|
1700
|
+
await this.deleteMemoryFragments(tx, memoryId);
|
|
1701
|
+
await tx.delete(embeddingTable).where(eq(embeddingTable.memoryId, memoryId));
|
|
1702
|
+
})
|
|
1703
|
+
);
|
|
1704
|
+
await tx.delete(memoryTable).where(and(eq(memoryTable.roomId, roomId), eq(memoryTable.type, tableName)));
|
|
1376
1705
|
});
|
|
1377
|
-
logger.debug("All memories removed successfully:", {
|
|
1378
|
-
roomId,
|
|
1379
|
-
tableName
|
|
1380
|
-
});
|
|
1706
|
+
logger.debug("All memories removed successfully:", { roomId, tableName });
|
|
1381
1707
|
});
|
|
1382
1708
|
}
|
|
1383
1709
|
/**
|
|
@@ -1394,28 +1720,42 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1394
1720
|
if (unique7) {
|
|
1395
1721
|
conditions.push(eq(memoryTable.unique, true));
|
|
1396
1722
|
}
|
|
1397
|
-
const result = await this.db.select({ count:
|
|
1723
|
+
const result = await this.db.select({ count: sql13`count(*)` }).from(memoryTable).where(and(...conditions));
|
|
1398
1724
|
return Number(result[0]?.count ?? 0);
|
|
1399
1725
|
});
|
|
1400
1726
|
}
|
|
1401
1727
|
/**
|
|
1402
|
-
* Asynchronously retrieves
|
|
1403
|
-
* @param {UUID}
|
|
1404
|
-
* @returns {Promise<Room | null>} A Promise that resolves to the
|
|
1728
|
+
* Asynchronously retrieves rooms from the database based on the provided parameters.
|
|
1729
|
+
* @param {UUID[]} roomIds - The IDs of the rooms to retrieve.
|
|
1730
|
+
* @returns {Promise<Room[] | null>} A Promise that resolves to the rooms if found, null otherwise.
|
|
1405
1731
|
*/
|
|
1406
|
-
async
|
|
1732
|
+
async getRoomsByIds(roomIds) {
|
|
1407
1733
|
return this.withDatabase(async () => {
|
|
1408
1734
|
const result = await this.db.select({
|
|
1409
1735
|
id: roomTable.id,
|
|
1736
|
+
name: roomTable.name,
|
|
1737
|
+
// Added name
|
|
1410
1738
|
channelId: roomTable.channelId,
|
|
1411
1739
|
agentId: roomTable.agentId,
|
|
1412
1740
|
serverId: roomTable.serverId,
|
|
1413
1741
|
worldId: roomTable.worldId,
|
|
1414
1742
|
type: roomTable.type,
|
|
1415
|
-
source: roomTable.source
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1743
|
+
source: roomTable.source,
|
|
1744
|
+
metadata: roomTable.metadata
|
|
1745
|
+
// Added metadata
|
|
1746
|
+
}).from(roomTable).where(and(inArray(roomTable.id, roomIds), eq(roomTable.agentId, this.agentId)));
|
|
1747
|
+
const rooms = result.map((room) => ({
|
|
1748
|
+
...room,
|
|
1749
|
+
id: room.id,
|
|
1750
|
+
name: room.name ?? void 0,
|
|
1751
|
+
agentId: room.agentId,
|
|
1752
|
+
serverId: room.serverId,
|
|
1753
|
+
worldId: room.worldId,
|
|
1754
|
+
channelId: room.channelId,
|
|
1755
|
+
type: room.type,
|
|
1756
|
+
metadata: room.metadata
|
|
1757
|
+
}));
|
|
1758
|
+
return rooms;
|
|
1419
1759
|
});
|
|
1420
1760
|
}
|
|
1421
1761
|
/**
|
|
@@ -1423,10 +1763,21 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1423
1763
|
* @param {UUID} worldId - The ID of the world to retrieve rooms from.
|
|
1424
1764
|
* @returns {Promise<Room[]>} A Promise that resolves to an array of rooms.
|
|
1425
1765
|
*/
|
|
1426
|
-
async
|
|
1766
|
+
async getRoomsByWorld(worldId) {
|
|
1427
1767
|
return this.withDatabase(async () => {
|
|
1428
1768
|
const result = await this.db.select().from(roomTable).where(eq(roomTable.worldId, worldId));
|
|
1429
|
-
|
|
1769
|
+
const rooms = result.map((room) => ({
|
|
1770
|
+
...room,
|
|
1771
|
+
id: room.id,
|
|
1772
|
+
name: room.name ?? void 0,
|
|
1773
|
+
agentId: room.agentId,
|
|
1774
|
+
serverId: room.serverId,
|
|
1775
|
+
worldId: room.worldId,
|
|
1776
|
+
channelId: room.channelId,
|
|
1777
|
+
type: room.type,
|
|
1778
|
+
metadata: room.metadata
|
|
1779
|
+
}));
|
|
1780
|
+
return rooms;
|
|
1430
1781
|
});
|
|
1431
1782
|
}
|
|
1432
1783
|
/**
|
|
@@ -1444,30 +1795,16 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1444
1795
|
* @param {Room} room - The room object to create.
|
|
1445
1796
|
* @returns {Promise<UUID>} A Promise that resolves to the ID of the created room.
|
|
1446
1797
|
*/
|
|
1447
|
-
async
|
|
1448
|
-
id,
|
|
1449
|
-
name,
|
|
1450
|
-
source,
|
|
1451
|
-
type,
|
|
1452
|
-
channelId,
|
|
1453
|
-
serverId,
|
|
1454
|
-
worldId,
|
|
1455
|
-
metadata
|
|
1456
|
-
}) {
|
|
1798
|
+
async createRooms(rooms) {
|
|
1457
1799
|
return this.withDatabase(async () => {
|
|
1458
|
-
const
|
|
1459
|
-
|
|
1460
|
-
id:
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
serverId,
|
|
1467
|
-
worldId,
|
|
1468
|
-
metadata
|
|
1469
|
-
}).onConflictDoNothing({ target: roomTable.id });
|
|
1470
|
-
return newRoomId;
|
|
1800
|
+
const roomsWithIds = rooms.map((room) => ({
|
|
1801
|
+
...room,
|
|
1802
|
+
id: room.id || v4()
|
|
1803
|
+
// ensure each room has a unique ID
|
|
1804
|
+
}));
|
|
1805
|
+
const insertedRooms = await this.db.insert(roomTable).values(roomsWithIds).onConflictDoNothing().returning();
|
|
1806
|
+
const insertedIds = insertedRooms.map((r) => r.id);
|
|
1807
|
+
return insertedIds;
|
|
1471
1808
|
});
|
|
1472
1809
|
}
|
|
1473
1810
|
/**
|
|
@@ -1533,6 +1870,28 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1533
1870
|
}
|
|
1534
1871
|
});
|
|
1535
1872
|
}
|
|
1873
|
+
async addParticipantsRoom(entityIds, roomId) {
|
|
1874
|
+
return this.withDatabase(async () => {
|
|
1875
|
+
try {
|
|
1876
|
+
const values = entityIds.map((id) => ({
|
|
1877
|
+
entityId: id,
|
|
1878
|
+
roomId,
|
|
1879
|
+
agentId: this.agentId
|
|
1880
|
+
}));
|
|
1881
|
+
await this.db.insert(participantTable).values(values).onConflictDoNothing().execute();
|
|
1882
|
+
logger.debug(entityIds.length, "Entities linked successfully");
|
|
1883
|
+
return true;
|
|
1884
|
+
} catch (error) {
|
|
1885
|
+
logger.error("Error adding participants", {
|
|
1886
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1887
|
+
entityIdSample: entityIds[0],
|
|
1888
|
+
roomId,
|
|
1889
|
+
agentId: this.agentId
|
|
1890
|
+
});
|
|
1891
|
+
return false;
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1536
1895
|
/**
|
|
1537
1896
|
* Asynchronously removes a participant from a room in the database based on the provided parameters.
|
|
1538
1897
|
* @param {UUID} entityId - The ID of the entity to remove from the room.
|
|
@@ -1576,13 +1935,13 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1576
1935
|
entityId: participantTable.entityId,
|
|
1577
1936
|
roomId: participantTable.roomId
|
|
1578
1937
|
}).from(participantTable).where(eq(participantTable.entityId, entityId));
|
|
1579
|
-
const
|
|
1580
|
-
if (!
|
|
1938
|
+
const entities = await this.getEntityByIds([entityId]);
|
|
1939
|
+
if (!entities || !entities.length) {
|
|
1581
1940
|
return [];
|
|
1582
1941
|
}
|
|
1583
1942
|
return result.map((row) => ({
|
|
1584
1943
|
id: row.id,
|
|
1585
|
-
entity
|
|
1944
|
+
entity: entities[0]
|
|
1586
1945
|
}));
|
|
1587
1946
|
});
|
|
1588
1947
|
}
|
|
@@ -1745,39 +2104,28 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1745
2104
|
*/
|
|
1746
2105
|
async getRelationships(params) {
|
|
1747
2106
|
return this.withDatabase(async () => {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
tags: result.tags || [],
|
|
1771
|
-
metadata: result.metadata || {},
|
|
1772
|
-
createdAt: result.createdAt?.toString()
|
|
1773
|
-
}));
|
|
1774
|
-
} catch (error) {
|
|
1775
|
-
logger.error("Error getting relationships:", {
|
|
1776
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1777
|
-
params
|
|
1778
|
-
});
|
|
1779
|
-
return [];
|
|
1780
|
-
}
|
|
2107
|
+
const conditions = [
|
|
2108
|
+
or(
|
|
2109
|
+
eq(relationshipTable.sourceEntityId, params.entityId),
|
|
2110
|
+
eq(relationshipTable.targetEntityId, params.entityId)
|
|
2111
|
+
),
|
|
2112
|
+
eq(relationshipTable.agentId, this.agentId),
|
|
2113
|
+
...params.tags && params.tags.length > 0 ? [
|
|
2114
|
+
sql13`${relationshipTable.tags} @> ARRAY[${sql13.raw(
|
|
2115
|
+
params.tags.map((tag) => `'${tag.replace(/'/g, "''")}'`).join(", ")
|
|
2116
|
+
)}]::text[]`
|
|
2117
|
+
] : []
|
|
2118
|
+
];
|
|
2119
|
+
const results = await this.db.select().from(relationshipTable).where(and(...conditions));
|
|
2120
|
+
return results.map((row) => ({
|
|
2121
|
+
id: row.id,
|
|
2122
|
+
sourceEntityId: row.sourceEntityId,
|
|
2123
|
+
targetEntityId: row.targetEntityId,
|
|
2124
|
+
agentId: row.agentId,
|
|
2125
|
+
tags: row.tags || [],
|
|
2126
|
+
metadata: row.metadata || {},
|
|
2127
|
+
createdAt: row.createdAt?.toString()
|
|
2128
|
+
}));
|
|
1781
2129
|
});
|
|
1782
2130
|
}
|
|
1783
2131
|
/**
|
|
@@ -1864,7 +2212,8 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1864
2212
|
const newWorldId = world.id || v4();
|
|
1865
2213
|
await this.db.insert(worldTable).values({
|
|
1866
2214
|
...world,
|
|
1867
|
-
id: newWorldId
|
|
2215
|
+
id: newWorldId,
|
|
2216
|
+
name: world.name || ""
|
|
1868
2217
|
});
|
|
1869
2218
|
return newWorldId;
|
|
1870
2219
|
});
|
|
@@ -1916,6 +2265,9 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1916
2265
|
* @returns {Promise<UUID>} A Promise that resolves to the ID of the created task.
|
|
1917
2266
|
*/
|
|
1918
2267
|
async createTask(task) {
|
|
2268
|
+
if (!task.worldId) {
|
|
2269
|
+
throw new Error("worldId is required");
|
|
2270
|
+
}
|
|
1919
2271
|
return this.withRetry(async () => {
|
|
1920
2272
|
return this.withDatabase(async () => {
|
|
1921
2273
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1932,35 +2284,37 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1932
2284
|
updatedAt: now,
|
|
1933
2285
|
agentId: this.agentId
|
|
1934
2286
|
};
|
|
1935
|
-
const result = await this.db.insert(taskTable).values(values).returning(
|
|
2287
|
+
const result = await this.db.insert(taskTable).values(values).returning();
|
|
1936
2288
|
return result[0].id;
|
|
1937
2289
|
});
|
|
1938
2290
|
});
|
|
1939
2291
|
}
|
|
1940
2292
|
/**
|
|
1941
2293
|
* Asynchronously retrieves tasks based on specified parameters.
|
|
1942
|
-
* @param params Object containing optional roomId and
|
|
2294
|
+
* @param params Object containing optional roomId, tags, and entityId to filter tasks
|
|
1943
2295
|
* @returns Promise resolving to an array of Task objects
|
|
1944
2296
|
*/
|
|
1945
2297
|
async getTasks(params) {
|
|
1946
2298
|
return this.withRetry(async () => {
|
|
1947
2299
|
return this.withDatabase(async () => {
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2300
|
+
const result = await this.db.select().from(taskTable).where(
|
|
2301
|
+
and(
|
|
2302
|
+
eq(taskTable.agentId, this.agentId),
|
|
2303
|
+
...params.roomId ? [eq(taskTable.roomId, params.roomId)] : [],
|
|
2304
|
+
...params.tags && params.tags.length > 0 ? [
|
|
2305
|
+
sql13`${taskTable.tags} @> ARRAY[${sql13.raw(
|
|
2306
|
+
params.tags.map((t) => `'${t.replace(/'/g, "''")}'`).join(", ")
|
|
2307
|
+
)}]::text[]`
|
|
2308
|
+
] : []
|
|
2309
|
+
)
|
|
2310
|
+
);
|
|
1957
2311
|
return result.map((row) => ({
|
|
1958
2312
|
id: row.id,
|
|
1959
2313
|
name: row.name,
|
|
1960
|
-
description: row.description,
|
|
2314
|
+
description: row.description ?? "",
|
|
1961
2315
|
roomId: row.roomId,
|
|
1962
2316
|
worldId: row.worldId,
|
|
1963
|
-
tags: row.tags,
|
|
2317
|
+
tags: row.tags || [],
|
|
1964
2318
|
metadata: row.metadata
|
|
1965
2319
|
}));
|
|
1966
2320
|
});
|
|
@@ -1978,7 +2332,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
1978
2332
|
return result.map((row) => ({
|
|
1979
2333
|
id: row.id,
|
|
1980
2334
|
name: row.name,
|
|
1981
|
-
description: row.description,
|
|
2335
|
+
description: row.description ?? "",
|
|
1982
2336
|
roomId: row.roomId,
|
|
1983
2337
|
worldId: row.worldId,
|
|
1984
2338
|
tags: row.tags || [],
|
|
@@ -2003,7 +2357,7 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
2003
2357
|
return {
|
|
2004
2358
|
id: row.id,
|
|
2005
2359
|
name: row.name,
|
|
2006
|
-
description: row.description,
|
|
2360
|
+
description: row.description ?? "",
|
|
2007
2361
|
roomId: row.roomId,
|
|
2008
2362
|
worldId: row.worldId,
|
|
2009
2363
|
tags: row.tags || [],
|
|
@@ -2053,70 +2407,53 @@ var BaseDrizzleAdapter = class extends DatabaseAdapter {
|
|
|
2053
2407
|
* @returns Promise resolving when the deletion is complete
|
|
2054
2408
|
*/
|
|
2055
2409
|
async deleteTask(id) {
|
|
2056
|
-
|
|
2057
|
-
await this.
|
|
2058
|
-
await this.db.delete(taskTable).where(and(eq(taskTable.id, id), eq(taskTable.agentId, this.agentId)));
|
|
2059
|
-
});
|
|
2410
|
+
return this.withDatabase(async () => {
|
|
2411
|
+
await this.db.delete(taskTable).where(eq(taskTable.id, id));
|
|
2060
2412
|
});
|
|
2061
2413
|
}
|
|
2062
|
-
|
|
2063
|
-
* Asynchronously retrieves group chat memories from all rooms under a given server.
|
|
2064
|
-
* It fetches all room IDs associated with the `serverId`, then retrieves memories
|
|
2065
|
-
* from those rooms in descending order (latest to oldest), with an optional count limit.
|
|
2066
|
-
*
|
|
2067
|
-
* @param {Object} params - Parameters for fetching memories.
|
|
2068
|
-
* @param {UUID} params.serverId - The server ID to fetch memories for.
|
|
2069
|
-
* @param {number} [params.count] - The maximum number of memories to retrieve.
|
|
2070
|
-
* @returns {Promise<Memory[]>} - A promise that resolves to an array of memory objects.
|
|
2071
|
-
*/
|
|
2072
|
-
async getMemoriesByServerId(params) {
|
|
2414
|
+
async getMemoriesByWorldId(params) {
|
|
2073
2415
|
return this.withDatabase(async () => {
|
|
2074
|
-
const
|
|
2075
|
-
if (
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
createdAt: row.memory.createdAt,
|
|
2086
|
-
content: typeof row.memory.content === "string" ? JSON.parse(row.memory.content) : row.memory.content,
|
|
2087
|
-
entityId: row.memory.entityId,
|
|
2088
|
-
agentId: row.memory.agentId,
|
|
2089
|
-
roomId: row.memory.roomId,
|
|
2090
|
-
unique: row.memory.unique,
|
|
2091
|
-
embedding: row.embedding ?? void 0
|
|
2092
|
-
}));
|
|
2416
|
+
const rooms = await this.db.select({ id: roomTable.id }).from(roomTable).where(and(eq(roomTable.worldId, params.worldId), eq(roomTable.agentId, this.agentId)));
|
|
2417
|
+
if (rooms.length === 0) {
|
|
2418
|
+
return [];
|
|
2419
|
+
}
|
|
2420
|
+
const roomIds = rooms.map((room) => room.id);
|
|
2421
|
+
const memories = await this.getMemoriesByRoomIds({
|
|
2422
|
+
roomIds,
|
|
2423
|
+
tableName: params.tableName || "messages",
|
|
2424
|
+
limit: params.count
|
|
2425
|
+
});
|
|
2426
|
+
return memories;
|
|
2093
2427
|
});
|
|
2094
2428
|
}
|
|
2095
|
-
|
|
2096
|
-
* Asynchronously deletes all rooms associated with a specific serverId.
|
|
2097
|
-
* @param {UUID} serverId - The server ID to delete rooms for.
|
|
2098
|
-
* @returns {Promise<void>} A Promise that resolves when the rooms are deleted.
|
|
2099
|
-
*/
|
|
2100
|
-
async deleteRoomsByServerId(serverId) {
|
|
2429
|
+
async deleteRoomsByWorldId(worldId) {
|
|
2101
2430
|
return this.withDatabase(async () => {
|
|
2102
|
-
await this.db.
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
await tx.delete(embeddingTable).where(
|
|
2107
|
-
inArray(
|
|
2108
|
-
embeddingTable.memoryId,
|
|
2109
|
-
tx.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.roomId, roomIds))
|
|
2110
|
-
)
|
|
2431
|
+
const rooms = await this.db.select({ id: roomTable.id }).from(roomTable).where(and(eq(roomTable.worldId, worldId), eq(roomTable.agentId, this.agentId)));
|
|
2432
|
+
if (rooms.length === 0) {
|
|
2433
|
+
logger.debug(
|
|
2434
|
+
`No rooms found for worldId ${worldId} and agentId ${this.agentId} to delete.`
|
|
2111
2435
|
);
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
const roomIds = rooms.map((room) => room.id);
|
|
2439
|
+
if (roomIds.length > 0) {
|
|
2440
|
+
await this.db.delete(logTable).where(inArray(logTable.roomId, roomIds));
|
|
2441
|
+
logger.debug(`Deleted logs for ${roomIds.length} rooms in world ${worldId}.`);
|
|
2442
|
+
await this.db.delete(participantTable).where(inArray(participantTable.roomId, roomIds));
|
|
2443
|
+
logger.debug(`Deleted participants for ${roomIds.length} rooms in world ${worldId}.`);
|
|
2444
|
+
const memoriesInRooms = await this.db.select({ id: memoryTable.id }).from(memoryTable).where(inArray(memoryTable.roomId, roomIds));
|
|
2445
|
+
const memoryIdsInRooms = memoriesInRooms.map((m) => m.id);
|
|
2446
|
+
if (memoryIdsInRooms.length > 0) {
|
|
2447
|
+
await this.db.delete(embeddingTable).where(inArray(embeddingTable.memoryId, memoryIdsInRooms));
|
|
2448
|
+
logger.debug(
|
|
2449
|
+
`Deleted embeddings for ${memoryIdsInRooms.length} memories in world ${worldId}.`
|
|
2450
|
+
);
|
|
2451
|
+
await this.db.delete(memoryTable).where(inArray(memoryTable.id, memoryIdsInRooms));
|
|
2452
|
+
logger.debug(`Deleted ${memoryIdsInRooms.length} memories in world ${worldId}.`);
|
|
2453
|
+
}
|
|
2454
|
+
await this.db.delete(roomTable).where(inArray(roomTable.id, roomIds));
|
|
2455
|
+
logger.debug(`Deleted ${roomIds.length} rooms for worldId ${worldId}.`);
|
|
2456
|
+
}
|
|
2120
2457
|
});
|
|
2121
2458
|
}
|
|
2122
2459
|
};
|
|
@@ -2171,6 +2508,14 @@ var PgliteDatabaseAdapter = class extends BaseDrizzleAdapter {
|
|
|
2171
2508
|
async close() {
|
|
2172
2509
|
await this.manager.close();
|
|
2173
2510
|
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Asynchronously retrieves the connection from the manager.
|
|
2513
|
+
*
|
|
2514
|
+
* @returns {Promise<PGlite>} A Promise that resolves with the connection.
|
|
2515
|
+
*/
|
|
2516
|
+
async getConnection() {
|
|
2517
|
+
return this.manager.getConnection();
|
|
2518
|
+
}
|
|
2174
2519
|
};
|
|
2175
2520
|
|
|
2176
2521
|
// src/pg/adapter.ts
|
|
@@ -2233,6 +2578,14 @@ var PgDatabaseAdapter = class extends BaseDrizzleAdapter {
|
|
|
2233
2578
|
async close() {
|
|
2234
2579
|
await this.manager.close();
|
|
2235
2580
|
}
|
|
2581
|
+
/**
|
|
2582
|
+
* Asynchronously retrieves the connection from the manager.
|
|
2583
|
+
*
|
|
2584
|
+
* @returns {Promise<PgPool>} A Promise that resolves with the connection.
|
|
2585
|
+
*/
|
|
2586
|
+
async getConnection() {
|
|
2587
|
+
return this.manager.getConnection();
|
|
2588
|
+
}
|
|
2236
2589
|
};
|
|
2237
2590
|
|
|
2238
2591
|
// src/index.ts
|
|
@@ -2242,17 +2595,8 @@ if (!globalSymbols[GLOBAL_SINGLETONS]) {
|
|
|
2242
2595
|
globalSymbols[GLOBAL_SINGLETONS] = {};
|
|
2243
2596
|
}
|
|
2244
2597
|
var globalSingletons = globalSymbols[GLOBAL_SINGLETONS];
|
|
2245
|
-
function expandTildePath(filepath) {
|
|
2246
|
-
if (filepath && typeof filepath === "string" && filepath.startsWith("~")) {
|
|
2247
|
-
return filepath.replace(/^~/, os.homedir());
|
|
2248
|
-
}
|
|
2249
|
-
return filepath;
|
|
2250
|
-
}
|
|
2251
|
-
__name(expandTildePath, "expandTildePath");
|
|
2252
2598
|
function createDatabaseAdapter(config, agentId) {
|
|
2253
|
-
|
|
2254
|
-
config.dataDir = expandTildePath(config.dataDir);
|
|
2255
|
-
}
|
|
2599
|
+
const dataDir = resolvePgliteDir(config.dataDir);
|
|
2256
2600
|
if (config.postgresUrl) {
|
|
2257
2601
|
if (!globalSingletons.postgresConnectionManager) {
|
|
2258
2602
|
globalSingletons.postgresConnectionManager = new PostgresConnectionManager(
|
|
@@ -2261,7 +2605,6 @@ function createDatabaseAdapter(config, agentId) {
|
|
|
2261
2605
|
}
|
|
2262
2606
|
return new PgDatabaseAdapter(agentId, globalSingletons.postgresConnectionManager);
|
|
2263
2607
|
}
|
|
2264
|
-
const dataDir = config.dataDir ?? "./elizadb";
|
|
2265
2608
|
if (!globalSingletons.pgLiteClientManager) {
|
|
2266
2609
|
globalSingletons.pgLiteClientManager = new PGliteClientManager({ dataDir });
|
|
2267
2610
|
}
|
|
@@ -2273,7 +2616,7 @@ var sqlPlugin = {
|
|
|
2273
2616
|
description: "SQL database adapter plugin using Drizzle ORM",
|
|
2274
2617
|
init: /* @__PURE__ */ __name(async (_, runtime) => {
|
|
2275
2618
|
const config = {
|
|
2276
|
-
dataDir: runtime.getSetting("PGLITE_DATA_DIR")
|
|
2619
|
+
dataDir: resolvePgliteDir(runtime.getSetting("PGLITE_DATA_DIR")),
|
|
2277
2620
|
postgresUrl: runtime.getSetting("POSTGRES_URL")
|
|
2278
2621
|
};
|
|
2279
2622
|
try {
|