@elizaos/core 1.0.0-alpha.2 → 1.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,30 +1,98 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ // ../../node_modules/dedent/dist/dedent.js
28
+ var require_dedent = __commonJS({
29
+ "../../node_modules/dedent/dist/dedent.js"(exports, module) {
30
+ "use strict";
31
+ function dedent3(strings) {
32
+ var raw2 = void 0;
33
+ if (typeof strings === "string") {
34
+ raw2 = [strings];
35
+ } else {
36
+ raw2 = strings.raw;
37
+ }
38
+ var result = "";
39
+ for (var i = 0; i < raw2.length; i++) {
40
+ result += raw2[i].replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`");
41
+ if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {
42
+ result += arguments.length <= i + 1 ? void 0 : arguments[i + 1];
43
+ }
44
+ }
45
+ var lines = result.split("\n");
46
+ var mindent = null;
47
+ lines.forEach(function(l) {
48
+ var m = l.match(/^(\s+)\S+/);
49
+ if (m) {
50
+ var indent = m[1].length;
51
+ if (!mindent) {
52
+ mindent = indent;
53
+ } else {
54
+ mindent = Math.min(mindent, indent);
55
+ }
56
+ }
57
+ });
58
+ if (mindent !== null) {
59
+ result = lines.map(function(l) {
60
+ return l[0] === " " ? l.slice(mindent) : l;
61
+ }).join("\n");
62
+ }
63
+ result = result.trim();
64
+ return result.replace(/\\n/g, "\n");
65
+ }
66
+ if (typeof module !== "undefined") {
67
+ module.exports = dedent3;
68
+ }
69
+ }
70
+ });
71
+
1
72
  // src/types.ts
2
- var GoalStatus = /* @__PURE__ */ ((GoalStatus2) => {
3
- GoalStatus2["DONE"] = "DONE";
4
- GoalStatus2["FAILED"] = "FAILED";
5
- GoalStatus2["IN_PROGRESS"] = "IN_PROGRESS";
6
- return GoalStatus2;
7
- })(GoalStatus || {});
8
73
  var ModelTypes = {
9
- SMALL: "text_small",
74
+ SMALL: "TEXT_SMALL",
10
75
  // kept for backwards compatibility
11
- MEDIUM: "text_large",
76
+ MEDIUM: "TEXT_LARGE",
12
77
  // kept for backwards compatibility
13
- LARGE: "text_large",
78
+ LARGE: "TEXT_LARGE",
14
79
  // kept for backwards compatibility
15
- TEXT_SMALL: "text_small",
16
- TEXT_LARGE: "text_large",
17
- TEXT_EMBEDDING: "text_embedding",
80
+ TEXT_SMALL: "TEXT_SMALL",
81
+ TEXT_LARGE: "TEXT_LARGE",
82
+ TEXT_EMBEDDING: "TEXT_EMBEDDING",
18
83
  TEXT_TOKENIZER_ENCODE: "TEXT_TOKENIZER_ENCODE",
19
84
  TEXT_TOKENIZER_DECODE: "TEXT_TOKENIZER_DECODE",
20
- TEXT_REASONING_SMALL: "reasoning_small",
21
- TEXT_REASONING_LARGE: "reasoning_large",
22
- IMAGE: "image",
23
- IMAGE_DESCRIPTION: "image_description",
24
- TRANSCRIPTION: "transcription",
25
- TEXT_TO_SPEECH: "text_to_speech",
26
- AUDIO: "audio",
27
- VIDEO: "video"
85
+ TEXT_REASONING_SMALL: "REASONING_SMALL",
86
+ TEXT_REASONING_LARGE: "REASONING_LARGE",
87
+ TEXT_COMPLETION: "TEXT_COMPLETION",
88
+ IMAGE: "IMAGE",
89
+ IMAGE_DESCRIPTION: "IMAGE_DESCRIPTION",
90
+ TRANSCRIPTION: "TRANSCRIPTION",
91
+ TEXT_TO_SPEECH: "TEXT_TO_SPEECH",
92
+ AUDIO: "AUDIO",
93
+ VIDEO: "VIDEO",
94
+ OBJECT_SMALL: "OBJECT_SMALL",
95
+ OBJECT_LARGE: "OBJECT_LARGE"
28
96
  };
29
97
  var ServiceTypes = {
30
98
  TRANSCRIPTION: "transcription",
@@ -59,17 +127,11 @@ var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
59
127
  return ChannelType2;
60
128
  })(ChannelType || {});
61
129
  var Service = class {
62
- /** Runtime instance */
63
- runtime;
64
130
  constructor(runtime) {
65
131
  if (runtime) {
66
132
  this.runtime = runtime;
67
133
  }
68
134
  }
69
- /** Service type */
70
- static serviceType;
71
- /** Service configuration */
72
- config;
73
135
  /** Start service connection */
74
136
  static async start(_runtime) {
75
137
  throw new Error("Not implemented");
@@ -89,7 +151,6 @@ var CacheKeyPrefix = /* @__PURE__ */ ((CacheKeyPrefix2) => {
89
151
  return CacheKeyPrefix2;
90
152
  })(CacheKeyPrefix || {});
91
153
  var TeeLogDAO = class {
92
- db;
93
154
  };
94
155
  var TEEMode = /* @__PURE__ */ ((TEEMode2) => {
95
156
  TEEMode2["OFF"] = "OFF";
@@ -109,6 +170,37 @@ var Role = /* @__PURE__ */ ((Role2) => {
109
170
  Role2["NONE"] = "NONE";
110
171
  return Role2;
111
172
  })(Role || {});
173
+ var EventTypes = /* @__PURE__ */ ((EventTypes2) => {
174
+ EventTypes2["WORLD_JOINED"] = "WORLD_JOINED";
175
+ EventTypes2["WORLD_CONNECTED"] = "WORLD_CONNECTED";
176
+ EventTypes2["WORLD_LEFT"] = "WORLD_LEFT";
177
+ EventTypes2["ENTITY_JOINED"] = "ENTITY_JOINED";
178
+ EventTypes2["ENTITY_LEFT"] = "ENTITY_LEFT";
179
+ EventTypes2["ENTITY_UPDATED"] = "ENTITY_UPDATED";
180
+ EventTypes2["ROOM_JOINED"] = "ROOM_JOINED";
181
+ EventTypes2["ROOM_LEFT"] = "ROOM_LEFT";
182
+ EventTypes2["MESSAGE_RECEIVED"] = "MESSAGE_RECEIVED";
183
+ EventTypes2["MESSAGE_SENT"] = "MESSAGE_SENT";
184
+ EventTypes2["VOICE_MESSAGE_RECEIVED"] = "VOICE_MESSAGE_RECEIVED";
185
+ EventTypes2["VOICE_MESSAGE_SENT"] = "VOICE_MESSAGE_SENT";
186
+ EventTypes2["REACTION_RECEIVED"] = "REACTION_RECEIVED";
187
+ EventTypes2["POST_GENERATED"] = "POST_GENERATED";
188
+ EventTypes2["INTERACTION_RECEIVED"] = "INTERACTION_RECEIVED";
189
+ EventTypes2["RUN_STARTED"] = "RUN_STARTED";
190
+ EventTypes2["RUN_ENDED"] = "RUN_ENDED";
191
+ EventTypes2["RUN_TIMEOUT"] = "RUN_TIMEOUT";
192
+ EventTypes2["ACTION_STARTED"] = "ACTION_STARTED";
193
+ EventTypes2["ACTION_COMPLETED"] = "ACTION_COMPLETED";
194
+ EventTypes2["EVALUATOR_STARTED"] = "EVALUATOR_STARTED";
195
+ EventTypes2["EVALUATOR_COMPLETED"] = "EVALUATOR_COMPLETED";
196
+ return EventTypes2;
197
+ })(EventTypes || {});
198
+ var PlatformPrefix = /* @__PURE__ */ ((PlatformPrefix2) => {
199
+ PlatformPrefix2["DISCORD"] = "DISCORD";
200
+ PlatformPrefix2["TELEGRAM"] = "TELEGRAM";
201
+ PlatformPrefix2["TWITTER"] = "TWITTER";
202
+ return PlatformPrefix2;
203
+ })(PlatformPrefix || {});
112
204
 
113
205
  // src/actions.ts
114
206
  import { names, uniqueNamesGenerator } from "unique-names-generator";
@@ -160,10 +252,6 @@ function formatActions(actions) {
160
252
 
161
253
  // src/database.ts
162
254
  var DatabaseAdapter = class {
163
- /**
164
- * The database instance.
165
- */
166
- db;
167
255
  };
168
256
 
169
257
  // src/prompts.ts
@@ -175,13 +263,21 @@ import { names as names2, uniqueNamesGenerator as uniqueNamesGenerator2 } from "
175
263
  import pino from "pino";
176
264
  import pretty from "pino-pretty";
177
265
  var InMemoryDestination = class {
178
- logs = [];
179
- maxLogs = 1e3;
180
- // Keep last 1000 logs
181
- stream;
266
+ /**
267
+ * Constructor for creating a new instance of the class.
268
+ * @param {DestinationStream|null} stream - The stream to assign to the instance. Can be null.
269
+ */
182
270
  constructor(stream2) {
271
+ this.logs = [];
272
+ this.maxLogs = 1e3;
183
273
  this.stream = stream2;
184
274
  }
275
+ /**
276
+ * Writes a log entry to the memory buffer and forwards it to the pretty print stream if available.
277
+ *
278
+ * @param {string | LogEntry} data - The data to be written, which can be either a string or a LogEntry object.
279
+ * @returns {void}
280
+ */
185
281
  write(data) {
186
282
  const logEntry = typeof data === "string" ? JSON.parse(data) : data;
187
283
  if (!logEntry.time) {
@@ -196,6 +292,11 @@ var InMemoryDestination = class {
196
292
  this.stream.write(stringData);
197
293
  }
198
294
  }
295
+ /**
296
+ * Retrieves the recent logs from the system.
297
+ *
298
+ * @returns {LogEntry[]} An array of LogEntry objects representing the recent logs.
299
+ */
199
300
  recentLogs() {
200
301
  return this.logs;
201
302
  }
@@ -264,7 +365,27 @@ var composePrompt = ({
264
365
  }) => {
265
366
  const templateStr = typeof template === "function" ? template({ state }) : template;
266
367
  const templateFunction = handlebars.compile(templateStr);
267
- const output = composeRandomUser(templateFunction(state.values), 10);
368
+ const output = composeRandomUser(templateFunction(state), 10);
369
+ return output;
370
+ };
371
+ var composePromptFromState = ({
372
+ state,
373
+ template
374
+ }) => {
375
+ const templateStr = typeof template === "function" ? template({ state }) : template;
376
+ const templateFunction = handlebars.compile(templateStr);
377
+ const stateKeys = Object.keys(state);
378
+ const filteredKeys = stateKeys.filter(
379
+ (key) => !["text", "values", "data"].includes(key)
380
+ );
381
+ const filteredState = filteredKeys.reduce((acc, key) => {
382
+ acc[key] = state[key];
383
+ return acc;
384
+ }, {});
385
+ const output = composeRandomUser(
386
+ templateFunction({ ...filteredState, ...state.values }),
387
+ 10
388
+ );
268
389
  return output;
269
390
  };
270
391
  var addHeader = (header, body) => {
@@ -279,7 +400,7 @@ var composeRandomUser = (template, length) => {
279
400
  );
280
401
  let result = template;
281
402
  for (let i = 0; i < exampleNames.length; i++) {
282
- result = result.replaceAll(`{{user${i + 1}}}`, exampleNames[i]);
403
+ result = result.replaceAll(`{{name${i + 1}}}`, exampleNames[i]);
283
404
  }
284
405
  return result;
285
406
  };
@@ -390,6 +511,7 @@ Response format should be formatted in a valid JSON block like this:
390
511
  \`\`\`json
391
512
  {
392
513
  "name": "{{agentName}}",
514
+ "reasoning": "<string>",
393
515
  "action": "RESPOND" | "IGNORE" | "STOP",
394
516
  "providers": ["<string>", "<string>", ...]
395
517
  }
@@ -680,13 +802,13 @@ async function getRecentInteractions(runtime, sourceEntityId, candidateEntities,
680
802
  }
681
803
  async function findEntityByName(runtime, message, state) {
682
804
  try {
683
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
805
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
684
806
  if (!room) {
685
807
  logger.warn("Room not found for entity search");
686
808
  return null;
687
809
  }
688
- const world = room.worldId ? await runtime.getDatabaseAdapter().getWorld(room.worldId) : null;
689
- const entitiesInRoom = await runtime.getDatabaseAdapter().getEntitiesForRoom(room.id, true);
810
+ const world = room.worldId ? await runtime.getWorld(room.worldId) : null;
811
+ const entitiesInRoom = await runtime.getEntitiesForRoom(room.id, true);
690
812
  const filteredEntities = await Promise.all(
691
813
  entitiesInRoom.map(async (entity) => {
692
814
  if (!entity.components) return entity;
@@ -703,13 +825,13 @@ async function findEntityByName(runtime, message, state) {
703
825
  return entity;
704
826
  })
705
827
  );
706
- const relationships = await runtime.getDatabaseAdapter().getRelationships({
828
+ const relationships = await runtime.getRelationships({
707
829
  entityId: message.entityId
708
830
  });
709
831
  const relationshipEntities = await Promise.all(
710
832
  relationships.map(async (rel) => {
711
833
  const entityId = rel.sourceEntityId === message.entityId ? rel.targetEntityId : rel.sourceEntityId;
712
- return runtime.getDatabaseAdapter().getEntityById(entityId);
834
+ return runtime.getEntityById(entityId);
713
835
  })
714
836
  );
715
837
  const allEntities = [
@@ -725,7 +847,6 @@ async function findEntityByName(runtime, message, state) {
725
847
  );
726
848
  const prompt = composePrompt({
727
849
  state: {
728
- ...state,
729
850
  roomName: room.name || room.id,
730
851
  worldName: world?.name || "Unknown",
731
852
  entitiesInRoom: JSON.stringify(filteredEntities, null, 2),
@@ -744,7 +865,7 @@ async function findEntityByName(runtime, message, state) {
744
865
  return null;
745
866
  }
746
867
  if (resolution.type === "EXACT_MATCH" && resolution.entityId) {
747
- const entity = await runtime.getDatabaseAdapter().getEntityById(resolution.entityId);
868
+ const entity = await runtime.getEntityById(resolution.entityId);
748
869
  if (entity) {
749
870
  if (entity.components) {
750
871
  const worldRoles = world?.metadata?.roles || {};
@@ -801,8 +922,8 @@ async function getEntityDetails({
801
922
  roomId
802
923
  }) {
803
924
  const [room, roomEntities] = await Promise.all([
804
- runtime.getDatabaseAdapter().getRoom(roomId),
805
- runtime.getDatabaseAdapter().getEntitiesForRoom(roomId, true)
925
+ runtime.getRoom(roomId),
926
+ runtime.getEntitiesForRoom(roomId, true)
806
927
  ]);
807
928
  const uniqueEntities = /* @__PURE__ */ new Map();
808
929
  for (const entity of roomEntities) {
@@ -834,9 +955,9 @@ async function getEntityDetails({
834
955
  }
835
956
 
836
957
  // src/environment.ts
837
- import { config } from "dotenv";
838
958
  import fs from "node:fs";
839
959
  import path from "node:path";
960
+ import { config } from "dotenv";
840
961
 
841
962
  // ../../node_modules/zod/lib/index.mjs
842
963
  var util;
@@ -5078,14 +5199,6 @@ async function handlePluginImporting(plugins) {
5078
5199
  var defaultMatchThreshold = 0.1;
5079
5200
  var defaultMatchCount = 10;
5080
5201
  var MemoryManager = class {
5081
- /**
5082
- * The AgentRuntime instance associated with this manager.
5083
- */
5084
- runtime;
5085
- /**
5086
- * The name of the database table this manager operates on.
5087
- */
5088
- tableName;
5089
5202
  /**
5090
5203
  * Constructs a new MemoryManager instance.
5091
5204
  * @param opts Options for the manager.
@@ -5138,7 +5251,9 @@ var MemoryManager = class {
5138
5251
  try {
5139
5252
  memory.embedding = await this.runtime.useModel(
5140
5253
  ModelTypes.TEXT_EMBEDDING,
5141
- memoryText
5254
+ {
5255
+ text: memoryText
5256
+ }
5142
5257
  );
5143
5258
  } catch (error) {
5144
5259
  logger_default.error("Failed to generate embedding:", error);
@@ -5158,7 +5273,7 @@ var MemoryManager = class {
5158
5273
  * @returns A Promise resolving to an array of Memory objects.
5159
5274
  */
5160
5275
  async getMemories(opts) {
5161
- return await this.runtime.getDatabaseAdapter().getMemories({
5276
+ return await this.runtime.getMemories({
5162
5277
  roomId: opts.roomId,
5163
5278
  count: opts.count,
5164
5279
  unique: opts.unique,
@@ -5168,7 +5283,7 @@ var MemoryManager = class {
5168
5283
  });
5169
5284
  }
5170
5285
  async getCachedEmbeddings(content) {
5171
- return await this.runtime.getDatabaseAdapter().getCachedEmbeddings({
5286
+ return await this.runtime.getCachedEmbeddings({
5172
5287
  query_table_name: this.tableName,
5173
5288
  query_threshold: 2,
5174
5289
  query_input: content,
@@ -5196,7 +5311,7 @@ var MemoryManager = class {
5196
5311
  agentId,
5197
5312
  unique = true
5198
5313
  } = opts;
5199
- return await this.runtime.getDatabaseAdapter().searchMemories({
5314
+ return await this.runtime.searchMemories({
5200
5315
  tableName: this.tableName,
5201
5316
  roomId,
5202
5317
  embedding,
@@ -5216,7 +5331,7 @@ var MemoryManager = class {
5216
5331
  this.validateMetadata(memory.metadata);
5217
5332
  this.validateMetadataRequirements(memory.metadata);
5218
5333
  }
5219
- const existingMessage = await this.runtime.getDatabaseAdapter().getMemoryById(memory.id);
5334
+ const existingMessage = await this.runtime.getMemoryById(memory.id);
5220
5335
  if (existingMessage) {
5221
5336
  logger_default.debug("Memory already exists, skipping");
5222
5337
  return;
@@ -5244,18 +5359,18 @@ var MemoryManager = class {
5244
5359
  null
5245
5360
  );
5246
5361
  }
5247
- const memoryId = await this.runtime.getDatabaseAdapter().createMemory(memory, this.tableName, unique);
5362
+ const memoryId = await this.runtime.createMemory(memory, this.tableName, unique);
5248
5363
  return memoryId;
5249
5364
  }
5250
5365
  async getMemoriesByRoomIds(params) {
5251
- return await this.runtime.getDatabaseAdapter().getMemoriesByRoomIds({
5366
+ return await this.runtime.getMemoriesByRoomIds({
5252
5367
  tableName: this.tableName,
5253
5368
  roomIds: params.roomIds,
5254
5369
  limit: params.limit
5255
5370
  });
5256
5371
  }
5257
5372
  async getMemoryById(id) {
5258
- const result = await this.runtime.getDatabaseAdapter().getMemoryById(id);
5373
+ const result = await this.runtime.getMemoryById(id);
5259
5374
  if (result && result.agentId !== this.runtime.agentId) return null;
5260
5375
  return result;
5261
5376
  }
@@ -5265,7 +5380,7 @@ var MemoryManager = class {
5265
5380
  * @returns A Promise that resolves when the operation completes.
5266
5381
  */
5267
5382
  async removeMemory(memoryId) {
5268
- await this.runtime.getDatabaseAdapter().removeMemory(memoryId, this.tableName);
5383
+ await this.runtime.removeMemory(memoryId, this.tableName);
5269
5384
  }
5270
5385
  /**
5271
5386
  * Removes all memories associated with a set of user IDs.
@@ -5273,7 +5388,7 @@ var MemoryManager = class {
5273
5388
  * @returns A Promise that resolves when the operation completes.
5274
5389
  */
5275
5390
  async removeAllMemories(roomId) {
5276
- await this.runtime.getDatabaseAdapter().removeAllMemories(roomId, this.tableName);
5391
+ await this.runtime.removeAllMemories(roomId, this.tableName);
5277
5392
  }
5278
5393
  /**
5279
5394
  * Counts the number of memories associated with a set of user IDs, with an option for uniqueness.
@@ -5282,7 +5397,7 @@ var MemoryManager = class {
5282
5397
  * @returns A Promise resolving to the count of memories.
5283
5398
  */
5284
5399
  async countMemories(roomId, unique = true) {
5285
- return await this.runtime.getDatabaseAdapter().countMemories(roomId, unique, this.tableName);
5400
+ return await this.runtime.countMemories(roomId, unique, this.tableName);
5286
5401
  }
5287
5402
  validateMetadataRequirements(metadata) {
5288
5403
  if (metadata.type === "fragment" /* FRAGMENT */) {
@@ -5300,15 +5415,15 @@ var MemoryManager = class {
5300
5415
  async function getUserServerRole(runtime, entityId, serverId) {
5301
5416
  try {
5302
5417
  const worldId = createUniqueUuid(runtime, serverId);
5303
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
5418
+ const world = await runtime.getWorld(worldId);
5304
5419
  if (!world || !world.metadata?.roles) {
5305
5420
  return "NONE" /* NONE */;
5306
5421
  }
5307
- if (world.metadata.roles[entityId]?.role) {
5308
- return world.metadata.roles[entityId].role;
5422
+ if (world.metadata.roles[entityId]) {
5423
+ return world.metadata.roles[entityId];
5309
5424
  }
5310
- if (world.metadata.roles[entityId]?.role) {
5311
- return world.metadata.roles[entityId].role;
5425
+ if (world.metadata.roles[entityId]) {
5426
+ return world.metadata.roles[entityId];
5312
5427
  }
5313
5428
  return "NONE" /* NONE */;
5314
5429
  } catch (error) {
@@ -5322,7 +5437,7 @@ async function findWorldForOwner(runtime, entityId) {
5322
5437
  logger.error("User ID is required to find server");
5323
5438
  return null;
5324
5439
  }
5325
- const worlds = await runtime.getDatabaseAdapter().getAllWorlds();
5440
+ const worlds = await runtime.getAllWorlds();
5326
5441
  if (!worlds || worlds.length === 0) {
5327
5442
  logger.info("No worlds found for this agent");
5328
5443
  return null;
@@ -5352,7 +5467,7 @@ var optionExtractionTemplate = `# Task: Extract selected task and option from us
5352
5467
 
5353
5468
  # Available Tasks:
5354
5469
  {{#each tasks}}
5355
- Task {{taskId}}: {{name}}
5470
+ Task ID: {{taskId}} - {{name}}
5356
5471
  Available options:
5357
5472
  {{#each options}}
5358
5473
  - {{name}}: {{description}}
@@ -5367,13 +5482,13 @@ Available options:
5367
5482
  # Instructions:
5368
5483
  1. Review the user's message and identify which task and option they are selecting
5369
5484
  2. Match against the available tasks and their options, including ABORT
5370
- 3. Return the task ID and selected option name exactly as listed above
5485
+ 3. Return the task ID (shortened UUID) and selected option name exactly as listed above
5371
5486
  4. If no clear selection is made, return null for both fields
5372
5487
 
5373
5488
  Return in JSON format:
5374
5489
  \`\`\`json
5375
5490
  {
5376
- "taskId": number | null,
5491
+ "taskId": "string" | null,
5377
5492
  "selectedOption": "OPTION_NAME" | null
5378
5493
  }
5379
5494
  \`\`\`
@@ -5384,11 +5499,11 @@ var choiceAction = {
5384
5499
  similes: ["SELECT_OPTION", "SELECT", "PICK", "CHOOSE"],
5385
5500
  description: "Selects an option for a pending task that has multiple options",
5386
5501
  validate: async (runtime, message, state) => {
5387
- const pendingTasks = await runtime.getDatabaseAdapter().getTasks({
5502
+ const pendingTasks = await runtime.getTasks({
5388
5503
  roomId: message.roomId,
5389
5504
  tags: ["AWAITING_CHOICE"]
5390
5505
  });
5391
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
5506
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
5392
5507
  const userRole = await getUserServerRole(
5393
5508
  runtime,
5394
5509
  message.entityId,
@@ -5401,10 +5516,7 @@ var choiceAction = {
5401
5516
  },
5402
5517
  handler: async (runtime, message, state, _options, callback, responses) => {
5403
5518
  try {
5404
- for (const response of responses) {
5405
- await callback(response.content);
5406
- }
5407
- const pendingTasks = await runtime.getDatabaseAdapter().getTasks({
5519
+ const pendingTasks = await runtime.getTasks({
5408
5520
  roomId: message.roomId,
5409
5521
  tags: ["AWAITING_CHOICE"]
5410
5522
  });
@@ -5417,18 +5529,26 @@ var choiceAction = {
5417
5529
  if (!tasksWithOptions.length) {
5418
5530
  throw new Error("No tasks currently have options to select from.");
5419
5531
  }
5420
- const formattedTasks = tasksWithOptions.map((task, index) => ({
5421
- taskId: index + 1,
5422
- name: task.name,
5423
- options: task.metadata.options.map((opt) => ({
5424
- name: typeof opt === "string" ? opt : opt.name,
5425
- description: typeof opt === "string" ? opt : opt.description || opt.name
5426
- }))
5427
- }));
5532
+ const formattedTasks = tasksWithOptions.map((task) => {
5533
+ const shortId = task.id.substring(0, 8);
5534
+ return {
5535
+ taskId: shortId,
5536
+ fullId: task.id,
5537
+ name: task.name,
5538
+ options: task.metadata.options.map((opt) => ({
5539
+ name: typeof opt === "string" ? opt : opt.name,
5540
+ description: typeof opt === "string" ? opt : opt.description || opt.name
5541
+ }))
5542
+ };
5543
+ });
5544
+ const tasksString = formattedTasks.map((task) => {
5545
+ return `Task ID: ${task.taskId} - ${task.name}
5546
+ Available options:
5547
+ ${task.options.map((opt) => `- ${opt.name}: ${opt.description}`).join("\n")}`;
5548
+ }).join("\n");
5428
5549
  const prompt = composePrompt({
5429
5550
  state: {
5430
- ...state,
5431
- tasks: formattedTasks,
5551
+ tasks: tasksString,
5432
5552
  recentMessages: message.content.text
5433
5553
  },
5434
5554
  template: optionExtractionTemplate
@@ -5440,20 +5560,45 @@ var choiceAction = {
5440
5560
  const parsed = parseJSONObjectFromText(result);
5441
5561
  const { taskId, selectedOption } = parsed;
5442
5562
  if (taskId && selectedOption) {
5443
- const selectedTask = tasksWithOptions[taskId - 1];
5563
+ const taskMap = new Map(
5564
+ formattedTasks.map((task) => [task.taskId, task])
5565
+ );
5566
+ const taskInfo = taskMap.get(taskId);
5567
+ if (!taskInfo) {
5568
+ await callback({
5569
+ text: `Could not find a task matching ID: ${taskId}. Please try again.`,
5570
+ actions: ["SELECT_OPTION_ERROR"],
5571
+ source: message.content.source
5572
+ });
5573
+ return;
5574
+ }
5575
+ const selectedTask = tasksWithOptions.find(
5576
+ (task) => task.id === taskInfo.fullId
5577
+ );
5578
+ if (!selectedTask) {
5579
+ await callback({
5580
+ text: "Error locating the selected task. Please try again.",
5581
+ actions: ["SELECT_OPTION_ERROR"],
5582
+ source: message.content.source
5583
+ });
5584
+ return;
5585
+ }
5444
5586
  if (selectedOption === "ABORT") {
5445
- await runtime.getDatabaseAdapter().deleteTask(selectedTask.id);
5587
+ await runtime.deleteTask(selectedTask.id);
5446
5588
  await callback({
5447
5589
  text: `Task "${selectedTask.name}" has been cancelled.`,
5448
- actions: ["CHOOSE_OPTION"],
5590
+ actions: ["CHOOSE_OPTION_CANCELLED"],
5449
5591
  source: message.content.source
5450
5592
  });
5451
5593
  return;
5452
5594
  }
5453
5595
  try {
5454
5596
  const taskWorker = runtime.getTaskWorker(selectedTask.name);
5455
- await taskWorker.execute(runtime, { option: selectedOption });
5456
- await runtime.getDatabaseAdapter().deleteTask(selectedTask.id);
5597
+ await taskWorker.execute(
5598
+ runtime,
5599
+ { option: selectedOption },
5600
+ selectedTask
5601
+ );
5457
5602
  await callback({
5458
5603
  text: `Selected option: ${selectedOption} for task: ${selectedTask.name}`,
5459
5604
  actions: ["CHOOSE_OPTION"],
@@ -5471,8 +5616,9 @@ var choiceAction = {
5471
5616
  }
5472
5617
  }
5473
5618
  let optionsText = "Please select a valid option from one of these tasks:\n\n";
5474
- tasksWithOptions.forEach((task, index) => {
5475
- optionsText += `${index + 1}. **${task.name}**:
5619
+ tasksWithOptions.forEach((task) => {
5620
+ const shortId = task.id.substring(0, 8);
5621
+ optionsText += `**${task.name}** (ID: ${shortId}):
5476
5622
  `;
5477
5623
  const options2 = task.metadata.options.map(
5478
5624
  (opt) => typeof opt === "string" ? opt : opt.name
@@ -5566,12 +5712,12 @@ var followRoomAction = {
5566
5712
  return false;
5567
5713
  }
5568
5714
  const roomId = message.roomId;
5569
- const roomState = await runtime.getDatabaseAdapter().getParticipantUserState(roomId, runtime.agentId);
5715
+ const roomState = await runtime.getParticipantUserState(roomId, runtime.agentId);
5570
5716
  return roomState !== "FOLLOWED" && roomState !== "MUTED";
5571
5717
  },
5572
5718
  handler: async (runtime, message, state, _options, _callback, _responses) => {
5573
5719
  async function _shouldFollow(state2) {
5574
- const shouldFollowPrompt = composePrompt({
5720
+ const shouldFollowPrompt = composePromptFromState({
5575
5721
  state: state2,
5576
5722
  template: shouldFollowTemplate
5577
5723
  // Define this template separately
@@ -5618,9 +5764,9 @@ var followRoomAction = {
5618
5764
  return false;
5619
5765
  }
5620
5766
  if (await _shouldFollow(state)) {
5621
- await runtime.getDatabaseAdapter().setParticipantUserState(message.roomId, runtime.agentId, "FOLLOWED");
5767
+ await runtime.setParticipantUserState(message.roomId, runtime.agentId, "FOLLOWED");
5622
5768
  }
5623
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
5769
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
5624
5770
  await runtime.getMemoryManager("messages").createMemory({
5625
5771
  entityId: message.entityId,
5626
5772
  agentId: message.agentId,
@@ -6150,12 +6296,12 @@ var muteRoomAction = {
6150
6296
  description: "Mutes a room, ignoring all messages unless explicitly mentioned. Only do this if explicitly asked to, or if you're annoying people.",
6151
6297
  validate: async (runtime, message) => {
6152
6298
  const roomId = message.roomId;
6153
- const roomState = await runtime.getDatabaseAdapter().getParticipantUserState(roomId, runtime.agentId);
6299
+ const roomState = await runtime.getParticipantUserState(roomId, runtime.agentId);
6154
6300
  return roomState !== "MUTED";
6155
6301
  },
6156
6302
  handler: async (runtime, message, state, _options, _callback, _responses) => {
6157
6303
  async function _shouldMute(state2) {
6158
- const shouldMutePrompt = composePrompt({
6304
+ const shouldMutePrompt = composePromptFromState({
6159
6305
  state: state2,
6160
6306
  template: shouldMuteTemplate
6161
6307
  // Define this template separately
@@ -6201,9 +6347,9 @@ var muteRoomAction = {
6201
6347
  return false;
6202
6348
  }
6203
6349
  if (await _shouldMute(state)) {
6204
- await runtime.getDatabaseAdapter().setParticipantUserState(message.roomId, runtime.agentId, "MUTED");
6350
+ await runtime.setParticipantUserState(message.roomId, runtime.agentId, "MUTED");
6205
6351
  }
6206
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
6352
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
6207
6353
  await runtime.getMemoryManager("messages").createMemory({
6208
6354
  entityId: message.entityId,
6209
6355
  agentId: message.agentId,
@@ -6328,14 +6474,7 @@ var muteRoomAction = {
6328
6474
  // src/actions/none.ts
6329
6475
  var noneAction = {
6330
6476
  name: "NONE",
6331
- similes: [
6332
- "NO_ACTION",
6333
- "NO_RESPONSE",
6334
- "NO_REACTION",
6335
- "RESPONSE",
6336
- "REPLY",
6337
- "DEFAULT"
6338
- ],
6477
+ similes: ["NO_ACTION", "NO_RESPONSE", "NO_REACTION"],
6339
6478
  validate: async (_runtime, _message) => {
6340
6479
  return true;
6341
6480
  },
@@ -6494,7 +6633,7 @@ var replyAction = {
6494
6633
  ...message.content.providers ?? [],
6495
6634
  "RECENT_MESSAGES"
6496
6635
  ]);
6497
- const prompt = composePrompt({
6636
+ const prompt = composePromptFromState({
6498
6637
  state,
6499
6638
  template: replyTemplate
6500
6639
  });
@@ -6574,233 +6713,110 @@ var replyAction = {
6574
6713
  };
6575
6714
 
6576
6715
  // src/actions/roles.ts
6577
- var generateObject = async ({
6578
- runtime,
6579
- prompt,
6580
- modelType,
6581
- stopSequences = [],
6582
- output = "object",
6583
- enumValues = [],
6584
- schema
6585
- }) => {
6586
- if (!prompt) {
6587
- const errorMessage = "generateObject prompt is empty";
6588
- console.error(errorMessage);
6589
- throw new Error(errorMessage);
6590
- }
6591
- if (output === "enum" && enumValues) {
6592
- const response2 = await runtime.useModel(modelType, {
6593
- runtime,
6594
- prompt,
6595
- modelType,
6596
- stopSequences,
6597
- maxTokens: 8,
6598
- object: true
6599
- });
6600
- const cleanedResponse = response2.trim();
6601
- if (enumValues.includes(cleanedResponse)) {
6602
- return cleanedResponse;
6603
- }
6604
- const matchedValue = enumValues.find(
6605
- (value) => cleanedResponse.toLowerCase().includes(value.toLowerCase())
6606
- );
6607
- if (matchedValue) {
6608
- return matchedValue;
6609
- }
6610
- logger.error(`Invalid enum value received: ${cleanedResponse}`);
6611
- logger.error(`Expected one of: ${enumValues.join(", ")}`);
6612
- return null;
6613
- }
6614
- const response = await runtime.useModel(modelType, {
6615
- runtime,
6616
- prompt,
6617
- modelType,
6618
- stopSequences,
6619
- object: true
6620
- });
6621
- let jsonString = response;
6622
- const firstChar = output === "array" ? "[" : "{";
6623
- const lastChar = output === "array" ? "]" : "}";
6624
- const firstBracket = response.indexOf(firstChar);
6625
- const lastBracket = response.lastIndexOf(lastChar);
6626
- if (firstBracket !== -1 && lastBracket !== -1 && firstBracket < lastBracket) {
6627
- jsonString = response.slice(firstBracket, lastBracket + 1);
6628
- }
6629
- if (jsonString.length === 0) {
6630
- logger.error(`Failed to extract JSON ${output} from model response`);
6631
- return null;
6632
- }
6633
- try {
6634
- const json = JSON.parse(jsonString);
6635
- if (schema) {
6636
- return schema.parse(json);
6637
- }
6638
- return json;
6639
- } catch (_error) {
6640
- logger.error(`Failed to parse JSON ${output}`);
6641
- logger.error(jsonString);
6642
- return null;
6643
- }
6644
- };
6716
+ var import_dedent = __toESM(require_dedent(), 1);
6645
6717
  var canModifyRole = (currentRole, targetRole, newRole) => {
6646
- if (currentRole === "OWNER" /* OWNER */) {
6647
- return targetRole !== "OWNER" /* OWNER */;
6648
- }
6649
- if (currentRole === "ADMIN" /* ADMIN */) {
6650
- return (!targetRole || targetRole === "NONE" /* NONE */) && !["OWNER" /* OWNER */, "ADMIN" /* ADMIN */].includes(newRole);
6718
+ if (targetRole === currentRole) return false;
6719
+ switch (currentRole) {
6720
+ // Owners can do everything
6721
+ case "OWNER" /* OWNER */:
6722
+ return true;
6723
+ // Admins can only create/modify users up to their level
6724
+ case "ADMIN" /* ADMIN */:
6725
+ return newRole !== "OWNER" /* OWNER */;
6726
+ // Normal users can't modify roles
6727
+ case "NONE" /* NONE */:
6728
+ default:
6729
+ return false;
6651
6730
  }
6652
- return false;
6653
6731
  };
6654
- var extractionTemplate = `# Task: Extract role assignments from the conversation
6655
-
6656
- # Current Server Members:
6657
- {{serverMembers}}
6658
-
6659
- # Available Roles:
6660
- - OWNER: Full control over the organization
6661
- - ADMIN: Administrative privileges
6662
- - NONE: Standard member access
6663
-
6664
- # Recent Conversation:
6665
- {{recentMessages}}
6666
-
6667
- # Current speaker role: {{speakerRole}}
6668
-
6669
- # Instructions: Analyze the conversation and extract any role assignments being made by the speaker.
6670
- Only extract role assignments if:
6671
- 1. The speaker has appropriate permissions to make the change
6672
- 2. The role assignment is clearly stated
6673
- 3. The target user is a valid server member
6674
- 4. The new role is one of: OWNER, ADMIN, or NONE
6675
-
6676
- Return the results in this JSON format:
6677
- {
6678
- "roleAssignments": [
6679
- {
6680
- "entityId": "<UUID of the entity being assigned to>",
6681
- "newRole": "ROLE_NAME"
6682
- }
6683
- ]
6684
- }
6685
-
6686
- If no valid role assignments are found, return an empty array.`;
6687
- async function generateObjectArray({
6688
- runtime,
6689
- prompt,
6690
- modelType = ModelTypes.TEXT_SMALL,
6691
- schema,
6692
- schemaName,
6693
- schemaDescription
6694
- }) {
6695
- if (!prompt) {
6696
- logger.error("generateObjectArray prompt is empty");
6697
- return [];
6698
- }
6699
- const result = await generateObject({
6700
- runtime,
6701
- prompt,
6702
- modelType,
6703
- output: "array",
6704
- schema
6705
- });
6706
- if (!Array.isArray(result)) {
6707
- logger.error("Generated result is not an array");
6708
- return [];
6709
- }
6710
- return schema ? schema.parse(result) : result;
6711
- }
6712
6732
  var updateRoleAction = {
6713
6733
  name: "UPDATE_ROLE",
6714
- similes: ["CHANGE_ROLE", "SET_ROLE", "MODIFY_ROLE"],
6715
- description: "Updates the role for a user with respect to the agent, world being the server they are in. For example, if an admin tells the agent that a user is their boss, set their role to ADMIN. Can only be used to set roles to ADMIN, OWNER or NONE. Can't be used to ban.",
6734
+ similes: ["CHANGE_ROLE", "SET_PERMISSIONS", "ASSIGN_ROLE", "MAKE_ADMIN"],
6735
+ description: "Assigns a role (Admin, Owner, None) to a user or list of users in a channel.",
6716
6736
  validate: async (runtime, message, state) => {
6717
- logger.info("Starting role update validation");
6718
- if (message.content.source !== "discord") {
6719
- logger.info("Validation failed: Not a discord message");
6720
- return false;
6721
- }
6722
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
6723
- if (!room) {
6724
- throw new Error("No room found");
6725
- }
6726
- if (room.type !== "GROUP" /* GROUP */) {
6727
- return false;
6728
- }
6729
- const serverId = room.serverId;
6730
- if (!serverId) {
6731
- throw new Error("No server ID found");
6732
- }
6733
- try {
6734
- const worldId = createUniqueUuid(runtime, serverId);
6735
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
6736
- const requesterId = message.entityId;
6737
- if (!world.metadata?.roles) {
6738
- logger.info(`No roles found for server ${serverId}`);
6739
- return false;
6740
- }
6741
- const requesterRole = world.metadata.roles[requesterId];
6742
- logger.info(`Requester ${requesterId} role:`, requesterRole);
6743
- if (!requesterRole) {
6744
- logger.info("Validation failed: No requester role found");
6745
- return false;
6746
- }
6747
- if (!["OWNER" /* OWNER */, "ADMIN" /* ADMIN */].includes(requesterRole)) {
6748
- logger.info(
6749
- `Validation failed: Role ${requesterRole} insufficient for role management`
6750
- );
6751
- return false;
6752
- }
6753
- return true;
6754
- } catch (error) {
6755
- logger.error("Error validating updateOrgRole action:", error);
6756
- return false;
6757
- }
6737
+ const channelType = message.content.channelType;
6738
+ const serverId = message.content.serverId;
6739
+ return (
6740
+ // First, check if this is a supported channel type
6741
+ (channelType === "GROUP" /* GROUP */ || channelType === "WORLD" /* WORLD */) && // Then, check if we have a server ID
6742
+ !!serverId
6743
+ );
6758
6744
  },
6759
- handler: async (runtime, message, state, _options, callback, responses) => {
6760
- for (const response of responses) {
6761
- await callback(response.content);
6762
- }
6763
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
6764
- const world = await runtime.getDatabaseAdapter().getWorld(room.worldId);
6765
- if (!room) {
6766
- throw new Error("No room found");
6745
+ handler: async (runtime, message, state, _options, callback) => {
6746
+ const { roomId } = message;
6747
+ const channelType = message.content.channelType;
6748
+ const serverId = message.content.serverId;
6749
+ const worldId = runtime.getSetting("WORLD_ID");
6750
+ let world;
6751
+ if (worldId) {
6752
+ world = await runtime.getWorld(worldId);
6767
6753
  }
6768
- const serverId = world.serverId;
6769
- const requesterId = message.entityId;
6770
- if (!world || !world.metadata) {
6771
- logger.error(`No world or metadata found for server ${serverId}`);
6754
+ if (!world) {
6755
+ logger.error("World not found");
6772
6756
  await callback({
6773
- text: "Unable to process role changes due to missing server data.",
6774
- actions: ["UPDATE_ROLE"],
6775
- source: "discord"
6757
+ text: "I couldn't find the world. This action only works in a world."
6776
6758
  });
6777
6759
  return;
6778
6760
  }
6779
- if (!world.metadata.roles) {
6761
+ if (!world.metadata?.roles) {
6762
+ world.metadata = world.metadata || {};
6780
6763
  world.metadata.roles = {};
6781
6764
  }
6782
- const requesterRole = world.metadata.roles[requesterId] || "NONE" /* NONE */;
6783
- const entities = await runtime.getDatabaseAdapter().getEntitiesForRoom(room.id, true);
6784
- const serverMembersContext = entities.map((entity) => {
6785
- const discordData = entity.components?.find(
6786
- (c) => c.type === "discord"
6787
- )?.data;
6788
- const name2 = discordData?.username || entity.names[0];
6789
- const id = entity.id;
6790
- return `${name2} (${id})`;
6791
- }).join("\n");
6765
+ const entities = await runtime.getEntitiesForRoom(roomId);
6766
+ const requesterRole = world.metadata.roles[message.entityId] || "NONE" /* NONE */;
6792
6767
  const extractionPrompt = composePrompt({
6793
6768
  state: {
6794
- ...state,
6795
- serverMembers: serverMembersContext,
6796
- speakerRole: requesterRole
6797
- },
6798
- template: extractionTemplate
6799
- });
6800
- const result = await generateObjectArray({
6801
- runtime,
6769
+ ...state.values,
6770
+ content: state.text
6771
+ },
6772
+ template: import_dedent.default`
6773
+ # Task: Parse Role Assignment
6774
+
6775
+ I need to extract user role assignments from the input text. Users can be referenced by name, username, or mention.
6776
+
6777
+ The available role types are:
6778
+ - OWNER: Full control over the server and all settings
6779
+ - ADMIN: Ability to manage channels and moderate content
6780
+ - NONE: Regular user with no special permissions
6781
+
6782
+ # Current context:
6783
+ {{content}}
6784
+
6785
+ Format your response as a JSON array of objects, each with:
6786
+ - entityId: The name or ID of the user
6787
+ - newRole: The role to assign (OWNER, ADMIN, or NONE)
6788
+
6789
+ Example:
6790
+ \`\`\`json
6791
+ [
6792
+ {
6793
+ "entityId": "John",
6794
+ "newRole": "ADMIN"
6795
+ },
6796
+ {
6797
+ "entityId": "Sarah",
6798
+ "newRole": "OWNER"
6799
+ }
6800
+ ]
6801
+ \`\`\`
6802
+ `
6803
+ });
6804
+ const result = await runtime.useModel(ModelTypes.OBJECT_LARGE, {
6802
6805
  prompt: extractionPrompt,
6803
- modelType: ModelTypes.TEXT_SMALL
6806
+ schema: {
6807
+ type: "array",
6808
+ items: {
6809
+ type: "object",
6810
+ properties: {
6811
+ entityId: { type: "string" },
6812
+ newRole: {
6813
+ type: "string",
6814
+ enum: Object.values(Role)
6815
+ }
6816
+ },
6817
+ required: ["entityId", "newRole"]
6818
+ }
6819
+ }
6804
6820
  });
6805
6821
  if (!result?.length) {
6806
6822
  await callback({
@@ -6838,7 +6854,7 @@ var updateRoleAction = {
6838
6854
  });
6839
6855
  }
6840
6856
  if (worldUpdated) {
6841
- await runtime.getDatabaseAdapter().updateWorld(world);
6857
+ await runtime.updateWorld(world);
6842
6858
  logger.info(`Updated roles in world metadata for server ${serverId}`);
6843
6859
  }
6844
6860
  },
@@ -6949,7 +6965,7 @@ var sendMessageAction = {
6949
6965
  validate: async (runtime, message, _state) => {
6950
6966
  const worldId = message.roomId;
6951
6967
  const agentId = runtime.agentId;
6952
- const roomComponents = await runtime.getDatabaseAdapter().getComponents(message.roomId, worldId, agentId);
6968
+ const roomComponents = await runtime.getComponents(message.roomId, worldId, agentId);
6953
6969
  const availableSources = new Set(roomComponents.map((c) => c.type));
6954
6970
  return availableSources.size > 0;
6955
6971
  },
@@ -6959,9 +6975,9 @@ var sendMessageAction = {
6959
6975
  await callback(response.content);
6960
6976
  }
6961
6977
  const sourceEntityId = message.entityId;
6962
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
6978
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
6963
6979
  const worldId = room.worldId;
6964
- const targetPrompt = composePrompt({
6980
+ const targetPrompt = composePromptFromState({
6965
6981
  state,
6966
6982
  template: targetExtractionTemplate
6967
6983
  });
@@ -6989,7 +7005,7 @@ var sendMessageAction = {
6989
7005
  });
6990
7006
  return;
6991
7007
  }
6992
- const userComponent = await runtime.getDatabaseAdapter().getComponent(targetEntity.id, source, worldId, sourceEntityId);
7008
+ const userComponent = await runtime.getComponent(targetEntity.id, source, worldId, sourceEntityId);
6993
7009
  if (!userComponent) {
6994
7010
  await callback({
6995
7011
  text: `I couldn't find ${source} information for that user. Could you please provide their ${source} details?`,
@@ -7029,7 +7045,7 @@ var sendMessageAction = {
7029
7045
  });
7030
7046
  }
7031
7047
  } else if (targetData.targetType === "room") {
7032
- const rooms = await runtime.getDatabaseAdapter().getRooms(worldId);
7048
+ const rooms = await runtime.getRooms(worldId);
7033
7049
  const targetRoom = rooms.find((r) => {
7034
7050
  return r.name.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
7035
7051
  });
@@ -7131,6 +7147,7 @@ var sendMessageAction = {
7131
7147
  };
7132
7148
 
7133
7149
  // src/actions/settings.ts
7150
+ var import_dedent2 = __toESM(require_dedent(), 1);
7134
7151
  var messageCompletionFooter = `
7135
7152
  # Instructions: Write the next message for {{agentName}}. Include the appropriate action from the list: {{actionNames}}
7136
7153
  Response format should be formatted in a valid JSON block like this:
@@ -7223,137 +7240,12 @@ var completionTemplate = `# Task: Generate a response for settings completion
7223
7240
  Write a natural, conversational response that {{agentName}} would send about the successful completion of settings.
7224
7241
  Include the actions array ["ONBOARDING_COMPLETE"] in your response.
7225
7242
  ${messageCompletionFooter}`;
7226
- var extractionTemplate2 = `# Task: Extract setting values from the conversation
7227
-
7228
- # Available Settings:
7229
- {{#each settings}}
7230
- {{key}}:
7231
- Name: {{name}}
7232
- Description: {{description}}
7233
- Current Value: {{value}}
7234
- Required: {{required}}
7235
- Validation Rules: {{#if validation}}Present{{else}}None{{/if}}
7236
- {{/each}}
7237
-
7238
- # Current Settings Status:
7239
- {{settingsStatus}}
7240
-
7241
- # Recent Conversation:
7242
- {{recentMessages}}
7243
-
7244
- # Instructions:
7245
- 1. Review the ENTIRE conversation and identify ALL values provided for settings
7246
- 2. For each setting mentioned, extract:
7247
- - The setting key (must exactly match one of the available settings above)
7248
- - The provided value that matches the setting's description and purpose
7249
- 3. Return an array of ALL setting updates found, even if mentioned earlier in the conversation
7250
-
7251
- Return ONLY a JSON array of objects with 'key' and 'value' properties. Format:
7252
- [
7253
- { "key": "SETTING_NAME", "value": "extracted value" },
7254
- { "key": "ANOTHER_SETTING", "value": "another value" }
7255
- ]
7256
-
7257
- IMPORTANT: Only include settings from the Available Settings list above. Ignore any other potential settings.`;
7258
- var generateObject2 = async ({
7259
- runtime,
7260
- prompt,
7261
- modelType = ModelTypes.TEXT_LARGE,
7262
- stopSequences = [],
7263
- output = "object",
7264
- enumValues = [],
7265
- schema
7266
- }) => {
7267
- if (!prompt) {
7268
- const errorMessage = "generateObject prompt is empty";
7269
- console.error(errorMessage);
7270
- throw new Error(errorMessage);
7271
- }
7272
- if (output === "enum" && enumValues) {
7273
- const response2 = await runtime.useModel(modelType, {
7274
- runtime,
7275
- prompt,
7276
- modelType,
7277
- stopSequences,
7278
- maxTokens: 8,
7279
- object: true
7280
- });
7281
- const cleanedResponse = response2.trim();
7282
- if (enumValues.includes(cleanedResponse)) {
7283
- return cleanedResponse;
7284
- }
7285
- const matchedValue = enumValues.find(
7286
- (value) => cleanedResponse.toLowerCase().includes(value.toLowerCase())
7287
- );
7288
- if (matchedValue) {
7289
- return matchedValue;
7290
- }
7291
- logger.error(`Invalid enum value received: ${cleanedResponse}`);
7292
- logger.error(`Expected one of: ${enumValues.join(", ")}`);
7293
- return null;
7294
- }
7295
- const response = await runtime.useModel(modelType, {
7296
- runtime,
7297
- prompt,
7298
- modelType,
7299
- stopSequences,
7300
- object: true
7301
- });
7302
- let jsonString = response;
7303
- const firstChar = output === "array" ? "[" : "{";
7304
- const lastChar = output === "array" ? "]" : "}";
7305
- const firstBracket = response.indexOf(firstChar);
7306
- const lastBracket = response.lastIndexOf(lastChar);
7307
- if (firstBracket !== -1 && lastBracket !== -1 && firstBracket < lastBracket) {
7308
- jsonString = response.slice(firstBracket, lastBracket + 1);
7309
- }
7310
- if (jsonString.length === 0) {
7311
- logger.error(`Failed to extract JSON ${output} from model response`);
7312
- return null;
7313
- }
7314
- try {
7315
- const json = JSON.parse(jsonString);
7316
- if (schema) {
7317
- return schema.parse(json);
7318
- }
7319
- return json;
7320
- } catch (_error) {
7321
- logger.error(`Failed to parse JSON ${output}`);
7322
- logger.error(jsonString);
7323
- return null;
7324
- }
7325
- };
7326
- async function generateObjectArray2({
7327
- runtime,
7328
- prompt,
7329
- modelType = ModelTypes.TEXT_SMALL,
7330
- schema,
7331
- schemaName,
7332
- schemaDescription
7333
- }) {
7334
- if (!prompt) {
7335
- logger.error("generateObjectArray prompt is empty");
7336
- return [];
7337
- }
7338
- const result = await generateObject2({
7339
- runtime,
7340
- prompt,
7341
- modelType,
7342
- output: "array",
7343
- schema
7344
- });
7345
- if (!Array.isArray(result)) {
7346
- logger.error("Generated result is not an array");
7347
- return [];
7348
- }
7349
- return schema ? schema.parse(result) : result;
7350
- }
7351
- async function getWorldSettings(runtime, serverId) {
7352
- try {
7353
- const worldId = createUniqueUuid(runtime, serverId);
7354
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
7355
- if (!world || !world.metadata?.settings) {
7356
- return null;
7243
+ async function getWorldSettings(runtime, serverId) {
7244
+ try {
7245
+ const worldId = createUniqueUuid(runtime, serverId);
7246
+ const world = await runtime.getWorld(worldId);
7247
+ if (!world || !world.metadata?.settings) {
7248
+ return null;
7357
7249
  }
7358
7250
  return world.metadata.settings;
7359
7251
  } catch (error) {
@@ -7364,7 +7256,7 @@ async function getWorldSettings(runtime, serverId) {
7364
7256
  async function updateWorldSettings(runtime, serverId, worldSettings) {
7365
7257
  try {
7366
7258
  const worldId = createUniqueUuid(runtime, serverId);
7367
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
7259
+ const world = await runtime.getWorld(worldId);
7368
7260
  if (!world) {
7369
7261
  logger.error(`No world found for server ${serverId}`);
7370
7262
  return false;
@@ -7373,7 +7265,7 @@ async function updateWorldSettings(runtime, serverId, worldSettings) {
7373
7265
  world.metadata = {};
7374
7266
  }
7375
7267
  world.metadata.settings = worldSettings;
7376
- await runtime.getDatabaseAdapter().updateWorld(world);
7268
+ await runtime.updateWorld(world);
7377
7269
  return true;
7378
7270
  } catch (error) {
7379
7271
  logger.error(`Error updating settings state: ${error}`);
@@ -7405,40 +7297,48 @@ function categorizeSettings(worldSettings) {
7405
7297
  return { configured, requiredUnconfigured, optionalUnconfigured };
7406
7298
  }
7407
7299
  async function extractSettingValues(runtime, _message, state, worldSettings) {
7300
+ const { requiredUnconfigured, optionalUnconfigured } = categorizeSettings(worldSettings);
7301
+ const settingsContext = requiredUnconfigured.concat(optionalUnconfigured).map(([key, setting]) => {
7302
+ const requiredStr = setting.required ? "Required." : "Optional.";
7303
+ return `${key}: ${setting.description} ${requiredStr}`;
7304
+ }).join("\n");
7305
+ const basePrompt = import_dedent2.default`
7306
+ I need to extract settings values from the user's message.
7307
+
7308
+ Available settings:
7309
+ ${settingsContext}
7310
+
7311
+ User message: ${state.text}
7312
+
7313
+ For each setting mentioned in the user's message, extract the value.
7314
+
7315
+ Only return settings that are clearly mentioned in the user's message.
7316
+ If a setting is mentioned but no clear value is provided, do not include it.
7317
+ `;
7408
7318
  try {
7409
- const prompt = composePrompt({
7410
- state: {
7411
- ...state,
7412
- settings: Object.entries(worldSettings).filter(([key]) => !key.startsWith("_")).map(([key, setting]) => ({
7413
- key,
7414
- ...setting
7415
- })),
7416
- settingsStatus: formatSettingsList(worldSettings)
7417
- },
7418
- template: extractionTemplate2
7419
- });
7420
- const extractions = await generateObjectArray2({
7421
- runtime,
7422
- prompt,
7423
- modelType: ModelTypes.TEXT_LARGE
7424
- });
7425
- logger.info(`Extracted ${extractions.length} potential setting updates`);
7426
- const validExtractions = extractions.filter((update) => {
7427
- const setting = worldSettings[update.key];
7428
- if (!setting) {
7429
- logger.info(`Ignored extraction for unknown setting: ${update.key}`);
7430
- return false;
7431
- }
7432
- if (setting.validation && !setting.validation(update.value)) {
7433
- logger.info(`Validation failed for setting ${update.key}`);
7434
- return false;
7319
+ const result = await runtime.useModel(ModelTypes.OBJECT_LARGE, {
7320
+ prompt: basePrompt,
7321
+ output: "array",
7322
+ schema: {
7323
+ type: "array",
7324
+ items: {
7325
+ type: "object",
7326
+ properties: {
7327
+ key: { type: "string" },
7328
+ value: { type: "string" }
7329
+ },
7330
+ required: ["key", "value"]
7331
+ }
7435
7332
  }
7436
- return true;
7437
7333
  });
7438
- logger.info(`Validated ${validExtractions.length} setting updates`);
7439
- return validExtractions;
7334
+ if (!result || !Array.isArray(result)) {
7335
+ return [];
7336
+ }
7337
+ return result.filter(({ key, value }) => {
7338
+ return Boolean(key && value && worldSettings[key]);
7339
+ });
7440
7340
  } catch (error) {
7441
- logger.error("Error extracting setting values:", error);
7341
+ console.error("Error extracting settings:", error);
7442
7342
  return [];
7443
7343
  }
7444
7344
  }
@@ -7498,7 +7398,6 @@ async function handleOnboardingComplete(runtime, worldSettings, state, callback)
7498
7398
  try {
7499
7399
  const prompt = composePrompt({
7500
7400
  state: {
7501
- ...state,
7502
7401
  settingsStatus: formatSettingsList(worldSettings)
7503
7402
  },
7504
7403
  template: completionTemplate
@@ -7528,12 +7427,12 @@ async function generateSuccessResponse(runtime, worldSettings, state, messages,
7528
7427
  await handleOnboardingComplete(runtime, worldSettings, state, callback);
7529
7428
  return;
7530
7429
  }
7430
+ const requiredUnconfiguredString = requiredUnconfigured.map(([key, setting]) => `${key}: ${setting.name}`).join("\n");
7531
7431
  const prompt = composePrompt({
7532
7432
  state: {
7533
- ...state,
7534
7433
  updateMessages: messages.join("\n"),
7535
- nextSetting: requiredUnconfigured[0][1],
7536
- remainingRequired: requiredUnconfigured.length
7434
+ nextSetting: requiredUnconfiguredString,
7435
+ remainingRequired: requiredUnconfigured.length.toString()
7537
7436
  },
7538
7437
  template: successTemplate
7539
7438
  });
@@ -7562,11 +7461,11 @@ async function generateFailureResponse(runtime, worldSettings, state, callback)
7562
7461
  await handleOnboardingComplete(runtime, worldSettings, state, callback);
7563
7462
  return;
7564
7463
  }
7464
+ const requiredUnconfiguredString = requiredUnconfigured.map(([key, setting]) => `${key}: ${setting.name}`).join("\n");
7565
7465
  const prompt = composePrompt({
7566
7466
  state: {
7567
- ...state,
7568
- nextSetting: requiredUnconfigured[0][1],
7569
- remainingRequired: requiredUnconfigured.length
7467
+ nextSetting: requiredUnconfiguredString,
7468
+ remainingRequired: requiredUnconfigured.length.toString()
7570
7469
  },
7571
7470
  template: failureTemplate
7572
7471
  });
@@ -7590,7 +7489,7 @@ async function generateFailureResponse(runtime, worldSettings, state, callback)
7590
7489
  }
7591
7490
  async function generateErrorResponse(runtime, state, callback) {
7592
7491
  try {
7593
- const prompt = composePrompt({
7492
+ const prompt = composePromptFromState({
7594
7493
  state,
7595
7494
  template: errorTemplate
7596
7495
  });
@@ -7615,7 +7514,7 @@ async function generateErrorResponse(runtime, state, callback) {
7615
7514
  var updateSettingsAction = {
7616
7515
  name: "UPDATE_SETTINGS",
7617
7516
  similes: ["UPDATE_SETTING", "SAVE_SETTING", "SET_CONFIGURATION", "CONFIGURE"],
7618
- description: "Saves a setting during the settings process",
7517
+ description: "Saves a configuration setting during the onboarding process, or update an existing setting. Use this when you are onboarding with a world owner or admin.",
7619
7518
  validate: async (runtime, message, _state) => {
7620
7519
  try {
7621
7520
  if (message.content.channelType !== "DM" /* DM */) {
@@ -7909,12 +7808,12 @@ var unfollowRoomAction = {
7909
7808
  description: "Stop following this channel. You can still respond if explicitly mentioned, but you won't automatically chime in anymore. Unfollow if you're annoying people or have been asked to.",
7910
7809
  validate: async (runtime, message) => {
7911
7810
  const roomId = message.roomId;
7912
- const roomState = await runtime.getDatabaseAdapter().getParticipantUserState(roomId, runtime.agentId);
7811
+ const roomState = await runtime.getParticipantUserState(roomId, runtime.agentId);
7913
7812
  return roomState === "FOLLOWED";
7914
7813
  },
7915
7814
  handler: async (runtime, message, state, _options, _callback, _responses) => {
7916
7815
  async function _shouldUnfollow(state2) {
7917
- const shouldUnfollowPrompt = composePrompt({
7816
+ const shouldUnfollowPrompt = composePromptFromState({
7918
7817
  state: state2,
7919
7818
  template: shouldUnfollowTemplate
7920
7819
  // Define this template separately
@@ -7926,8 +7825,8 @@ var unfollowRoomAction = {
7926
7825
  return parsedResponse;
7927
7826
  }
7928
7827
  if (await _shouldUnfollow(state)) {
7929
- await runtime.getDatabaseAdapter().setParticipantUserState(message.roomId, runtime.agentId, null);
7930
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
7828
+ await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
7829
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
7931
7830
  await runtime.getMemoryManager("messages").createMemory({
7932
7831
  entityId: message.entityId,
7933
7832
  agentId: message.agentId,
@@ -8224,12 +8123,12 @@ var unmuteRoomAction = {
8224
8123
  description: "Unmutes a room, allowing the agent to consider responding to messages again.",
8225
8124
  validate: async (runtime, message) => {
8226
8125
  const roomId = message.roomId;
8227
- const roomState = await runtime.getDatabaseAdapter().getParticipantUserState(roomId, runtime.agentId);
8126
+ const roomState = await runtime.getParticipantUserState(roomId, runtime.agentId);
8228
8127
  return roomState === "MUTED";
8229
8128
  },
8230
8129
  handler: async (runtime, message, state, _options, _callback, _responses) => {
8231
8130
  async function _shouldUnmute(state2) {
8232
- const shouldUnmutePrompt = composePrompt({
8131
+ const shouldUnmutePrompt = composePromptFromState({
8233
8132
  state: state2,
8234
8133
  template: shouldUnmuteTemplate
8235
8134
  // Define this template separately
@@ -8276,9 +8175,9 @@ var unmuteRoomAction = {
8276
8175
  return false;
8277
8176
  }
8278
8177
  if (await _shouldUnmute(state)) {
8279
- await runtime.getDatabaseAdapter().setParticipantUserState(message.roomId, runtime.agentId, null);
8178
+ await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
8280
8179
  }
8281
- const room = await runtime.getDatabaseAdapter().getRoom(message.roomId);
8180
+ const room = await runtime.getRoom(message.roomId);
8282
8181
  await runtime.getMemoryManager("messages").createMemory({
8283
8182
  entityId: message.entityId,
8284
8183
  agentId: message.agentId,
@@ -8438,15 +8337,9 @@ Example outputs:
8438
8337
 
8439
8338
  Make sure to include the \`\`\`json\`\`\` tags around the JSON object.`;
8440
8339
  var updateEntityAction = {
8441
- name: "UPDATE_ENTITY",
8442
- similes: [
8443
- "CREATE_ENTITY",
8444
- "UPDATE_USER",
8445
- "EDIT_ENTITY",
8446
- "UPDATE_COMPONENT",
8447
- "CREATE_COMPONENT"
8448
- ],
8449
- description: "Add or edit contact details for a user entity (like twitter, discord, email address, etc.)",
8340
+ name: "UPDATE_CONTACT",
8341
+ similes: ["UPDATE_ENTITY"],
8342
+ description: "Add or edit contact details for a person you are talking to or observing in the conversation. Use this when you learn this information from the conversation about a contact. This is for the agent to relate entities across platforms, not for world settings or configuration.",
8450
8343
  validate: async (_runtime, _message, _state) => {
8451
8344
  return true;
8452
8345
  },
@@ -8458,7 +8351,7 @@ var updateEntityAction = {
8458
8351
  const sourceEntityId = message.entityId;
8459
8352
  const _roomId = message.roomId;
8460
8353
  const agentId = runtime.agentId;
8461
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
8354
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
8462
8355
  const worldId = room.worldId;
8463
8356
  const entity = await findEntityByName(runtime, message, state);
8464
8357
  if (!entity) {
@@ -8470,7 +8363,7 @@ var updateEntityAction = {
8470
8363
  return;
8471
8364
  }
8472
8365
  let existingComponent = null;
8473
- const prompt = composePrompt({
8366
+ const prompt = composePromptFromState({
8474
8367
  state,
8475
8368
  template: componentTemplate
8476
8369
  });
@@ -8499,9 +8392,9 @@ var updateEntityAction = {
8499
8392
  }
8500
8393
  const componentType = parsedResult.source.toLowerCase();
8501
8394
  const componentData = parsedResult.data;
8502
- existingComponent = await runtime.getDatabaseAdapter().getComponent(entity.id, componentType, worldId, sourceEntityId);
8395
+ existingComponent = await runtime.getComponent(entity.id, componentType, worldId, sourceEntityId);
8503
8396
  if (existingComponent) {
8504
- await runtime.getDatabaseAdapter().updateComponent({
8397
+ await runtime.updateComponent({
8505
8398
  id: existingComponent.id,
8506
8399
  entityId: entity.id,
8507
8400
  worldId,
@@ -8517,7 +8410,7 @@ var updateEntityAction = {
8517
8410
  source: message.content.source
8518
8411
  });
8519
8412
  } else {
8520
- await runtime.getDatabaseAdapter().createComponent({
8413
+ await runtime.createComponent({
8521
8414
  id: uuidv4(),
8522
8415
  entityId: entity.id,
8523
8416
  worldId,
@@ -8591,265 +8484,6 @@ var updateEntityAction = {
8591
8484
  ]
8592
8485
  };
8593
8486
 
8594
- // src/evaluators/goal.ts
8595
- var goalsTemplate = `# TASK: Update Goal
8596
- Analyze the conversation and update the status of the goals based on the new information provided.
8597
-
8598
- # INSTRUCTIONS
8599
-
8600
- - Review the conversation and identify any progress towards the objectives of the current goals.
8601
- - Update the objectives if they have been completed or if there is new information about them.
8602
- - Update the status of the goal to 'DONE' if all objectives are completed.
8603
- - If no progress is made, do not change the status of the goal.
8604
-
8605
- # START OF ACTUAL TASK INFORMATION
8606
-
8607
- {{goals}}
8608
- {{recentMessages}}
8609
-
8610
- TASK: Analyze the conversation and update the status of the goals based on the new information provided. Respond with a JSON array of goals to update.
8611
- - Each item must include the goal ID, as well as the fields in the goal to update.
8612
- - For updating objectives, include the entire objectives array including unchanged fields.
8613
- - Only include goals which need to be updated.
8614
- - Goal status options are 'IN_PROGRESS', 'DONE' and 'FAILED'. If the goal is active it should always be 'IN_PROGRESS'.
8615
- - If the goal has been successfully completed, set status to DONE. If the goal cannot be completed, set status to FAILED.
8616
- - If those goal is still in progress, do not include the status field.
8617
-
8618
- Response format should be:
8619
- \`\`\`json
8620
- [
8621
- {
8622
- "id": <goal uuid>, // required
8623
- "status": "IN_PROGRESS" | "DONE" | "FAILED", // optional
8624
- "objectives": [ // optional
8625
- { "description": "Objective description", "completed": true | false },
8626
- { "description": "Objective description", "completed": true | false }
8627
- ] // NOTE: If updating objectives, include the entire objectives array including unchanged fields.
8628
- }
8629
- ]
8630
- \`\`\``;
8631
- async function handler(runtime, message, state, options2 = { onlyInProgress: true }) {
8632
- const prompt = composePrompt({
8633
- state,
8634
- template: runtime.character.templates?.goalsTemplate || goalsTemplate
8635
- });
8636
- const response = await runtime.useModel(ModelTypes.TEXT_SMALL, {
8637
- runtime,
8638
- prompt
8639
- });
8640
- const updates = parseJsonArrayFromText(response);
8641
- const goalsData = await runtime.getDatabaseAdapter().getGoals({
8642
- roomId: message.roomId,
8643
- onlyInProgress: options2.onlyInProgress
8644
- });
8645
- const updatedGoals = goalsData.map((goal) => {
8646
- const update = updates?.find((u) => u.id === goal.id);
8647
- if (update) {
8648
- return {
8649
- ...goal,
8650
- ...update,
8651
- objectives: goal.objectives.map((objective) => {
8652
- const updatedObjective = update.objectives?.find(
8653
- (uo) => uo.description === objective.description
8654
- );
8655
- return updatedObjective ? { ...objective, ...updatedObjective } : objective;
8656
- })
8657
- };
8658
- }
8659
- return null;
8660
- }).filter(Boolean);
8661
- for (const goal of updatedGoals) {
8662
- const id = goal.id;
8663
- if (goal.id) goal.id = void 0;
8664
- await runtime.getDatabaseAdapter().updateGoal({ ...goal, id });
8665
- }
8666
- return updatedGoals;
8667
- }
8668
- var goalEvaluator = {
8669
- name: "UPDATE_GOAL",
8670
- similes: [
8671
- "UPDATE_GOALS",
8672
- "EDIT_GOAL",
8673
- "UPDATE_GOAL_STATUS",
8674
- "UPDATE_OBJECTIVES"
8675
- ],
8676
- validate: async (runtime, message) => {
8677
- const goals = await runtime.getDatabaseAdapter().getGoals({
8678
- count: 1,
8679
- onlyInProgress: true,
8680
- roomId: message.roomId
8681
- });
8682
- return goals.length > 0;
8683
- },
8684
- description: "Analyze the conversation and update the status of the goals based on the new information provided.",
8685
- handler,
8686
- examples: [
8687
- {
8688
- prompt: `People in the scene:
8689
- {{name1}}: An avid reader and member of a book club.
8690
- {{name2}}: The organizer of the book club.
8691
-
8692
- Goals:
8693
- - Name: Finish reading "War and Peace"
8694
- id: 12345-67890-12345-67890
8695
- Status: IN_PROGRESS
8696
- Objectives:
8697
- - Read up to chapter 20 by the end of the month
8698
- - Discuss the first part in the next meeting`,
8699
- messages: [
8700
- {
8701
- name: "{{name1}}",
8702
- content: {
8703
- text: "I've just finished chapter 20 of 'War and Peace'"
8704
- }
8705
- },
8706
- {
8707
- name: "{{name2}}",
8708
- content: {
8709
- text: "Were you able to grasp the complexities of the characters"
8710
- }
8711
- },
8712
- {
8713
- name: "{{name1}}",
8714
- content: {
8715
- text: "Yep. I've prepared some notes for our discussion"
8716
- }
8717
- }
8718
- ],
8719
- outcome: `[
8720
- {
8721
- "id": "12345-67890-12345-67890",
8722
- "status": "DONE",
8723
- "objectives": [
8724
- { "description": "Read up to chapter 20 by the end of the month", "completed": true },
8725
- { "description": "Prepare notes for the next discussion", "completed": true }
8726
- ]
8727
- }
8728
- ]`
8729
- },
8730
- {
8731
- prompt: `People in the scene:
8732
- {{name1}}: A fitness enthusiast working towards a marathon.
8733
- {{name2}}: A personal trainer.
8734
-
8735
- Goals:
8736
- - Name: Complete a marathon
8737
- id: 23456-78901-23456-78901
8738
- Status: IN_PROGRESS
8739
- Objectives:
8740
- - Increase running distance to 30 miles a week
8741
- - Complete a half-marathon as practice`,
8742
- messages: [
8743
- {
8744
- name: "{{name1}}",
8745
- content: { text: "I managed to run 30 miles this week" }
8746
- },
8747
- {
8748
- name: "{{name2}}",
8749
- content: {
8750
- text: "Impressive progress! How do you feel about the half-marathon next month?"
8751
- }
8752
- },
8753
- {
8754
- name: "{{name1}}",
8755
- content: {
8756
- text: "I feel confident. The training is paying off."
8757
- }
8758
- }
8759
- ],
8760
- outcome: `[
8761
- {
8762
- "id": "23456-78901-23456-78901",
8763
- "objectives": [
8764
- { "description": "Increase running distance to 30 miles a week", "completed": true },
8765
- { "description": "Complete a half-marathon as practice", "completed": false }
8766
- ]
8767
- }
8768
- ]`
8769
- },
8770
- {
8771
- prompt: `People in the scene:
8772
- {{name1}}: A student working on a final year project.
8773
- {{name2}}: The project supervisor.
8774
-
8775
- Goals:
8776
- - Name: Finish the final year project
8777
- id: 34567-89012-34567-89012
8778
- Status: IN_PROGRESS
8779
- Objectives:
8780
- - Submit the first draft of the thesis
8781
- - Complete the project prototype`,
8782
- messages: [
8783
- {
8784
- name: "{{name1}}",
8785
- content: {
8786
- text: "I've submitted the first draft of my thesis."
8787
- }
8788
- },
8789
- {
8790
- name: "{{name2}}",
8791
- content: {
8792
- text: "Well done. How is the prototype coming along?"
8793
- }
8794
- },
8795
- {
8796
- name: "{{name1}}",
8797
- content: {
8798
- text: "It's almost done. I just need to finalize the testing phase."
8799
- }
8800
- }
8801
- ],
8802
- outcome: `[
8803
- {
8804
- "id": "34567-89012-34567-89012",
8805
- "objectives": [
8806
- { "description": "Submit the first draft of the thesis", "completed": true },
8807
- { "description": "Complete the project prototype", "completed": false }
8808
- ]
8809
- }
8810
- ]`
8811
- },
8812
- {
8813
- prompt: `People in the scene:
8814
- {{name1}}: A project manager working on a software development project.
8815
- {{name2}}: A software developer in the project team.
8816
-
8817
- Goals:
8818
- - Name: Launch the new software version
8819
- id: 45678-90123-45678-90123
8820
- Status: IN_PROGRESS
8821
- Objectives:
8822
- - Complete the coding for the new features
8823
- - Perform comprehensive testing of the software`,
8824
- messages: [
8825
- {
8826
- name: "{{name1}}",
8827
- content: {
8828
- text: "How's the progress on the new features?"
8829
- }
8830
- },
8831
- {
8832
- name: "{{name2}}",
8833
- content: {
8834
- text: "We've encountered some unexpected challenges and are currently troubleshooting."
8835
- }
8836
- },
8837
- {
8838
- name: "{{name1}}",
8839
- content: {
8840
- text: "Let's move on and cancel the task."
8841
- }
8842
- }
8843
- ],
8844
- outcome: `[
8845
- {
8846
- "id": "45678-90123-45678-90123",
8847
- "status": "FAILED"
8848
- ]`
8849
- }
8850
- ]
8851
- };
8852
-
8853
8487
  // src/evaluators/reflection.ts
8854
8488
  var relationshipSchema = z.object({
8855
8489
  sourceEntityId: z.string(),
@@ -8944,9 +8578,9 @@ function resolveEntity(entityId, entities) {
8944
8578
  if (entity) {
8945
8579
  return entity.id;
8946
8580
  }
8947
- throw new Error(`Could not resolve name "${name}" to a valid UUID`);
8581
+ throw new Error(`Could not resolve entityId "${entityId}" to a valid UUID`);
8948
8582
  }
8949
- var generateObject3 = async ({
8583
+ var generateObject = async ({
8950
8584
  runtime,
8951
8585
  prompt,
8952
8586
  modelType = ModelTypes.TEXT_SMALL,
@@ -9014,14 +8648,14 @@ var generateObject3 = async ({
9014
8648
  return null;
9015
8649
  }
9016
8650
  };
9017
- async function handler2(runtime, message, state) {
8651
+ async function handler(runtime, message, state) {
9018
8652
  const { agentId, roomId } = message;
9019
8653
  const factsManager = new MemoryManager({
9020
8654
  runtime,
9021
8655
  tableName: "facts"
9022
8656
  });
9023
8657
  const [existingRelationships, entities, knownFacts] = await Promise.all([
9024
- runtime.getDatabaseAdapter().getRelationships({
8658
+ runtime.getRelationships({
9025
8659
  entityId: message.entityId
9026
8660
  }),
9027
8661
  getEntityDetails({ runtime, roomId }),
@@ -9034,7 +8668,7 @@ async function handler2(runtime, message, state) {
9034
8668
  ]);
9035
8669
  const prompt = composePrompt({
9036
8670
  state: {
9037
- ...state,
8671
+ ...state.values,
9038
8672
  knownFacts: formatFacts(knownFacts),
9039
8673
  roomType: message.content.channelType,
9040
8674
  entitiesInRoom: JSON.stringify(entities),
@@ -9043,7 +8677,7 @@ async function handler2(runtime, message, state) {
9043
8677
  },
9044
8678
  template: runtime.character.templates?.reflectionTemplate || reflectionTemplate
9045
8679
  });
9046
- const reflection = await generateObject3({
8680
+ const reflection = await generateObject({
9047
8681
  runtime,
9048
8682
  prompt,
9049
8683
  modelType: ModelTypes.TEXT_SMALL,
@@ -9090,13 +8724,13 @@ async function handler2(runtime, message, state) {
9090
8724
  const updatedTags = Array.from(
9091
8725
  /* @__PURE__ */ new Set([...existingRelationship.tags || [], ...relationship.tags])
9092
8726
  );
9093
- await runtime.getDatabaseAdapter().updateRelationship({
8727
+ await runtime.updateRelationship({
9094
8728
  ...existingRelationship,
9095
8729
  tags: updatedTags,
9096
8730
  metadata: updatedMetadata
9097
8731
  });
9098
8732
  } else {
9099
- await runtime.getDatabaseAdapter().createRelationship({
8733
+ await runtime.createRelationship({
9100
8734
  sourceEntityId: sourceId,
9101
8735
  targetEntityId: targetId,
9102
8736
  tags: relationship.tags,
@@ -9107,7 +8741,7 @@ async function handler2(runtime, message, state) {
9107
8741
  });
9108
8742
  }
9109
8743
  }
9110
- await runtime.getDatabaseAdapter().setCache(
8744
+ await runtime.setCache(
9111
8745
  `${message.roomId}-reflection-last-processed`,
9112
8746
  message.id
9113
8747
  );
@@ -9122,7 +8756,7 @@ var reflectionEvaluator = {
9122
8756
  "ASSESS_SITUATION"
9123
8757
  ],
9124
8758
  validate: async (runtime, message) => {
9125
- const lastMessageId = await runtime.getDatabaseAdapter().getCache(`${message.roomId}-reflection-last-processed`);
8759
+ const lastMessageId = await runtime.getCache(`${message.roomId}-reflection-last-processed`);
9126
8760
  const messages = await runtime.getMemoryManager("messages").getMemories({
9127
8761
  roomId: message.roomId,
9128
8762
  count: runtime.getConversationLength()
@@ -9139,7 +8773,7 @@ var reflectionEvaluator = {
9139
8773
  return messages.length > reflectionInterval;
9140
8774
  },
9141
8775
  description: "Generate a self-reflective thought on the conversation, then extract facts and relationships between entities in the conversation.",
9142
- handler: handler2,
8776
+ handler,
9143
8777
  examples: [
9144
8778
  {
9145
8779
  prompt: `Agent Name: Sarah
@@ -9309,42 +8943,7 @@ function formatFacts(facts) {
9309
8943
  return facts.reverse().map((fact) => fact.content.text).join("\n");
9310
8944
  }
9311
8945
 
9312
- // src/providers/providers.ts
9313
- var providersProvider = {
9314
- name: "PROVIDERS",
9315
- description: "List of all data providers the agent can use to get additional information",
9316
- get: async (runtime, _message) => {
9317
- const dynamicProviders = runtime.providers.filter(
9318
- (provider) => provider.dynamic === true
9319
- );
9320
- const providerDescriptions = dynamicProviders.map((provider) => {
9321
- return `- **${provider.name}**: ${provider.description || "No description available"}`;
9322
- });
9323
- const headerText = "# Providers\n\nThese providers are available for the agent to select and use:";
9324
- if (providerDescriptions.length === 0) {
9325
- return {
9326
- text: addHeader(
9327
- headerText,
9328
- "No dynamic providers are currently available."
9329
- )
9330
- };
9331
- }
9332
- const providersText = providerDescriptions.join("\n");
9333
- const text = addHeader(headerText, providersText);
9334
- const data = {
9335
- dynamicProviders: dynamicProviders.map((provider) => ({
9336
- name: provider.name,
9337
- description: provider.description || ""
9338
- }))
9339
- };
9340
- return {
9341
- text,
9342
- data
9343
- };
9344
- }
9345
- };
9346
-
9347
- // src/providers/actionExamples.ts
8946
+ // src/providers/actions.ts
9348
8947
  var actionsProvider = {
9349
8948
  name: "ACTIONS",
9350
8949
  description: "Possible response actions",
@@ -9384,6 +8983,8 @@ var actionsProvider = {
9384
8983
  // src/providers/anxiety.ts
9385
8984
  var anxietyProvider = {
9386
8985
  name: "ANXIETY",
8986
+ description: "Social directions for the AI to follow based on the channel type",
8987
+ dynamic: true,
9387
8988
  get: async (_runtime, message) => {
9388
8989
  const channelType = message.content.channelType;
9389
8990
  const groupAnxietyExamples = [
@@ -9464,7 +9065,8 @@ var anxietyProvider = {
9464
9065
  // src/providers/attachments.ts
9465
9066
  var attachmentsProvider = {
9466
9067
  name: "ATTACHMENTS",
9467
- description: "List of attachments in the current conversation",
9068
+ description: "List of attachments sent during the current conversation, including names, descriptions, and summaries",
9069
+ dynamic: true,
9468
9070
  get: async (runtime, message) => {
9469
9071
  let allAttachments = message.content.attachments || [];
9470
9072
  const { roomId } = message;
@@ -9567,13 +9169,12 @@ var characterProvider = {
9567
9169
  get: async (runtime, message, state) => {
9568
9170
  const character = runtime.character;
9569
9171
  const agentName = character.name;
9570
- let bio = character.bio || "";
9571
- if (Array.isArray(bio)) {
9572
- bio = bio.sort(() => 0.5 - Math.random()).slice(0, 3).join(" ");
9573
- }
9172
+ const bioText = Array.isArray(character.bio) ? character.bio.sort(() => 0.5 - Math.random()).slice(0, 10).join(" ") : character.bio || "";
9173
+ const bio = addHeader(`# About ${character.name}`, bioText);
9574
9174
  const system = character.system ?? "";
9575
- const topic = character.topics && character.topics.length > 0 ? character.topics[Math.floor(Math.random() * character.topics.length)] : null;
9576
- const topics = character.topics && character.topics.length > 0 ? `${character.name} is interested in ${character.topics.sort(() => 0.5 - Math.random()).slice(0, 5).map((topic2, index, array) => {
9175
+ const topicString = character.topics && character.topics.length > 0 ? character.topics[Math.floor(Math.random() * character.topics.length)] : null;
9176
+ const topic = topicString ? `${character.name} is currently interested in ${topicString}` : "";
9177
+ const topics = character.topics && character.topics.length > 0 ? `${character.name} is also interested in ${character.topics.filter((topic2) => topic2 !== topicString).sort(() => 0.5 - Math.random()).slice(0, 5).map((topic2, index, array) => {
9577
9178
  if (index === array.length - 2) {
9578
9179
  return `${topic2} and `;
9579
9180
  }
@@ -9582,7 +9183,8 @@ var characterProvider = {
9582
9183
  }
9583
9184
  return `${topic2}, `;
9584
9185
  }).join("")}` : "";
9585
- const adjective = character.adjectives && character.adjectives.length > 0 ? character.adjectives[Math.floor(Math.random() * character.adjectives.length)] : "";
9186
+ const adjectiveString = character.adjectives && character.adjectives.length > 0 ? character.adjectives[Math.floor(Math.random() * character.adjectives.length)] : "";
9187
+ const adjective = adjectiveString ? `${character.name} is ${adjectiveString}` : "";
9586
9188
  const formattedCharacterPostExamples = !character.postExamples ? "" : character.postExamples.sort(() => 0.5 - Math.random()).map((post) => {
9587
9189
  const messageString = `${post}`;
9588
9190
  return messageString;
@@ -9598,9 +9200,9 @@ var characterProvider = {
9598
9200
  );
9599
9201
  return example.map((message2) => {
9600
9202
  let messageString = `${message2.name}: ${message2.content.text}${message2.content.actions ? ` (actions: ${message2.content.actions.join(", ")})` : ""}`;
9601
- exampleNames.forEach((name2, index) => {
9602
- const placeholder = `{{user${index + 1}}}`;
9603
- messageString = messageString.replaceAll(placeholder, name2);
9203
+ exampleNames.forEach((name, index) => {
9204
+ const placeholder = `{{name${index + 1}}}`;
9205
+ messageString = messageString.replaceAll(placeholder, name);
9604
9206
  });
9605
9207
  return messageString;
9606
9208
  }).join("\n");
@@ -9609,7 +9211,7 @@ var characterProvider = {
9609
9211
  `# Example Conversations for ${character.name}`,
9610
9212
  formattedCharacterMessageExamples
9611
9213
  ) : "";
9612
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
9214
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
9613
9215
  const isPostFormat = room?.type === "FEED" /* FEED */ || room?.type === "THREAD" /* THREAD */;
9614
9216
  const postDirections = character?.style?.all?.length > 0 || character?.style?.post?.length > 0 ? addHeader(
9615
9217
  `# Post Directions for ${character.name}`,
@@ -9643,9 +9245,29 @@ var characterProvider = {
9643
9245
  characterPostExamples,
9644
9246
  characterMessageExamples
9645
9247
  };
9646
- const text = [directions, examples].filter(Boolean).join("\n\n");
9248
+ const data = {
9249
+ bio,
9250
+ adjective,
9251
+ topic,
9252
+ topics,
9253
+ character,
9254
+ directions,
9255
+ examples,
9256
+ system
9257
+ };
9258
+ const text = [
9259
+ bio,
9260
+ adjective,
9261
+ topic,
9262
+ topics,
9263
+ adjective,
9264
+ directions,
9265
+ examples,
9266
+ system
9267
+ ].filter(Boolean).join("\n\n");
9647
9268
  return {
9648
9269
  values,
9270
+ data,
9649
9271
  text
9650
9272
  };
9651
9273
  }
@@ -9656,7 +9278,7 @@ var choiceProvider = {
9656
9278
  name: "CHOICE",
9657
9279
  get: async (runtime, message) => {
9658
9280
  try {
9659
- const pendingTasks = await runtime.getDatabaseAdapter().getTasks({
9281
+ const pendingTasks = await runtime.getTasks({
9660
9282
  roomId: message.roomId,
9661
9283
  tags: ["AWAITING_CHOICE"]
9662
9284
  });
@@ -9748,7 +9370,8 @@ Data: ${JSON.stringify(entity.metadata)}
9748
9370
  }
9749
9371
  var entitiesProvider = {
9750
9372
  name: "ENTITIES",
9751
- description: "Entities in the current conversation",
9373
+ description: "People in the current conversation",
9374
+ dynamic: true,
9752
9375
  get: async (runtime, message) => {
9753
9376
  const { roomId, entityId } = message;
9754
9377
  const entitiesData = await getEntityDetails({ runtime, roomId });
@@ -9786,16 +9409,16 @@ function formatEvaluatorExamples(evaluators) {
9786
9409
  );
9787
9410
  let formattedPrompt = example.prompt;
9788
9411
  let formattedOutcome = example.outcome;
9789
- exampleNames.forEach((name2, index) => {
9790
- const placeholder = `{{user${index + 1}}}`;
9791
- formattedPrompt = formattedPrompt.replaceAll(placeholder, name2);
9792
- formattedOutcome = formattedOutcome.replaceAll(placeholder, name2);
9412
+ exampleNames.forEach((name, index) => {
9413
+ const placeholder = `{{name${index + 1}}}`;
9414
+ formattedPrompt = formattedPrompt.replaceAll(placeholder, name);
9415
+ formattedOutcome = formattedOutcome.replaceAll(placeholder, name);
9793
9416
  });
9794
9417
  const formattedMessages = example.messages.map((message) => {
9795
9418
  let messageString = `${message.name}: ${message.content.text}`;
9796
- exampleNames.forEach((name2, index) => {
9797
- const placeholder = `{{user${index + 1}}}`;
9798
- messageString = messageString.replaceAll(placeholder, name2);
9419
+ exampleNames.forEach((name, index) => {
9420
+ const placeholder = `{{name${index + 1}}}`;
9421
+ messageString = messageString.replaceAll(placeholder, name);
9799
9422
  });
9800
9423
  return messageString + (message.content.actions ? ` (${message.content.actions.join(", ")})` : "");
9801
9424
  }).join("\n");
@@ -9857,7 +9480,7 @@ function formatFacts2(facts) {
9857
9480
  }
9858
9481
  var factsProvider = {
9859
9482
  name: "FACTS",
9860
- description: "Key facts that {{agentName}} knows",
9483
+ description: "Key facts that the agent knows",
9861
9484
  dynamic: true,
9862
9485
  get: async (runtime, message, _state) => {
9863
9486
  const recentMessages = await runtime.getMemoryManager("messages").getMemories({
@@ -9866,10 +9489,9 @@ var factsProvider = {
9866
9489
  unique: false
9867
9490
  });
9868
9491
  const last5Messages = recentMessages.slice(-5).map((message2) => message2.content.text).join("\n");
9869
- const embedding = await runtime.useModel(
9870
- ModelTypes.TEXT_EMBEDDING,
9871
- last5Messages
9872
- );
9492
+ const embedding = await runtime.useModel(ModelTypes.TEXT_EMBEDDING, {
9493
+ text: last5Messages
9494
+ });
9873
9495
  const memoryManager = new MemoryManager({
9874
9496
  runtime,
9875
9497
  tableName: "facts"
@@ -9919,7 +9541,7 @@ var factsProvider = {
9919
9541
  // src/providers/knowledge.ts
9920
9542
  var knowledgeProvider = {
9921
9543
  name: "KNOWLEDGE",
9922
- description: "Knowledge from the knowledge base that {{agentName}} knows",
9544
+ description: "Knowledge from the knowledge base that the agent knows",
9923
9545
  dynamic: true,
9924
9546
  get: async (runtime, message) => {
9925
9547
  const knowledgeData = await runtime.getKnowledge(message);
@@ -9939,25 +9561,60 @@ var knowledgeProvider = {
9939
9561
  }
9940
9562
  };
9941
9563
 
9942
- // src/providers/recentMessages.ts
9943
- var getRecentInteractions2 = async (runtime, sourceEntityId, targetEntityId, excludeRoomId) => {
9944
- const rooms = await runtime.getDatabaseAdapter().getRoomsForParticipants([sourceEntityId, targetEntityId]);
9945
- return runtime.getMemoryManager("messages").getMemoriesByRoomIds({
9946
- // filter out the current room id from rooms
9947
- roomIds: rooms.filter((room) => room !== excludeRoomId),
9948
- limit: 20
9949
- });
9950
- };
9951
- var recentMessagesProvider = {
9952
- name: "RECENT_MESSAGES",
9953
- description: "Recent messages, interactions and other memories",
9954
- position: 100,
9955
- get: async (runtime, message) => {
9956
- const { roomId } = message;
9957
- const conversationLength = runtime.getConversationLength();
9564
+ // src/providers/providers.ts
9565
+ var providersProvider = {
9566
+ name: "PROVIDERS",
9567
+ description: "List of all data providers the agent can use to get additional information",
9568
+ get: async (runtime, _message) => {
9569
+ const dynamicProviders = runtime.providers.filter(
9570
+ (provider) => provider.dynamic === true
9571
+ );
9572
+ const providerDescriptions = dynamicProviders.map((provider) => {
9573
+ return `- **${provider.name}**: ${provider.description || "No description available"}`;
9574
+ });
9575
+ const headerText = "# Providers\n\nThese providers are available for the agent to select and use:";
9576
+ if (providerDescriptions.length === 0) {
9577
+ return {
9578
+ text: addHeader(
9579
+ headerText,
9580
+ "No dynamic providers are currently available."
9581
+ )
9582
+ };
9583
+ }
9584
+ const providersText = providerDescriptions.join("\n");
9585
+ const text = addHeader(headerText, providersText);
9586
+ const data = {
9587
+ dynamicProviders: dynamicProviders.map((provider) => ({
9588
+ name: provider.name,
9589
+ description: provider.description || ""
9590
+ }))
9591
+ };
9592
+ return {
9593
+ text,
9594
+ data
9595
+ };
9596
+ }
9597
+ };
9598
+
9599
+ // src/providers/recentMessages.ts
9600
+ var getRecentInteractions2 = async (runtime, sourceEntityId, targetEntityId, excludeRoomId) => {
9601
+ const rooms = await runtime.getRoomsForParticipants([sourceEntityId, targetEntityId]);
9602
+ return runtime.getMemoryManager("messages").getMemoriesByRoomIds({
9603
+ // filter out the current room id from rooms
9604
+ roomIds: rooms.filter((room) => room !== excludeRoomId),
9605
+ limit: 20
9606
+ });
9607
+ };
9608
+ var recentMessagesProvider = {
9609
+ name: "RECENT_MESSAGES",
9610
+ description: "Recent messages, interactions and other memories",
9611
+ position: 100,
9612
+ get: async (runtime, message) => {
9613
+ const { roomId } = message;
9614
+ const conversationLength = runtime.getConversationLength();
9958
9615
  const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
9959
9616
  getEntityDetails({ runtime, roomId }),
9960
- runtime.getDatabaseAdapter().getRoom(roomId),
9617
+ runtime.getRoom(roomId),
9961
9618
  runtime.getMemoryManager("messages").getMemories({
9962
9619
  roomId,
9963
9620
  count: conversationLength,
@@ -10005,7 +9662,7 @@ var recentMessagesProvider = {
10005
9662
  if (remainingEntityIds.length > 0) {
10006
9663
  const entities = await Promise.all(
10007
9664
  remainingEntityIds.map(
10008
- (entityId) => runtime.getDatabaseAdapter().getEntityById(entityId)
9665
+ (entityId) => runtime.getEntityById(entityId)
10009
9666
  )
10010
9667
  );
10011
9668
  entities.forEach((entity, index) => {
@@ -10079,7 +9736,7 @@ async function formatRelationships(runtime, relationships) {
10079
9736
  new Set(sortedRelationships.map((rel) => rel.targetEntityId))
10080
9737
  );
10081
9738
  const entities = await Promise.all(
10082
- uniqueEntityIds.map((id) => runtime.getDatabaseAdapter().getEntityById(id))
9739
+ uniqueEntityIds.map((id) => runtime.getEntityById(id))
10083
9740
  );
10084
9741
  const entityMap = /* @__PURE__ */ new Map();
10085
9742
  entities.forEach((entity, index) => {
@@ -10111,8 +9768,9 @@ ${formatMetadata(entity.metadata)}
10111
9768
  var relationshipsProvider = {
10112
9769
  name: "RELATIONSHIPS",
10113
9770
  description: "Relationships between {{agentName}} and other people, or between other people that {{agentName}} has observed interacting with",
9771
+ dynamic: true,
10114
9772
  get: async (runtime, message) => {
10115
- const relationships = await runtime.getDatabaseAdapter().getRelationships({
9773
+ const relationships = await runtime.getRelationships({
10116
9774
  entityId: message.entityId
10117
9775
  });
10118
9776
  if (!relationships || relationships.length === 0) {
@@ -10159,7 +9817,7 @@ var roleProvider = {
10159
9817
  name: "ROLES",
10160
9818
  description: "Roles in the server, default are OWNER, ADMIN and MEMBER (as well as NONE)",
10161
9819
  get: async (runtime, message, state) => {
10162
- const room = state.data.room ?? await runtime.getDatabaseAdapter().getRoom(message.roomId);
9820
+ const room = state.data.room ?? await runtime.getRoom(message.roomId);
10163
9821
  if (!room) {
10164
9822
  throw new Error("No room found");
10165
9823
  }
@@ -10181,7 +9839,7 @@ var roleProvider = {
10181
9839
  try {
10182
9840
  logger.info(`Using server ID: ${serverId}`);
10183
9841
  const worldId = createUniqueUuid(runtime, serverId);
10184
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
9842
+ const world = await runtime.getWorld(worldId);
10185
9843
  if (!world || !world.metadata?.ownership?.ownerId) {
10186
9844
  logger.info(
10187
9845
  `No ownership data found for server ${serverId}, initializing empty role hierarchy`
@@ -10214,8 +9872,8 @@ var roleProvider = {
10214
9872
  const members = [];
10215
9873
  for (const entityId of Object.keys(roles)) {
10216
9874
  const userRole = roles[entityId];
10217
- const user = await runtime.getDatabaseAdapter().getEntityById(entityId);
10218
- const name2 = user.metadata[room.source]?.name;
9875
+ const user = await runtime.getEntityById(entityId);
9876
+ const name = user.metadata[room.source]?.name;
10219
9877
  const username = user.metadata[room.source]?.username;
10220
9878
  const names4 = user.names;
10221
9879
  if (owners.some((owner) => owner.username === username) || admins.some((admin) => admin.username === username) || members.some((member) => member.username === username)) {
@@ -10223,13 +9881,13 @@ var roleProvider = {
10223
9881
  }
10224
9882
  switch (userRole) {
10225
9883
  case "OWNER":
10226
- owners.push({ name: name2, username, names: names4 });
9884
+ owners.push({ name, username, names: names4 });
10227
9885
  break;
10228
9886
  case "ADMIN":
10229
- admins.push({ name: name2, username, names: names4 });
9887
+ admins.push({ name, username, names: names4 });
10230
9888
  break;
10231
9889
  default:
10232
- members.push({ name: name2, username, names: names4 });
9890
+ members.push({ name, username, names: names4 });
10233
9891
  break;
10234
9892
  }
10235
9893
  }
@@ -10300,17 +9958,43 @@ function createSettingFromConfig(configSetting) {
10300
9958
  }
10301
9959
  function getSalt(runtime) {
10302
9960
  const secretSalt = process.env.SECRET_SALT || "secretsalt";
10303
- return secretSalt + runtime.agentId;
9961
+ const agentId = runtime.agentId;
9962
+ if (!agentId) {
9963
+ logger.warn("AgentId is missing when generating encryption salt");
9964
+ }
9965
+ const salt = secretSalt + (agentId || "");
9966
+ logger.debug(
9967
+ `Generated salt with length: ${salt.length} (truncated for security)`
9968
+ );
9969
+ return salt;
10304
9970
  }
10305
9971
  function saltSettingValue(setting, salt) {
10306
9972
  const settingCopy = { ...setting };
10307
9973
  if (setting.secret === true && typeof setting.value === "string" && setting.value) {
10308
- const key = crypto.createHash("sha256").update(salt).digest().slice(0, 32);
10309
- const iv = crypto.randomBytes(16);
10310
- const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
10311
- let encrypted = cipher.update(setting.value, "utf8", "hex");
10312
- encrypted += cipher.final("hex");
10313
- settingCopy.value = `${iv.toString("hex")}:${encrypted}`;
9974
+ try {
9975
+ const parts = setting.value.split(":");
9976
+ if (parts.length === 2) {
9977
+ try {
9978
+ const possibleIv = Buffer.from(parts[0], "hex");
9979
+ if (possibleIv.length === 16) {
9980
+ logger.debug(
9981
+ "Value appears to be already encrypted, skipping re-encryption"
9982
+ );
9983
+ return settingCopy;
9984
+ }
9985
+ } catch (e) {
9986
+ }
9987
+ }
9988
+ const key = crypto.createHash("sha256").update(salt).digest().slice(0, 32);
9989
+ const iv = crypto.randomBytes(16);
9990
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
9991
+ let encrypted = cipher.update(setting.value, "utf8", "hex");
9992
+ encrypted += cipher.final("hex");
9993
+ settingCopy.value = `${iv.toString("hex")}:${encrypted}`;
9994
+ logger.debug(`Successfully encrypted value with IV length: ${iv.length}`);
9995
+ } catch (error) {
9996
+ logger.error(`Error encrypting setting value: ${error}`);
9997
+ }
10314
9998
  }
10315
9999
  return settingCopy;
10316
10000
  }
@@ -10320,10 +10004,17 @@ function unsaltSettingValue(setting, salt) {
10320
10004
  try {
10321
10005
  const parts = setting.value.split(":");
10322
10006
  if (parts.length !== 2) {
10323
- throw new Error("Invalid encrypted value format");
10007
+ logger.warn(
10008
+ `Invalid encrypted value format for setting - expected 'iv:encrypted'`
10009
+ );
10010
+ return settingCopy;
10324
10011
  }
10325
10012
  const iv = Buffer.from(parts[0], "hex");
10326
10013
  const encrypted = parts[1];
10014
+ if (iv.length !== 16) {
10015
+ logger.warn(`Invalid IV length (${iv.length}) - expected 16 bytes`);
10016
+ return settingCopy;
10017
+ }
10327
10018
  const key = crypto.createHash("sha256").update(salt).digest().slice(0, 32);
10328
10019
  const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
10329
10020
  let decrypted = decipher.update(encrypted, "hex", "utf8");
@@ -10352,7 +10043,7 @@ function unsaltWorldSettings(worldSettings, salt) {
10352
10043
  async function updateWorldSettings2(runtime, serverId, worldSettings) {
10353
10044
  try {
10354
10045
  const worldId = createUniqueUuid(runtime, serverId);
10355
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
10046
+ const world = await runtime.getWorld(worldId);
10356
10047
  if (!world) {
10357
10048
  logger.error(`No world found for server ${serverId}`);
10358
10049
  return false;
@@ -10363,7 +10054,7 @@ async function updateWorldSettings2(runtime, serverId, worldSettings) {
10363
10054
  const salt = getSalt(runtime);
10364
10055
  const saltedSettings = saltWorldSettings(worldSettings, salt);
10365
10056
  world.metadata.settings = saltedSettings;
10366
- await runtime.getDatabaseAdapter().updateWorld(world);
10057
+ await runtime.updateWorld(world);
10367
10058
  return true;
10368
10059
  } catch (error) {
10369
10060
  logger.error(`Error updating settings state: ${error}`);
@@ -10373,7 +10064,7 @@ async function updateWorldSettings2(runtime, serverId, worldSettings) {
10373
10064
  async function getWorldSettings2(runtime, serverId) {
10374
10065
  try {
10375
10066
  const worldId = createUniqueUuid(runtime, serverId);
10376
- const world = await runtime.getDatabaseAdapter().getWorld(worldId);
10067
+ const world = await runtime.getWorld(worldId);
10377
10068
  if (!world || !world.metadata?.settings) {
10378
10069
  return null;
10379
10070
  }
@@ -10405,7 +10096,7 @@ async function initializeOnboarding(runtime, world, config2) {
10405
10096
  world.metadata = {};
10406
10097
  }
10407
10098
  world.metadata.settings = worldSettings;
10408
- await runtime.getDatabaseAdapter().updateWorld(world);
10099
+ await runtime.updateWorld(world);
10409
10100
  logger.info(`Initialized settings config for server ${world.serverId}`);
10410
10101
  return worldSettings;
10411
10102
  } catch (error) {
@@ -10422,7 +10113,7 @@ var formatSettingValue = (setting, isOnboarding) => {
10422
10113
  };
10423
10114
  function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
10424
10115
  try {
10425
- const formattedSettings = Object.entries(worldSettings).map(([_key, setting]) => {
10116
+ const formattedSettings = Object.entries(worldSettings).map(([key, setting]) => {
10426
10117
  if (typeof setting !== "object" || !setting.name) return null;
10427
10118
  const description = setting.description || "";
10428
10119
  const usageDescription = setting.usageDescription || "";
@@ -10430,6 +10121,7 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
10430
10121
  return null;
10431
10122
  }
10432
10123
  return {
10124
+ key,
10433
10125
  name: setting.name,
10434
10126
  value: formatSettingValue(setting, isOnboarding),
10435
10127
  description,
@@ -10446,9 +10138,13 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
10446
10138
  return `# PRIORITY TASK: Onboarding with ${state.senderName}
10447
10139
  ${runtime.character.name} still needs to configure ${requiredUnconfigured} required settings:
10448
10140
 
10449
- ${formattedSettings.filter((s) => s.required && !s.configured).map((s) => `${s.name}: ${s.usageDescription}
10450
- Value: ${s.value}`).join(
10451
- "\n\n"
10141
+ ${formattedSettings.filter((s) => s.required && !s.configured).map((s) => `${s.key}: ${s.value}
10142
+ (${s.name}) ${s.usageDescription}`).join("\n\n")}
10143
+
10144
+ Valid settings keys: ${Object.keys(
10145
+ worldSettings
10146
+ ).join(
10147
+ ", "
10452
10148
  )}
10453
10149
 
10454
10150
  If the user gives any information related to the settings, ${runtime.character.name} should use the UPDATE_SETTINGS action to update the settings with this new information. ${runtime.character.name} can update any, some or all settings.`;
@@ -10478,7 +10174,7 @@ var settingsProvider = {
10478
10174
  get: async (runtime, message, state) => {
10479
10175
  try {
10480
10176
  const [room, userWorld] = await Promise.all([
10481
- runtime.getDatabaseAdapter().getRoom(message.roomId),
10177
+ runtime.getRoom(message.roomId),
10482
10178
  findWorldForOwner(runtime, message.entityId)
10483
10179
  ]).catch((error) => {
10484
10180
  logger.error(`Error fetching initial data: ${error}`);
@@ -10516,7 +10212,7 @@ var settingsProvider = {
10516
10212
  }
10517
10213
  } else {
10518
10214
  try {
10519
- world = await runtime.getDatabaseAdapter().getWorld(room.worldId);
10215
+ world = await runtime.getWorld(room.worldId);
10520
10216
  serverId = world.serverId;
10521
10217
  if (serverId) {
10522
10218
  worldSettings = await getWorldSettings2(runtime, serverId);
@@ -10625,18 +10321,266 @@ var timeProvider = {
10625
10321
  }
10626
10322
  };
10627
10323
 
10324
+ // src/services/scenario.ts
10325
+ import { v4 as uuidv42 } from "uuid";
10326
+ var ScenarioService = class _ScenarioService extends Service {
10327
+ /**
10328
+ * Constructor for creating a new instance of the class.
10329
+ *
10330
+ * @param runtime - The IAgentRuntime instance to be passed to the constructor.
10331
+ */
10332
+ constructor(runtime) {
10333
+ super(runtime);
10334
+ this.runtime = runtime;
10335
+ this.capabilityDescription = "The agent is currently in a scenario testing environment. It can create rooms, send messages, and talk to other agents in a live interactive testing environment.";
10336
+ this.messageHandlers = /* @__PURE__ */ new Map();
10337
+ this.worlds = /* @__PURE__ */ new Map();
10338
+ this.activeActions = /* @__PURE__ */ new Map();
10339
+ this.activeEvaluators = /* @__PURE__ */ new Map();
10340
+ this.setupEventListeners();
10341
+ }
10342
+ static {
10343
+ this.serviceType = "scenario";
10344
+ }
10345
+ setupEventListeners() {
10346
+ this.runtime.registerEvent("ACTION_STARTED" /* ACTION_STARTED */, async (data) => {
10347
+ this.activeActions.set(data.actionId, {
10348
+ actionId: data.actionId,
10349
+ actionName: data.actionName,
10350
+ startTime: Date.now(),
10351
+ completed: false
10352
+ });
10353
+ return Promise.resolve();
10354
+ });
10355
+ this.runtime.registerEvent("ACTION_COMPLETED" /* ACTION_COMPLETED */, async (data) => {
10356
+ const action = this.activeActions.get(data.actionId);
10357
+ if (action) {
10358
+ action.completed = true;
10359
+ action.error = data.error;
10360
+ }
10361
+ return Promise.resolve();
10362
+ });
10363
+ this.runtime.registerEvent("EVALUATOR_STARTED" /* EVALUATOR_STARTED */, async (data) => {
10364
+ this.activeEvaluators.set(data.evaluatorId, {
10365
+ evaluatorId: data.evaluatorId,
10366
+ evaluatorName: data.evaluatorName,
10367
+ startTime: Date.now(),
10368
+ completed: false
10369
+ });
10370
+ logger_default.debug("Evaluator started", data);
10371
+ return Promise.resolve();
10372
+ });
10373
+ this.runtime.registerEvent("EVALUATOR_COMPLETED" /* EVALUATOR_COMPLETED */, async (data) => {
10374
+ const evaluator = this.activeEvaluators.get(data.evaluatorId);
10375
+ if (evaluator) {
10376
+ evaluator.completed = true;
10377
+ evaluator.error = data.error;
10378
+ }
10379
+ logger_default.debug("Evaluator completed", data);
10380
+ return Promise.resolve();
10381
+ });
10382
+ }
10383
+ /**
10384
+ * Start the scenario service with the given runtime.
10385
+ * @param {IAgentRuntime} runtime - The agent runtime
10386
+ * @returns {Promise<ScenarioService>} - The started scenario service
10387
+ */
10388
+ static async start(runtime) {
10389
+ const service = new _ScenarioService(runtime);
10390
+ return service;
10391
+ }
10392
+ /**
10393
+ * Stops the Scenario service associated with the given runtime.
10394
+ *
10395
+ * @param {IAgentRuntime} runtime The runtime to stop the service for.
10396
+ * @throws {Error} When the Scenario service is not found.
10397
+ */
10398
+ static async stop(runtime) {
10399
+ const service = runtime.getService(_ScenarioService.serviceType);
10400
+ if (!service) {
10401
+ throw new Error("Scenario service not found");
10402
+ }
10403
+ service.stop();
10404
+ }
10405
+ /**
10406
+ * Asynchronously stops the current process by clearing all message handlers and worlds.
10407
+ */
10408
+ async stop() {
10409
+ this.messageHandlers.clear();
10410
+ this.worlds.clear();
10411
+ this.activeActions.clear();
10412
+ this.activeEvaluators.clear();
10413
+ }
10414
+ /**
10415
+ * Creates a new world with the specified name and owner.
10416
+ * @param name The name of the world
10417
+ * @param ownerName The name of the world owner
10418
+ * @returns The created world's ID
10419
+ */
10420
+ async createWorld(name, ownerName) {
10421
+ const serverId = createUniqueUuid(this.runtime.agentId, name);
10422
+ const worldId = uuidv42();
10423
+ const ownerId = uuidv42();
10424
+ const world = {
10425
+ id: worldId,
10426
+ name,
10427
+ serverId,
10428
+ agentId: this.runtime.agentId,
10429
+ // TODO: get the server id, create it or whatever
10430
+ metadata: {
10431
+ // this is wrong, the owner needs to be tracked by scenario and similar to how we do it with Discord etc
10432
+ owner: {
10433
+ id: ownerId,
10434
+ name: ownerName
10435
+ }
10436
+ }
10437
+ };
10438
+ this.worlds.set(worldId, world);
10439
+ return worldId;
10440
+ }
10441
+ /**
10442
+ * Creates a room in the specified world.
10443
+ * @param worldId The ID of the world to create the room in
10444
+ * @param name The name of the room
10445
+ * @returns The created room's ID
10446
+ */
10447
+ async createRoom(worldId, name) {
10448
+ const world = this.worlds.get(worldId);
10449
+ if (!world) {
10450
+ throw new Error(`World ${worldId} not found`);
10451
+ }
10452
+ const roomId = uuidv42();
10453
+ await this.runtime.ensureRoomExists({
10454
+ id: roomId,
10455
+ name,
10456
+ source: "scenario",
10457
+ type: "GROUP" /* GROUP */,
10458
+ channelId: roomId,
10459
+ serverId: worldId
10460
+ });
10461
+ return roomId;
10462
+ }
10463
+ /**
10464
+ * Adds a participant to a room
10465
+ * @param worldId The world ID
10466
+ * @param roomId The room ID
10467
+ * @param participantId The participant's ID
10468
+ */
10469
+ async addParticipant(worldId, roomId, participantId) {
10470
+ const world = this.worlds.get(worldId);
10471
+ if (!world) {
10472
+ throw new Error(`World ${worldId} not found`);
10473
+ }
10474
+ const room = this.runtime.getRoom(roomId);
10475
+ if (!room) {
10476
+ throw new Error(`Room ${roomId} not found in world ${worldId}`);
10477
+ }
10478
+ await this.runtime.addParticipant(roomId, participantId);
10479
+ }
10480
+ /**
10481
+ * Sends a message in a specific room
10482
+ * @param sender The runtime of the sending agent
10483
+ * @param worldId The world ID
10484
+ * @param roomId The room ID
10485
+ * @param text The message text
10486
+ */
10487
+ async sendMessage(sender, worldId, roomId, text) {
10488
+ const world = this.worlds.get(worldId);
10489
+ if (!world) {
10490
+ throw new Error(`World ${worldId} not found`);
10491
+ }
10492
+ const memory = {
10493
+ entityId: sender.agentId,
10494
+ agentId: sender.agentId,
10495
+ roomId,
10496
+ content: {
10497
+ text,
10498
+ source: "scenario",
10499
+ name: sender.character.name,
10500
+ userName: sender.character.name,
10501
+ channelType: "GROUP" /* GROUP */
10502
+ }
10503
+ };
10504
+ const participants = await this.runtime.getParticipantsForRoom(roomId);
10505
+ for (const participantId of participants) {
10506
+ this.runtime.emitEvent("MESSAGE_RECEIVED", {
10507
+ runtime: this.runtime,
10508
+ message: memory,
10509
+ roomId,
10510
+ entityId: participantId,
10511
+ source: "scenario",
10512
+ type: "GROUP" /* GROUP */
10513
+ });
10514
+ }
10515
+ }
10516
+ /**
10517
+ * Waits for all active actions and evaluators to complete
10518
+ * @param timeout Maximum time to wait in milliseconds
10519
+ * @returns True if all completed successfully, false if timeout occurred
10520
+ */
10521
+ async waitForCompletion(timeout = 3e4) {
10522
+ const startTime = Date.now();
10523
+ while (Date.now() - startTime < timeout) {
10524
+ const allActionsComplete = Array.from(this.activeActions.values()).every(
10525
+ (action) => action.completed
10526
+ );
10527
+ const allEvaluatorsComplete = Array.from(this.activeEvaluators.values()).every(
10528
+ (evaluator) => evaluator.completed
10529
+ );
10530
+ if (allActionsComplete && allEvaluatorsComplete) {
10531
+ return true;
10532
+ }
10533
+ await new Promise((resolve) => setTimeout(resolve, 100));
10534
+ }
10535
+ return false;
10536
+ }
10537
+ /**
10538
+ * Gets the current state of all active actions and evaluators
10539
+ */
10540
+ getActiveState() {
10541
+ return {
10542
+ actions: Array.from(this.activeActions.values()),
10543
+ evaluators: Array.from(this.activeEvaluators.values())
10544
+ };
10545
+ }
10546
+ /**
10547
+ * Cleans up the scenario state
10548
+ */
10549
+ async cleanup() {
10550
+ this.worlds.clear();
10551
+ this.activeActions.clear();
10552
+ this.activeEvaluators.clear();
10553
+ this.messageHandlers.clear();
10554
+ }
10555
+ };
10556
+
10628
10557
  // src/services/task.ts
10629
10558
  var TaskService = class _TaskService extends Service {
10630
- timer = null;
10631
- TICK_INTERVAL = 1e3;
10632
- // Check every second
10633
- static serviceType = ServiceTypes.TASK;
10634
- capabilityDescription = "The agent is able to schedule and execute tasks";
10559
+ constructor() {
10560
+ super(...arguments);
10561
+ this.timer = null;
10562
+ this.TICK_INTERVAL = 1e3;
10563
+ this.capabilityDescription = "The agent is able to schedule and execute tasks";
10564
+ }
10565
+ static {
10566
+ // Check every second
10567
+ this.serviceType = ServiceTypes.TASK;
10568
+ }
10569
+ /**
10570
+ * Start the TaskService with the given runtime.
10571
+ * @param {IAgentRuntime} runtime - The runtime for the TaskService.
10572
+ * @returns {Promise<TaskService>} A promise that resolves with the TaskService instance.
10573
+ */
10635
10574
  static async start(runtime) {
10636
10575
  const service = new _TaskService(runtime);
10637
10576
  await service.startTimer();
10577
+ await service.createTestTasks();
10638
10578
  return service;
10639
10579
  }
10580
+ /**
10581
+ * Asynchronously creates test tasks by registering task workers for repeating and one-time tasks,
10582
+ * validates the tasks, executes the tasks, and creates the tasks if they do not already exist.
10583
+ */
10640
10584
  async createTestTasks() {
10641
10585
  this.runtime.registerTaskWorker({
10642
10586
  name: "REPEATING_TEST_TASK",
@@ -10658,9 +10602,9 @@ var TaskService = class _TaskService extends Service {
10658
10602
  logger_default.debug("Executing one-time test task");
10659
10603
  }
10660
10604
  });
10661
- const tasks = await this.runtime.getDatabaseAdapter().getTasksByName("REPEATING_TEST_TASK");
10605
+ const tasks = await this.runtime.getTasksByName("REPEATING_TEST_TASK");
10662
10606
  if (tasks.length === 0) {
10663
- await this.runtime.getDatabaseAdapter().createTask({
10607
+ await this.runtime.createTask({
10664
10608
  name: "REPEATING_TEST_TASK",
10665
10609
  description: "A test task that repeats every minute",
10666
10610
  metadata: {
@@ -10672,7 +10616,7 @@ var TaskService = class _TaskService extends Service {
10672
10616
  tags: ["queue", "repeat", "test"]
10673
10617
  });
10674
10618
  }
10675
- await this.runtime.getDatabaseAdapter().createTask({
10619
+ await this.runtime.createTask({
10676
10620
  name: "ONETIME_TEST_TASK",
10677
10621
  description: "A test task that runs once",
10678
10622
  metadata: {
@@ -10681,14 +10625,29 @@ var TaskService = class _TaskService extends Service {
10681
10625
  tags: ["queue", "test"]
10682
10626
  });
10683
10627
  }
10628
+ /**
10629
+ * Starts a timer that runs a function to check tasks at a specified interval.
10630
+ */
10684
10631
  startTimer() {
10685
10632
  if (this.timer) {
10686
10633
  clearInterval(this.timer);
10687
10634
  }
10688
10635
  this.timer = setInterval(async () => {
10689
- await this.checkTasks();
10636
+ try {
10637
+ await this.checkTasks();
10638
+ } catch (error) {
10639
+ logger_default.error("Error checking tasks:", error);
10640
+ }
10690
10641
  }, this.TICK_INTERVAL);
10691
10642
  }
10643
+ /**
10644
+ * Validates an array of Task objects.
10645
+ * Skips tasks without IDs or if no worker is found for the task.
10646
+ * If a worker has a `validate` function, it will run the validation using the `runtime`, `Memory`, and `State` parameters.
10647
+ * If the validation fails, the task will be skipped and the error will be logged.
10648
+ * @param {Task[]} tasks - An array of Task objects to validate.
10649
+ * @returns {Promise<Task[]>} - A Promise that resolves with an array of validated Task objects.
10650
+ */
10692
10651
  async validateTasks(tasks) {
10693
10652
  const validatedTasks = [];
10694
10653
  for (const task of tasks) {
@@ -10718,9 +10677,14 @@ var TaskService = class _TaskService extends Service {
10718
10677
  }
10719
10678
  return validatedTasks;
10720
10679
  }
10680
+ /**
10681
+ * Asynchronous method that checks tasks with "queue" tag, validates and sorts them, then executes them based on interval and tags.
10682
+ *
10683
+ * @returns {Promise<void>} Promise that resolves once all tasks are checked and executed
10684
+ */
10721
10685
  async checkTasks() {
10722
10686
  try {
10723
- const allTasks = await this.runtime.getDatabaseAdapter().getTasks({
10687
+ const allTasks = await this.runtime.getTasks({
10724
10688
  tags: ["queue"]
10725
10689
  });
10726
10690
  const tasks = await this.validateTasks(allTasks);
@@ -10729,8 +10693,17 @@ var TaskService = class _TaskService extends Service {
10729
10693
  }
10730
10694
  const now = Date.now();
10731
10695
  for (const task of tasks) {
10732
- const taskStartTime = new Date(task.updatedAt || 0).getTime();
10733
- const updateIntervalMs = task.metadata.updateInterval ?? 0;
10696
+ let taskStartTime;
10697
+ if (typeof task.updatedAt === "number") {
10698
+ taskStartTime = task.updatedAt;
10699
+ } else if (task.metadata?.updatedAt && typeof task.metadata.updatedAt === "number") {
10700
+ taskStartTime = task.metadata.updatedAt;
10701
+ } else if (task.updatedAt) {
10702
+ taskStartTime = new Date(task.updatedAt).getTime();
10703
+ } else {
10704
+ taskStartTime = 0;
10705
+ }
10706
+ const updateIntervalMs = task.metadata?.updateInterval ?? 0;
10734
10707
  if (!task.tags?.includes("repeat")) {
10735
10708
  await this.executeTask(task);
10736
10709
  continue;
@@ -10746,6 +10719,11 @@ var TaskService = class _TaskService extends Service {
10746
10719
  logger_default.error("Error checking tasks:", error);
10747
10720
  }
10748
10721
  }
10722
+ /**
10723
+ * Executes a given task asynchronously.
10724
+ *
10725
+ * @param {Task} task - The task to be executed.
10726
+ */
10749
10727
  async executeTask(task) {
10750
10728
  try {
10751
10729
  if (!task) {
@@ -10758,10 +10736,10 @@ var TaskService = class _TaskService extends Service {
10758
10736
  return;
10759
10737
  }
10760
10738
  logger_default.debug(`Executing task ${task.name} (${task.id})`);
10761
- await worker.execute(this.runtime, task.metadata || {});
10739
+ await worker.execute(this.runtime, task.metadata || {}, task);
10762
10740
  logger_default.debug("task.tags are", task.tags);
10763
10741
  if (task.tags?.includes("repeat")) {
10764
- await this.runtime.getDatabaseAdapter().updateTask(task.id, {
10742
+ await this.runtime.updateTask(task.id, {
10765
10743
  metadata: {
10766
10744
  ...task.metadata,
10767
10745
  updatedAt: Date.now()
@@ -10771,7 +10749,7 @@ var TaskService = class _TaskService extends Service {
10771
10749
  `Updated repeating task ${task.name} (${task.id}) with new timestamp`
10772
10750
  );
10773
10751
  } else {
10774
- await this.runtime.getDatabaseAdapter().deleteTask(task.id);
10752
+ await this.runtime.deleteTask(task.id);
10775
10753
  logger_default.debug(
10776
10754
  `Deleted non-repeating task ${task.name} (${task.id}) after execution`
10777
10755
  );
@@ -10780,12 +10758,21 @@ var TaskService = class _TaskService extends Service {
10780
10758
  logger_default.error(`Error executing task ${task.id}:`, error);
10781
10759
  }
10782
10760
  }
10761
+ /**
10762
+ * Stops the TASK service in the given agent runtime.
10763
+ *
10764
+ * @param {IAgentRuntime} runtime - The agent runtime containing the service.
10765
+ * @returns {Promise<void>} - A promise that resolves once the service has been stopped.
10766
+ */
10783
10767
  static async stop(runtime) {
10784
10768
  const service = runtime.getService(ServiceTypes.TASK);
10785
10769
  if (service) {
10786
10770
  await service.stop();
10787
10771
  }
10788
10772
  }
10773
+ /**
10774
+ * Stops the timer if it is currently running.
10775
+ */
10789
10776
  async stop() {
10790
10777
  if (this.timer) {
10791
10778
  clearInterval(this.timer);
@@ -10794,270 +10781,276 @@ var TaskService = class _TaskService extends Service {
10794
10781
  }
10795
10782
  };
10796
10783
 
10797
- // src/services/scenario.ts
10798
- import { v4 as uuidv42 } from "uuid";
10799
- var ScenarioService = class _ScenarioService extends Service {
10800
- constructor(runtime) {
10801
- super(runtime);
10802
- this.runtime = runtime;
10803
- }
10804
- static serviceType = "scenario";
10805
- capabilityDescription = "The agent is currently in a scenario testing environment. It can create rooms, send messages, and talk to other agents in a live interactive testing environment.";
10806
- messageHandlers = /* @__PURE__ */ new Map();
10807
- rooms = /* @__PURE__ */ new Map();
10808
- static async start(runtime) {
10809
- const service = new _ScenarioService(runtime);
10810
- return service;
10811
- }
10812
- static async stop(runtime) {
10813
- const service = runtime.getService(_ScenarioService.serviceType);
10814
- if (!service) {
10815
- throw new Error("Scenario service not found");
10816
- }
10817
- service.stop();
10818
- }
10819
- async stop() {
10820
- this.messageHandlers.clear();
10821
- this.rooms.clear();
10822
- }
10823
- // Create a room for an agent
10824
- async createRoom(agentId, name2) {
10825
- const roomId = uuidv42();
10826
- await this.runtime.ensureRoomExists({
10827
- id: roomId,
10828
- name: name2 || `Room for ${agentId}`,
10829
- source: "scenario",
10830
- type: "GROUP" /* GROUP */,
10831
- channelId: roomId,
10832
- serverId: null
10833
- });
10834
- this.rooms.set(agentId, { roomId });
10784
+ // src/bootstrap.ts
10785
+ var latestResponseIds = /* @__PURE__ */ new Map();
10786
+ var messageReceivedHandler = async ({
10787
+ runtime,
10788
+ message,
10789
+ callback
10790
+ }) => {
10791
+ const responseId = v4();
10792
+ if (!latestResponseIds.has(runtime.agentId)) {
10793
+ latestResponseIds.set(runtime.agentId, /* @__PURE__ */ new Map());
10835
10794
  }
10836
- // Save a message in all agents' memory without emitting events
10837
- async saveMessage(sender, receivers, text) {
10838
- for (const receiver of receivers) {
10839
- const roomData = this.rooms.get(receiver.agentId);
10840
- if (!roomData) continue;
10841
- const entityId = createUniqueUuid(receiver, sender.agentId);
10842
- await receiver.ensureConnection({
10843
- entityId,
10844
- roomId: roomData.roomId,
10845
- userName: sender.character.name,
10846
- name: sender.character.name,
10847
- source: "scenario",
10848
- type: "GROUP" /* GROUP */
10795
+ const agentResponses = latestResponseIds.get(runtime.agentId);
10796
+ agentResponses.set(message.roomId, responseId);
10797
+ const runId = v4();
10798
+ const startTime = Date.now();
10799
+ await runtime.emitEvent("RUN_STARTED" /* RUN_STARTED */, {
10800
+ runtime,
10801
+ runId,
10802
+ messageId: message.id,
10803
+ roomId: message.roomId,
10804
+ entityId: message.entityId,
10805
+ startTime,
10806
+ status: "started",
10807
+ source: "messageHandler"
10808
+ });
10809
+ const timeoutDuration = 5 * 60 * 1e3;
10810
+ let timeoutId;
10811
+ const timeoutPromise = new Promise((_, reject) => {
10812
+ timeoutId = setTimeout(async () => {
10813
+ await runtime.emitEvent("RUN_TIMEOUT" /* RUN_TIMEOUT */, {
10814
+ runtime,
10815
+ runId,
10816
+ messageId: message.id,
10817
+ roomId: message.roomId,
10818
+ entityId: message.entityId,
10819
+ startTime,
10820
+ status: "timeout",
10821
+ endTime: Date.now(),
10822
+ duration: Date.now() - startTime,
10823
+ error: "Run exceeded 5 minute timeout",
10824
+ source: "messageHandler"
10849
10825
  });
10850
- const memory = {
10851
- entityId,
10852
- agentId: receiver.agentId,
10853
- roomId: roomData.roomId,
10854
- content: {
10855
- text,
10856
- source: "scenario",
10857
- name: sender.character.name,
10858
- userName: sender.character.name,
10859
- channelType: "GROUP" /* GROUP */
10860
- }
10861
- };
10862
- await receiver.getMemoryManager("messages").createMemory(memory);
10863
- }
10864
- }
10865
- // Send a live message that triggers handlers
10866
- async sendMessage(sender, receivers, text) {
10867
- for (const receiver of receivers) {
10868
- const roomData = this.rooms.get(receiver.agentId);
10869
- if (!roomData) continue;
10870
- const entityId = createUniqueUuid(receiver, sender.agentId);
10871
- if (receiver.agentId !== sender.agentId) {
10872
- await receiver.ensureConnection({
10873
- entityId,
10874
- roomId: roomData.roomId,
10875
- userName: sender.character.name,
10876
- name: sender.character.name,
10877
- source: "scenario",
10878
- type: "GROUP" /* GROUP */
10826
+ reject(new Error("Run exceeded 5 minute timeout"));
10827
+ }, timeoutDuration);
10828
+ });
10829
+ const processingPromise = (async () => {
10830
+ try {
10831
+ if (message.entityId === runtime.agentId) {
10832
+ throw new Error("Message is from the agent itself");
10833
+ }
10834
+ await Promise.all([
10835
+ runtime.getMemoryManager("messages").addEmbeddingToMemory(message),
10836
+ runtime.getMemoryManager("messages").createMemory(message)
10837
+ ]);
10838
+ const agentUserState = await runtime.getParticipantUserState(message.roomId, runtime.agentId);
10839
+ if (agentUserState === "MUTED" && !message.content.text.toLowerCase().includes(runtime.character.name.toLowerCase())) {
10840
+ console.log("Ignoring muted room");
10841
+ return;
10842
+ }
10843
+ let state = await runtime.composeState(message, [
10844
+ "PROVIDERS",
10845
+ "SHOULD_RESPOND",
10846
+ "CHARACTER",
10847
+ "RECENT_MESSAGES",
10848
+ "ENTITIES"
10849
+ ]);
10850
+ const shouldRespondPrompt = composePromptFromState({
10851
+ state,
10852
+ template: runtime.character.templates?.shouldRespondTemplate || shouldRespondTemplate
10853
+ });
10854
+ logger.debug(
10855
+ `*** Should Respond Prompt for ${runtime.character.name} ***`,
10856
+ shouldRespondPrompt
10857
+ );
10858
+ const response = await runtime.useModel(ModelTypes.TEXT_SMALL, {
10859
+ prompt: shouldRespondPrompt
10860
+ });
10861
+ logger.debug(
10862
+ `*** Should Respond Response for ${runtime.character.name} ***`,
10863
+ response
10864
+ );
10865
+ const responseObject = parseJSONObjectFromText(response);
10866
+ const providers = responseObject.providers;
10867
+ const shouldRespond = responseObject?.action && responseObject.action === "RESPOND";
10868
+ state = await runtime.composeState(message, null, providers);
10869
+ let responseMessages = [];
10870
+ if (shouldRespond) {
10871
+ const prompt = composePromptFromState({
10872
+ state,
10873
+ template: runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate
10879
10874
  });
10880
- } else {
10881
- await receiver.ensureConnection({
10882
- entityId: sender.agentId,
10883
- roomId: roomData.roomId,
10884
- userName: sender.character.name,
10885
- name: sender.character.name,
10886
- source: "scenario",
10887
- type: "GROUP" /* GROUP */
10875
+ let responseContent = null;
10876
+ let retries = 0;
10877
+ const maxRetries = 3;
10878
+ while (retries < maxRetries && (!responseContent?.thought || !responseContent?.plan || !responseContent?.actions)) {
10879
+ const response2 = await runtime.useModel(ModelTypes.TEXT_SMALL, {
10880
+ prompt
10881
+ });
10882
+ responseContent = parseJSONObjectFromText(response2);
10883
+ retries++;
10884
+ if (!responseContent?.thought || !responseContent?.plan || !responseContent?.actions) {
10885
+ logger.warn("*** Missing required fields, retrying... ***");
10886
+ }
10887
+ }
10888
+ const currentResponseId = agentResponses.get(message.roomId);
10889
+ if (currentResponseId !== responseId) {
10890
+ logger.info(
10891
+ `Response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
10892
+ );
10893
+ return;
10894
+ }
10895
+ responseContent.plan = responseContent.plan?.trim();
10896
+ responseContent.inReplyTo = createUniqueUuid(runtime, message.id);
10897
+ responseMessages = [
10898
+ {
10899
+ id: v4(),
10900
+ entityId: runtime.agentId,
10901
+ agentId: runtime.agentId,
10902
+ content: responseContent,
10903
+ roomId: message.roomId,
10904
+ createdAt: Date.now()
10905
+ }
10906
+ ];
10907
+ await runtime.getMemoryManager("messages").createMemory({
10908
+ entityId: runtime.agentId,
10909
+ agentId: runtime.agentId,
10910
+ content: {
10911
+ thought: responseContent.thought,
10912
+ plan: responseContent.plan,
10913
+ actions: responseContent.actions,
10914
+ providers: responseContent.providers
10915
+ },
10916
+ roomId: message.roomId,
10917
+ createdAt: Date.now()
10888
10918
  });
10889
- }
10890
- const memory = {
10891
- entityId: receiver.agentId !== sender.agentId ? entityId : sender.agentId,
10892
- agentId: receiver.agentId,
10893
- roomId: roomData.roomId,
10894
- content: {
10895
- text,
10896
- source: "scenario",
10897
- name: sender.character.name,
10898
- userName: sender.character.name,
10899
- channelType: "GROUP" /* GROUP */
10919
+ agentResponses.delete(message.roomId);
10920
+ if (agentResponses.size === 0) {
10921
+ latestResponseIds.delete(runtime.agentId);
10900
10922
  }
10901
- };
10902
- receiver.emitEvent("MESSAGE_RECEIVED", {
10903
- runtime: receiver,
10904
- message: memory,
10905
- roomId: roomData.roomId,
10906
- entityId: receiver.agentId !== sender.agentId ? entityId : sender.agentId,
10907
- source: "scenario",
10908
- type: "GROUP" /* GROUP */
10923
+ await runtime.processActions(message, responseMessages, state, callback);
10924
+ }
10925
+ await runtime.evaluate(
10926
+ message,
10927
+ state,
10928
+ shouldRespond,
10929
+ callback,
10930
+ responseMessages
10931
+ );
10932
+ await runtime.emitEvent("RUN_ENDED" /* RUN_ENDED */, {
10933
+ runtime,
10934
+ runId,
10935
+ messageId: message.id,
10936
+ roomId: message.roomId,
10937
+ entityId: message.entityId,
10938
+ startTime,
10939
+ status: "completed",
10940
+ endTime: Date.now(),
10941
+ duration: Date.now() - startTime,
10942
+ source: "messageHandler"
10909
10943
  });
10944
+ } catch (error) {
10945
+ await runtime.emitEvent("RUN_ENDED" /* RUN_ENDED */, {
10946
+ runtime,
10947
+ runId,
10948
+ messageId: message.id,
10949
+ roomId: message.roomId,
10950
+ entityId: message.entityId,
10951
+ startTime,
10952
+ status: "completed",
10953
+ endTime: Date.now(),
10954
+ duration: Date.now() - startTime,
10955
+ error: error.message,
10956
+ source: "messageHandler"
10957
+ });
10958
+ throw error;
10910
10959
  }
10911
- }
10912
- // Get conversation history for all participants
10913
- async getConversations(participants) {
10914
- const conversations = await Promise.all(
10915
- participants.map(async (member) => {
10916
- const roomData = this.rooms.get(member.agentId);
10917
- if (!roomData) return [];
10918
- return member.getMemoryManager("messages").getMemories({
10919
- roomId: roomData.roomId
10920
- });
10921
- })
10922
- );
10923
- logger.info("\nConversation logs per agent:");
10924
- conversations.forEach((convo, i) => {
10925
- logger.info(`
10926
- ${participants[i].character.name}'s perspective:`);
10927
- convo.forEach(
10928
- (msg) => logger.info(`${msg.content.name}: ${msg.content.text}`)
10929
- );
10930
- });
10931
- return conversations;
10960
+ })();
10961
+ try {
10962
+ await Promise.race([processingPromise, timeoutPromise]);
10963
+ } finally {
10964
+ clearTimeout(timeoutId);
10932
10965
  }
10933
10966
  };
10934
-
10935
- // src/bootstrap.ts
10936
- var latestResponseIds = /* @__PURE__ */ new Map();
10937
- var messageReceivedHandler = async ({
10967
+ var reactionReceivedHandler = async ({
10968
+ runtime,
10969
+ message
10970
+ }) => {
10971
+ try {
10972
+ await runtime.getMemoryManager("messages").createMemory(message);
10973
+ } catch (error) {
10974
+ if (error.code === "23505") {
10975
+ logger.warn("Duplicate reaction memory, skipping");
10976
+ return;
10977
+ }
10978
+ logger.error("Error in reaction handler:", error);
10979
+ }
10980
+ };
10981
+ var postGeneratedHandler = async ({
10938
10982
  runtime,
10939
10983
  message,
10940
10984
  callback
10941
10985
  }) => {
10942
- const responseId = v4();
10943
- if (!latestResponseIds.has(runtime.agentId)) {
10944
- latestResponseIds.set(runtime.agentId, /* @__PURE__ */ new Map());
10945
- }
10946
- const agentResponses = latestResponseIds.get(runtime.agentId);
10947
- agentResponses.set(message.roomId, responseId);
10948
- if (message.entityId === runtime.agentId) {
10949
- throw new Error("Message is from the agent itself");
10950
- }
10951
10986
  await Promise.all([
10952
10987
  runtime.getMemoryManager("messages").addEmbeddingToMemory(message),
10953
10988
  runtime.getMemoryManager("messages").createMemory(message)
10954
10989
  ]);
10955
- const agentUserState = await runtime.getDatabaseAdapter().getParticipantUserState(message.roomId, runtime.agentId);
10956
- if (agentUserState === "MUTED" && !message.content.text.toLowerCase().includes(runtime.character.name.toLowerCase())) {
10957
- console.log("Ignoring muted room");
10958
- return;
10959
- }
10960
10990
  let state = await runtime.composeState(message, [
10961
10991
  "PROVIDERS",
10962
- "SHOULD_RESPOND",
10963
10992
  "CHARACTER",
10964
10993
  "RECENT_MESSAGES",
10965
10994
  "ENTITIES"
10966
10995
  ]);
10967
- const shouldRespondPrompt = composePrompt({
10996
+ const providers = state.providers || [];
10997
+ state = await runtime.composeState(message, null, providers);
10998
+ const promptTemplate = runtime.character.templates?.postTemplate || runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate;
10999
+ const prompt = composePromptFromState({
10968
11000
  state,
10969
- template: runtime.character.templates?.shouldRespondTemplate || shouldRespondTemplate
10970
- });
10971
- const response = await runtime.useModel(ModelTypes.TEXT_SMALL, {
10972
- prompt: shouldRespondPrompt
11001
+ template: promptTemplate
10973
11002
  });
10974
- const responseObject = parseJSONObjectFromText(response);
10975
- const providers = responseObject.providers;
10976
- const shouldRespond = responseObject?.action && responseObject.action === "RESPOND";
10977
- state = await runtime.composeState(message, null, providers);
10978
- let responseMessages = [];
10979
- if (shouldRespond) {
10980
- const prompt = composePrompt({
10981
- state,
10982
- template: runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate
10983
- });
10984
- let responseContent = null;
10985
- let retries = 0;
10986
- const maxRetries = 3;
10987
- while (retries < maxRetries && (!responseContent?.thought || !responseContent?.plan || !responseContent?.actions)) {
10988
- const response2 = await runtime.useModel(ModelTypes.TEXT_SMALL, {
10989
- prompt
10990
- });
10991
- responseContent = parseJSONObjectFromText(response2);
10992
- retries++;
10993
- if (!responseContent?.thought || !responseContent?.plan || !responseContent?.actions) {
10994
- logger.warn("*** Missing required fields, retrying... ***");
10995
- }
10996
- }
10997
- const currentResponseId = agentResponses.get(message.roomId);
10998
- if (currentResponseId !== responseId) {
10999
- logger.info(
11000
- `Response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
11001
- );
11002
- return;
11003
+ let responseContent = null;
11004
+ let retries = 0;
11005
+ const maxRetries = 3;
11006
+ while (retries < maxRetries && (!responseContent?.thought || !responseContent?.plan || !responseContent?.text)) {
11007
+ const response = await runtime.useModel(ModelTypes.TEXT_SMALL, {
11008
+ prompt
11009
+ });
11010
+ responseContent = parseJSONObjectFromText(response);
11011
+ retries++;
11012
+ if (!responseContent?.thought || !responseContent?.plan || !responseContent?.text) {
11013
+ logger.warn("*** Missing required fields, retrying... ***");
11003
11014
  }
11004
- responseContent.plan = responseContent.plan?.trim();
11005
- responseContent.inReplyTo = createUniqueUuid(runtime, message.id);
11006
- responseMessages = [
11007
- {
11008
- id: v4(),
11009
- entityId: runtime.agentId,
11010
- agentId: runtime.agentId,
11011
- content: responseContent,
11012
- roomId: message.roomId,
11013
- createdAt: Date.now()
11014
- }
11015
- ];
11016
- await runtime.getMemoryManager("messages").createMemory({
11015
+ }
11016
+ const responseMessages = [
11017
+ {
11018
+ id: v4(),
11017
11019
  entityId: runtime.agentId,
11018
11020
  agentId: runtime.agentId,
11019
- content: {
11020
- thought: responseContent.thought,
11021
- plan: responseContent.plan,
11022
- actions: responseContent.actions,
11023
- providers: responseContent.providers
11024
- },
11021
+ content: responseContent,
11025
11022
  roomId: message.roomId,
11026
11023
  createdAt: Date.now()
11027
- });
11028
- agentResponses.delete(message.roomId);
11029
- if (agentResponses.size === 0) {
11030
- latestResponseIds.delete(runtime.agentId);
11031
11024
  }
11032
- await runtime.processActions(message, responseMessages, state, callback);
11033
- }
11025
+ ];
11026
+ await runtime.getMemoryManager("messages").createMemory({
11027
+ entityId: runtime.agentId,
11028
+ agentId: runtime.agentId,
11029
+ content: {
11030
+ thought: responseContent.thought,
11031
+ plan: responseContent.plan,
11032
+ text: responseContent.text,
11033
+ providers: responseContent.providers
11034
+ },
11035
+ roomId: message.roomId,
11036
+ createdAt: Date.now()
11037
+ });
11038
+ await runtime.processActions(message, responseMessages, state, callback);
11034
11039
  await runtime.evaluate(
11035
11040
  message,
11036
11041
  state,
11037
- shouldRespond,
11042
+ true,
11043
+ // Post generation is always a "responding" scenario
11038
11044
  callback,
11039
11045
  responseMessages
11040
11046
  );
11041
11047
  };
11042
- var reactionReceivedHandler = async ({
11043
- runtime,
11044
- message
11045
- }) => {
11046
- try {
11047
- await runtime.getMemoryManager("messages").createMemory(message);
11048
- } catch (error) {
11049
- if (error.code === "23505") {
11050
- logger.warn("Duplicate reaction memory, skipping");
11051
- return;
11052
- }
11053
- logger.error("Error in reaction handler:", error);
11054
- }
11055
- };
11056
- var syncSingleUser = async (entityId, runtime, user, serverId, channelId, type, source) => {
11057
- logger.info(`Syncing user: ${user.username || user.id}`);
11048
+ var syncSingleUser = async (entityId, runtime, serverId, channelId, type, source) => {
11049
+ const entity = await runtime.getEntityById(entityId);
11050
+ logger.info(`Syncing user: ${entity.metadata[source].username || entity.id}`);
11058
11051
  try {
11059
11052
  if (!channelId) {
11060
- logger.warn(`Cannot sync user ${user.id} without a valid channelId`);
11053
+ logger.warn(`Cannot sync user ${entity.id} without a valid channelId`);
11061
11054
  return;
11062
11055
  }
11063
11056
  const roomId = createUniqueUuid(runtime, channelId);
@@ -11065,15 +11058,15 @@ var syncSingleUser = async (entityId, runtime, user, serverId, channelId, type,
11065
11058
  await runtime.ensureConnection({
11066
11059
  entityId,
11067
11060
  roomId,
11068
- userName: user.username || user.displayName || `User${user.id}`,
11069
- name: user.displayName || user.username || `User${user.id}`,
11061
+ userName: entity.metadata[source].username || entity.id,
11062
+ name: entity.metadata[source].name || entity.metadata[source].username || `User${entity.id}`,
11070
11063
  source,
11071
11064
  channelId,
11072
11065
  serverId,
11073
11066
  type,
11074
11067
  worldId
11075
11068
  });
11076
- logger.success(`Successfully synced user: ${user.username || user.id}`);
11069
+ logger.success(`Successfully synced user: ${entity.id}`);
11077
11070
  } catch (error) {
11078
11071
  logger.error(
11079
11072
  `Error syncing user: ${error instanceof Error ? error.message : String(error)}`
@@ -11084,7 +11077,7 @@ var handleServerSync = async ({
11084
11077
  runtime,
11085
11078
  world,
11086
11079
  rooms,
11087
- users,
11080
+ entities,
11088
11081
  source
11089
11082
  }) => {
11090
11083
  logger.info(`Handling server sync event for server: ${world.name}`);
@@ -11111,10 +11104,10 @@ var handleServerSync = async ({
11111
11104
  });
11112
11105
  }
11113
11106
  }
11114
- if (users && users.length > 0) {
11107
+ if (entities && entities.length > 0) {
11115
11108
  const batchSize = 50;
11116
- for (let i = 0; i < users.length; i += batchSize) {
11117
- const entityBatch = users.slice(i, i + batchSize);
11109
+ for (let i = 0; i < entities.length; i += batchSize) {
11110
+ const entityBatch = entities.slice(i, i + batchSize);
11118
11111
  const firstRoomUserIsIn = rooms.length > 0 ? rooms[0] : null;
11119
11112
  await Promise.all(
11120
11113
  entityBatch.map(async (entity) => {
@@ -11137,7 +11130,7 @@ var handleServerSync = async ({
11137
11130
  }
11138
11131
  })
11139
11132
  );
11140
- if (i + batchSize < users.length) {
11133
+ if (i + batchSize < entities.length) {
11141
11134
  await new Promise((resolve) => setTimeout(resolve, 500));
11142
11135
  }
11143
11136
  }
@@ -11152,54 +11145,114 @@ var handleServerSync = async ({
11152
11145
  }
11153
11146
  };
11154
11147
  var events = {
11155
- MESSAGE_RECEIVED: [
11156
- async ({ runtime, message, callback }) => {
11148
+ ["MESSAGE_RECEIVED" /* MESSAGE_RECEIVED */]: [
11149
+ async (payload) => {
11157
11150
  await messageReceivedHandler({
11158
- runtime,
11159
- message,
11160
- callback
11151
+ runtime: payload.runtime,
11152
+ message: payload.message,
11153
+ callback: payload.callback
11161
11154
  });
11162
11155
  }
11163
11156
  ],
11164
- VOICE_MESSAGE_RECEIVED: [
11165
- async ({ runtime, message, callback }) => {
11157
+ ["VOICE_MESSAGE_RECEIVED" /* VOICE_MESSAGE_RECEIVED */]: [
11158
+ async (payload) => {
11166
11159
  await messageReceivedHandler({
11167
- runtime,
11168
- message,
11169
- callback
11160
+ runtime: payload.runtime,
11161
+ message: payload.message,
11162
+ callback: payload.callback
11170
11163
  });
11171
11164
  }
11172
11165
  ],
11173
- REACTION_RECEIVED: [reactionReceivedHandler],
11174
- // Both events now use the same handler function
11175
- SERVER_JOINED: [handleServerSync],
11176
- SERVER_CONNECTED: [handleServerSync],
11177
- USER_JOINED: [
11178
- async ({
11179
- runtime,
11180
- user,
11181
- serverId,
11182
- entityId,
11183
- channelId,
11184
- channelType,
11185
- source
11186
- }) => {
11166
+ ["REACTION_RECEIVED" /* REACTION_RECEIVED */]: [
11167
+ async (payload) => {
11168
+ await reactionReceivedHandler({
11169
+ runtime: payload.runtime,
11170
+ message: payload.message
11171
+ });
11172
+ }
11173
+ ],
11174
+ ["POST_GENERATED" /* POST_GENERATED */]: [
11175
+ async (payload) => {
11176
+ await postGeneratedHandler({
11177
+ runtime: payload.runtime,
11178
+ message: payload.message,
11179
+ callback: payload.callback
11180
+ });
11181
+ }
11182
+ ],
11183
+ ["MESSAGE_SENT" /* MESSAGE_SENT */]: [
11184
+ async (payload) => {
11185
+ logger.debug(`Message sent: ${payload.message.content.text}`);
11186
+ }
11187
+ ],
11188
+ ["WORLD_JOINED" /* WORLD_JOINED */]: [
11189
+ async (payload) => {
11190
+ await handleServerSync(payload);
11191
+ }
11192
+ ],
11193
+ ["WORLD_CONNECTED" /* WORLD_CONNECTED */]: [
11194
+ async (payload) => {
11195
+ await handleServerSync(payload);
11196
+ }
11197
+ ],
11198
+ ["ENTITY_JOINED" /* ENTITY_JOINED */]: [
11199
+ async (payload) => {
11187
11200
  await syncSingleUser(
11188
- entityId,
11189
- runtime,
11190
- user,
11191
- serverId,
11192
- channelId,
11193
- channelType,
11194
- source
11201
+ payload.entityId,
11202
+ payload.runtime,
11203
+ payload.worldId,
11204
+ payload.roomId,
11205
+ payload.metadata.type,
11206
+ payload.source
11195
11207
  );
11196
11208
  }
11209
+ ],
11210
+ ["ENTITY_LEFT" /* ENTITY_LEFT */]: [
11211
+ async (payload) => {
11212
+ try {
11213
+ const entity = await payload.runtime.getEntityById(payload.entityId);
11214
+ if (entity) {
11215
+ entity.metadata = {
11216
+ ...entity.metadata,
11217
+ status: "INACTIVE",
11218
+ leftAt: Date.now()
11219
+ };
11220
+ await payload.runtime.updateEntity(entity);
11221
+ }
11222
+ logger.info(`User ${payload.entityId} left world ${payload.worldId}`);
11223
+ } catch (error) {
11224
+ logger.error(`Error handling user left: ${error.message}`);
11225
+ }
11226
+ }
11227
+ ],
11228
+ ["ACTION_STARTED" /* ACTION_STARTED */]: [
11229
+ async (payload) => {
11230
+ logger.debug(`Action started: ${payload.actionName} (${payload.actionId})`);
11231
+ }
11232
+ ],
11233
+ ["ACTION_COMPLETED" /* ACTION_COMPLETED */]: [
11234
+ async (payload) => {
11235
+ const status = payload.error ? `failed: ${payload.error.message}` : "completed";
11236
+ logger.debug(`Action ${status}: ${payload.actionName} (${payload.actionId})`);
11237
+ }
11238
+ ],
11239
+ ["EVALUATOR_STARTED" /* EVALUATOR_STARTED */]: [
11240
+ async (payload) => {
11241
+ logger.debug(`Evaluator started: ${payload.evaluatorName} (${payload.evaluatorId})`);
11242
+ }
11243
+ ],
11244
+ ["EVALUATOR_COMPLETED" /* EVALUATOR_COMPLETED */]: [
11245
+ async (payload) => {
11246
+ const status = payload.error ? `failed: ${payload.error.message}` : "completed";
11247
+ logger.debug(`Evaluator ${status}: ${payload.evaluatorName} (${payload.evaluatorId})`);
11248
+ }
11197
11249
  ]
11198
11250
  };
11199
11251
  var bootstrapPlugin = {
11200
11252
  name: "bootstrap",
11201
11253
  description: "Agent bootstrap with basic actions and evaluators",
11202
11254
  actions: [
11255
+ replyAction,
11203
11256
  followRoomAction,
11204
11257
  unfollowRoomAction,
11205
11258
  ignoreAction,
@@ -11210,17 +11263,15 @@ var bootstrapPlugin = {
11210
11263
  updateEntityAction,
11211
11264
  choiceAction,
11212
11265
  roles_default,
11213
- settings_default,
11214
- replyAction
11266
+ settings_default
11215
11267
  ],
11216
11268
  events,
11217
- evaluators: [reflectionEvaluator, goalEvaluator],
11269
+ evaluators: [reflectionEvaluator],
11218
11270
  providers: [
11219
11271
  evaluatorsProvider,
11220
11272
  anxietyProvider,
11221
11273
  knowledgeProvider,
11222
11274
  timeProvider,
11223
- characterProvider,
11224
11275
  entitiesProvider,
11225
11276
  relationshipsProvider,
11226
11277
  choiceProvider,
@@ -11231,6 +11282,7 @@ var bootstrapPlugin = {
11231
11282
  attachmentsProvider,
11232
11283
  providersProvider,
11233
11284
  actionsProvider,
11285
+ characterProvider,
11234
11286
  recentMessagesProvider
11235
11287
  ],
11236
11288
  services: [TaskService, ScenarioService]
@@ -11278,24 +11330,21 @@ function stringToUuid(target) {
11278
11330
 
11279
11331
  // src/runtime.ts
11280
11332
  var AgentRuntime = class {
11281
- #conversationLength = 32;
11282
- agentId;
11283
- character;
11284
- databaseAdapter;
11285
- actions = [];
11286
- evaluators = [];
11287
- providers = [];
11288
- plugins = [];
11289
- events = /* @__PURE__ */ new Map();
11290
- stateCache = /* @__PURE__ */ new Map();
11291
- fetch = fetch;
11292
- services = /* @__PURE__ */ new Map();
11293
- adapters;
11294
- knowledgeRoot;
11295
- models = /* @__PURE__ */ new Map();
11296
- routes = [];
11297
- taskWorkers = /* @__PURE__ */ new Map();
11298
11333
  constructor(opts) {
11334
+ this.#conversationLength = 32;
11335
+ this.actions = [];
11336
+ this.evaluators = [];
11337
+ this.providers = [];
11338
+ this.plugins = [];
11339
+ this.events = /* @__PURE__ */ new Map();
11340
+ this.stateCache = /* @__PURE__ */ new Map();
11341
+ this.fetch = fetch;
11342
+ this.services = /* @__PURE__ */ new Map();
11343
+ this.models = /* @__PURE__ */ new Map();
11344
+ this.routes = [];
11345
+ this.taskWorkers = /* @__PURE__ */ new Map();
11346
+ // Event emitter methods
11347
+ this.eventHandlers = /* @__PURE__ */ new Map();
11299
11348
  this.agentId = opts.character?.id ?? opts?.agentId ?? stringToUuid(opts.character?.name ?? uuidv43());
11300
11349
  this.character = opts.character;
11301
11350
  logger.debug(`[AgentRuntime] Process working directory: ${process.cwd()}`);
@@ -11307,29 +11356,46 @@ var AgentRuntime = class {
11307
11356
  }
11308
11357
  logger.success(`Agent ID: ${this.agentId}`);
11309
11358
  this.fetch = opts.fetch ?? this.fetch;
11310
- this.adapters = opts.adapters ?? [];
11359
+ this.adapter = opts.adapter;
11311
11360
  const plugins = opts?.plugins ?? [];
11312
11361
  if (!opts?.ignoreBootstrap) {
11313
11362
  plugins.push(bootstrapPlugin);
11314
11363
  }
11315
11364
  this.plugins = plugins;
11316
11365
  }
11366
+ #conversationLength;
11317
11367
  /**
11318
11368
  * Registers a plugin with the runtime and initializes its components
11319
11369
  * @param plugin The plugin to register
11320
11370
  */
11321
11371
  async registerPlugin(plugin) {
11322
11372
  if (!plugin) {
11323
- return;
11373
+ throw new Error("*** registerPlugin plugin is undefined");
11324
11374
  }
11325
11375
  if (!this.plugins.some((p) => p.name === plugin.name)) {
11326
11376
  this.plugins.push(plugin);
11327
11377
  }
11328
- if (plugin.adapters) {
11329
- for (const adapter of plugin.adapters) {
11330
- this.adapters.push(adapter);
11378
+ if (plugin.init) {
11379
+ try {
11380
+ await plugin.init(plugin.config || {}, this);
11381
+ } catch (error) {
11382
+ const errorMessage = error instanceof Error ? error.message : String(error);
11383
+ if (errorMessage.includes("API key") || errorMessage.includes("environment variables") || errorMessage.includes("Invalid plugin configuration")) {
11384
+ console.warn(
11385
+ `Plugin ${plugin.name} requires configuration. ${errorMessage}`
11386
+ );
11387
+ console.warn(
11388
+ "Please check your environment variables and ensure all required API keys are set."
11389
+ );
11390
+ console.warn("You can set these in your .eliza/.env file.");
11391
+ } else {
11392
+ throw error;
11393
+ }
11331
11394
  }
11332
11395
  }
11396
+ if (plugin.adapter) {
11397
+ this.registerDatabaseAdapter(plugin.adapter);
11398
+ }
11333
11399
  if (plugin.actions) {
11334
11400
  for (const action of plugin.actions) {
11335
11401
  this.registerAction(action);
@@ -11346,10 +11412,10 @@ var AgentRuntime = class {
11346
11412
  }
11347
11413
  }
11348
11414
  if (plugin.models) {
11349
- for (const [modelType, handler3] of Object.entries(plugin.models)) {
11415
+ for (const [modelType, handler2] of Object.entries(plugin.models)) {
11350
11416
  this.registerModel(
11351
11417
  modelType,
11352
- handler3
11418
+ handler2
11353
11419
  );
11354
11420
  }
11355
11421
  }
@@ -11370,9 +11436,6 @@ var AgentRuntime = class {
11370
11436
  plugin.services.map((service) => this.registerService(service))
11371
11437
  );
11372
11438
  }
11373
- if (plugin.init) {
11374
- await plugin.init(plugin.config, this);
11375
- }
11376
11439
  }
11377
11440
  getAllServices() {
11378
11441
  return this.services;
@@ -11385,15 +11448,39 @@ var AgentRuntime = class {
11385
11448
  }
11386
11449
  }
11387
11450
  async initialize() {
11451
+ const registeredPluginNames = /* @__PURE__ */ new Set();
11452
+ const pluginRegistrationPromises = [];
11453
+ if (this.character.plugins) {
11454
+ const characterPlugins = await handlePluginImporting(
11455
+ this.character.plugins
11456
+ );
11457
+ for (const plugin of characterPlugins) {
11458
+ if (plugin && !registeredPluginNames.has(plugin.name)) {
11459
+ registeredPluginNames.add(plugin.name);
11460
+ pluginRegistrationPromises.push(this.registerPlugin(plugin));
11461
+ }
11462
+ }
11463
+ }
11464
+ for (const plugin of [...this.plugins]) {
11465
+ if (plugin && !registeredPluginNames.has(plugin.name)) {
11466
+ registeredPluginNames.add(plugin.name);
11467
+ pluginRegistrationPromises.push(this.registerPlugin(plugin));
11468
+ }
11469
+ }
11470
+ await this.adapter.init();
11388
11471
  try {
11389
- await this.getDatabaseAdapter().ensureAgentExists(
11472
+ const agentExists = await this.adapter.ensureAgentExists(
11390
11473
  this.character
11391
11474
  );
11392
- const agentEntity = await this.getDatabaseAdapter().getEntityById(
11475
+ const agent = await this.adapter.getAgent(this.agentId);
11476
+ if (!agent) {
11477
+ throw new Error(`Agent ${this.agentId} does not exist in database after ensureAgentExists call`);
11478
+ }
11479
+ const agentEntity = await this.adapter.getEntityById(
11393
11480
  this.agentId
11394
11481
  );
11395
11482
  if (!agentEntity) {
11396
- const created = await this.getDatabaseAdapter().createEntity({
11483
+ const created = await this.adapter.createEntity({
11397
11484
  id: this.agentId,
11398
11485
  agentId: this.agentId,
11399
11486
  names: Array.from(
@@ -11414,25 +11501,6 @@ var AgentRuntime = class {
11414
11501
  );
11415
11502
  throw error;
11416
11503
  }
11417
- const registeredPluginNames = /* @__PURE__ */ new Set();
11418
- const pluginRegistrationPromises = [];
11419
- if (this.character.plugins) {
11420
- const characterPlugins = await handlePluginImporting(
11421
- this.character.plugins
11422
- );
11423
- for (const plugin of characterPlugins) {
11424
- if (plugin && !registeredPluginNames.has(plugin.name)) {
11425
- registeredPluginNames.add(plugin.name);
11426
- pluginRegistrationPromises.push(this.registerPlugin(plugin));
11427
- }
11428
- }
11429
- }
11430
- for (const plugin of [...this.plugins]) {
11431
- if (plugin && !registeredPluginNames.has(plugin.name)) {
11432
- registeredPluginNames.add(plugin.name);
11433
- pluginRegistrationPromises.push(this.registerPlugin(plugin));
11434
- }
11435
- }
11436
11504
  try {
11437
11505
  await Promise.all([
11438
11506
  this.ensureRoomExists({
@@ -11450,9 +11518,9 @@ var AgentRuntime = class {
11450
11518
  throw error;
11451
11519
  }
11452
11520
  try {
11453
- const participants = await this.getDatabaseAdapter().getParticipantsForRoom(this.agentId);
11521
+ const participants = await this.adapter.getParticipantsForRoom(this.agentId);
11454
11522
  if (!participants.includes(this.agentId)) {
11455
- const added = await this.getDatabaseAdapter().addParticipant(
11523
+ const added = await this.adapter.addParticipant(
11456
11524
  this.agentId,
11457
11525
  this.agentId
11458
11526
  );
@@ -11510,10 +11578,9 @@ var AgentRuntime = class {
11510
11578
  logger.warn("Empty text for knowledge query");
11511
11579
  return [];
11512
11580
  }
11513
- const embedding = await this.useModel(
11514
- ModelTypes.TEXT_EMBEDDING,
11515
- message?.content?.text
11516
- );
11581
+ const embedding = await this.useModel(ModelTypes.TEXT_EMBEDDING, {
11582
+ text: message?.content?.text
11583
+ });
11517
11584
  const fragments = await this.getMemoryManager("knowledge").searchMemories({
11518
11585
  embedding,
11519
11586
  roomId: message.agentId,
@@ -11626,13 +11693,13 @@ var AgentRuntime = class {
11626
11693
  return this.#conversationLength;
11627
11694
  }
11628
11695
  registerDatabaseAdapter(adapter) {
11629
- this.adapters.push(adapter);
11630
- }
11631
- getDatabaseAdapters() {
11632
- return this.adapters;
11633
- }
11634
- getDatabaseAdapter() {
11635
- return this.adapters[0];
11696
+ if (this.adapter) {
11697
+ logger.warn(
11698
+ "Database adapter already registered. Additional adapters will be ignored. This may lead to unexpected behavior."
11699
+ );
11700
+ } else {
11701
+ this.adapter = adapter;
11702
+ }
11636
11703
  }
11637
11704
  /**
11638
11705
  * Register a provider for the agent to use.
@@ -11649,7 +11716,13 @@ var AgentRuntime = class {
11649
11716
  logger.success(
11650
11717
  `${this.character.name}(${this.agentId}) - Registering action: ${action.name}`
11651
11718
  );
11652
- this.actions.push(action);
11719
+ if (this.actions.find((a) => a.name === action.name)) {
11720
+ logger.warn(
11721
+ `${this.character.name}(${this.agentId}) - Action ${action.name} already exists. Skipping registration.`
11722
+ );
11723
+ } else {
11724
+ this.actions.push(action);
11725
+ }
11653
11726
  }
11654
11727
  /**
11655
11728
  * Register an evaluator to assess and guide the agent's responses.
@@ -11722,11 +11795,11 @@ var AgentRuntime = class {
11722
11795
  logger.error(`Action ${action.name} has no handler.`);
11723
11796
  continue;
11724
11797
  }
11725
- logger.success(`Executing handler for action: ${action.name}`);
11726
11798
  try {
11727
11799
  logger.info(`Executing handler for action: ${action.name}`);
11728
11800
  await action.handler(this, message, state, {}, callback, responses);
11729
- await this.getDatabaseAdapter().log({
11801
+ logger.success(`Action ${action.name} executed successfully.`);
11802
+ this.adapter.log({
11730
11803
  entityId: message.entityId,
11731
11804
  roomId: message.roomId,
11732
11805
  type: "action",
@@ -11787,7 +11860,7 @@ var AgentRuntime = class {
11787
11860
  callback,
11788
11861
  responses
11789
11862
  );
11790
- await this.getDatabaseAdapter().log({
11863
+ this.adapter.log({
11791
11864
  entityId: message.entityId,
11792
11865
  roomId: message.roomId,
11793
11866
  type: "evaluator",
@@ -11804,13 +11877,13 @@ var AgentRuntime = class {
11804
11877
  return evaluators;
11805
11878
  }
11806
11879
  async ensureParticipantInRoom(entityId, roomId) {
11807
- const entity = await this.getDatabaseAdapter().getEntityById(entityId);
11880
+ const entity = await this.adapter.getEntityById(entityId);
11808
11881
  if (!entity) {
11809
11882
  throw new Error(`User ${entityId} not found`);
11810
11883
  }
11811
- const participants = await this.getDatabaseAdapter().getParticipantsForRoom(roomId);
11884
+ const participants = await this.adapter.getParticipantsForRoom(roomId);
11812
11885
  if (!participants.includes(entityId)) {
11813
- const added = await this.getDatabaseAdapter().addParticipant(
11886
+ const added = await this.adapter.addParticipant(
11814
11887
  entityId,
11815
11888
  roomId
11816
11889
  );
@@ -11832,7 +11905,7 @@ var AgentRuntime = class {
11832
11905
  entityId,
11833
11906
  roomId,
11834
11907
  userName,
11835
- name: name2,
11908
+ name,
11836
11909
  source,
11837
11910
  type,
11838
11911
  channelId,
@@ -11845,16 +11918,16 @@ var AgentRuntime = class {
11845
11918
  if (!worldId && serverId) {
11846
11919
  worldId = createUniqueUuid(this, serverId);
11847
11920
  }
11848
- const names4 = [name2, userName];
11921
+ const names4 = [name, userName];
11849
11922
  const metadata = {
11850
11923
  [source]: {
11851
- name: name2,
11924
+ name,
11852
11925
  userName
11853
11926
  }
11854
11927
  };
11855
- const entity = await this.getDatabaseAdapter().getEntityById(entityId);
11928
+ const entity = await this.adapter.getEntityById(entityId);
11856
11929
  if (!entity) {
11857
- await this.getDatabaseAdapter().createEntity({
11930
+ await this.adapter.createEntity({
11858
11931
  id: entityId,
11859
11932
  names: names4,
11860
11933
  metadata,
@@ -11891,19 +11964,19 @@ var AgentRuntime = class {
11891
11964
  /**
11892
11965
  * Ensure the existence of a world.
11893
11966
  */
11894
- async ensureWorldExists({ id, name: name2, serverId, metadata }) {
11967
+ async ensureWorldExists({ id, name, serverId, metadata }) {
11895
11968
  try {
11896
- const world = await this.getDatabaseAdapter().getWorld(id);
11969
+ const world = await this.adapter.getWorld(id);
11897
11970
  if (!world) {
11898
11971
  logger.info("Creating world:", {
11899
11972
  id,
11900
- name: name2,
11973
+ name,
11901
11974
  serverId,
11902
11975
  agentId: this.agentId
11903
11976
  });
11904
- await this.getDatabaseAdapter().createWorld({
11977
+ await this.adapter.createWorld({
11905
11978
  id,
11906
- name: name2,
11979
+ name,
11907
11980
  agentId: this.agentId,
11908
11981
  serverId: serverId || "default",
11909
11982
  metadata
@@ -11926,18 +11999,18 @@ var AgentRuntime = class {
11926
11999
  */
11927
12000
  async ensureRoomExists({
11928
12001
  id,
11929
- name: name2,
12002
+ name,
11930
12003
  source,
11931
12004
  type,
11932
12005
  channelId,
11933
12006
  serverId,
11934
12007
  worldId
11935
12008
  }) {
11936
- const room = await this.getDatabaseAdapter().getRoom(id);
12009
+ const room = await this.adapter.getRoom(id);
11937
12010
  if (!room) {
11938
- await this.getDatabaseAdapter().createRoom({
12011
+ await this.adapter.createRoom({
11939
12012
  id,
11940
- name: name2,
12013
+ name,
11941
12014
  agentId: this.agentId,
11942
12015
  source,
11943
12016
  type,
@@ -11964,14 +12037,14 @@ var AgentRuntime = class {
11964
12037
  const existingProviderNames = cachedState.data.providers ? Object.keys(cachedState.data.providers) : [];
11965
12038
  const providerNames = /* @__PURE__ */ new Set();
11966
12039
  if (filterList && filterList.length > 0) {
11967
- filterList.forEach((name2) => providerNames.add(name2));
12040
+ filterList.forEach((name) => providerNames.add(name));
11968
12041
  } else {
11969
12042
  this.providers.filter(
11970
12043
  (p) => !p.private && !p.dynamic && !existingProviderNames.includes(p.name)
11971
12044
  ).forEach((p) => providerNames.add(p.name));
11972
12045
  }
11973
12046
  if (includeList && includeList.length > 0) {
11974
- includeList.forEach((name2) => providerNames.add(name2));
12047
+ includeList.forEach((name) => providerNames.add(name));
11975
12048
  }
11976
12049
  const providersToGet = Array.from(
11977
12050
  new Set(this.providers.filter((p) => providerNames.has(p.name)))
@@ -12035,7 +12108,7 @@ ${newProvidersText}`;
12035
12108
  getService(service) {
12036
12109
  const serviceInstance = this.services.get(service);
12037
12110
  if (!serviceInstance) {
12038
- logger.error(`Service ${service} not found`);
12111
+ logger.warn(`Service ${service} not found`);
12039
12112
  return null;
12040
12113
  }
12041
12114
  return serviceInstance;
@@ -12061,12 +12134,12 @@ ${newProvidersText}`;
12061
12134
  `${this.character.name}(${this.agentId}) - Service ${serviceType} registered successfully`
12062
12135
  );
12063
12136
  }
12064
- registerModel(modelType, handler3) {
12137
+ registerModel(modelType, handler2) {
12065
12138
  const modelKey = typeof modelType === "string" ? modelType : ModelTypes[modelType];
12066
12139
  if (!this.models.has(modelKey)) {
12067
12140
  this.models.set(modelKey, []);
12068
12141
  }
12069
- this.models.get(modelKey)?.push(handler3);
12142
+ this.models.get(modelKey)?.push(handler2);
12070
12143
  }
12071
12144
  getModel(modelType) {
12072
12145
  const modelKey = typeof modelType === "string" ? modelType : ModelTypes[modelType];
@@ -12076,43 +12149,71 @@ ${newProvidersText}`;
12076
12149
  }
12077
12150
  return models[0];
12078
12151
  }
12152
+ /**
12153
+ * Use a model with strongly typed parameters and return values based on model type
12154
+ * @template T - The model type to use
12155
+ * @template R - The expected return type, defaults to the type defined in ModelResultMap[T]
12156
+ * @param {T} modelType - The type of model to use
12157
+ * @param {ModelParamsMap[T] | any} params - The parameters for the model, typed based on model type
12158
+ * @returns {Promise<R>} - The model result, typed based on the provided generic type parameter
12159
+ */
12079
12160
  async useModel(modelType, params) {
12080
12161
  const modelKey = typeof modelType === "string" ? modelType : ModelTypes[modelType];
12081
12162
  const model = this.getModel(modelKey);
12082
12163
  if (!model) {
12083
12164
  throw new Error(`No handler found for delegate type: ${modelKey}`);
12084
12165
  }
12085
- const response = await model(this, params);
12086
- await this.getDatabaseAdapter().log({
12166
+ logger.debug(
12167
+ `[useModel] ${modelKey} input:`,
12168
+ JSON.stringify(params, null, 2)
12169
+ );
12170
+ let paramsWithRuntime;
12171
+ if (params === null || params === void 0 || typeof params !== "object" || Array.isArray(params)) {
12172
+ paramsWithRuntime = params;
12173
+ } else {
12174
+ paramsWithRuntime = {
12175
+ ...params,
12176
+ runtime: this
12177
+ };
12178
+ }
12179
+ const startTime = performance.now();
12180
+ const response = await model(this, paramsWithRuntime);
12181
+ const elapsedTime = performance.now() - startTime;
12182
+ logger.info(
12183
+ `[useModel] ${modelKey} completed in ${elapsedTime.toFixed(2)}ms`
12184
+ );
12185
+ logger.debug(
12186
+ `[useModel] ${modelKey} output:`,
12187
+ JSON.stringify(response, null, 2)
12188
+ );
12189
+ this.adapter.log({
12087
12190
  entityId: this.agentId,
12088
12191
  roomId: this.agentId,
12089
12192
  body: {
12090
12193
  modelType,
12091
12194
  modelKey,
12092
- params: params ? Object.keys(params) : [],
12195
+ params: params ? typeof params === "object" ? Object.keys(params) : typeof params : null,
12093
12196
  response: Array.isArray(response) && response.every((x) => typeof x === "number") ? "[array]" : response
12094
12197
  },
12095
- type: `useModel:${modelType}`
12198
+ type: `useModel:${modelKey}`
12096
12199
  });
12097
12200
  return response;
12098
12201
  }
12099
- registerEvent(event, handler3) {
12202
+ registerEvent(event, handler2) {
12100
12203
  if (!this.events.has(event)) {
12101
12204
  this.events.set(event, []);
12102
12205
  }
12103
- this.events.get(event)?.push(handler3);
12206
+ this.events.get(event)?.push(handler2);
12104
12207
  }
12105
12208
  getEvent(event) {
12106
12209
  return this.events.get(event);
12107
12210
  }
12108
- emitEvent(event, params) {
12211
+ async emitEvent(event, params) {
12109
12212
  const events2 = Array.isArray(event) ? event : [event];
12110
12213
  for (const eventName of events2) {
12111
12214
  const eventHandlers = this.events.get(eventName);
12112
12215
  if (eventHandlers) {
12113
- for (const handler3 of eventHandlers) {
12114
- handler3(params);
12115
- }
12216
+ await Promise.all(eventHandlers.map((handler2) => handler2(params)));
12116
12217
  }
12117
12218
  }
12118
12219
  }
@@ -12120,7 +12221,7 @@ ${newProvidersText}`;
12120
12221
  logger.debug(
12121
12222
  `[AgentRuntime][${this.character.name}] Starting ensureEmbeddingDimension`
12122
12223
  );
12123
- if (!this.getDatabaseAdapter()) {
12224
+ if (!this.adapter) {
12124
12225
  throw new Error(
12125
12226
  `[AgentRuntime][${this.character.name}] Database adapter not initialized before ensureEmbeddingDimension`
12126
12227
  );
@@ -12144,7 +12245,7 @@ ${newProvidersText}`;
12144
12245
  logger.debug(
12145
12246
  `[AgentRuntime][${this.character.name}] Setting embedding dimension: ${embedding.length}`
12146
12247
  );
12147
- await this.getDatabaseAdapter().ensureEmbeddingDimension(
12248
+ await this.adapter.ensureEmbeddingDimension(
12148
12249
  embedding.length
12149
12250
  );
12150
12251
  logger.debug(
@@ -12166,8 +12267,230 @@ ${newProvidersText}`;
12166
12267
  }
12167
12268
  this.taskWorkers.set(taskHandler.name, taskHandler);
12168
12269
  }
12169
- getTaskWorker(name2) {
12170
- return this.taskWorkers.get(name2);
12270
+ /**
12271
+ * Get a task worker by name
12272
+ */
12273
+ getTaskWorker(name) {
12274
+ return this.taskWorkers.get(name);
12275
+ }
12276
+ // Implement database adapter methods
12277
+ get db() {
12278
+ return this.adapter.db;
12279
+ }
12280
+ async init() {
12281
+ await this.adapter.init();
12282
+ }
12283
+ async close() {
12284
+ await this.adapter.close();
12285
+ }
12286
+ async getAgent(agentId) {
12287
+ return await this.adapter.getAgent(agentId);
12288
+ }
12289
+ async getAgents() {
12290
+ return await this.adapter.getAgents();
12291
+ }
12292
+ async createAgent(agent) {
12293
+ return await this.adapter.createAgent(agent);
12294
+ }
12295
+ async updateAgent(agentId, agent) {
12296
+ return await this.adapter.updateAgent(agentId, agent);
12297
+ }
12298
+ async deleteAgent(agentId) {
12299
+ return await this.adapter.deleteAgent(agentId);
12300
+ }
12301
+ async ensureAgentExists(agent) {
12302
+ await this.adapter.ensureAgentExists(agent);
12303
+ }
12304
+ async getEntityById(entityId) {
12305
+ return await this.adapter.getEntityById(entityId);
12306
+ }
12307
+ async getEntitiesForRoom(roomId, includeComponents) {
12308
+ return await this.adapter.getEntitiesForRoom(roomId, includeComponents);
12309
+ }
12310
+ async createEntity(entity) {
12311
+ return await this.adapter.createEntity(entity);
12312
+ }
12313
+ async updateEntity(entity) {
12314
+ await this.adapter.updateEntity(entity);
12315
+ }
12316
+ async getComponent(entityId, type, worldId, sourceEntityId) {
12317
+ return await this.adapter.getComponent(entityId, type, worldId, sourceEntityId);
12318
+ }
12319
+ async getComponents(entityId, worldId, sourceEntityId) {
12320
+ return await this.adapter.getComponents(entityId, worldId, sourceEntityId);
12321
+ }
12322
+ async createComponent(component) {
12323
+ return await this.adapter.createComponent(component);
12324
+ }
12325
+ async updateComponent(component) {
12326
+ await this.adapter.updateComponent(component);
12327
+ }
12328
+ async deleteComponent(componentId) {
12329
+ await this.adapter.deleteComponent(componentId);
12330
+ }
12331
+ async getMemories(params) {
12332
+ return await this.adapter.getMemories(params);
12333
+ }
12334
+ async getMemoryById(id) {
12335
+ return await this.adapter.getMemoryById(id);
12336
+ }
12337
+ async getMemoriesByIds(ids, tableName) {
12338
+ return await this.adapter.getMemoriesByIds(ids, tableName);
12339
+ }
12340
+ async getMemoriesByRoomIds(params) {
12341
+ return await this.adapter.getMemoriesByRoomIds(params);
12342
+ }
12343
+ async getCachedEmbeddings(params) {
12344
+ return await this.adapter.getCachedEmbeddings(params);
12345
+ }
12346
+ async log(params) {
12347
+ await this.adapter.log(params);
12348
+ }
12349
+ async searchMemories(params) {
12350
+ return await this.adapter.searchMemories(params);
12351
+ }
12352
+ async createMemory(memory, tableName, unique) {
12353
+ return await this.adapter.createMemory(memory, tableName, unique);
12354
+ }
12355
+ async removeMemory(memoryId, tableName) {
12356
+ await this.adapter.removeMemory(memoryId, tableName);
12357
+ }
12358
+ async removeAllMemories(roomId, tableName) {
12359
+ await this.adapter.removeAllMemories(roomId, tableName);
12360
+ }
12361
+ async countMemories(roomId, unique, tableName) {
12362
+ return await this.adapter.countMemories(roomId, unique, tableName);
12363
+ }
12364
+ async createWorld(world) {
12365
+ return await this.adapter.createWorld(world);
12366
+ }
12367
+ async getWorld(id) {
12368
+ return await this.adapter.getWorld(id);
12369
+ }
12370
+ async getAllWorlds() {
12371
+ return await this.adapter.getAllWorlds();
12372
+ }
12373
+ async updateWorld(world) {
12374
+ await this.adapter.updateWorld(world);
12375
+ }
12376
+ async getRoom(roomId) {
12377
+ return await this.adapter.getRoom(roomId);
12378
+ }
12379
+ async createRoom({
12380
+ id,
12381
+ name,
12382
+ source,
12383
+ type,
12384
+ channelId,
12385
+ serverId,
12386
+ worldId
12387
+ }) {
12388
+ return await this.adapter.createRoom({
12389
+ id,
12390
+ name,
12391
+ source,
12392
+ type,
12393
+ channelId,
12394
+ serverId,
12395
+ worldId
12396
+ });
12397
+ }
12398
+ async deleteRoom(roomId) {
12399
+ await this.adapter.deleteRoom(roomId);
12400
+ }
12401
+ async updateRoom(room) {
12402
+ await this.adapter.updateRoom(room);
12403
+ }
12404
+ async getRoomsForParticipant(entityId) {
12405
+ return await this.adapter.getRoomsForParticipant(entityId);
12406
+ }
12407
+ async getRoomsForParticipants(userIds) {
12408
+ return await this.adapter.getRoomsForParticipants(userIds);
12409
+ }
12410
+ async getRooms(worldId) {
12411
+ return await this.adapter.getRooms(worldId);
12412
+ }
12413
+ async addParticipant(entityId, roomId) {
12414
+ return await this.adapter.addParticipant(entityId, roomId);
12415
+ }
12416
+ async removeParticipant(entityId, roomId) {
12417
+ return await this.adapter.removeParticipant(entityId, roomId);
12418
+ }
12419
+ async getParticipantsForEntity(entityId) {
12420
+ return await this.adapter.getParticipantsForEntity(entityId);
12421
+ }
12422
+ async getParticipantsForRoom(roomId) {
12423
+ return await this.adapter.getParticipantsForRoom(roomId);
12424
+ }
12425
+ async getParticipantUserState(roomId, entityId) {
12426
+ return await this.adapter.getParticipantUserState(roomId, entityId);
12427
+ }
12428
+ async setParticipantUserState(roomId, entityId, state) {
12429
+ await this.adapter.setParticipantUserState(roomId, entityId, state);
12430
+ }
12431
+ async createRelationship(params) {
12432
+ return await this.adapter.createRelationship(params);
12433
+ }
12434
+ async updateRelationship(relationship) {
12435
+ await this.adapter.updateRelationship(relationship);
12436
+ }
12437
+ async getRelationship(params) {
12438
+ return await this.adapter.getRelationship(params);
12439
+ }
12440
+ async getRelationships(params) {
12441
+ return await this.adapter.getRelationships(params);
12442
+ }
12443
+ async getCache(key) {
12444
+ return await this.adapter.getCache(key);
12445
+ }
12446
+ async setCache(key, value) {
12447
+ return await this.adapter.setCache(key, value);
12448
+ }
12449
+ async deleteCache(key) {
12450
+ return await this.adapter.deleteCache(key);
12451
+ }
12452
+ async createTask(task) {
12453
+ return await this.adapter.createTask(task);
12454
+ }
12455
+ async getTasks(params) {
12456
+ return await this.adapter.getTasks(params);
12457
+ }
12458
+ async getTask(id) {
12459
+ return await this.adapter.getTask(id);
12460
+ }
12461
+ async getTasksByName(name) {
12462
+ return await this.adapter.getTasksByName(name);
12463
+ }
12464
+ async updateTask(id, task) {
12465
+ await this.adapter.updateTask(id, task);
12466
+ }
12467
+ async deleteTask(id) {
12468
+ await this.adapter.deleteTask(id);
12469
+ }
12470
+ // Event emitter methods
12471
+ on(event, callback) {
12472
+ if (!this.eventHandlers.has(event)) {
12473
+ this.eventHandlers.set(event, []);
12474
+ }
12475
+ this.eventHandlers.get(event).push(callback);
12476
+ }
12477
+ off(event, callback) {
12478
+ if (!this.eventHandlers.has(event)) {
12479
+ return;
12480
+ }
12481
+ const handlers = this.eventHandlers.get(event);
12482
+ const index = handlers.indexOf(callback);
12483
+ if (index !== -1) {
12484
+ handlers.splice(index, 1);
12485
+ }
12486
+ }
12487
+ emit(event, data) {
12488
+ if (!this.eventHandlers.has(event)) {
12489
+ return;
12490
+ }
12491
+ for (const handler2 of this.eventHandlers.get(event)) {
12492
+ handler2(data);
12493
+ }
12171
12494
  }
12172
12495
  };
12173
12496
  export {
@@ -12176,12 +12499,13 @@ export {
12176
12499
  ChannelType,
12177
12500
  CharacterSchema,
12178
12501
  DatabaseAdapter,
12179
- GoalStatus,
12502
+ EventTypes,
12180
12503
  KnowledgeScope,
12181
12504
  MemoryManager,
12182
12505
  MemoryType,
12183
12506
  MessageExampleSchema,
12184
12507
  ModelTypes,
12508
+ PlatformPrefix,
12185
12509
  PluginSchema,
12186
12510
  Role,
12187
12511
  Service,
@@ -12194,6 +12518,7 @@ export {
12194
12518
  cleanJsonResponse,
12195
12519
  composeActionExamples,
12196
12520
  composePrompt,
12521
+ composePromptFromState,
12197
12522
  composeRandomUser,
12198
12523
  configureSettings,
12199
12524
  createUniqueUuid,