@elizaos/plugin-bootstrap 1.0.0-beta.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -72,17 +72,19 @@ var require_dedent = __commonJS({
72
72
  // src/index.ts
73
73
  import {
74
74
  asUUID,
75
- ChannelType as ChannelType9,
75
+ ChannelType as ChannelType10,
76
76
  composePromptFromState as composePromptFromState9,
77
77
  createUniqueUuid as createUniqueUuid4,
78
78
  EventType as EventType2,
79
- logger as logger16,
79
+ logger as logger19,
80
80
  messageHandlerTemplate,
81
81
  ModelType as ModelType13,
82
- parseJSONObjectFromText as parseJSONObjectFromText4,
83
82
  postCreationTemplate,
84
83
  shouldRespondTemplate,
85
- truncateToCompleteSentence
84
+ truncateToCompleteSentence,
85
+ parseKeyValueXml,
86
+ imageDescriptionTemplate,
87
+ ContentType
86
88
  } from "@elizaos/core";
87
89
 
88
90
  // ../../node_modules/uuid/dist/esm/stringify.js
@@ -174,6 +176,10 @@ var choiceAction = {
174
176
  similes: ["SELECT_OPTION", "SELECT", "PICK", "CHOOSE"],
175
177
  description: "Selects an option for a pending task that has multiple options",
176
178
  validate: async (runtime, message, state) => {
179
+ if (!state) {
180
+ logger.error("State is required for validating the action");
181
+ throw new Error("State is required for validating the action");
182
+ }
177
183
  const pendingTasks = await runtime.getTasks({
178
184
  roomId: message.roomId,
179
185
  tags: ["AWAITING_CHOICE"]
@@ -186,121 +192,120 @@ var choiceAction = {
186
192
  return pendingTasks && pendingTasks.length > 0 && pendingTasks.some((task) => task.metadata?.options);
187
193
  },
188
194
  handler: async (runtime, message, state, _options, callback, responses) => {
189
- try {
190
- const pendingTasks = await runtime.getTasks({
191
- roomId: message.roomId,
192
- tags: ["AWAITING_CHOICE"]
193
- });
194
- if (!pendingTasks?.length) {
195
- throw new Error("No pending tasks with options found");
195
+ const pendingTasks = await runtime.getTasks({
196
+ roomId: message.roomId,
197
+ tags: ["AWAITING_CHOICE"]
198
+ });
199
+ if (!pendingTasks?.length) {
200
+ throw new Error("No pending tasks with options found");
201
+ }
202
+ const tasksWithOptions = pendingTasks.filter((task) => task.metadata?.options);
203
+ if (!tasksWithOptions.length) {
204
+ throw new Error("No tasks currently have options to select from.");
205
+ }
206
+ const formattedTasks = tasksWithOptions.map((task) => {
207
+ const shortId = task.id?.substring(0, 8);
208
+ return {
209
+ taskId: shortId,
210
+ fullId: task.id,
211
+ name: task.name,
212
+ options: task.metadata?.options?.map((opt) => ({
213
+ name: typeof opt === "string" ? opt : opt.name,
214
+ description: typeof opt === "string" ? opt : opt.description || opt.name
215
+ }))
216
+ };
217
+ });
218
+ const tasksString = formattedTasks.map((task) => {
219
+ return `Task ID: ${task.taskId} - ${task.name}
220
+ Available options:
221
+ ${task.options?.map((opt) => `- ${opt.name}: ${opt.description}`).join("\n")}`;
222
+ }).join("\n");
223
+ const prompt = composePrompt({
224
+ state: {
225
+ tasks: tasksString,
226
+ recentMessages: message.content.text || ""
227
+ },
228
+ template: optionExtractionTemplate
229
+ });
230
+ const result = await runtime.useModel(ModelType.TEXT_SMALL, {
231
+ prompt,
232
+ stopSequences: []
233
+ });
234
+ const parsed = parseJSONObjectFromText(result);
235
+ const { taskId, selectedOption } = parsed;
236
+ if (taskId && selectedOption) {
237
+ const taskMap = new Map(formattedTasks.map((task) => [task.taskId, task]));
238
+ const taskInfo = taskMap.get(taskId);
239
+ if (!taskInfo) {
240
+ await callback?.({
241
+ text: `Could not find a task matching ID: ${taskId}. Please try again.`,
242
+ actions: ["SELECT_OPTION_ERROR"],
243
+ source: message.content.source
244
+ });
245
+ return;
196
246
  }
197
- const tasksWithOptions = pendingTasks.filter((task) => task.metadata?.options);
198
- if (!tasksWithOptions.length) {
199
- throw new Error("No tasks currently have options to select from.");
247
+ const selectedTask = tasksWithOptions.find((task) => task.id === taskInfo.fullId);
248
+ if (!selectedTask) {
249
+ await callback?.({
250
+ text: "Error locating the selected task. Please try again.",
251
+ actions: ["SELECT_OPTION_ERROR"],
252
+ source: message.content.source
253
+ });
254
+ return;
200
255
  }
201
- const formattedTasks = tasksWithOptions.map((task) => {
202
- const shortId = task.id.substring(0, 8);
203
- return {
204
- taskId: shortId,
205
- fullId: task.id,
206
- name: task.name,
207
- options: task.metadata.options.map((opt) => ({
208
- name: typeof opt === "string" ? opt : opt.name,
209
- description: typeof opt === "string" ? opt : opt.description || opt.name
210
- }))
211
- };
212
- });
213
- const tasksString = formattedTasks.map((task) => {
214
- return `Task ID: ${task.taskId} - ${task.name}
215
- Available options:
216
- ${task.options.map((opt) => `- ${opt.name}: ${opt.description}`).join("\n")}`;
217
- }).join("\n");
218
- const prompt = composePrompt({
219
- state: {
220
- tasks: tasksString,
221
- recentMessages: message.content.text
222
- },
223
- template: optionExtractionTemplate
224
- });
225
- const result = await runtime.useModel(ModelType.TEXT_SMALL, {
226
- prompt,
227
- stopSequences: []
228
- });
229
- const parsed = parseJSONObjectFromText(result);
230
- const { taskId, selectedOption } = parsed;
231
- if (taskId && selectedOption) {
232
- const taskMap = new Map(formattedTasks.map((task) => [task.taskId, task]));
233
- const taskInfo = taskMap.get(taskId);
234
- if (!taskInfo) {
235
- await callback({
236
- text: `Could not find a task matching ID: ${taskId}. Please try again.`,
237
- actions: ["SELECT_OPTION_ERROR"],
238
- source: message.content.source
239
- });
240
- return;
241
- }
242
- const selectedTask = tasksWithOptions.find((task) => task.id === taskInfo.fullId);
243
- if (!selectedTask) {
244
- await callback({
256
+ if (selectedOption === "ABORT") {
257
+ if (!selectedTask?.id) {
258
+ await callback?.({
245
259
  text: "Error locating the selected task. Please try again.",
246
260
  actions: ["SELECT_OPTION_ERROR"],
247
261
  source: message.content.source
248
262
  });
249
263
  return;
250
264
  }
251
- if (selectedOption === "ABORT") {
252
- await runtime.deleteTask(selectedTask.id);
253
- await callback({
254
- text: `Task "${selectedTask.name}" has been cancelled.`,
255
- actions: ["CHOOSE_OPTION_CANCELLED"],
256
- source: message.content.source
257
- });
258
- return;
259
- }
260
- try {
261
- const taskWorker = runtime.getTaskWorker(selectedTask.name);
262
- await taskWorker.execute(runtime, { option: selectedOption }, selectedTask);
263
- await callback({
264
- text: `Selected option: ${selectedOption} for task: ${selectedTask.name}`,
265
- actions: ["CHOOSE_OPTION"],
266
- source: message.content.source
267
- });
268
- return;
269
- } catch (error) {
270
- logger.error("Error executing task with option:", error);
271
- await callback({
272
- text: "There was an error processing your selection.",
273
- actions: ["SELECT_OPTION_ERROR"],
274
- source: message.content.source
275
- });
276
- return;
277
- }
265
+ await runtime.deleteTask(selectedTask.id);
266
+ await callback?.({
267
+ text: `Task "${selectedTask.name}" has been cancelled.`,
268
+ actions: ["CHOOSE_OPTION_CANCELLED"],
269
+ source: message.content.source
270
+ });
271
+ return;
272
+ }
273
+ try {
274
+ const taskWorker = runtime.getTaskWorker(selectedTask.name);
275
+ await taskWorker?.execute(runtime, { option: selectedOption }, selectedTask);
276
+ await callback?.({
277
+ text: `Selected option: ${selectedOption} for task: ${selectedTask.name}`,
278
+ actions: ["CHOOSE_OPTION"],
279
+ source: message.content.source
280
+ });
281
+ return;
282
+ } catch (error) {
283
+ logger.error("Error executing task with option:", error);
284
+ await callback?.({
285
+ text: "There was an error processing your selection.",
286
+ actions: ["SELECT_OPTION_ERROR"],
287
+ source: message.content.source
288
+ });
289
+ return;
278
290
  }
279
- let optionsText = "Please select a valid option from one of these tasks:\n\n";
280
- tasksWithOptions.forEach((task) => {
281
- const shortId = task.id.substring(0, 8);
282
- optionsText += `**${task.name}** (ID: ${shortId}):
283
- `;
284
- const options = task.metadata.options.map(
285
- (opt) => typeof opt === "string" ? opt : opt.name
286
- );
287
- options.push("ABORT");
288
- optionsText += options.map((opt) => `- ${opt}`).join("\n");
289
- optionsText += "\n\n";
290
- });
291
- await callback({
292
- text: optionsText,
293
- actions: ["SELECT_OPTION_INVALID"],
294
- source: message.content.source
295
- });
296
- } catch (error) {
297
- logger.error("Error in select option handler:", error);
298
- await callback({
299
- text: "There was an error processing the option selection.",
300
- actions: ["SELECT_OPTION_ERROR"],
301
- source: message.content.source
302
- });
303
291
  }
292
+ let optionsText = "Please select a valid option from one of these tasks:\n\n";
293
+ tasksWithOptions.forEach((task) => {
294
+ const shortId = task.id?.substring(0, 8);
295
+ optionsText += `**${task.name}** (ID: ${shortId}):
296
+ `;
297
+ const options = task.metadata?.options?.map(
298
+ (opt) => typeof opt === "string" ? opt : opt.name
299
+ );
300
+ options?.push("ABORT");
301
+ optionsText += options?.map((opt) => `- ${opt}`).join("\n");
302
+ optionsText += "\n\n";
303
+ });
304
+ await callback?.({
305
+ text: optionsText,
306
+ actions: ["SELECT_OPTION_INVALID"],
307
+ source: message.content.source
308
+ });
304
309
  },
305
310
  examples: [
306
311
  [
@@ -369,6 +374,10 @@ var followRoomAction = {
369
374
  return roomState !== "FOLLOWED" && roomState !== "MUTED";
370
375
  },
371
376
  handler: async (runtime, message, state, _options, _callback, _responses) => {
377
+ if (!state) {
378
+ logger2.error("State is required for followRoomAction");
379
+ throw new Error("State is required for followRoomAction");
380
+ }
372
381
  async function _shouldFollow(state2) {
373
382
  const shouldFollowPrompt = composePromptFromState({
374
383
  state: state2,
@@ -722,7 +731,10 @@ var ignoreAction = {
722
731
  return true;
723
732
  },
724
733
  description: "Call this action if ignoring the user. If the user is aggressive, creepy or is finished with the conversation, use this action. Or, if both you and the user have already said goodbye, use this action instead of saying bye again. Use IGNORE any time the conversation has naturally ended. Do not use IGNORE if the user has engaged directly, or if something went wrong an you need to tell them. Only ignore if the user should be ignored.",
725
- handler: async (_runtime, _message) => {
734
+ handler: async (_runtime, _message, _state, _options, callback, responses) => {
735
+ if (callback && responses?.[0]?.content) {
736
+ await callback(responses[0].content);
737
+ }
726
738
  return true;
727
739
  },
728
740
  examples: [
@@ -962,6 +974,10 @@ var muteRoomAction = {
962
974
  return roomState !== "MUTED";
963
975
  },
964
976
  handler: async (runtime, message, state, _options, _callback, _responses) => {
977
+ if (!state) {
978
+ logger3.error("State is required for muting a room");
979
+ throw new Error("State is required for muting a room");
980
+ }
965
981
  async function _shouldMute(state2) {
966
982
  const shouldMutePrompt = composePromptFromState2({
967
983
  state: state2,
@@ -1278,15 +1294,12 @@ import {
1278
1294
  composePromptFromState as composePromptFromState3,
1279
1295
  ModelType as ModelType4
1280
1296
  } from "@elizaos/core";
1281
- var replyTemplate = `# Task: Generate dialog and actions for the character {{agentName}}.
1297
+ var replyTemplate = `# Task: Generate dialog for the character {{agentName}}.
1282
1298
  {{providers}}
1283
1299
  # Instructions: Write the next message for {{agentName}}.
1284
- First, think about what you want to do next and plan your actions. Then, write the next message and include the actions you plan to take.
1285
1300
  "thought" should be a short description of what the agent is thinking about and planning.
1286
1301
  "message" should be the next message for {{agentName}} which they will send to the conversation.
1287
1302
 
1288
- These are the available valid actions: {{actionNames}}
1289
-
1290
1303
  Response format should be formatted in a valid JSON block like this:
1291
1304
  \`\`\`json
1292
1305
  {
@@ -1296,6 +1309,25 @@ Response format should be formatted in a valid JSON block like this:
1296
1309
  \`\`\`
1297
1310
 
1298
1311
  Your response should include the valid JSON block and nothing else.`;
1312
+ function getFirstAvailableField(obj, fields) {
1313
+ for (const field of fields) {
1314
+ if (typeof obj[field] === "string" && obj[field].trim() !== "") {
1315
+ return obj[field];
1316
+ }
1317
+ }
1318
+ return null;
1319
+ }
1320
+ function extractReplyContent(response, replyFieldKeys) {
1321
+ const hasReplyAction = response.content.actions?.includes("REPLY");
1322
+ const text = getFirstAvailableField(response.content, replyFieldKeys);
1323
+ if (!hasReplyAction || !text) return null;
1324
+ return {
1325
+ ...response.content,
1326
+ thought: response.content.thought,
1327
+ text,
1328
+ actions: ["REPLY"]
1329
+ };
1330
+ }
1299
1331
  var replyAction = {
1300
1332
  name: "REPLY",
1301
1333
  similes: ["GREET", "REPLY_TO_MESSAGE", "SEND_REPLY", "RESPOND", "RESPONSE"],
@@ -1303,11 +1335,17 @@ var replyAction = {
1303
1335
  validate: async (_runtime) => {
1304
1336
  return true;
1305
1337
  },
1306
- handler: async (runtime, message, state, _options, callback) => {
1307
- state = await runtime.composeState(message, [
1308
- ...message.content.providers ?? [],
1309
- "RECENT_MESSAGES"
1310
- ]);
1338
+ handler: async (runtime, message, state, _options, callback, responses) => {
1339
+ const replyFieldKeys = ["message", "text"];
1340
+ const existingReplies = responses?.map((r) => extractReplyContent(r, replyFieldKeys)).filter((reply) => reply !== null) ?? [];
1341
+ const allProviders = responses?.flatMap((res) => res.content?.providers ?? []) ?? [];
1342
+ if (existingReplies.length > 0 && allProviders.length === 0) {
1343
+ for (const reply of existingReplies) {
1344
+ await callback(reply);
1345
+ }
1346
+ return;
1347
+ }
1348
+ state = await runtime.composeState(message, [...allProviders ?? [], "RECENT_MESSAGES"]);
1311
1349
  const prompt = composePromptFromState3({
1312
1350
  state,
1313
1351
  template: replyTemplate
@@ -1424,17 +1462,20 @@ var updateRoleAction = {
1424
1462
  );
1425
1463
  },
1426
1464
  handler: async (runtime, message, state, _options, callback) => {
1465
+ if (!state) {
1466
+ logger4.error("State is required for role assignment");
1467
+ throw new Error("State is required for role assignment");
1468
+ }
1427
1469
  const { roomId } = message;
1428
- const channelType = message.content.channelType;
1429
1470
  const serverId = message.content.serverId;
1430
1471
  const worldId = runtime.getSetting("WORLD_ID");
1431
- let world;
1472
+ let world = null;
1432
1473
  if (worldId) {
1433
1474
  world = await runtime.getWorld(worldId);
1434
1475
  }
1435
1476
  if (!world) {
1436
1477
  logger4.error("World not found");
1437
- await callback({
1478
+ await callback?.({
1438
1479
  text: "I couldn't find the world. This action only works in a world."
1439
1480
  });
1440
1481
  return;
@@ -1504,7 +1545,7 @@ var updateRoleAction = {
1504
1545
  }
1505
1546
  );
1506
1547
  if (!result?.length) {
1507
- await callback({
1548
+ await callback?.({
1508
1549
  text: "No valid role assignments found in the request.",
1509
1550
  actions: ["UPDATE_ROLE"],
1510
1551
  source: "discord"
@@ -1519,8 +1560,8 @@ var updateRoleAction = {
1519
1560
  }
1520
1561
  const currentRole = world.metadata.roles[assignment.entityId];
1521
1562
  if (!canModifyRole(requesterRole, currentRole, assignment.newRole)) {
1522
- await callback({
1523
- text: `You don't have permission to change ${targetEntity.names[0]}'s role to ${assignment.newRole}.`,
1563
+ await callback?.({
1564
+ text: `You don't have permission to change ${targetEntity?.names[0]}'s role to ${assignment.newRole}.`,
1524
1565
  actions: ["UPDATE_ROLE"],
1525
1566
  source: "discord"
1526
1567
  });
@@ -1528,8 +1569,8 @@ var updateRoleAction = {
1528
1569
  }
1529
1570
  world.metadata.roles[assignment.entityId] = assignment.newRole;
1530
1571
  worldUpdated = true;
1531
- await callback({
1532
- text: `Updated ${targetEntity.names[0]}'s role to ${assignment.newRole}.`,
1572
+ await callback?.({
1573
+ text: `Updated ${targetEntity?.names[0]}'s role to ${assignment.newRole}.`,
1533
1574
  actions: ["UPDATE_ROLE"],
1534
1575
  source: "discord"
1535
1576
  });
@@ -1590,7 +1631,6 @@ var updateRoleAction = {
1590
1631
  ]
1591
1632
  ]
1592
1633
  };
1593
- var roles_default = updateRoleAction;
1594
1634
 
1595
1635
  // src/actions/sendMessage.ts
1596
1636
  import {
@@ -1659,6 +1699,18 @@ var sendMessageAction = {
1659
1699
  },
1660
1700
  handler: async (runtime, message, state, _options, callback, responses) => {
1661
1701
  try {
1702
+ if (!state) {
1703
+ logger5.error("State is required for sendMessage action");
1704
+ throw new Error("State is required for sendMessage action");
1705
+ }
1706
+ if (!callback) {
1707
+ logger5.error("Callback is required for sendMessage action");
1708
+ throw new Error("Callback is required for sendMessage action");
1709
+ }
1710
+ if (!responses) {
1711
+ logger5.error("Responses are required for sendMessage action");
1712
+ throw new Error("Responses are required for sendMessage action");
1713
+ }
1662
1714
  for (const response of responses) {
1663
1715
  await callback(response.content);
1664
1716
  }
@@ -1734,7 +1786,7 @@ var sendMessageAction = {
1734
1786
  } else if (targetData.targetType === "room") {
1735
1787
  const rooms = await runtime.getRooms(worldId);
1736
1788
  const targetRoom = rooms.find((r) => {
1737
- return r.name.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
1789
+ return r.name?.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
1738
1790
  });
1739
1791
  if (!targetRoom) {
1740
1792
  await callback({
@@ -1771,7 +1823,7 @@ var sendMessageAction = {
1771
1823
  }
1772
1824
  } catch (error) {
1773
1825
  logger5.error(`Error in sendMessage handler: ${error}`);
1774
- await callback({
1826
+ await callback?.({
1775
1827
  text: "There was an error processing your message request.",
1776
1828
  actions: ["SEND_MESSAGE_ERROR"],
1777
1829
  source: message.content.source
@@ -2007,7 +2059,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2007
2059
  If a setting is mentioned but no clear value is provided, do not include it.
2008
2060
  `;
2009
2061
  try {
2010
- let extractValidSettings = function(obj, worldSettings2) {
2062
+ let extractValidSettings2 = function(obj, worldSettings2) {
2011
2063
  const extracted = [];
2012
2064
  function traverse(node) {
2013
2065
  if (Array.isArray(node)) {
@@ -2027,6 +2079,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2027
2079
  traverse(obj);
2028
2080
  return extracted;
2029
2081
  };
2082
+ var extractValidSettings = extractValidSettings2;
2030
2083
  const result = await runtime.useModel(
2031
2084
  ModelType7.OBJECT_LARGE,
2032
2085
  {
@@ -2048,7 +2101,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2048
2101
  if (!result) {
2049
2102
  return [];
2050
2103
  }
2051
- const extractedSettings = extractValidSettings(result, worldSettings);
2104
+ const extractedSettings = extractValidSettings2(result, worldSettings);
2052
2105
  return extractedSettings;
2053
2106
  } catch (error) {
2054
2107
  console.error("Error extracting settings:", error);
@@ -2237,10 +2290,10 @@ var updateSettingsAction = {
2237
2290
  if (!worlds) {
2238
2291
  return false;
2239
2292
  }
2240
- const world = worlds.find((world2) => world2.metadata.settings);
2241
- const worldSettings = world.metadata.settings;
2293
+ const world = worlds.find((world2) => world2.metadata?.settings);
2294
+ const worldSettings = world?.metadata?.settings;
2242
2295
  if (!worldSettings) {
2243
- logger6.error(`No settings state found for server ${world.serverId}`);
2296
+ logger6.error(`No settings state found for server ${world?.serverId}`);
2244
2297
  return false;
2245
2298
  }
2246
2299
  logger6.debug(`Found valid settings state for server ${world.serverId}`);
@@ -2252,16 +2305,32 @@ var updateSettingsAction = {
2252
2305
  },
2253
2306
  handler: async (runtime, message, state, _options, callback) => {
2254
2307
  try {
2308
+ if (!state) {
2309
+ logger6.error("State is required for settings handler");
2310
+ throw new Error("State is required for settings handler");
2311
+ }
2312
+ if (!message) {
2313
+ logger6.error("Message is required for settings handler");
2314
+ throw new Error("Message is required for settings handler");
2315
+ }
2316
+ if (!callback) {
2317
+ logger6.error("Callback is required for settings handler");
2318
+ throw new Error("Callback is required for settings handler");
2319
+ }
2255
2320
  logger6.info(`Handler looking for server for user ${message.entityId}`);
2256
2321
  const worlds = await findWorldsForOwner(runtime, message.entityId);
2257
- const serverOwnership = worlds.find((world) => world.metadata.settings);
2322
+ const serverOwnership = worlds?.find((world) => world.metadata?.settings);
2258
2323
  if (!serverOwnership) {
2259
2324
  logger6.error(`No server found for user ${message.entityId} in handler`);
2260
2325
  await generateErrorResponse(runtime, state, callback);
2261
2326
  return;
2262
2327
  }
2263
- const serverId = serverOwnership.serverId;
2328
+ const serverId = serverOwnership?.serverId;
2264
2329
  logger6.info(`Using server ID: ${serverId}`);
2330
+ if (!serverId) {
2331
+ logger6.error(`No server ID found for user ${message.entityId} in handler`);
2332
+ return;
2333
+ }
2265
2334
  const worldSettings = await getWorldSettings(runtime, serverId);
2266
2335
  if (!worldSettings) {
2267
2336
  logger6.error(`No settings state found for server ${serverId} in handler`);
@@ -2298,7 +2367,9 @@ var updateSettingsAction = {
2298
2367
  }
2299
2368
  } catch (error) {
2300
2369
  logger6.error(`Error in settings handler: ${error}`);
2301
- await generateErrorResponse(runtime, state, callback);
2370
+ if (state && callback) {
2371
+ await generateErrorResponse(runtime, state, callback);
2372
+ }
2302
2373
  }
2303
2374
  },
2304
2375
  examples: [
@@ -2474,7 +2545,6 @@ var updateSettingsAction = {
2474
2545
  ]
2475
2546
  ]
2476
2547
  };
2477
- var settings_default = updateSettingsAction;
2478
2548
 
2479
2549
  // src/actions/unfollowRoom.ts
2480
2550
  import {
@@ -2517,7 +2587,7 @@ var unfollowRoomAction = {
2517
2587
  const parsedResponse = parseBooleanFromText(response.trim());
2518
2588
  return parsedResponse;
2519
2589
  }
2520
- if (await _shouldUnfollow(state)) {
2590
+ if (state && await _shouldUnfollow(state)) {
2521
2591
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
2522
2592
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
2523
2593
  await runtime.createMemory(
@@ -2880,10 +2950,14 @@ var unmuteRoomAction = {
2880
2950
  logger7.warn(`Unclear boolean response: ${response}, defaulting to false`);
2881
2951
  return false;
2882
2952
  }
2883
- if (await _shouldUnmute(state)) {
2953
+ if (state && await _shouldUnmute(state)) {
2884
2954
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
2885
2955
  }
2886
2956
  const room = await runtime.getRoom(message.roomId);
2957
+ if (!room) {
2958
+ logger7.warn(`Room not found: ${message.roomId}`);
2959
+ return false;
2960
+ }
2887
2961
  await runtime.createMemory(
2888
2962
  {
2889
2963
  entityId: message.entityId,
@@ -3059,6 +3133,22 @@ var updateEntityAction = {
3059
3133
  },
3060
3134
  handler: async (runtime, message, state, _options, callback, responses) => {
3061
3135
  try {
3136
+ if (!state) {
3137
+ logger8.error("State is required for the updateEntity action");
3138
+ throw new Error("State is required for the updateEntity action");
3139
+ }
3140
+ if (!callback) {
3141
+ logger8.error("State is required for the updateEntity action");
3142
+ throw new Error("Callback is required for the updateEntity action");
3143
+ }
3144
+ if (!responses) {
3145
+ logger8.error("Responses are required for the updateEntity action");
3146
+ throw new Error("Responses are required for the updateEntity action");
3147
+ }
3148
+ if (!message) {
3149
+ logger8.error("Message is required for the updateEntity action");
3150
+ throw new Error("Message is required for the updateEntity action");
3151
+ }
3062
3152
  for (const response of responses) {
3063
3153
  await callback(response.content);
3064
3154
  }
@@ -3121,7 +3211,8 @@ var updateEntityAction = {
3121
3211
  data: componentData,
3122
3212
  agentId,
3123
3213
  roomId: message.roomId,
3124
- sourceEntityId
3214
+ sourceEntityId,
3215
+ createdAt: existingComponent.createdAt
3125
3216
  });
3126
3217
  await callback({
3127
3218
  text: `I've updated the ${componentType} information for ${entity.names[0]}.`,
@@ -3137,7 +3228,8 @@ var updateEntityAction = {
3137
3228
  data: componentData,
3138
3229
  agentId,
3139
3230
  roomId: message.roomId,
3140
- sourceEntityId
3231
+ sourceEntityId,
3232
+ createdAt: Date.now()
3141
3233
  });
3142
3234
  await callback({
3143
3235
  text: `I've added new ${componentType} information for ${entity.names[0]}.`,
@@ -3147,7 +3239,7 @@ var updateEntityAction = {
3147
3239
  }
3148
3240
  } catch (error) {
3149
3241
  logger8.error(`Error in updateEntity handler: ${error}`);
3150
- await callback({
3242
+ await callback?.({
3151
3243
  text: "There was an error processing the entity information.",
3152
3244
  actions: ["UPDATE_ENTITY_ERROR"],
3153
3245
  source: message.content.source
@@ -3254,7 +3346,7 @@ Message Sender: {{senderName}} (ID: {{senderId}})
3254
3346
  {{knownFacts}}
3255
3347
 
3256
3348
  # Instructions:
3257
- 1. Generate a self-reflective thought on the conversation. How are you doing? You're not being annoying, are you?
3349
+ 1. Generate a self-reflective thought on the conversation about your performance and interaction quality.
3258
3350
  2. Extract new facts from the conversation.
3259
3351
  3. Identify and describe relationships between entities.
3260
3352
  - The sourceEntityId is the UUID of the entity initiating the interaction.
@@ -3288,23 +3380,27 @@ function resolveEntity(entityId, entities) {
3288
3380
  }
3289
3381
  let entity;
3290
3382
  entity = entities.find((a2) => a2.id === entityId);
3291
- if (entity) {
3383
+ if (entity?.id) {
3292
3384
  return entity.id;
3293
3385
  }
3294
- entity = entities.find((a2) => a2.id.includes(entityId));
3295
- if (entity) {
3386
+ entity = entities.find((a2) => a2.id?.includes(entityId));
3387
+ if (entity?.id) {
3296
3388
  return entity.id;
3297
3389
  }
3298
3390
  entity = entities.find(
3299
3391
  (a2) => a2.names.some((n2) => n2.toLowerCase().includes(entityId.toLowerCase()))
3300
3392
  );
3301
- if (entity) {
3393
+ if (entity?.id) {
3302
3394
  return entity.id;
3303
3395
  }
3304
3396
  throw new Error(`Could not resolve entityId "${entityId}" to a valid UUID`);
3305
3397
  }
3306
3398
  async function handler(runtime, message, state) {
3307
3399
  const { agentId, roomId } = message;
3400
+ if (!agentId || !roomId) {
3401
+ logger9.warn("Missing agentId or roomId in message", message);
3402
+ return;
3403
+ }
3308
3404
  const [existingRelationships, entities, knownFacts] = await Promise.all([
3309
3405
  runtime.getRelationships({
3310
3406
  entityId: message.entityId
@@ -3319,7 +3415,7 @@ async function handler(runtime, message, state) {
3319
3415
  ]);
3320
3416
  const prompt = composePrompt4({
3321
3417
  state: {
3322
- ...state.values,
3418
+ ...state?.values || {},
3323
3419
  knownFacts: formatFacts(knownFacts),
3324
3420
  roomType: message.content.channelType,
3325
3421
  entitiesInRoom: JSON.stringify(entities),
@@ -3399,7 +3495,10 @@ async function handler(runtime, message, state) {
3399
3495
  });
3400
3496
  }
3401
3497
  }
3402
- await runtime.setCache(`${message.roomId}-reflection-last-processed`, message.id);
3498
+ await runtime.setCache(
3499
+ `${message.roomId}-reflection-last-processed`,
3500
+ message?.id || ""
3501
+ );
3403
3502
  return reflection;
3404
3503
  } catch (error) {
3405
3504
  logger9.error("Error in reflection handler:", error);
@@ -3606,9 +3705,13 @@ var actionsProvider = {
3606
3705
  position: -1,
3607
3706
  get: async (runtime, message, state) => {
3608
3707
  const actionPromises = runtime.actions.map(async (action) => {
3609
- const result = await action.validate(runtime, message, state);
3610
- if (result) {
3611
- return action;
3708
+ try {
3709
+ const result = await action.validate(runtime, message, state);
3710
+ if (result) {
3711
+ return action;
3712
+ }
3713
+ } catch (e2) {
3714
+ console.error("ACTIONS GET -> validate err", action, e2);
3612
3715
  }
3613
3716
  return null;
3614
3717
  });
@@ -3639,7 +3742,6 @@ import { addHeader as addHeader2, ChannelType as ChannelType3 } from "@elizaos/c
3639
3742
  var anxietyProvider = {
3640
3743
  name: "ANXIETY",
3641
3744
  description: "Social directions for the AI to follow based on the channel type",
3642
- dynamic: true,
3643
3745
  get: async (_runtime, message) => {
3644
3746
  const channelType = message.content.channelType;
3645
3747
  const groupAnxietyExamples = [
@@ -3724,7 +3826,8 @@ var attachmentsProvider = {
3724
3826
  description: "List of attachments sent during the current conversation, including names, descriptions, and summaries",
3725
3827
  dynamic: true,
3726
3828
  get: async (runtime, message) => {
3727
- let allAttachments = message.content.attachments || [];
3829
+ const currentMessageAttachments = message.content.attachments || [];
3830
+ let allAttachments = [...currentMessageAttachments];
3728
3831
  const { roomId } = message;
3729
3832
  const conversationLength = runtime.getConversationLength();
3730
3833
  const recentMessagesData = await runtime.getMemories({
@@ -3740,17 +3843,24 @@ var attachmentsProvider = {
3740
3843
  if (lastMessageWithAttachment) {
3741
3844
  const lastMessageTime = lastMessageWithAttachment?.createdAt ?? Date.now();
3742
3845
  const oneHourBeforeLastMessage = lastMessageTime - 60 * 60 * 1e3;
3743
- allAttachments = recentMessagesData.reverse().flatMap((msg) => {
3846
+ const currentAttachmentsMap = new Map(
3847
+ currentMessageAttachments.map((att) => [att.id, att])
3848
+ );
3849
+ const recentAttachments = recentMessagesData.reverse().flatMap((msg) => {
3744
3850
  const msgTime = msg.createdAt ?? Date.now();
3745
3851
  const isWithinTime = msgTime >= oneHourBeforeLastMessage;
3746
3852
  const attachments = msg.content.attachments || [];
3747
- if (!isWithinTime) {
3748
- for (const attachment of attachments) {
3749
- attachment.text = "[Hidden]";
3853
+ return attachments.map((attachment) => {
3854
+ if (currentAttachmentsMap.has(attachment.id)) {
3855
+ return null;
3750
3856
  }
3751
- }
3752
- return attachments;
3857
+ if (!isWithinTime) {
3858
+ return { ...attachment, text: "[Hidden]" };
3859
+ }
3860
+ return attachment;
3861
+ }).filter((att) => att !== null);
3753
3862
  });
3863
+ allAttachments = [...currentMessageAttachments, ...recentAttachments];
3754
3864
  }
3755
3865
  }
3756
3866
  const formattedAttachments = allAttachments.map(
@@ -3832,7 +3942,7 @@ var characterProvider = {
3832
3942
  const bio = addHeader4(`# About ${character.name}`, bioText);
3833
3943
  const system = character.system ?? "";
3834
3944
  const topicString = character.topics && character.topics.length > 0 ? character.topics[Math.floor(Math.random() * character.topics.length)] : null;
3835
- const topic = topicString ? `${character.name} is currently interested in ${topicString}` : "";
3945
+ const topic = topicString || "";
3836
3946
  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) => {
3837
3947
  if (index === array.length - 2) {
3838
3948
  return `${topic2} and `;
@@ -3843,7 +3953,7 @@ var characterProvider = {
3843
3953
  return `${topic2}, `;
3844
3954
  }).join("")}` : "";
3845
3955
  const adjectiveString = character.adjectives && character.adjectives.length > 0 ? character.adjectives[Math.floor(Math.random() * character.adjectives.length)] : "";
3846
- const adjective = adjectiveString ? `${character.name} is ${adjectiveString}` : "";
3956
+ const adjective = adjectiveString || "";
3847
3957
  const formattedCharacterPostExamples = !character.postExamples ? "" : character.postExamples.sort(() => 0.5 - Math.random()).map((post) => {
3848
3958
  const messageString = `${post}`;
3849
3959
  return messageString;
@@ -3855,7 +3965,7 @@ var characterProvider = {
3855
3965
  () => Math.random().toString(36).substring(2, 8)
3856
3966
  );
3857
3967
  return example.map((message2) => {
3858
- let messageString = `${message2.name}: ${message2.content.text}${message2.content.action || message2.content.actions ? ` (actions: ${message2.content.action || message2.content.actions.join(", ")})` : ""}`;
3968
+ let messageString = `${message2.name}: ${message2.content.text}${message2.content.action || message2.content.actions ? ` (actions: ${message2.content.action || message2.content.actions?.join(", ")})` : ""}`;
3859
3969
  exampleNames.forEach((name, index) => {
3860
3970
  const placeholder = `{{name${index + 1}}}`;
3861
3971
  messageString = messageString.replaceAll(placeholder, name);
@@ -3869,7 +3979,7 @@ var characterProvider = {
3869
3979
  ) : "";
3870
3980
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
3871
3981
  const isPostFormat = room?.type === ChannelType4.FEED || room?.type === ChannelType4.THREAD;
3872
- const postDirections = character?.style?.all?.length > 0 || character?.style?.post?.length > 0 ? addHeader4(
3982
+ const postDirections = character?.style?.all?.length && character?.style?.all?.length > 0 || character?.style?.post?.length && character?.style?.post?.length > 0 ? addHeader4(
3873
3983
  `# Post Directions for ${character.name}`,
3874
3984
  (() => {
3875
3985
  const all = character?.style?.all || [];
@@ -3877,7 +3987,7 @@ var characterProvider = {
3877
3987
  return [...all, ...post].join("\n");
3878
3988
  })()
3879
3989
  ) : "";
3880
- const messageDirections = character?.style?.all?.length > 0 || character?.style?.chat?.length > 0 ? addHeader4(
3990
+ const messageDirections = character?.style?.all?.length && character?.style?.all?.length > 0 || character?.style?.chat?.length && character?.style?.chat?.length > 0 ? addHeader4(
3881
3991
  `# Message Directions for ${character.name}`,
3882
3992
  (() => {
3883
3993
  const all = character?.style?.all || [];
@@ -3911,7 +4021,9 @@ var characterProvider = {
3911
4021
  examples,
3912
4022
  system
3913
4023
  };
3914
- const text = [bio, adjective, topic, topics, adjective, directions, examples, system].filter(Boolean).join("\n\n");
4024
+ const topicSentence = topicString ? `${character.name} is currently interested in ${topicString}` : "";
4025
+ const adjectiveSentence = adjectiveString ? `${character.name} is ${adjectiveString}` : "";
4026
+ const text = [bio, adjectiveSentence, topicSentence, topics, directions, examples, system].filter(Boolean).join("\n\n");
3915
4027
  return {
3916
4028
  values,
3917
4029
  data,
@@ -3967,7 +4079,7 @@ var choiceProvider = {
3967
4079
  const options = task.metadata.options;
3968
4080
  options.forEach((option) => {
3969
4081
  if (typeof option === "string") {
3970
- const description = task.metadata?.options.find((o) => o.name === option)?.description || "";
4082
+ const description = task.metadata?.options?.find((o) => o.name === option)?.description || "";
3971
4083
  output += ` - \`${option}\` ${description ? `- ${description}` : ""}
3972
4084
  `;
3973
4085
  } else {
@@ -4102,7 +4214,7 @@ function formatEvaluatorExamples(evaluators) {
4102
4214
  const placeholder = `{{name${index + 1}}}`;
4103
4215
  messageString = messageString.replaceAll(placeholder, name);
4104
4216
  });
4105
- return messageString + (message.content.action || message.content.actions ? ` (${message.content.action || message.content.actions.join(", ")})` : "");
4217
+ return messageString + (message.content.action || message.content.actions ? ` (${message.content.action || message.content.actions?.join(", ")})` : "");
4106
4218
  }).join("\n");
4107
4219
  return `Prompt:
4108
4220
  ${formattedPrompt}
@@ -4151,6 +4263,7 @@ var evaluatorsProvider = {
4151
4263
 
4152
4264
  // src/providers/facts.ts
4153
4265
  import { ModelType as ModelType12 } from "@elizaos/core";
4266
+ import { logger as logger12 } from "@elizaos/core";
4154
4267
  function formatFacts2(facts) {
4155
4268
  return facts.reverse().map((fact) => fact.content.text).join("\n");
4156
4269
  }
@@ -4159,85 +4272,77 @@ var factsProvider = {
4159
4272
  description: "Key facts that the agent knows",
4160
4273
  dynamic: true,
4161
4274
  get: async (runtime, message, _state) => {
4162
- const recentMessages = await runtime.getMemories({
4163
- tableName: "messages",
4164
- roomId: message.roomId,
4165
- count: 10,
4166
- unique: false
4167
- });
4168
- const last5Messages = recentMessages.slice(-5).map((message2) => message2.content.text).join("\n");
4169
- const embedding = await runtime.useModel(ModelType12.TEXT_EMBEDDING, {
4170
- text: last5Messages
4171
- });
4172
- const [relevantFacts, recentFactsData] = await Promise.all([
4173
- runtime.searchMemories({
4174
- tableName: "facts",
4175
- embedding,
4176
- roomId: message.roomId,
4177
- count: 10
4178
- }),
4179
- runtime.getMemories({
4180
- tableName: "facts",
4275
+ try {
4276
+ const recentMessages = await runtime.getMemories({
4277
+ tableName: "messages",
4181
4278
  roomId: message.roomId,
4182
4279
  count: 10,
4183
- start: 0,
4184
- end: Date.now()
4185
- })
4186
- ]);
4187
- const allFacts = [...relevantFacts, ...recentFactsData].filter(
4188
- (fact, index, self) => index === self.findIndex((t) => t.id === fact.id)
4189
- );
4190
- if (allFacts.length === 0) {
4280
+ unique: false
4281
+ });
4282
+ const last5Messages = recentMessages.slice(-5).map((message2) => message2.content.text).join("\n");
4283
+ const embedding = await runtime.useModel(ModelType12.TEXT_EMBEDDING, {
4284
+ text: last5Messages
4285
+ });
4286
+ const [relevantFacts, recentFactsData] = await Promise.all([
4287
+ runtime.searchMemories({
4288
+ tableName: "facts",
4289
+ embedding,
4290
+ roomId: message.roomId,
4291
+ worldId: message.worldId,
4292
+ count: 6,
4293
+ query: message.content.text
4294
+ }),
4295
+ runtime.searchMemories({
4296
+ embedding,
4297
+ query: message.content.text,
4298
+ tableName: "facts",
4299
+ roomId: message.roomId,
4300
+ entityId: message.entityId,
4301
+ count: 6
4302
+ })
4303
+ ]);
4304
+ const allFacts = [...relevantFacts, ...recentFactsData].filter(
4305
+ (fact, index, self) => index === self.findIndex((t) => t.id === fact.id)
4306
+ );
4307
+ if (allFacts.length === 0) {
4308
+ return {
4309
+ values: {
4310
+ facts: ""
4311
+ },
4312
+ data: {
4313
+ facts: allFacts
4314
+ },
4315
+ text: "No facts available."
4316
+ };
4317
+ }
4318
+ const formattedFacts = formatFacts2(allFacts);
4319
+ const text = "Key facts that {{agentName}} knows:\n{{formattedFacts}}".replace("{{agentName}}", runtime.character.name).replace("{{formattedFacts}}", formattedFacts);
4191
4320
  return {
4192
4321
  values: {
4193
- facts: ""
4322
+ facts: formattedFacts
4194
4323
  },
4195
4324
  data: {
4196
4325
  facts: allFacts
4197
4326
  },
4198
- text: ""
4327
+ text
4328
+ };
4329
+ } catch (error) {
4330
+ logger12.error("Error in factsProvider:", error);
4331
+ return {
4332
+ values: {
4333
+ facts: ""
4334
+ },
4335
+ data: {
4336
+ facts: []
4337
+ },
4338
+ text: "Error retrieving facts."
4199
4339
  };
4200
4340
  }
4201
- const formattedFacts = formatFacts2(allFacts);
4202
- const text = "Key facts that {{agentName}} knows:\n{{formattedFacts}}".replace("{{agentName}}", runtime.character.name).replace("{{formattedFacts}}", formattedFacts);
4203
- return {
4204
- values: {
4205
- facts: formattedFacts
4206
- },
4207
- data: {
4208
- facts: allFacts
4209
- },
4210
- text
4211
- };
4212
- }
4213
- };
4214
-
4215
- // src/providers/knowledge.ts
4216
- import { addHeader as addHeader7 } from "@elizaos/core";
4217
- var knowledgeProvider = {
4218
- name: "KNOWLEDGE",
4219
- description: "Knowledge from the knowledge base that the agent knows",
4220
- dynamic: true,
4221
- get: async (runtime, message) => {
4222
- const knowledgeData = await runtime.getKnowledge(message);
4223
- const knowledge = knowledgeData && knowledgeData.length > 0 ? addHeader7(
4224
- "# Knowledge",
4225
- knowledgeData.map((knowledge2) => `- ${knowledge2.content.text}`).join("\n")
4226
- ) : "";
4227
- return {
4228
- data: {
4229
- knowledge
4230
- },
4231
- values: {
4232
- knowledge
4233
- },
4234
- text: knowledge
4235
- };
4236
4341
  }
4237
4342
  };
4238
4343
 
4239
4344
  // src/providers/providers.ts
4240
- import { addHeader as addHeader8 } from "@elizaos/core";
4345
+ import { addHeader as addHeader7 } from "@elizaos/core";
4241
4346
  var providersProvider = {
4242
4347
  name: "PROVIDERS",
4243
4348
  description: "List of all data providers the agent can use to get additional information",
@@ -4249,11 +4354,11 @@ var providersProvider = {
4249
4354
  const headerText = "# Providers\n\nThese providers are available for the agent to select and use:";
4250
4355
  if (providerDescriptions.length === 0) {
4251
4356
  return {
4252
- text: addHeader8(headerText, "No dynamic providers are currently available.")
4357
+ text: addHeader7(headerText, "No dynamic providers are currently available.")
4253
4358
  };
4254
4359
  }
4255
4360
  const providersText = providerDescriptions.join("\n");
4256
- const text = addHeader8(headerText, providersText);
4361
+ const text = addHeader7(headerText, providersText);
4257
4362
  const data = {
4258
4363
  dynamicProviders: dynamicProviders.map((provider) => ({
4259
4364
  name: provider.name,
@@ -4269,11 +4374,12 @@ var providersProvider = {
4269
4374
 
4270
4375
  // src/providers/recentMessages.ts
4271
4376
  import {
4272
- addHeader as addHeader9,
4377
+ addHeader as addHeader8,
4273
4378
  ChannelType as ChannelType5,
4274
4379
  formatMessages,
4275
4380
  formatPosts,
4276
- getEntityDetails as getEntityDetails3
4381
+ getEntityDetails as getEntityDetails3,
4382
+ logger as logger13
4277
4383
  } from "@elizaos/core";
4278
4384
  var getRecentInteractions = async (runtime, sourceEntityId, targetEntityId, excludeRoomId) => {
4279
4385
  const rooms = await runtime.getRoomsForParticipants([sourceEntityId, targetEntityId]);
@@ -4289,114 +4395,158 @@ var recentMessagesProvider = {
4289
4395
  description: "Recent messages, interactions and other memories",
4290
4396
  position: 100,
4291
4397
  get: async (runtime, message) => {
4292
- const { roomId } = message;
4293
- const conversationLength = runtime.getConversationLength();
4294
- const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
4295
- getEntityDetails3({ runtime, roomId }),
4296
- runtime.getRoom(roomId),
4297
- runtime.getMemories({
4298
- tableName: "messages",
4299
- roomId,
4300
- count: conversationLength,
4301
- unique: false
4302
- }),
4303
- message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
4304
- ]);
4305
- const isPostFormat = room?.type === ChannelType5.FEED || room?.type === ChannelType5.THREAD;
4306
- const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([
4307
- formatMessages({
4308
- messages: recentMessagesData,
4309
- entities: entitiesData
4310
- }),
4311
- formatPosts({
4312
- messages: recentMessagesData,
4313
- entities: entitiesData,
4314
- conversationHeader: false
4315
- })
4316
- ]);
4317
- const recentPosts = formattedRecentPosts && formattedRecentPosts.length > 0 ? addHeader9("# Posts in Thread", formattedRecentPosts) : "";
4318
- const metaData = message.metadata;
4319
- const recieveMessage = addHeader9(
4320
- "# Received Message:",
4321
- `${metaData?.entityName || "unknown"}: ${message.content.text}`
4322
- );
4323
- const recentMessages = formattedRecentMessages && formattedRecentMessages.length > 0 ? addHeader9("# Conversation Messages", formattedRecentMessages) : "";
4324
- const interactionEntityMap = /* @__PURE__ */ new Map();
4325
- if (recentInteractionsData.length > 0) {
4326
- const uniqueEntityIds = [
4327
- ...new Set(
4328
- recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId)
4329
- )
4330
- ];
4331
- const uniqueEntityIdSet = new Set(uniqueEntityIds);
4332
- const entitiesDataIdSet = /* @__PURE__ */ new Set();
4333
- entitiesData.forEach((entity) => {
4334
- if (uniqueEntityIdSet.has(entity.id)) {
4335
- interactionEntityMap.set(entity.id, entity);
4336
- entitiesDataIdSet.add(entity.id);
4337
- }
4338
- });
4339
- const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
4340
- if (remainingEntityIds.length > 0) {
4341
- const entities = await Promise.all(
4342
- remainingEntityIds.map((entityId) => runtime.getEntityById(entityId))
4343
- );
4344
- entities.forEach((entity, index) => {
4345
- if (entity) {
4346
- interactionEntityMap.set(remainingEntityIds[index], entity);
4398
+ try {
4399
+ const { roomId } = message;
4400
+ const conversationLength = runtime.getConversationLength();
4401
+ const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
4402
+ getEntityDetails3({ runtime, roomId }),
4403
+ runtime.getRoom(roomId),
4404
+ runtime.getMemories({
4405
+ tableName: "messages",
4406
+ roomId,
4407
+ count: conversationLength,
4408
+ unique: false
4409
+ }),
4410
+ message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
4411
+ ]);
4412
+ const isPostFormat = room?.type ? room.type === ChannelType5.FEED || room.type === ChannelType5.THREAD : false;
4413
+ const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([
4414
+ formatMessages({
4415
+ messages: recentMessagesData,
4416
+ entities: entitiesData
4417
+ }),
4418
+ formatPosts({
4419
+ messages: recentMessagesData,
4420
+ entities: entitiesData,
4421
+ conversationHeader: false
4422
+ })
4423
+ ]);
4424
+ const recentPosts = formattedRecentPosts && formattedRecentPosts.length > 0 ? addHeader8("# Posts in Thread", formattedRecentPosts) : "";
4425
+ const recentMessages = formattedRecentMessages && formattedRecentMessages.length > 0 ? addHeader8("# Conversation Messages", formattedRecentMessages) : "";
4426
+ if (!recentPosts && !recentMessages && recentMessagesData.length === 0 && !message.content.text) {
4427
+ return {
4428
+ data: {
4429
+ recentMessages: [],
4430
+ recentInteractions: []
4431
+ },
4432
+ values: {
4433
+ recentPosts: "",
4434
+ recentMessages: "",
4435
+ recentMessageInteractions: "",
4436
+ recentPostInteractions: "",
4437
+ recentInteractions: ""
4438
+ },
4439
+ text: "No recent messages available"
4440
+ };
4441
+ }
4442
+ const metaData = message.metadata;
4443
+ const senderName = entitiesData.find((entity) => entity.id === message.entityId)?.names[0] || metaData?.entityName || "Unknown User";
4444
+ const receivedMessageContent = message.content.text;
4445
+ const hasReceivedMessage = !!receivedMessageContent?.trim();
4446
+ const receivedMessageHeader = hasReceivedMessage ? addHeader8("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
4447
+ const focusHeader = hasReceivedMessage ? addHeader8(
4448
+ "# Focus your response",
4449
+ `You are replying to the above message from **${senderName}**. Keep your answer relevant to that message. Do not repeat earlier replies unless the sender asks again.`
4450
+ ) : "";
4451
+ const interactionEntityMap = /* @__PURE__ */ new Map();
4452
+ if (recentInteractionsData.length > 0) {
4453
+ const uniqueEntityIds = [
4454
+ ...new Set(
4455
+ recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId)
4456
+ )
4457
+ ];
4458
+ const uniqueEntityIdSet = new Set(uniqueEntityIds);
4459
+ const entitiesDataIdSet = /* @__PURE__ */ new Set();
4460
+ entitiesData.forEach((entity) => {
4461
+ if (uniqueEntityIdSet.has(entity.id)) {
4462
+ interactionEntityMap.set(entity.id, entity);
4463
+ entitiesDataIdSet.add(entity.id);
4347
4464
  }
4348
4465
  });
4466
+ const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
4467
+ if (remainingEntityIds.length > 0) {
4468
+ const entities = await Promise.all(
4469
+ remainingEntityIds.map((entityId) => runtime.getEntityById(entityId))
4470
+ );
4471
+ entities.forEach((entity, index) => {
4472
+ if (entity) {
4473
+ interactionEntityMap.set(remainingEntityIds[index], entity);
4474
+ }
4475
+ });
4476
+ }
4349
4477
  }
4350
- }
4351
- const getRecentMessageInteractions = async (recentInteractionsData2) => {
4352
- const formattedInteractions = recentInteractionsData2.map((message2) => {
4353
- const isSelf = message2.entityId === runtime.agentId;
4354
- let sender;
4355
- if (isSelf) {
4356
- sender = runtime.character.name;
4357
- } else {
4358
- sender = interactionEntityMap.get(message2.entityId)?.metadata?.username || "unknown";
4478
+ const getRecentMessageInteractions = async (recentInteractionsData2) => {
4479
+ const formattedInteractions = recentInteractionsData2.map((message2) => {
4480
+ const isSelf = message2.entityId === runtime.agentId;
4481
+ let sender;
4482
+ if (isSelf) {
4483
+ sender = runtime.character.name;
4484
+ } else {
4485
+ sender = interactionEntityMap.get(message2.entityId)?.metadata?.username || "unknown";
4486
+ }
4487
+ return `${sender}: ${message2.content.text}`;
4488
+ });
4489
+ return formattedInteractions.join("\n");
4490
+ };
4491
+ const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
4492
+ const combinedEntities = [...entities];
4493
+ const actorIds = new Set(entities.map((entity) => entity.id));
4494
+ for (const [id, entity] of interactionEntityMap.entries()) {
4495
+ if (!actorIds.has(id)) {
4496
+ combinedEntities.push(entity);
4497
+ }
4359
4498
  }
4360
- return `${sender}: ${message2.content.text}`;
4361
- });
4362
- return formattedInteractions.join("\n");
4363
- };
4364
- const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
4365
- const combinedEntities = [...entities];
4366
- const actorIds = new Set(entities.map((entity) => entity.id));
4367
- for (const [id, entity] of interactionEntityMap.entries()) {
4368
- if (!actorIds.has(id)) {
4369
- combinedEntities.push(entity);
4370
- }
4371
- }
4372
- const formattedInteractions = formatPosts({
4373
- messages: recentInteractionsData2,
4374
- entities: combinedEntities,
4375
- conversationHeader: true
4376
- });
4377
- return formattedInteractions;
4378
- };
4379
- const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
4380
- getRecentMessageInteractions(recentInteractionsData),
4381
- getRecentPostInteractions(recentInteractionsData, entitiesData)
4382
- ]);
4383
- const data = {
4384
- recentMessages: recentMessagesData,
4385
- recentInteractions: recentInteractionsData
4386
- };
4387
- const values = {
4388
- recentPosts,
4389
- recentMessages,
4390
- recentMessageInteractions,
4391
- recentPostInteractions,
4392
- recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions
4393
- };
4394
- const text = [isPostFormat ? recentPosts : recentMessages + recieveMessage].filter(Boolean).join("\n\n");
4395
- return {
4396
- data,
4397
- values,
4398
- text
4399
- };
4499
+ const formattedInteractions = formatPosts({
4500
+ messages: recentInteractionsData2,
4501
+ entities: combinedEntities,
4502
+ conversationHeader: true
4503
+ });
4504
+ return formattedInteractions;
4505
+ };
4506
+ const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
4507
+ getRecentMessageInteractions(recentInteractionsData),
4508
+ getRecentPostInteractions(recentInteractionsData, entitiesData)
4509
+ ]);
4510
+ const data = {
4511
+ recentMessages: recentMessagesData,
4512
+ recentInteractions: recentInteractionsData
4513
+ };
4514
+ const values = {
4515
+ recentPosts,
4516
+ recentMessages,
4517
+ recentMessageInteractions,
4518
+ recentPostInteractions,
4519
+ recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions
4520
+ };
4521
+ const text = [
4522
+ isPostFormat ? recentPosts : recentMessages,
4523
+ // Only add received message and focus headers if there are messages or a current message to process
4524
+ recentMessages || recentPosts || message.content.text ? receivedMessageHeader : "",
4525
+ recentMessages || recentPosts || message.content.text ? focusHeader : ""
4526
+ ].filter(Boolean).join("\n\n");
4527
+ return {
4528
+ data,
4529
+ values,
4530
+ text
4531
+ };
4532
+ } catch (error) {
4533
+ logger13.error("Error in recentMessagesProvider:", error);
4534
+ return {
4535
+ data: {
4536
+ recentMessages: [],
4537
+ recentInteractions: []
4538
+ },
4539
+ values: {
4540
+ recentPosts: "",
4541
+ recentMessages: "",
4542
+ recentMessageInteractions: "",
4543
+ recentPostInteractions: "",
4544
+ recentInteractions: ""
4545
+ },
4546
+ text: "Error retrieving recent messages."
4547
+ // Or 'No recent messages available' as the test expects
4548
+ };
4549
+ }
4400
4550
  }
4401
4551
  };
4402
4552
 
@@ -4485,7 +4635,7 @@ ${formattedRelationships}`
4485
4635
  import {
4486
4636
  ChannelType as ChannelType6,
4487
4637
  createUniqueUuid as createUniqueUuid2,
4488
- logger as logger12
4638
+ logger as logger14
4489
4639
  } from "@elizaos/core";
4490
4640
  var roleProvider = {
4491
4641
  name: "ROLES",
@@ -4510,106 +4660,108 @@ var roleProvider = {
4510
4660
  if (!serverId) {
4511
4661
  throw new Error("No server ID found");
4512
4662
  }
4513
- try {
4514
- logger12.info(`Using server ID: ${serverId}`);
4515
- const worldId = createUniqueUuid2(runtime, serverId);
4516
- const world = await runtime.getWorld(worldId);
4517
- if (!world || !world.metadata?.ownership?.ownerId) {
4518
- logger12.info(
4519
- `No ownership data found for server ${serverId}, initializing empty role hierarchy`
4520
- );
4521
- return {
4522
- data: {
4523
- roles: []
4524
- },
4525
- values: {
4526
- roles: "No role information available for this server."
4527
- },
4528
- text: "No role information available for this server."
4529
- };
4530
- }
4531
- const roles = world.metadata.roles || {};
4532
- if (Object.keys(roles).length === 0) {
4533
- logger12.info(`No roles found for server ${serverId}`);
4534
- return {
4535
- data: {
4536
- roles: []
4537
- },
4538
- values: {
4539
- roles: "No role information available for this server."
4540
- }
4541
- };
4542
- }
4543
- logger12.info(`Found ${Object.keys(roles).length} roles`);
4544
- const owners = [];
4545
- const admins = [];
4546
- const members = [];
4547
- for (const entityId of Object.keys(roles)) {
4548
- const userRole = roles[entityId];
4549
- const user = await runtime.getEntityById(entityId);
4550
- const name = user.metadata[room.source]?.name;
4551
- const username = user.metadata[room.source]?.username;
4552
- const names = user.names;
4553
- if (owners.some((owner) => owner.username === username) || admins.some((admin) => admin.username === username) || members.some((member) => member.username === username)) {
4554
- continue;
4555
- }
4556
- switch (userRole) {
4557
- case "OWNER":
4558
- owners.push({ name, username, names });
4559
- break;
4560
- case "ADMIN":
4561
- admins.push({ name, username, names });
4562
- break;
4563
- default:
4564
- members.push({ name, username, names });
4565
- break;
4566
- }
4567
- }
4568
- let response = "# Server Role Hierarchy\n\n";
4569
- if (owners.length > 0) {
4570
- response += "## Owners\n";
4571
- owners.forEach((owner) => {
4572
- response += `${owner.name} (${owner.names.join(", ")})
4573
- `;
4574
- });
4575
- response += "\n";
4576
- }
4577
- if (admins.length > 0) {
4578
- response += "## Administrators\n";
4579
- admins.forEach((admin) => {
4580
- response += `${admin.name} (${admin.names.join(", ")}) (${admin.username})
4581
- `;
4582
- });
4583
- response += "\n";
4584
- }
4585
- if (members.length > 0) {
4586
- response += "## Members\n";
4587
- members.forEach((member) => {
4588
- response += `${member.name} (${member.names.join(", ")}) (${member.username})
4589
- `;
4590
- });
4591
- }
4663
+ logger14.info(`Using server ID: ${serverId}`);
4664
+ const worldId = createUniqueUuid2(runtime, serverId);
4665
+ const world = await runtime.getWorld(worldId);
4666
+ if (!world || !world.metadata?.ownership?.ownerId) {
4667
+ logger14.info(
4668
+ `No ownership data found for server ${serverId}, initializing empty role hierarchy`
4669
+ );
4592
4670
  return {
4593
4671
  data: {
4594
- roles: response
4672
+ roles: []
4595
4673
  },
4596
4674
  values: {
4597
- roles: response
4675
+ roles: "No role information available for this server."
4598
4676
  },
4599
- text: response
4677
+ text: "No role information available for this server."
4600
4678
  };
4601
- } catch (error) {
4602
- logger12.error("Error in role provider:", error);
4679
+ }
4680
+ const roles = world.metadata.roles || {};
4681
+ if (Object.keys(roles).length === 0) {
4682
+ logger14.info(`No roles found for server ${serverId}`);
4603
4683
  return {
4604
4684
  data: {
4605
4685
  roles: []
4606
4686
  },
4607
4687
  values: {
4608
- roles: "There was an error retrieving role information."
4688
+ roles: "No role information available for this server."
4689
+ }
4690
+ };
4691
+ }
4692
+ logger14.info(`Found ${Object.keys(roles).length} roles`);
4693
+ const owners = [];
4694
+ const admins = [];
4695
+ const members = [];
4696
+ for (const entityId of Object.keys(roles)) {
4697
+ const userRole = roles[entityId];
4698
+ const user = await runtime.getEntityById(entityId);
4699
+ const name = user?.metadata?.[room.source]?.name;
4700
+ const username = user?.metadata?.[room.source]?.username;
4701
+ const names = user?.names;
4702
+ if (owners.some((owner) => owner.username === username) || admins.some((admin) => admin.username === username) || members.some((member) => member.username === username)) {
4703
+ continue;
4704
+ }
4705
+ if (!name || !username || !names) {
4706
+ logger14.warn(`User ${entityId} has no name or username, skipping`);
4707
+ continue;
4708
+ }
4709
+ switch (userRole) {
4710
+ case "OWNER":
4711
+ owners.push({ name, username, names });
4712
+ break;
4713
+ case "ADMIN":
4714
+ admins.push({ name, username, names });
4715
+ break;
4716
+ default:
4717
+ members.push({ name, username, names });
4718
+ break;
4719
+ }
4720
+ }
4721
+ let response = "# Server Role Hierarchy\n\n";
4722
+ if (owners.length > 0) {
4723
+ response += "## Owners\n";
4724
+ owners.forEach((owner) => {
4725
+ response += `${owner.name} (${owner.names.join(", ")})
4726
+ `;
4727
+ });
4728
+ response += "\n";
4729
+ }
4730
+ if (admins.length > 0) {
4731
+ response += "## Administrators\n";
4732
+ admins.forEach((admin) => {
4733
+ response += `${admin.name} (${admin.names.join(", ")}) (${admin.username})
4734
+ `;
4735
+ });
4736
+ response += "\n";
4737
+ }
4738
+ if (members.length > 0) {
4739
+ response += "## Members\n";
4740
+ members.forEach((member) => {
4741
+ response += `${member.name} (${member.names.join(", ")}) (${member.username})
4742
+ `;
4743
+ });
4744
+ }
4745
+ if (owners.length === 0 && admins.length === 0 && members.length === 0) {
4746
+ return {
4747
+ data: {
4748
+ roles: []
4749
+ },
4750
+ values: {
4751
+ roles: "No role information available for this server."
4609
4752
  },
4610
- text: "There was an error retrieving role information."
4753
+ text: "No role information available for this server."
4611
4754
  };
4612
4755
  }
4756
+ return {
4757
+ data: {
4758
+ roles: response
4759
+ },
4760
+ values: {
4761
+ roles: response
4762
+ },
4763
+ text: response
4764
+ };
4613
4765
  }
4614
4766
  };
4615
4767
 
@@ -4618,7 +4770,7 @@ import {
4618
4770
  ChannelType as ChannelType7,
4619
4771
  findWorldsForOwner as findWorldsForOwner2,
4620
4772
  getWorldSettings as getWorldSettings2,
4621
- logger as logger13
4773
+ logger as logger15
4622
4774
  } from "@elizaos/core";
4623
4775
  var formatSettingValue = (setting, isOnboarding) => {
4624
4776
  if (setting.value === null) return "Not set";
@@ -4645,13 +4797,13 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4645
4797
  };
4646
4798
  }).filter(Boolean);
4647
4799
  const requiredUnconfigured = formattedSettings.filter(
4648
- (s) => s.required && !s.configured
4800
+ (s) => s?.required && !s.configured
4649
4801
  ).length;
4650
4802
  if (isOnboarding) {
4651
4803
  const settingsList = formattedSettings.map((s) => {
4652
- const label = s.required ? "(Required)" : "(Optional)";
4653
- return `${s.key}: ${s.value} ${label}
4654
- (${s.name}) ${s.usageDescription}`;
4804
+ const label = s?.required ? "(Required)" : "(Optional)";
4805
+ return `${s?.key}: ${s?.value} ${label}
4806
+ (${s?.name}) ${s?.usageDescription}`;
4655
4807
  }).join("\n\n");
4656
4808
  const validKeys = `Valid setting keys: ${Object.keys(worldSettings).join(", ")}`;
4657
4809
  const commonInstructions = `Instructions for ${runtime.character.name}:
@@ -4661,7 +4813,7 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4661
4813
  - Do not call UPDATE_SETTINGS just because the user has started onboarding or you think a setting needs to be configured. Only update when the user clearly provides a specific value for a setting you are currently asking about.
4662
4814
  - Answer setting-related questions using only the name, description, and value from the list.`;
4663
4815
  if (requiredUnconfigured > 0) {
4664
- return `# PRIORITY TASK: Onboarding with ${state.senderName}
4816
+ return `# PRIORITY TASK: Onboarding with ${state?.senderName}
4665
4817
 
4666
4818
  ${runtime.character.name} needs to help the user configure ${requiredUnconfigured} required settings:
4667
4819
 
@@ -4685,11 +4837,11 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4685
4837
 
4686
4838
  ${requiredUnconfigured > 0 ? `IMPORTANT!: ${requiredUnconfigured} required settings still need configuration. ${runtime.character.name} should get onboarded with the OWNER as soon as possible.
4687
4839
 
4688
- ` : "All required settings are configured.\n\n"}${formattedSettings.map((s) => `### ${s.name}
4689
- **Value:** ${s.value}
4690
- **Description:** ${s.description}`).join("\n\n")}`;
4840
+ ` : "All required settings are configured.\n\n"}${formattedSettings.map((s) => `### ${s?.name}
4841
+ **Value:** ${s?.value}
4842
+ **Description:** ${s?.description}`).join("\n\n")}`;
4691
4843
  } catch (error) {
4692
- logger13.error(`Error generating status message: ${error}`);
4844
+ logger15.error(`Error generating status message: ${error}`);
4693
4845
  return "Error generating configuration status.";
4694
4846
  }
4695
4847
  }
@@ -4702,11 +4854,11 @@ var settingsProvider = {
4702
4854
  runtime.getRoom(message.roomId),
4703
4855
  findWorldsForOwner2(runtime, message.entityId)
4704
4856
  ]).catch((error) => {
4705
- logger13.error(`Error fetching initial data: ${error}`);
4857
+ logger15.error(`Error fetching initial data: ${error}`);
4706
4858
  throw new Error("Failed to retrieve room or user world information");
4707
4859
  });
4708
4860
  if (!room) {
4709
- logger13.error("No room found for settings provider");
4861
+ logger15.error("No room found for settings provider");
4710
4862
  return {
4711
4863
  data: {
4712
4864
  settings: []
@@ -4718,7 +4870,7 @@ var settingsProvider = {
4718
4870
  };
4719
4871
  }
4720
4872
  if (!room.worldId) {
4721
- logger13.debug("No world found for settings provider -- settings provider will be skipped");
4873
+ logger15.debug("No world found for settings provider -- settings provider will be skipped");
4722
4874
  return {
4723
4875
  data: {
4724
4876
  settings: []
@@ -4731,42 +4883,42 @@ var settingsProvider = {
4731
4883
  }
4732
4884
  const type = room.type;
4733
4885
  const isOnboarding = type === ChannelType7.DM;
4734
- let world;
4735
- let serverId;
4736
- let worldSettings;
4886
+ let world = null;
4887
+ let serverId = void 0;
4888
+ let worldSettings = null;
4737
4889
  if (isOnboarding) {
4738
- world = userWorlds.find((world2) => world2.metadata.settings);
4890
+ world = userWorlds?.find((world2) => world2.metadata?.settings);
4739
4891
  if (!world) {
4740
- logger13.error("No world found for user during onboarding");
4892
+ logger15.error("No world found for user during onboarding");
4741
4893
  throw new Error("No server ownership found for onboarding");
4742
4894
  }
4743
4895
  serverId = world.serverId;
4744
4896
  try {
4745
4897
  worldSettings = await getWorldSettings2(runtime, serverId);
4746
4898
  } catch (error) {
4747
- logger13.error(`Error fetching world settings: ${error}`);
4899
+ logger15.error(`Error fetching world settings: ${error}`);
4748
4900
  throw new Error(`Failed to retrieve settings for server ${serverId}`);
4749
4901
  }
4750
4902
  } else {
4751
4903
  try {
4752
4904
  world = await runtime.getWorld(room.worldId);
4753
4905
  if (!world) {
4754
- logger13.error(`No world found for room ${room.worldId}`);
4906
+ logger15.error(`No world found for room ${room.worldId}`);
4755
4907
  throw new Error(`No world found for room ${room.worldId}`);
4756
4908
  }
4757
4909
  serverId = world.serverId;
4758
4910
  if (serverId) {
4759
4911
  worldSettings = await getWorldSettings2(runtime, serverId);
4760
4912
  } else {
4761
- logger13.error(`No server ID found for world ${room.worldId}`);
4913
+ logger15.error(`No server ID found for world ${room.worldId}`);
4762
4914
  }
4763
4915
  } catch (error) {
4764
- logger13.error(`Error processing world data: ${error}`);
4916
+ logger15.error(`Error processing world data: ${error}`);
4765
4917
  throw new Error("Failed to process world information");
4766
4918
  }
4767
4919
  }
4768
4920
  if (!serverId) {
4769
- logger13.info(
4921
+ logger15.info(
4770
4922
  `No server ownership found for user ${message.entityId} after recovery attempt`
4771
4923
  );
4772
4924
  return isOnboarding ? {
@@ -4788,7 +4940,7 @@ var settingsProvider = {
4788
4940
  };
4789
4941
  }
4790
4942
  if (!worldSettings) {
4791
- logger13.info(`No settings state found for server ${serverId}`);
4943
+ logger15.info(`No settings state found for server ${serverId}`);
4792
4944
  return isOnboarding ? {
4793
4945
  data: {
4794
4946
  settings: []
@@ -4818,7 +4970,7 @@ var settingsProvider = {
4818
4970
  text: output
4819
4971
  };
4820
4972
  } catch (error) {
4821
- logger13.error(`Critical error in settings provider: ${error}`);
4973
+ logger15.error(`Critical error in settings provider: ${error}`);
4822
4974
  return {
4823
4975
  data: {
4824
4976
  settings: []
@@ -4855,13 +5007,174 @@ var timeProvider = {
4855
5007
  }
4856
5008
  };
4857
5009
 
5010
+ // src/providers/world.ts
5011
+ import {
5012
+ logger as logger16,
5013
+ addHeader as addHeader9,
5014
+ ChannelType as ChannelType8
5015
+ } from "@elizaos/core";
5016
+ var worldProvider = {
5017
+ name: "WORLD",
5018
+ description: "World and environment information",
5019
+ dynamic: true,
5020
+ get: async (runtime, message) => {
5021
+ try {
5022
+ logger16.debug("[\u{1F310}] World provider activated for roomId:", message.roomId);
5023
+ const currentRoom = await runtime.getRoom(message.roomId);
5024
+ if (!currentRoom) {
5025
+ logger16.warn(`World provider: Room not found for roomId ${message.roomId}`);
5026
+ return {
5027
+ data: {
5028
+ world: {
5029
+ info: "Unable to retrieve world information - room not found"
5030
+ }
5031
+ },
5032
+ text: "Unable to retrieve world information - room not found"
5033
+ };
5034
+ }
5035
+ logger16.debug(`[\u{1F310}] World provider: Found room "${currentRoom.name}" (${currentRoom.type})`);
5036
+ const worldId = currentRoom.worldId;
5037
+ if (!worldId) {
5038
+ logger16.warn(`World provider: World ID not found for roomId ${message.roomId}`);
5039
+ return {
5040
+ data: {
5041
+ world: {
5042
+ info: "Unable to retrieve world information - world ID not found"
5043
+ }
5044
+ },
5045
+ text: "Unable to retrieve world information - world ID not found"
5046
+ };
5047
+ }
5048
+ const world = await runtime.getWorld(worldId);
5049
+ if (!world) {
5050
+ logger16.warn(`World provider: World not found for worldId ${worldId}`);
5051
+ return {
5052
+ data: {
5053
+ world: {
5054
+ info: "Unable to retrieve world information - world not found"
5055
+ }
5056
+ },
5057
+ text: "Unable to retrieve world information - world not found"
5058
+ };
5059
+ }
5060
+ logger16.debug(`[\u{1F310}] World provider: Found world "${world.name}" (ID: ${world.id})`);
5061
+ const worldRooms = await runtime.getRooms(worldId);
5062
+ logger16.debug(
5063
+ `[\u{1F310}] World provider: Found ${worldRooms.length} rooms in world "${world.name}"`
5064
+ );
5065
+ const participants = await runtime.getParticipantsForRoom(message.roomId);
5066
+ logger16.debug(
5067
+ `[\u{1F310}] World provider: Found ${participants.length} participants in room "${currentRoom.name}"`
5068
+ );
5069
+ const channelsByType = {
5070
+ text: [],
5071
+ voice: [],
5072
+ dm: [],
5073
+ feed: [],
5074
+ thread: [],
5075
+ other: []
5076
+ };
5077
+ for (const room of worldRooms) {
5078
+ if (!room?.id || !room.name) {
5079
+ logger16.warn(`World provider: Room ID or name is missing for room ${room.id}`);
5080
+ continue;
5081
+ }
5082
+ const roomInfo = {
5083
+ id: room.id,
5084
+ name: room.name,
5085
+ isCurrentChannel: room.id === message.roomId
5086
+ };
5087
+ if (room.type === ChannelType8.GROUP || room.type === ChannelType8.WORLD || room.type === ChannelType8.FORUM) {
5088
+ channelsByType.text.push(roomInfo);
5089
+ } else if (room.type === ChannelType8.VOICE_GROUP || room.type === ChannelType8.VOICE_DM) {
5090
+ channelsByType.voice.push(roomInfo);
5091
+ } else if (room.type === ChannelType8.DM || room.type === ChannelType8.SELF) {
5092
+ channelsByType.dm.push(roomInfo);
5093
+ } else if (room.type === ChannelType8.FEED) {
5094
+ channelsByType.feed.push(roomInfo);
5095
+ } else if (room.type === ChannelType8.THREAD) {
5096
+ channelsByType.thread.push(roomInfo);
5097
+ } else {
5098
+ channelsByType.other.push({
5099
+ ...roomInfo,
5100
+ type: room.type
5101
+ });
5102
+ }
5103
+ }
5104
+ const worldInfoText = [
5105
+ `# World: ${world.name}`,
5106
+ `Current Channel: ${currentRoom.name} (${currentRoom.type})`,
5107
+ `Total Channels: ${worldRooms.length}`,
5108
+ `Participants in current channel: ${participants.length}`,
5109
+ "",
5110
+ `Text channels: ${channelsByType.text.length}`,
5111
+ `Voice channels: ${channelsByType.voice.length}`,
5112
+ `DM channels: ${channelsByType.dm.length}`,
5113
+ `Feed channels: ${channelsByType.feed.length}`,
5114
+ `Thread channels: ${channelsByType.thread.length}`,
5115
+ `Other channels: ${channelsByType.other.length}`
5116
+ ].join("\n");
5117
+ const data = {
5118
+ world: {
5119
+ id: world.id,
5120
+ name: world.name,
5121
+ serverId: world.serverId,
5122
+ metadata: world.metadata || {},
5123
+ currentRoom: {
5124
+ id: currentRoom.id,
5125
+ name: currentRoom.name,
5126
+ type: currentRoom.type,
5127
+ channelId: currentRoom.channelId,
5128
+ participantCount: participants.length
5129
+ },
5130
+ channels: channelsByType,
5131
+ channelStats: {
5132
+ total: worldRooms.length,
5133
+ text: channelsByType.text.length,
5134
+ voice: channelsByType.voice.length,
5135
+ dm: channelsByType.dm.length,
5136
+ feed: channelsByType.feed.length,
5137
+ thread: channelsByType.thread.length,
5138
+ other: channelsByType.other.length
5139
+ }
5140
+ }
5141
+ };
5142
+ const values = {
5143
+ worldName: world.name,
5144
+ currentChannelName: currentRoom.name,
5145
+ worldInfo: worldInfoText
5146
+ };
5147
+ const formattedText = addHeader9("# World Information", worldInfoText);
5148
+ logger16.debug("[\u{1F310}] World provider completed successfully");
5149
+ return {
5150
+ data,
5151
+ values,
5152
+ text: formattedText
5153
+ };
5154
+ } catch (error) {
5155
+ logger16.error(
5156
+ `Error in world provider: ${error instanceof Error ? error.message : String(error)}`
5157
+ );
5158
+ return {
5159
+ data: {
5160
+ world: {
5161
+ info: "Error retrieving world information",
5162
+ error: error instanceof Error ? error.message : "Unknown error"
5163
+ }
5164
+ },
5165
+ text: "Error retrieving world information"
5166
+ };
5167
+ }
5168
+ }
5169
+ };
5170
+
4858
5171
  // src/services/scenario.ts
4859
5172
  import {
4860
- ChannelType as ChannelType8,
5173
+ ChannelType as ChannelType9,
4861
5174
  EventType,
4862
5175
  Service,
4863
5176
  createUniqueUuid as createUniqueUuid3,
4864
- logger as logger14
5177
+ logger as logger17
4865
5178
  } from "@elizaos/core";
4866
5179
  var ScenarioService = class _ScenarioService extends Service {
4867
5180
  /**
@@ -4875,7 +5188,7 @@ var ScenarioService = class _ScenarioService extends Service {
4875
5188
  this.setupEventListeners();
4876
5189
  }
4877
5190
  static serviceType = "scenario";
4878
- 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.";
5191
+ capabilityDescription = "The agent is currently in a scenario testing environment. It can Create groups, send messages, and talk to other agents in a live interactive testing environment.";
4879
5192
  messageHandlers = /* @__PURE__ */ new Map();
4880
5193
  worlds = /* @__PURE__ */ new Map();
4881
5194
  activeActions = /* @__PURE__ */ new Map();
@@ -4905,7 +5218,7 @@ var ScenarioService = class _ScenarioService extends Service {
4905
5218
  startTime: Date.now(),
4906
5219
  completed: false
4907
5220
  });
4908
- logger14.debug("Evaluator started", data);
5221
+ logger17.debug("[Bootstrap] Evaluator started", data);
4909
5222
  return Promise.resolve();
4910
5223
  });
4911
5224
  this.runtime.registerEvent(
@@ -4916,7 +5229,7 @@ var ScenarioService = class _ScenarioService extends Service {
4916
5229
  evaluator.completed = true;
4917
5230
  evaluator.error = data.error;
4918
5231
  }
4919
- logger14.debug("Evaluator completed", data);
5232
+ logger17.debug("[Bootstrap] Evaluator completed", data);
4920
5233
  return Promise.resolve();
4921
5234
  }
4922
5235
  );
@@ -4995,9 +5308,10 @@ var ScenarioService = class _ScenarioService extends Service {
4995
5308
  id: roomId,
4996
5309
  name,
4997
5310
  source: "scenario",
4998
- type: ChannelType8.GROUP,
5311
+ type: ChannelType9.GROUP,
4999
5312
  channelId: roomId,
5000
- serverId: worldId
5313
+ serverId: worldId,
5314
+ worldId
5001
5315
  });
5002
5316
  return roomId;
5003
5317
  }
@@ -5039,7 +5353,7 @@ var ScenarioService = class _ScenarioService extends Service {
5039
5353
  source: "scenario",
5040
5354
  name: sender.character.name,
5041
5355
  userName: sender.character.name,
5042
- channelType: ChannelType8.GROUP
5356
+ channelType: ChannelType9.GROUP
5043
5357
  }
5044
5358
  };
5045
5359
  const participants = await this.runtime.getParticipantsForRoom(roomId);
@@ -5050,7 +5364,7 @@ var ScenarioService = class _ScenarioService extends Service {
5050
5364
  roomId,
5051
5365
  entityId: participantId,
5052
5366
  source: "scenario",
5053
- type: ChannelType8.GROUP
5367
+ type: ChannelType9.GROUP
5054
5368
  });
5055
5369
  }
5056
5370
  }
@@ -5097,7 +5411,7 @@ var ScenarioService = class _ScenarioService extends Service {
5097
5411
 
5098
5412
  // src/services/task.ts
5099
5413
  import {
5100
- logger as logger15,
5414
+ logger as logger18,
5101
5415
  Service as Service2,
5102
5416
  ServiceType
5103
5417
  } from "@elizaos/core";
@@ -5125,21 +5439,21 @@ var TaskService = class _TaskService extends Service2 {
5125
5439
  this.runtime.registerTaskWorker({
5126
5440
  name: "REPEATING_TEST_TASK",
5127
5441
  validate: async (_runtime, _message, _state) => {
5128
- logger15.debug("Validating repeating test task");
5442
+ logger18.debug("[Bootstrap] Validating repeating test task");
5129
5443
  return true;
5130
5444
  },
5131
5445
  execute: async (_runtime, _options) => {
5132
- logger15.debug("Executing repeating test task");
5446
+ logger18.debug("[Bootstrap] Executing repeating test task");
5133
5447
  }
5134
5448
  });
5135
5449
  this.runtime.registerTaskWorker({
5136
5450
  name: "ONETIME_TEST_TASK",
5137
5451
  validate: async (_runtime, _message, _state) => {
5138
- logger15.debug("Validating one-time test task");
5452
+ logger18.debug("[Bootstrap] Validating one-time test task");
5139
5453
  return true;
5140
5454
  },
5141
5455
  execute: async (_runtime, _options) => {
5142
- logger15.debug("Executing one-time test task");
5456
+ logger18.debug("[Bootstrap] Executing one-time test task");
5143
5457
  }
5144
5458
  });
5145
5459
  const tasks = await this.runtime.getTasksByName("REPEATING_TEST_TASK");
@@ -5176,7 +5490,7 @@ var TaskService = class _TaskService extends Service2 {
5176
5490
  try {
5177
5491
  await this.checkTasks();
5178
5492
  } catch (error) {
5179
- logger15.error("Error checking tasks:", error);
5493
+ logger18.error("[Bootstrap] Error checking tasks:", error);
5180
5494
  }
5181
5495
  }, this.TICK_INTERVAL);
5182
5496
  }
@@ -5205,7 +5519,7 @@ var TaskService = class _TaskService extends Service2 {
5205
5519
  continue;
5206
5520
  }
5207
5521
  } catch (error) {
5208
- logger15.error(`Error validating task ${task.name}:`, error);
5522
+ logger18.error(`[Bootstrap] Error validating task ${task.name}:`, error);
5209
5523
  continue;
5210
5524
  }
5211
5525
  }
@@ -5227,6 +5541,10 @@ var TaskService = class _TaskService extends Service2 {
5227
5541
  const now = Date.now();
5228
5542
  for (const task of tasks) {
5229
5543
  let taskStartTime;
5544
+ if (!task.tags?.includes("repeat")) {
5545
+ await this.executeTask(task);
5546
+ continue;
5547
+ }
5230
5548
  if (typeof task.updatedAt === "number") {
5231
5549
  taskStartTime = task.updatedAt;
5232
5550
  } else if (task.metadata?.updatedAt && typeof task.metadata.updatedAt === "number") {
@@ -5241,15 +5559,22 @@ var TaskService = class _TaskService extends Service2 {
5241
5559
  await this.executeTask(task);
5242
5560
  continue;
5243
5561
  }
5562
+ if (task.metadata?.updatedAt === task.metadata?.createdAt) {
5563
+ if (task.tags?.includes("immediate")) {
5564
+ logger18.debug("[Bootstrap] Immediately running task", task.name);
5565
+ await this.executeTask(task);
5566
+ continue;
5567
+ }
5568
+ }
5244
5569
  if (now - taskStartTime >= updateIntervalMs) {
5245
- logger15.debug(
5246
- `Executing task ${task.name} - interval of ${updateIntervalMs}ms has elapsed`
5570
+ logger18.debug(
5571
+ `[Bootstrap] Executing task ${task.name} - interval of ${updateIntervalMs}ms has elapsed`
5247
5572
  );
5248
5573
  await this.executeTask(task);
5249
5574
  }
5250
5575
  }
5251
5576
  } catch (error) {
5252
- logger15.error("Error checking tasks:", error);
5577
+ logger18.error("[Bootstrap] Error checking tasks:", error);
5253
5578
  }
5254
5579
  }
5255
5580
  /**
@@ -5259,18 +5584,15 @@ var TaskService = class _TaskService extends Service2 {
5259
5584
  */
5260
5585
  async executeTask(task) {
5261
5586
  try {
5262
- if (!task) {
5263
- logger15.debug(`Task ${task.id} not found`);
5587
+ if (!task || !task.id) {
5588
+ logger18.debug(`[Bootstrap] Task not found`);
5264
5589
  return;
5265
5590
  }
5266
5591
  const worker = this.runtime.getTaskWorker(task.name);
5267
5592
  if (!worker) {
5268
- logger15.debug(`No worker found for task type: ${task.name}`);
5593
+ logger18.debug(`[Bootstrap] No worker found for task type: ${task.name}`);
5269
5594
  return;
5270
5595
  }
5271
- logger15.debug(`Executing task ${task.name} (${task.id})`);
5272
- await worker.execute(this.runtime, task.metadata || {}, task);
5273
- logger15.debug("task.tags are", task.tags);
5274
5596
  if (task.tags?.includes("repeat")) {
5275
5597
  await this.runtime.updateTask(task.id, {
5276
5598
  metadata: {
@@ -5278,13 +5600,20 @@ var TaskService = class _TaskService extends Service2 {
5278
5600
  updatedAt: Date.now()
5279
5601
  }
5280
5602
  });
5281
- logger15.debug(`Updated repeating task ${task.name} (${task.id}) with new timestamp`);
5282
- } else {
5603
+ logger18.debug(
5604
+ `[Bootstrap] Updated repeating task ${task.name} (${task.id}) with new timestamp`
5605
+ );
5606
+ }
5607
+ logger18.debug(`[Bootstrap] Executing task ${task.name} (${task.id})`);
5608
+ await worker.execute(this.runtime, task.metadata || {}, task);
5609
+ if (!task.tags?.includes("repeat")) {
5283
5610
  await this.runtime.deleteTask(task.id);
5284
- logger15.debug(`Deleted non-repeating task ${task.name} (${task.id}) after execution`);
5611
+ logger18.debug(
5612
+ `[Bootstrap] Deleted non-repeating task ${task.name} (${task.id}) after execution`
5613
+ );
5285
5614
  }
5286
5615
  } catch (error) {
5287
- logger15.error(`Error executing task ${task.id}:`, error);
5616
+ logger18.error(`[Bootstrap] Error executing task ${task.id}:`, error);
5288
5617
  }
5289
5618
  }
5290
5619
  /**
@@ -5328,184 +5657,382 @@ async function fetchMediaData(attachments) {
5328
5657
  })
5329
5658
  );
5330
5659
  }
5660
+ async function processAttachments(attachments, runtime) {
5661
+ if (!attachments || attachments.length === 0) {
5662
+ return [];
5663
+ }
5664
+ logger19.debug(`[Bootstrap] Processing ${attachments.length} attachment(s)`);
5665
+ const processedAttachments = [];
5666
+ for (const attachment of attachments) {
5667
+ try {
5668
+ const processedAttachment = { ...attachment };
5669
+ if (attachment.contentType === ContentType.IMAGE && !attachment.description) {
5670
+ logger19.debug(`[Bootstrap] Generating description for image: ${attachment.url}`);
5671
+ try {
5672
+ const response = await runtime.useModel(ModelType13.IMAGE_DESCRIPTION, {
5673
+ prompt: imageDescriptionTemplate,
5674
+ imageUrl: attachment.url
5675
+ });
5676
+ if (typeof response === "string") {
5677
+ const parsedXml = parseKeyValueXml(response);
5678
+ if (parsedXml?.description && parsedXml?.text) {
5679
+ processedAttachment.description = parsedXml.description;
5680
+ processedAttachment.title = parsedXml.title || "Image";
5681
+ processedAttachment.text = parsedXml.text;
5682
+ logger19.debug(
5683
+ `[Bootstrap] Generated description: ${processedAttachment.description?.substring(0, 100)}...`
5684
+ );
5685
+ } else {
5686
+ logger19.warn(`[Bootstrap] Failed to parse XML response for image description`);
5687
+ }
5688
+ } else if (response && typeof response === "object" && "description" in response) {
5689
+ processedAttachment.description = response.description;
5690
+ processedAttachment.title = response.title || "Image";
5691
+ processedAttachment.text = response.description;
5692
+ logger19.debug(
5693
+ `[Bootstrap] Generated description: ${processedAttachment.description?.substring(0, 100)}...`
5694
+ );
5695
+ } else {
5696
+ logger19.warn(`[Bootstrap] Unexpected response format for image description`);
5697
+ }
5698
+ } catch (error) {
5699
+ logger19.error(`[Bootstrap] Error generating image description:`, error);
5700
+ }
5701
+ }
5702
+ processedAttachments.push(processedAttachment);
5703
+ } catch (error) {
5704
+ logger19.error(`[Bootstrap] Failed to process attachment ${attachment.url}:`, error);
5705
+ processedAttachments.push(attachment);
5706
+ }
5707
+ }
5708
+ return processedAttachments;
5709
+ }
5710
+ function shouldBypassShouldRespond(runtime, room, source) {
5711
+ if (!room) return false;
5712
+ function normalizeEnvList(value) {
5713
+ if (!value || typeof value !== "string") return [];
5714
+ const cleaned = value.trim().replace(/^\[|\]$/g, "");
5715
+ return cleaned.split(",").map((v) => v.trim()).filter(Boolean);
5716
+ }
5717
+ const defaultBypassTypes = [
5718
+ ChannelType10.DM,
5719
+ ChannelType10.VOICE_DM,
5720
+ ChannelType10.SELF,
5721
+ ChannelType10.API
5722
+ ];
5723
+ const defaultBypassSources = ["client_chat"];
5724
+ const bypassTypesSetting = normalizeEnvList(runtime.getSetting("SHOULD_RESPOND_BYPASS_TYPES"));
5725
+ const bypassSourcesSetting = normalizeEnvList(
5726
+ runtime.getSetting("SHOULD_RESPOND_BYPASS_SOURCES")
5727
+ );
5728
+ const bypassTypes = new Set(
5729
+ [...defaultBypassTypes.map((t) => t.toString()), ...bypassTypesSetting].map(
5730
+ (s) => s.trim().toLowerCase()
5731
+ )
5732
+ );
5733
+ const bypassSources = [...defaultBypassSources, ...bypassSourcesSetting].map(
5734
+ (s) => s.trim().toLowerCase()
5735
+ );
5736
+ const roomType = room.type?.toString().toLowerCase();
5737
+ const sourceStr = source?.toLowerCase() || "";
5738
+ return bypassTypes.has(roomType) || bypassSources.some((pattern) => sourceStr.includes(pattern));
5739
+ }
5331
5740
  var messageReceivedHandler = async ({
5332
5741
  runtime,
5333
5742
  message,
5334
5743
  callback,
5335
5744
  onComplete
5336
5745
  }) => {
5337
- const responseId = v4_default();
5338
- if (!latestResponseIds.has(runtime.agentId)) {
5339
- latestResponseIds.set(runtime.agentId, /* @__PURE__ */ new Map());
5340
- }
5341
- const agentResponses = latestResponseIds.get(runtime.agentId);
5342
- if (!agentResponses) {
5343
- throw new Error("Agent responses map not found");
5344
- }
5345
- agentResponses.set(message.roomId, responseId);
5346
- const runId = asUUID(v4_default());
5347
- const startTime = Date.now();
5348
- await runtime.emitEvent(EventType2.RUN_STARTED, {
5349
- runtime,
5350
- runId,
5351
- messageId: message.id,
5352
- roomId: message.roomId,
5353
- entityId: message.entityId,
5354
- startTime,
5355
- status: "started",
5356
- source: "messageHandler"
5357
- });
5358
5746
  const timeoutDuration = 60 * 60 * 1e3;
5359
- let timeoutId;
5360
- const timeoutPromise = new Promise((_, reject) => {
5361
- timeoutId = setTimeout(async () => {
5362
- await runtime.emitEvent(EventType2.RUN_TIMEOUT, {
5363
- runtime,
5364
- runId,
5365
- messageId: message.id,
5366
- roomId: message.roomId,
5367
- entityId: message.entityId,
5368
- startTime,
5369
- status: "timeout",
5370
- endTime: Date.now(),
5371
- duration: Date.now() - startTime,
5372
- error: "Run exceeded 60 minute timeout",
5373
- source: "messageHandler"
5374
- });
5375
- reject(new Error("Run exceeded 60 minute timeout"));
5376
- }, timeoutDuration);
5377
- });
5378
- const processingPromise = (async () => {
5379
- try {
5380
- if (message.entityId === runtime.agentId) {
5381
- throw new Error("Message is from the agent itself");
5382
- }
5383
- await Promise.all([
5384
- runtime.addEmbeddingToMemory(message),
5385
- runtime.createMemory(message, "messages")
5386
- ]);
5387
- const agentUserState = await runtime.getParticipantUserState(message.roomId, runtime.agentId);
5388
- if (agentUserState === "MUTED" && !message.content.text?.toLowerCase().includes(runtime.character.name.toLowerCase())) {
5389
- logger16.debug("Ignoring muted room");
5390
- return;
5391
- }
5392
- let state = await runtime.composeState(message, [
5393
- "PROVIDERS",
5394
- "SHOULD_RESPOND",
5395
- "CHARACTER",
5396
- "RECENT_MESSAGES",
5397
- "ENTITIES"
5398
- ]);
5399
- const shouldRespondPrompt = composePromptFromState9({
5400
- state,
5401
- template: runtime.character.templates?.shouldRespondTemplate || shouldRespondTemplate
5402
- });
5403
- logger16.debug(
5404
- `*** Should Respond Prompt for ${runtime.character.name} ***
5405
- `,
5406
- shouldRespondPrompt
5407
- );
5408
- const response = await runtime.useModel(ModelType13.TEXT_SMALL, {
5409
- prompt: shouldRespondPrompt
5410
- });
5411
- logger16.debug(`*** Should Respond Response for ${runtime.character.name} ***
5412
- `, response);
5413
- logger16.debug(`*** Raw Response Type: ${typeof response} ***`);
5414
- let processedResponse = response;
5415
- if (typeof response === "string" && response.includes("```")) {
5416
- logger16.debug("*** Response contains code block markers, attempting to clean up ***");
5417
- processedResponse = response.replace(/```json\n|\n```|```/g, "");
5418
- logger16.debug("*** Processed Response ***\n", processedResponse);
5419
- }
5420
- const responseObject = parseJSONObjectFromText4(processedResponse);
5421
- logger16.debug("*** Parsed Response Object ***", responseObject);
5422
- const providers = responseObject?.providers;
5423
- logger16.debug("*** Providers Value ***", providers);
5424
- const shouldRespond = responseObject?.action && responseObject.action === "RESPOND";
5425
- logger16.debug("*** Should Respond ***", shouldRespond);
5426
- state = await runtime.composeState(message, null, providers);
5427
- let responseMessages = [];
5428
- if (shouldRespond) {
5429
- const prompt = composePromptFromState9({
5430
- state,
5431
- template: runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate
5747
+ let timeoutId = void 0;
5748
+ try {
5749
+ logger19.info(`[Bootstrap] Message received from ${message.entityId} in room ${message.roomId}`);
5750
+ const responseId = v4_default();
5751
+ if (!latestResponseIds.has(runtime.agentId)) {
5752
+ latestResponseIds.set(runtime.agentId, /* @__PURE__ */ new Map());
5753
+ }
5754
+ const agentResponses = latestResponseIds.get(runtime.agentId);
5755
+ if (!agentResponses) {
5756
+ throw new Error("Agent responses map not found");
5757
+ }
5758
+ agentResponses.set(message.roomId, responseId);
5759
+ const runId = asUUID(v4_default());
5760
+ const startTime = Date.now();
5761
+ await runtime.emitEvent(EventType2.RUN_STARTED, {
5762
+ runtime,
5763
+ runId,
5764
+ messageId: message.id,
5765
+ roomId: message.roomId,
5766
+ entityId: message.entityId,
5767
+ startTime,
5768
+ status: "started",
5769
+ source: "messageHandler"
5770
+ });
5771
+ const timeoutPromise = new Promise((_, reject) => {
5772
+ timeoutId = setTimeout(async () => {
5773
+ await runtime.emitEvent(EventType2.RUN_TIMEOUT, {
5774
+ runtime,
5775
+ runId,
5776
+ messageId: message.id,
5777
+ roomId: message.roomId,
5778
+ entityId: message.entityId,
5779
+ startTime,
5780
+ status: "timeout",
5781
+ endTime: Date.now(),
5782
+ duration: Date.now() - startTime,
5783
+ error: "Run exceeded 60 minute timeout",
5784
+ source: "messageHandler"
5432
5785
  });
5433
- let responseContent = null;
5434
- let retries = 0;
5435
- const maxRetries = 3;
5436
- while (retries < maxRetries && (!responseContent?.thought || !responseContent?.actions)) {
5437
- const response2 = await runtime.useModel(ModelType13.TEXT_SMALL, {
5438
- prompt
5439
- });
5440
- responseContent = parseJSONObjectFromText4(response2);
5441
- retries++;
5442
- if (!responseContent?.thought && !responseContent?.actions) {
5443
- logger16.warn("*** Missing required fields, retrying... ***");
5444
- }
5786
+ reject(new Error("Run exceeded 60 minute timeout"));
5787
+ }, timeoutDuration);
5788
+ });
5789
+ const processingPromise = (async () => {
5790
+ try {
5791
+ if (message.entityId === runtime.agentId) {
5792
+ logger19.debug(`[Bootstrap] Skipping message from self (${runtime.agentId})`);
5793
+ throw new Error("Message is from the agent itself");
5445
5794
  }
5446
- const currentResponseId = agentResponses.get(message.roomId);
5447
- if (currentResponseId !== responseId) {
5448
- logger16.info(
5449
- `Response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
5450
- );
5795
+ logger19.debug(
5796
+ `[Bootstrap] Processing message: ${truncateToCompleteSentence(message.content.text || "", 50)}...`
5797
+ );
5798
+ logger19.debug("[Bootstrap] Saving message to memory and embeddings");
5799
+ await Promise.all([
5800
+ runtime.addEmbeddingToMemory(message),
5801
+ runtime.createMemory(message, "messages")
5802
+ ]);
5803
+ const agentUserState = await runtime.getParticipantUserState(
5804
+ message.roomId,
5805
+ runtime.agentId
5806
+ );
5807
+ if (agentUserState === "MUTED" && !message.content.text?.toLowerCase().includes(runtime.character.name.toLowerCase())) {
5808
+ logger19.debug(`[Bootstrap] Ignoring muted room ${message.roomId}`);
5451
5809
  return;
5452
5810
  }
5453
- if (responseContent) {
5454
- responseContent.inReplyTo = createUniqueUuid4(runtime, message.id);
5455
- responseMessages = [
5456
- {
5811
+ let state = await runtime.composeState(
5812
+ message,
5813
+ ["ANXIETY", "SHOULD_RESPOND", "ENTITIES", "CHARACTER", "RECENT_MESSAGES", "ACTIONS"],
5814
+ true
5815
+ );
5816
+ const room = await runtime.getRoom(message.roomId);
5817
+ const shouldSkipShouldRespond = shouldBypassShouldRespond(
5818
+ runtime,
5819
+ room ?? void 0,
5820
+ message.content.source
5821
+ );
5822
+ if (message.content.attachments && message.content.attachments.length > 0) {
5823
+ message.content.attachments = await processAttachments(
5824
+ message.content.attachments,
5825
+ runtime
5826
+ );
5827
+ }
5828
+ let shouldRespond = true;
5829
+ if (!shouldSkipShouldRespond) {
5830
+ const shouldRespondPrompt = composePromptFromState9({
5831
+ state,
5832
+ template: runtime.character.templates?.shouldRespondTemplate || shouldRespondTemplate
5833
+ });
5834
+ logger19.debug(
5835
+ `[Bootstrap] Evaluating response for ${runtime.character.name}
5836
+ Prompt: ${shouldRespondPrompt}`
5837
+ );
5838
+ const response = await runtime.useModel(ModelType13.TEXT_SMALL, {
5839
+ prompt: shouldRespondPrompt
5840
+ });
5841
+ logger19.debug(
5842
+ `[Bootstrap] Response evaluation for ${runtime.character.name}:
5843
+ ${response}`
5844
+ );
5845
+ logger19.debug(`[Bootstrap] Response type: ${typeof response}`);
5846
+ const responseObject = parseKeyValueXml(response);
5847
+ logger19.debug("[Bootstrap] Parsed response:", responseObject);
5848
+ shouldRespond = responseObject?.action && responseObject.action === "RESPOND";
5849
+ } else {
5850
+ logger19.debug(
5851
+ `[Bootstrap] Skipping shouldRespond check for ${runtime.character.name} because ${room?.type} ${room?.source}`
5852
+ );
5853
+ shouldRespond = true;
5854
+ }
5855
+ let responseMessages = [];
5856
+ console.log("shouldRespond is", shouldRespond);
5857
+ console.log("shouldSkipShouldRespond", shouldSkipShouldRespond);
5858
+ if (shouldRespond) {
5859
+ state = await runtime.composeState(message, ["ACTIONS"]);
5860
+ if (!state.values.actionNames) {
5861
+ logger19.warn("actionNames data missing from state, even though it was requested");
5862
+ }
5863
+ const prompt = composePromptFromState9({
5864
+ state,
5865
+ template: runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate
5866
+ });
5867
+ let responseContent = null;
5868
+ let retries = 0;
5869
+ const maxRetries = 3;
5870
+ while (retries < maxRetries && (!responseContent?.thought || !responseContent?.actions)) {
5871
+ let response = await runtime.useModel(ModelType13.TEXT_LARGE, {
5872
+ prompt
5873
+ });
5874
+ logger19.debug("[Bootstrap] *** Raw LLM Response ***\n", response);
5875
+ const parsedXml = parseKeyValueXml(response);
5876
+ logger19.debug("[Bootstrap] *** Parsed XML Content ***\n", parsedXml);
5877
+ if (parsedXml) {
5878
+ responseContent = {
5879
+ ...parsedXml,
5880
+ thought: parsedXml.thought || "",
5881
+ actions: parsedXml.actions || ["IGNORE"],
5882
+ providers: parsedXml.providers || [],
5883
+ text: parsedXml.text || "",
5884
+ simple: parsedXml.simple || false
5885
+ };
5886
+ } else {
5887
+ responseContent = null;
5888
+ }
5889
+ retries++;
5890
+ if (!responseContent?.thought || !responseContent?.actions) {
5891
+ logger19.warn(
5892
+ "[Bootstrap] *** Missing required fields (thought or actions), retrying... ***\n",
5893
+ response,
5894
+ parsedXml,
5895
+ responseContent
5896
+ );
5897
+ }
5898
+ }
5899
+ const currentResponseId = agentResponses.get(message.roomId);
5900
+ if (currentResponseId !== responseId) {
5901
+ logger19.info(
5902
+ `Response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
5903
+ );
5904
+ return;
5905
+ }
5906
+ if (responseContent && message.id) {
5907
+ responseContent.inReplyTo = createUniqueUuid4(runtime, message.id);
5908
+ const isSimple = responseContent.actions?.length === 1 && responseContent.actions[0].toUpperCase() === "REPLY" && (!responseContent.providers || responseContent.providers.length === 0);
5909
+ responseContent.simple = isSimple;
5910
+ const responseMesssage = {
5457
5911
  id: asUUID(v4_default()),
5458
5912
  entityId: runtime.agentId,
5459
5913
  agentId: runtime.agentId,
5460
5914
  content: responseContent,
5461
5915
  roomId: message.roomId,
5462
5916
  createdAt: Date.now()
5917
+ };
5918
+ responseMessages = [responseMesssage];
5919
+ }
5920
+ agentResponses.delete(message.roomId);
5921
+ if (agentResponses.size === 0) {
5922
+ latestResponseIds.delete(runtime.agentId);
5923
+ }
5924
+ if (responseContent?.providers?.length && responseContent?.providers?.length > 0) {
5925
+ state = await runtime.composeState(message, responseContent?.providers || []);
5926
+ }
5927
+ if (responseContent && responseContent.simple && responseContent.text) {
5928
+ if (responseContent.providers && responseContent.providers.length > 0) {
5929
+ logger19.debug("[Bootstrap] Simple response used providers", responseContent.providers);
5463
5930
  }
5464
- ];
5465
- callback(responseContent);
5466
- }
5467
- agentResponses.delete(message.roomId);
5468
- if (agentResponses.size === 0) {
5469
- latestResponseIds.delete(runtime.agentId);
5931
+ await callback(responseContent);
5932
+ } else {
5933
+ await runtime.processActions(
5934
+ message,
5935
+ responseMessages,
5936
+ state,
5937
+ async (memory) => {
5938
+ return [];
5939
+ }
5940
+ );
5941
+ if (responseMessages.length) {
5942
+ for (const responseMessage of responseMessages) {
5943
+ if (responseMessage.content.providers && responseMessage.content.providers.length > 0) {
5944
+ logger19.debug(
5945
+ "[Bootstrap] Complex response used providers",
5946
+ responseMessage.content.providers
5947
+ );
5948
+ }
5949
+ }
5950
+ for (const memory of responseMessages) {
5951
+ await callback(memory.content);
5952
+ }
5953
+ }
5954
+ }
5955
+ await runtime.evaluate(
5956
+ message,
5957
+ state,
5958
+ shouldRespond,
5959
+ async (memory) => {
5960
+ return [];
5961
+ },
5962
+ responseMessages
5963
+ );
5964
+ } else {
5965
+ logger19.debug("[Bootstrap] Agent decided not to respond (shouldRespond is false).");
5966
+ const currentResponseId = agentResponses.get(message.roomId);
5967
+ if (currentResponseId !== responseId) {
5968
+ logger19.info(
5969
+ `Ignore response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
5970
+ );
5971
+ return;
5972
+ }
5973
+ if (!message.id) {
5974
+ logger19.error("[Bootstrap] Message ID is missing, cannot create ignore response.");
5975
+ return;
5976
+ }
5977
+ const ignoreContent = {
5978
+ thought: "Agent decided not to respond to this message.",
5979
+ actions: ["IGNORE"],
5980
+ simple: true,
5981
+ // Treat it as simple for callback purposes
5982
+ inReplyTo: createUniqueUuid4(runtime, message.id)
5983
+ // Reference original message
5984
+ };
5985
+ await callback(ignoreContent);
5986
+ const ignoreMemory = {
5987
+ id: asUUID(v4_default()),
5988
+ entityId: runtime.agentId,
5989
+ agentId: runtime.agentId,
5990
+ content: ignoreContent,
5991
+ roomId: message.roomId,
5992
+ createdAt: Date.now()
5993
+ };
5994
+ await runtime.createMemory(ignoreMemory, "messages");
5995
+ logger19.debug("[Bootstrap] Saved ignore response to memory", {
5996
+ memoryId: ignoreMemory.id
5997
+ });
5998
+ agentResponses.delete(message.roomId);
5999
+ if (agentResponses.size === 0) {
6000
+ latestResponseIds.delete(runtime.agentId);
6001
+ }
5470
6002
  }
5471
- await runtime.processActions(message, responseMessages, state, callback);
6003
+ await runtime.emitEvent(EventType2.RUN_ENDED, {
6004
+ runtime,
6005
+ runId,
6006
+ messageId: message.id,
6007
+ roomId: message.roomId,
6008
+ entityId: message.entityId,
6009
+ startTime,
6010
+ status: "completed",
6011
+ endTime: Date.now(),
6012
+ duration: Date.now() - startTime,
6013
+ source: "messageHandler"
6014
+ });
6015
+ } catch (error) {
6016
+ console.error("error is", error);
6017
+ await runtime.emitEvent(EventType2.RUN_ENDED, {
6018
+ runtime,
6019
+ runId,
6020
+ messageId: message.id,
6021
+ roomId: message.roomId,
6022
+ entityId: message.entityId,
6023
+ startTime,
6024
+ status: "error",
6025
+ endTime: Date.now(),
6026
+ duration: Date.now() - startTime,
6027
+ error: error.message,
6028
+ source: "messageHandler"
6029
+ });
5472
6030
  }
5473
- onComplete?.();
5474
- await runtime.evaluate(message, state, shouldRespond, callback, responseMessages);
5475
- await runtime.emitEvent(EventType2.RUN_ENDED, {
5476
- runtime,
5477
- runId,
5478
- messageId: message.id,
5479
- roomId: message.roomId,
5480
- entityId: message.entityId,
5481
- startTime,
5482
- status: "completed",
5483
- endTime: Date.now(),
5484
- duration: Date.now() - startTime,
5485
- source: "messageHandler"
5486
- });
5487
- } catch (error) {
5488
- onComplete?.();
5489
- await runtime.emitEvent(EventType2.RUN_ENDED, {
5490
- runtime,
5491
- runId,
5492
- messageId: message.id,
5493
- roomId: message.roomId,
5494
- entityId: message.entityId,
5495
- startTime,
5496
- status: "completed",
5497
- endTime: Date.now(),
5498
- duration: Date.now() - startTime,
5499
- error: error.message,
5500
- source: "messageHandler"
5501
- });
5502
- throw error;
5503
- }
5504
- })();
5505
- try {
6031
+ })();
5506
6032
  await Promise.race([processingPromise, timeoutPromise]);
5507
6033
  } finally {
5508
6034
  clearTimeout(timeoutId);
6035
+ onComplete?.();
5509
6036
  }
5510
6037
  };
5511
6038
  var reactionReceivedHandler = async ({
@@ -5516,10 +6043,10 @@ var reactionReceivedHandler = async ({
5516
6043
  await runtime.createMemory(message, "messages");
5517
6044
  } catch (error) {
5518
6045
  if (error.code === "23505") {
5519
- logger16.warn("Duplicate reaction memory, skipping");
6046
+ logger19.warn("[Bootstrap] Duplicate reaction memory, skipping");
5520
6047
  return;
5521
6048
  }
5522
- logger16.error("Error in reaction handler:", error);
6049
+ logger19.error("[Bootstrap] Error in reaction handler:", error);
5523
6050
  }
5524
6051
  };
5525
6052
  var postGeneratedHandler = async ({
@@ -5530,7 +6057,7 @@ var postGeneratedHandler = async ({
5530
6057
  roomId,
5531
6058
  source
5532
6059
  }) => {
5533
- logger16.info("Generating new post...");
6060
+ logger19.info("[Bootstrap] Generating new post...");
5534
6061
  await runtime.ensureWorldExists({
5535
6062
  id: worldId,
5536
6063
  name: `${runtime.character.name}'s Feed`,
@@ -5541,7 +6068,7 @@ var postGeneratedHandler = async ({
5541
6068
  id: roomId,
5542
6069
  name: `${runtime.character.name}'s Feed`,
5543
6070
  source,
5544
- type: ChannelType9.FEED,
6071
+ type: ChannelType10.FEED,
5545
6072
  channelId: `${userId}-home`,
5546
6073
  serverId: userId,
5547
6074
  worldId
@@ -5551,30 +6078,116 @@ var postGeneratedHandler = async ({
5551
6078
  entityId: runtime.agentId,
5552
6079
  agentId: runtime.agentId,
5553
6080
  roomId,
5554
- content: {}
6081
+ content: {},
6082
+ metadata: {
6083
+ entityName: runtime.character.name,
6084
+ type: "message"
6085
+ }
5555
6086
  };
5556
- const state = await runtime.composeState(message, null, [
6087
+ let state = await runtime.composeState(message, [
6088
+ "PROVIDERS",
5557
6089
  "CHARACTER",
5558
6090
  "RECENT_MESSAGES",
5559
6091
  "ENTITIES"
5560
6092
  ]);
6093
+ const entity = await runtime.getEntityById(runtime.agentId);
6094
+ if (entity?.metadata?.twitter?.userName) {
6095
+ state.values.twitterUserName = entity?.metadata?.twitter?.userName;
6096
+ }
6097
+ const prompt = composePromptFromState9({
6098
+ state,
6099
+ template: runtime.character.templates?.messageHandlerTemplate || messageHandlerTemplate
6100
+ });
6101
+ let responseContent = null;
6102
+ let retries = 0;
6103
+ const maxRetries = 3;
6104
+ while (retries < maxRetries && (!responseContent?.thought || !responseContent?.actions)) {
6105
+ const response = await runtime.useModel(ModelType13.TEXT_SMALL, {
6106
+ prompt
6107
+ });
6108
+ console.log("prompt is", prompt);
6109
+ console.log("response is", response);
6110
+ const parsedXml = parseKeyValueXml(response);
6111
+ if (parsedXml) {
6112
+ responseContent = {
6113
+ thought: parsedXml.thought || "",
6114
+ actions: parsedXml.actions || ["IGNORE"],
6115
+ providers: parsedXml.providers || [],
6116
+ text: parsedXml.text || "",
6117
+ simple: parsedXml.simple || false
6118
+ };
6119
+ } else {
6120
+ responseContent = null;
6121
+ }
6122
+ retries++;
6123
+ if (!responseContent?.thought || !responseContent?.actions) {
6124
+ logger19.warn(
6125
+ "[Bootstrap] *** Missing required fields, retrying... ***\n",
6126
+ response,
6127
+ parsedXml,
6128
+ responseContent
6129
+ );
6130
+ }
6131
+ }
6132
+ state = await runtime.composeState(message, responseContent?.providers);
5561
6133
  const postPrompt = composePromptFromState9({
5562
6134
  state,
5563
6135
  template: runtime.character.templates?.postCreationTemplate || postCreationTemplate
5564
6136
  });
5565
- const jsonResponse = await runtime.useModel(ModelType13.OBJECT_LARGE, {
5566
- prompt: postPrompt,
5567
- output: "no-schema"
6137
+ const xmlResponseText = await runtime.useModel(ModelType13.TEXT_LARGE, {
6138
+ prompt: postPrompt
5568
6139
  });
6140
+ const parsedXmlResponse = parseKeyValueXml(xmlResponseText);
6141
+ if (!parsedXmlResponse) {
6142
+ logger19.error(
6143
+ "[Bootstrap] Failed to parse XML response for post creation. Raw response:",
6144
+ xmlResponseText
6145
+ );
6146
+ return;
6147
+ }
5569
6148
  function cleanupPostText(text) {
5570
6149
  let cleanedText2 = text.replace(/^['"](.*)['"]$/, "$1");
5571
6150
  cleanedText2 = cleanedText2.replaceAll(/\\n/g, "\n\n");
6151
+ cleanedText2 = cleanedText2.replace(/([^\n])\n([^\n])/g, "$1\n\n$2");
5572
6152
  if (cleanedText2.length > 280) {
5573
6153
  cleanedText2 = truncateToCompleteSentence(cleanedText2, 280);
5574
6154
  }
5575
6155
  return cleanedText2;
5576
6156
  }
5577
- const cleanedText = cleanupPostText(jsonResponse.post);
6157
+ const cleanedText = cleanupPostText(parsedXmlResponse.post || "");
6158
+ const RM = state.providerData?.find((pd) => pd.providerName === "RECENT_MESSAGES");
6159
+ if (RM) {
6160
+ for (const m of RM.data.recentMessages) {
6161
+ if (cleanedText === m.content.text) {
6162
+ logger19.log("[Bootstrap] Already recently posted that, retrying", cleanedText);
6163
+ postGeneratedHandler({
6164
+ runtime,
6165
+ callback,
6166
+ worldId,
6167
+ userId,
6168
+ roomId,
6169
+ source
6170
+ });
6171
+ return;
6172
+ }
6173
+ }
6174
+ }
6175
+ const oaiRefusalRegex = /((i\s+do\s+not|i'm\s+not)\s+(feel\s+)?comfortable\s+generating\s+that\s+type\s+of\s+content)|(inappropriate|explicit|respectful|offensive|guidelines|aim\s+to\s+(be\s+)?helpful|communicate\s+respectfully)/i;
6176
+ const anthropicRefusalRegex = /(i'?m\s+unable\s+to\s+help\s+with\s+that\s+request|due\s+to\s+safety\s+concerns|that\s+may\s+violate\s+(our\s+)?guidelines|provide\s+helpful\s+and\s+safe\s+responses|let'?s\s+try\s+a\s+different\s+direction|goes\s+against\s+(our\s+)?use\s+case\s+policies|ensure\s+safe\s+and\s+responsible\s+use)/i;
6177
+ const googleRefusalRegex = /(i\s+can'?t\s+help\s+with\s+that|that\s+goes\s+against\s+(our\s+)?(policy|policies)|i'?m\s+still\s+learning|response\s+must\s+follow\s+(usage|safety)\s+policies|i'?ve\s+been\s+designed\s+to\s+avoid\s+that)/i;
6178
+ const generalRefusalRegex = /(response\s+was\s+withheld|content\s+was\s+filtered|this\s+request\s+cannot\s+be\s+completed|violates\s+our\s+safety\s+policy|content\s+is\s+not\s+available)/i;
6179
+ if (oaiRefusalRegex.test(cleanedText) || anthropicRefusalRegex.test(cleanedText) || googleRefusalRegex.test(cleanedText) || generalRefusalRegex.test(cleanedText)) {
6180
+ logger19.log("[Bootstrap] Got prompt moderation refusal, retrying", cleanedText);
6181
+ postGeneratedHandler({
6182
+ runtime,
6183
+ callback,
6184
+ worldId,
6185
+ userId,
6186
+ roomId,
6187
+ source
6188
+ });
6189
+ return;
6190
+ }
5578
6191
  const responseMessages = [
5579
6192
  {
5580
6193
  id: v4_default(),
@@ -5583,8 +6196,8 @@ var postGeneratedHandler = async ({
5583
6196
  content: {
5584
6197
  text: cleanedText,
5585
6198
  source,
5586
- channelType: ChannelType9.FEED,
5587
- thought: jsonResponse.thought || "",
6199
+ channelType: ChannelType10.FEED,
6200
+ thought: parsedXmlResponse.thought || "",
5588
6201
  type: "post"
5589
6202
  },
5590
6203
  roomId: message.roomId,
@@ -5592,15 +6205,15 @@ var postGeneratedHandler = async ({
5592
6205
  }
5593
6206
  ];
5594
6207
  for (const message2 of responseMessages) {
5595
- await callback(message2.content);
6208
+ await callback?.(message2.content);
5596
6209
  }
5597
6210
  };
5598
6211
  var syncSingleUser = async (entityId, runtime, serverId, channelId, type, source) => {
5599
- const entity = await runtime.getEntityById(entityId);
5600
- logger16.info(`Syncing user: ${entity.metadata[source].username || entity.id}`);
5601
6212
  try {
6213
+ const entity = await runtime.getEntityById(entityId);
6214
+ logger19.info(`[Bootstrap] Syncing user: ${entity?.metadata?.[source]?.username || entityId}`);
5602
6215
  if (!channelId) {
5603
- logger16.warn(`Cannot sync user ${entity.id} without a valid channelId`);
6216
+ logger19.warn(`[Bootstrap] Cannot sync user ${entity?.id} without a valid channelId`);
5604
6217
  return;
5605
6218
  }
5606
6219
  const roomId = createUniqueUuid4(runtime, channelId);
@@ -5608,17 +6221,19 @@ var syncSingleUser = async (entityId, runtime, serverId, channelId, type, source
5608
6221
  await runtime.ensureConnection({
5609
6222
  entityId,
5610
6223
  roomId,
5611
- userName: entity.metadata[source].username || entity.id,
5612
- name: entity.metadata[source].name || entity.metadata[source].username || `User${entity.id}`,
6224
+ userName: entity?.metadata?.[source].username || entityId,
6225
+ name: entity?.metadata?.[source].name || entity?.metadata?.[source].username || `User${entityId}`,
5613
6226
  source,
5614
6227
  channelId,
5615
6228
  serverId,
5616
6229
  type,
5617
6230
  worldId
5618
6231
  });
5619
- logger16.success(`Successfully synced user: ${entity.id}`);
6232
+ logger19.success(`[Bootstrap] Successfully synced user: ${entity?.id}`);
5620
6233
  } catch (error) {
5621
- logger16.error(`Error syncing user: ${error instanceof Error ? error.message : String(error)}`);
6234
+ logger19.error(
6235
+ `[Bootstrap] Error syncing user: ${error instanceof Error ? error.message : String(error)}`
6236
+ );
5622
6237
  }
5623
6238
  };
5624
6239
  var handleServerSync = async ({
@@ -5629,7 +6244,7 @@ var handleServerSync = async ({
5629
6244
  source,
5630
6245
  onComplete
5631
6246
  }) => {
5632
- logger16.debug(`Handling server sync event for server: ${world.name}`);
6247
+ logger19.debug(`[Bootstrap] Handling server sync event for server: ${world.name}`);
5633
6248
  try {
5634
6249
  await runtime.ensureWorldExists({
5635
6250
  id: world.id,
@@ -5658,14 +6273,22 @@ var handleServerSync = async ({
5658
6273
  for (let i2 = 0; i2 < entities.length; i2 += batchSize) {
5659
6274
  const entityBatch = entities.slice(i2, i2 + batchSize);
5660
6275
  const firstRoomUserIsIn = rooms.length > 0 ? rooms[0] : null;
6276
+ if (!firstRoomUserIsIn) {
6277
+ logger19.warn(`[Bootstrap] No rooms found for syncing users`);
6278
+ continue;
6279
+ }
5661
6280
  await Promise.all(
5662
6281
  entityBatch.map(async (entity) => {
5663
6282
  try {
6283
+ if (!entity?.id) {
6284
+ logger19.warn(`[Bootstrap] No entity ID found for syncing users`);
6285
+ return;
6286
+ }
5664
6287
  await runtime.ensureConnection({
5665
6288
  entityId: entity.id,
5666
6289
  roomId: firstRoomUserIsIn.id,
5667
- userName: entity.metadata[source].username,
5668
- name: entity.metadata[source].name,
6290
+ userName: entity.metadata?.[source].username,
6291
+ name: entity.metadata?.[source].name,
5669
6292
  source,
5670
6293
  channelId: firstRoomUserIsIn.channelId,
5671
6294
  serverId: world.serverId,
@@ -5673,7 +6296,7 @@ var handleServerSync = async ({
5673
6296
  worldId: world.id
5674
6297
  });
5675
6298
  } catch (err) {
5676
- logger16.warn(`Failed to sync user ${entity.metadata.username}: ${err}`);
6299
+ logger19.warn(`[Bootstrap] Failed to sync user ${entity.metadata?.username}: ${err}`);
5677
6300
  }
5678
6301
  })
5679
6302
  );
@@ -5682,17 +6305,58 @@ var handleServerSync = async ({
5682
6305
  }
5683
6306
  }
5684
6307
  }
5685
- logger16.debug(`Successfully synced standardized world structure for ${world.name}`);
6308
+ logger19.debug(`Successfully synced standardized world structure for ${world.name}`);
5686
6309
  onComplete?.();
5687
6310
  } catch (error) {
5688
- logger16.error(
6311
+ logger19.error(
5689
6312
  `Error processing standardized server data: ${error instanceof Error ? error.message : String(error)}`
5690
6313
  );
5691
6314
  }
5692
6315
  };
6316
+ var controlMessageHandler = async ({
6317
+ runtime,
6318
+ message,
6319
+ source
6320
+ }) => {
6321
+ try {
6322
+ logger19.debug(
6323
+ `[controlMessageHandler] Processing control message: ${message.payload.action} for room ${message.roomId}`
6324
+ );
6325
+ const serviceNames = Array.from(runtime.getAllServices().keys());
6326
+ const websocketServiceName = serviceNames.find(
6327
+ (name) => name.toLowerCase().includes("websocket") || name.toLowerCase().includes("socket")
6328
+ );
6329
+ if (websocketServiceName) {
6330
+ const websocketService = runtime.getService(websocketServiceName);
6331
+ if (websocketService && "sendMessage" in websocketService) {
6332
+ await websocketService.sendMessage({
6333
+ type: "controlMessage",
6334
+ payload: {
6335
+ action: message.payload.action,
6336
+ target: message.payload.target,
6337
+ roomId: message.roomId
6338
+ }
6339
+ });
6340
+ logger19.debug(
6341
+ `[controlMessageHandler] Control message ${message.payload.action} sent successfully`
6342
+ );
6343
+ } else {
6344
+ logger19.error("[controlMessageHandler] WebSocket service does not have sendMessage method");
6345
+ }
6346
+ } else {
6347
+ logger19.error("[controlMessageHandler] No WebSocket service found to send control message");
6348
+ }
6349
+ } catch (error) {
6350
+ logger19.error(`[controlMessageHandler] Error processing control message: ${error}`);
6351
+ }
6352
+ };
5693
6353
  var events = {
5694
6354
  [EventType2.MESSAGE_RECEIVED]: [
5695
6355
  async (payload) => {
6356
+ if (!payload.callback) {
6357
+ logger19.error("No callback provided for message");
6358
+ return;
6359
+ }
5696
6360
  await messageReceivedHandler({
5697
6361
  runtime: payload.runtime,
5698
6362
  message: payload.message,
@@ -5703,10 +6367,15 @@ var events = {
5703
6367
  ],
5704
6368
  [EventType2.VOICE_MESSAGE_RECEIVED]: [
5705
6369
  async (payload) => {
6370
+ if (!payload.callback) {
6371
+ logger19.error("No callback provided for voice message");
6372
+ return;
6373
+ }
5706
6374
  await messageReceivedHandler({
5707
6375
  runtime: payload.runtime,
5708
6376
  message: payload.message,
5709
- callback: payload.callback
6377
+ callback: payload.callback,
6378
+ onComplete: payload.onComplete
5710
6379
  });
5711
6380
  }
5712
6381
  ],
@@ -5725,7 +6394,7 @@ var events = {
5725
6394
  ],
5726
6395
  [EventType2.MESSAGE_SENT]: [
5727
6396
  async (payload) => {
5728
- logger16.debug(`Message sent: ${payload.message.content.text}`);
6397
+ logger19.debug(`[Bootstrap] Message sent: ${payload.message.content.text}`);
5729
6398
  }
5730
6399
  ],
5731
6400
  [EventType2.WORLD_JOINED]: [
@@ -5740,6 +6409,18 @@ var events = {
5740
6409
  ],
5741
6410
  [EventType2.ENTITY_JOINED]: [
5742
6411
  async (payload) => {
6412
+ if (!payload.worldId) {
6413
+ logger19.error("[Bootstrap] No callback provided for entity joined");
6414
+ return;
6415
+ }
6416
+ if (!payload.roomId) {
6417
+ logger19.error("[Bootstrap] No roomId provided for entity joined");
6418
+ return;
6419
+ }
6420
+ if (!payload.metadata?.type) {
6421
+ logger19.error("[Bootstrap] No type provided for entity joined");
6422
+ return;
6423
+ }
5743
6424
  await syncSingleUser(
5744
6425
  payload.entityId,
5745
6426
  payload.runtime,
@@ -5762,34 +6443,39 @@ var events = {
5762
6443
  };
5763
6444
  await payload.runtime.updateEntity(entity);
5764
6445
  }
5765
- logger16.info(`User ${payload.entityId} left world ${payload.worldId}`);
6446
+ logger19.info(`[Bootstrap] User ${payload.entityId} left world ${payload.worldId}`);
5766
6447
  } catch (error) {
5767
- logger16.error(`Error handling user left: ${error.message}`);
6448
+ logger19.error(`[Bootstrap] Error handling user left: ${error.message}`);
5768
6449
  }
5769
6450
  }
5770
6451
  ],
5771
6452
  [EventType2.ACTION_STARTED]: [
5772
6453
  async (payload) => {
5773
- logger16.debug(`Action started: ${payload.actionName} (${payload.actionId})`);
6454
+ logger19.debug(`[Bootstrap] Action started: ${payload.actionName} (${payload.actionId})`);
5774
6455
  }
5775
6456
  ],
5776
6457
  [EventType2.ACTION_COMPLETED]: [
5777
6458
  async (payload) => {
5778
6459
  const status = payload.error ? `failed: ${payload.error.message}` : "completed";
5779
- logger16.debug(`Action ${status}: ${payload.actionName} (${payload.actionId})`);
6460
+ logger19.debug(`[Bootstrap] Action ${status}: ${payload.actionName} (${payload.actionId})`);
5780
6461
  }
5781
6462
  ],
5782
6463
  [EventType2.EVALUATOR_STARTED]: [
5783
6464
  async (payload) => {
5784
- logger16.debug(`Evaluator started: ${payload.evaluatorName} (${payload.evaluatorId})`);
6465
+ logger19.debug(
6466
+ `[Bootstrap] Evaluator started: ${payload.evaluatorName} (${payload.evaluatorId})`
6467
+ );
5785
6468
  }
5786
6469
  ],
5787
6470
  [EventType2.EVALUATOR_COMPLETED]: [
5788
6471
  async (payload) => {
5789
6472
  const status = payload.error ? `failed: ${payload.error.message}` : "completed";
5790
- logger16.debug(`Evaluator ${status}: ${payload.evaluatorName} (${payload.evaluatorId})`);
6473
+ logger19.debug(
6474
+ `[Bootstrap] Evaluator ${status}: ${payload.evaluatorName} (${payload.evaluatorId})`
6475
+ );
5791
6476
  }
5792
- ]
6477
+ ],
6478
+ CONTROL_MESSAGE: [controlMessageHandler]
5793
6479
  };
5794
6480
  var bootstrapPlugin = {
5795
6481
  name: "bootstrap",
@@ -5805,15 +6491,15 @@ var bootstrapPlugin = {
5805
6491
  sendMessageAction,
5806
6492
  updateEntityAction,
5807
6493
  choiceAction,
5808
- roles_default,
5809
- settings_default
6494
+ updateRoleAction,
6495
+ updateSettingsAction
5810
6496
  ],
6497
+ // this is jank, these events are not valid
5811
6498
  events,
5812
6499
  evaluators: [reflectionEvaluator],
5813
6500
  providers: [
5814
6501
  evaluatorsProvider,
5815
6502
  anxietyProvider,
5816
- knowledgeProvider,
5817
6503
  timeProvider,
5818
6504
  entitiesProvider,
5819
6505
  relationshipsProvider,
@@ -5826,14 +6512,46 @@ var bootstrapPlugin = {
5826
6512
  providersProvider,
5827
6513
  actionsProvider,
5828
6514
  characterProvider,
5829
- recentMessagesProvider
6515
+ recentMessagesProvider,
6516
+ worldProvider
5830
6517
  ],
5831
6518
  services: [TaskService, ScenarioService]
5832
6519
  };
5833
6520
  var index_default = bootstrapPlugin;
5834
6521
  export {
6522
+ actionsProvider,
6523
+ anxietyProvider,
6524
+ attachmentsProvider,
5835
6525
  bootstrapPlugin,
6526
+ capabilitiesProvider,
6527
+ characterProvider,
6528
+ choiceAction,
6529
+ choiceProvider,
5836
6530
  index_default as default,
5837
- fetchMediaData
6531
+ entitiesProvider,
6532
+ evaluatorsProvider,
6533
+ factsProvider,
6534
+ fetchMediaData,
6535
+ followRoomAction,
6536
+ ignoreAction,
6537
+ muteRoomAction,
6538
+ noneAction,
6539
+ processAttachments,
6540
+ providersProvider,
6541
+ recentMessagesProvider,
6542
+ reflectionEvaluator,
6543
+ relationshipsProvider,
6544
+ replyAction,
6545
+ roleProvider,
6546
+ sendMessageAction,
6547
+ settingsProvider,
6548
+ shouldBypassShouldRespond,
6549
+ timeProvider,
6550
+ unfollowRoomAction,
6551
+ unmuteRoomAction,
6552
+ updateEntityAction,
6553
+ updateRoleAction,
6554
+ updateSettingsAction,
6555
+ worldProvider
5838
6556
  };
5839
6557
  //# sourceMappingURL=index.js.map