@elizaos/plugin-bootstrap 1.0.0-beta.48 → 1.0.0-beta.50

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
@@ -76,7 +76,7 @@ import {
76
76
  composePromptFromState as composePromptFromState9,
77
77
  createUniqueUuid as createUniqueUuid4,
78
78
  EventType as EventType2,
79
- logger as logger17,
79
+ logger as logger19,
80
80
  messageHandlerTemplate,
81
81
  ModelType as ModelType13,
82
82
  postCreationTemplate,
@@ -174,6 +174,10 @@ var choiceAction = {
174
174
  similes: ["SELECT_OPTION", "SELECT", "PICK", "CHOOSE"],
175
175
  description: "Selects an option for a pending task that has multiple options",
176
176
  validate: async (runtime, message, state) => {
177
+ if (!state) {
178
+ logger.error("State is required for validating the action");
179
+ throw new Error("State is required for validating the action");
180
+ }
177
181
  const pendingTasks = await runtime.getTasks({
178
182
  roomId: message.roomId,
179
183
  tags: ["AWAITING_CHOICE"]
@@ -186,121 +190,120 @@ var choiceAction = {
186
190
  return pendingTasks && pendingTasks.length > 0 && pendingTasks.some((task) => task.metadata?.options);
187
191
  },
188
192
  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");
193
+ const pendingTasks = await runtime.getTasks({
194
+ roomId: message.roomId,
195
+ tags: ["AWAITING_CHOICE"]
196
+ });
197
+ if (!pendingTasks?.length) {
198
+ throw new Error("No pending tasks with options found");
199
+ }
200
+ const tasksWithOptions = pendingTasks.filter((task) => task.metadata?.options);
201
+ if (!tasksWithOptions.length) {
202
+ throw new Error("No tasks currently have options to select from.");
203
+ }
204
+ const formattedTasks = tasksWithOptions.map((task) => {
205
+ const shortId = task.id?.substring(0, 8);
206
+ return {
207
+ taskId: shortId,
208
+ fullId: task.id,
209
+ name: task.name,
210
+ options: task.metadata?.options?.map((opt) => ({
211
+ name: typeof opt === "string" ? opt : opt.name,
212
+ description: typeof opt === "string" ? opt : opt.description || opt.name
213
+ }))
214
+ };
215
+ });
216
+ const tasksString = formattedTasks.map((task) => {
217
+ return `Task ID: ${task.taskId} - ${task.name}
218
+ Available options:
219
+ ${task.options?.map((opt) => `- ${opt.name}: ${opt.description}`).join("\n")}`;
220
+ }).join("\n");
221
+ const prompt = composePrompt({
222
+ state: {
223
+ tasks: tasksString,
224
+ recentMessages: message.content.text || ""
225
+ },
226
+ template: optionExtractionTemplate
227
+ });
228
+ const result = await runtime.useModel(ModelType.TEXT_SMALL, {
229
+ prompt,
230
+ stopSequences: []
231
+ });
232
+ const parsed = parseJSONObjectFromText(result);
233
+ const { taskId, selectedOption } = parsed;
234
+ if (taskId && selectedOption) {
235
+ const taskMap = new Map(formattedTasks.map((task) => [task.taskId, task]));
236
+ const taskInfo = taskMap.get(taskId);
237
+ if (!taskInfo) {
238
+ await callback?.({
239
+ text: `Could not find a task matching ID: ${taskId}. Please try again.`,
240
+ actions: ["SELECT_OPTION_ERROR"],
241
+ source: message.content.source
242
+ });
243
+ return;
196
244
  }
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.");
245
+ const selectedTask = tasksWithOptions.find((task) => task.id === taskInfo.fullId);
246
+ if (!selectedTask) {
247
+ await callback?.({
248
+ text: "Error locating the selected task. Please try again.",
249
+ actions: ["SELECT_OPTION_ERROR"],
250
+ source: message.content.source
251
+ });
252
+ return;
200
253
  }
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({
254
+ if (selectedOption === "ABORT") {
255
+ if (!selectedTask?.id) {
256
+ await callback?.({
245
257
  text: "Error locating the selected task. Please try again.",
246
258
  actions: ["SELECT_OPTION_ERROR"],
247
259
  source: message.content.source
248
260
  });
249
261
  return;
250
262
  }
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
- }
263
+ await runtime.deleteTask(selectedTask.id);
264
+ await callback?.({
265
+ text: `Task "${selectedTask.name}" has been cancelled.`,
266
+ actions: ["CHOOSE_OPTION_CANCELLED"],
267
+ source: message.content.source
268
+ });
269
+ return;
270
+ }
271
+ try {
272
+ const taskWorker = runtime.getTaskWorker(selectedTask.name);
273
+ await taskWorker?.execute(runtime, { option: selectedOption }, selectedTask);
274
+ await callback?.({
275
+ text: `Selected option: ${selectedOption} for task: ${selectedTask.name}`,
276
+ actions: ["CHOOSE_OPTION"],
277
+ source: message.content.source
278
+ });
279
+ return;
280
+ } catch (error) {
281
+ logger.error("Error executing task with option:", error);
282
+ await callback?.({
283
+ text: "There was an error processing your selection.",
284
+ actions: ["SELECT_OPTION_ERROR"],
285
+ source: message.content.source
286
+ });
287
+ return;
278
288
  }
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
289
  }
290
+ let optionsText = "Please select a valid option from one of these tasks:\n\n";
291
+ tasksWithOptions.forEach((task) => {
292
+ const shortId = task.id?.substring(0, 8);
293
+ optionsText += `**${task.name}** (ID: ${shortId}):
294
+ `;
295
+ const options = task.metadata?.options?.map(
296
+ (opt) => typeof opt === "string" ? opt : opt.name
297
+ );
298
+ options?.push("ABORT");
299
+ optionsText += options?.map((opt) => `- ${opt}`).join("\n");
300
+ optionsText += "\n\n";
301
+ });
302
+ await callback?.({
303
+ text: optionsText,
304
+ actions: ["SELECT_OPTION_INVALID"],
305
+ source: message.content.source
306
+ });
304
307
  },
305
308
  examples: [
306
309
  [
@@ -369,6 +372,10 @@ var followRoomAction = {
369
372
  return roomState !== "FOLLOWED" && roomState !== "MUTED";
370
373
  },
371
374
  handler: async (runtime, message, state, _options, _callback, _responses) => {
375
+ if (!state) {
376
+ logger2.error("State is required for followRoomAction");
377
+ throw new Error("State is required for followRoomAction");
378
+ }
372
379
  async function _shouldFollow(state2) {
373
380
  const shouldFollowPrompt = composePromptFromState({
374
381
  state: state2,
@@ -965,6 +972,10 @@ var muteRoomAction = {
965
972
  return roomState !== "MUTED";
966
973
  },
967
974
  handler: async (runtime, message, state, _options, _callback, _responses) => {
975
+ if (!state) {
976
+ logger3.error("State is required for muting a room");
977
+ throw new Error("State is required for muting a room");
978
+ }
968
979
  async function _shouldMute(state2) {
969
980
  const shouldMutePrompt = composePromptFromState2({
970
981
  state: state2,
@@ -1438,17 +1449,20 @@ var updateRoleAction = {
1438
1449
  );
1439
1450
  },
1440
1451
  handler: async (runtime, message, state, _options, callback) => {
1452
+ if (!state) {
1453
+ logger4.error("State is required for role assignment");
1454
+ throw new Error("State is required for role assignment");
1455
+ }
1441
1456
  const { roomId } = message;
1442
- const channelType = message.content.channelType;
1443
1457
  const serverId = message.content.serverId;
1444
1458
  const worldId = runtime.getSetting("WORLD_ID");
1445
- let world;
1459
+ let world = null;
1446
1460
  if (worldId) {
1447
1461
  world = await runtime.getWorld(worldId);
1448
1462
  }
1449
1463
  if (!world) {
1450
1464
  logger4.error("World not found");
1451
- await callback({
1465
+ await callback?.({
1452
1466
  text: "I couldn't find the world. This action only works in a world."
1453
1467
  });
1454
1468
  return;
@@ -1518,7 +1532,7 @@ var updateRoleAction = {
1518
1532
  }
1519
1533
  );
1520
1534
  if (!result?.length) {
1521
- await callback({
1535
+ await callback?.({
1522
1536
  text: "No valid role assignments found in the request.",
1523
1537
  actions: ["UPDATE_ROLE"],
1524
1538
  source: "discord"
@@ -1533,8 +1547,8 @@ var updateRoleAction = {
1533
1547
  }
1534
1548
  const currentRole = world.metadata.roles[assignment.entityId];
1535
1549
  if (!canModifyRole(requesterRole, currentRole, assignment.newRole)) {
1536
- await callback({
1537
- text: `You don't have permission to change ${targetEntity.names[0]}'s role to ${assignment.newRole}.`,
1550
+ await callback?.({
1551
+ text: `You don't have permission to change ${targetEntity?.names[0]}'s role to ${assignment.newRole}.`,
1538
1552
  actions: ["UPDATE_ROLE"],
1539
1553
  source: "discord"
1540
1554
  });
@@ -1542,8 +1556,8 @@ var updateRoleAction = {
1542
1556
  }
1543
1557
  world.metadata.roles[assignment.entityId] = assignment.newRole;
1544
1558
  worldUpdated = true;
1545
- await callback({
1546
- text: `Updated ${targetEntity.names[0]}'s role to ${assignment.newRole}.`,
1559
+ await callback?.({
1560
+ text: `Updated ${targetEntity?.names[0]}'s role to ${assignment.newRole}.`,
1547
1561
  actions: ["UPDATE_ROLE"],
1548
1562
  source: "discord"
1549
1563
  });
@@ -1672,6 +1686,18 @@ var sendMessageAction = {
1672
1686
  },
1673
1687
  handler: async (runtime, message, state, _options, callback, responses) => {
1674
1688
  try {
1689
+ if (!state) {
1690
+ logger5.error("State is required for sendMessage action");
1691
+ throw new Error("State is required for sendMessage action");
1692
+ }
1693
+ if (!callback) {
1694
+ logger5.error("Callback is required for sendMessage action");
1695
+ throw new Error("Callback is required for sendMessage action");
1696
+ }
1697
+ if (!responses) {
1698
+ logger5.error("Responses are required for sendMessage action");
1699
+ throw new Error("Responses are required for sendMessage action");
1700
+ }
1675
1701
  for (const response of responses) {
1676
1702
  await callback(response.content);
1677
1703
  }
@@ -1747,7 +1773,7 @@ var sendMessageAction = {
1747
1773
  } else if (targetData.targetType === "room") {
1748
1774
  const rooms = await runtime.getRooms(worldId);
1749
1775
  const targetRoom = rooms.find((r) => {
1750
- return r.name.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
1776
+ return r.name?.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
1751
1777
  });
1752
1778
  if (!targetRoom) {
1753
1779
  await callback({
@@ -1784,7 +1810,7 @@ var sendMessageAction = {
1784
1810
  }
1785
1811
  } catch (error) {
1786
1812
  logger5.error(`Error in sendMessage handler: ${error}`);
1787
- await callback({
1813
+ await callback?.({
1788
1814
  text: "There was an error processing your message request.",
1789
1815
  actions: ["SEND_MESSAGE_ERROR"],
1790
1816
  source: message.content.source
@@ -2020,7 +2046,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2020
2046
  If a setting is mentioned but no clear value is provided, do not include it.
2021
2047
  `;
2022
2048
  try {
2023
- let extractValidSettings = function(obj, worldSettings2) {
2049
+ let extractValidSettings2 = function(obj, worldSettings2) {
2024
2050
  const extracted = [];
2025
2051
  function traverse(node) {
2026
2052
  if (Array.isArray(node)) {
@@ -2040,6 +2066,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2040
2066
  traverse(obj);
2041
2067
  return extracted;
2042
2068
  };
2069
+ var extractValidSettings = extractValidSettings2;
2043
2070
  const result = await runtime.useModel(
2044
2071
  ModelType7.OBJECT_LARGE,
2045
2072
  {
@@ -2061,7 +2088,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
2061
2088
  if (!result) {
2062
2089
  return [];
2063
2090
  }
2064
- const extractedSettings = extractValidSettings(result, worldSettings);
2091
+ const extractedSettings = extractValidSettings2(result, worldSettings);
2065
2092
  return extractedSettings;
2066
2093
  } catch (error) {
2067
2094
  console.error("Error extracting settings:", error);
@@ -2250,10 +2277,10 @@ var updateSettingsAction = {
2250
2277
  if (!worlds) {
2251
2278
  return false;
2252
2279
  }
2253
- const world = worlds.find((world2) => world2.metadata.settings);
2254
- const worldSettings = world.metadata.settings;
2280
+ const world = worlds.find((world2) => world2.metadata?.settings);
2281
+ const worldSettings = world?.metadata?.settings;
2255
2282
  if (!worldSettings) {
2256
- logger6.error(`No settings state found for server ${world.serverId}`);
2283
+ logger6.error(`No settings state found for server ${world?.serverId}`);
2257
2284
  return false;
2258
2285
  }
2259
2286
  logger6.debug(`Found valid settings state for server ${world.serverId}`);
@@ -2265,16 +2292,32 @@ var updateSettingsAction = {
2265
2292
  },
2266
2293
  handler: async (runtime, message, state, _options, callback) => {
2267
2294
  try {
2295
+ if (!state) {
2296
+ logger6.error("State is required for settings handler");
2297
+ throw new Error("State is required for settings handler");
2298
+ }
2299
+ if (!message) {
2300
+ logger6.error("Message is required for settings handler");
2301
+ throw new Error("Message is required for settings handler");
2302
+ }
2303
+ if (!callback) {
2304
+ logger6.error("Callback is required for settings handler");
2305
+ throw new Error("Callback is required for settings handler");
2306
+ }
2268
2307
  logger6.info(`Handler looking for server for user ${message.entityId}`);
2269
2308
  const worlds = await findWorldsForOwner(runtime, message.entityId);
2270
- const serverOwnership = worlds.find((world) => world.metadata.settings);
2309
+ const serverOwnership = worlds?.find((world) => world.metadata?.settings);
2271
2310
  if (!serverOwnership) {
2272
2311
  logger6.error(`No server found for user ${message.entityId} in handler`);
2273
2312
  await generateErrorResponse(runtime, state, callback);
2274
2313
  return;
2275
2314
  }
2276
- const serverId = serverOwnership.serverId;
2315
+ const serverId = serverOwnership?.serverId;
2277
2316
  logger6.info(`Using server ID: ${serverId}`);
2317
+ if (!serverId) {
2318
+ logger6.error(`No server ID found for user ${message.entityId} in handler`);
2319
+ return;
2320
+ }
2278
2321
  const worldSettings = await getWorldSettings(runtime, serverId);
2279
2322
  if (!worldSettings) {
2280
2323
  logger6.error(`No settings state found for server ${serverId} in handler`);
@@ -2311,7 +2354,9 @@ var updateSettingsAction = {
2311
2354
  }
2312
2355
  } catch (error) {
2313
2356
  logger6.error(`Error in settings handler: ${error}`);
2314
- await generateErrorResponse(runtime, state, callback);
2357
+ if (state && callback) {
2358
+ await generateErrorResponse(runtime, state, callback);
2359
+ }
2315
2360
  }
2316
2361
  },
2317
2362
  examples: [
@@ -2529,7 +2574,7 @@ var unfollowRoomAction = {
2529
2574
  const parsedResponse = parseBooleanFromText(response.trim());
2530
2575
  return parsedResponse;
2531
2576
  }
2532
- if (await _shouldUnfollow(state)) {
2577
+ if (state && await _shouldUnfollow(state)) {
2533
2578
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
2534
2579
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
2535
2580
  await runtime.createMemory(
@@ -2892,10 +2937,14 @@ var unmuteRoomAction = {
2892
2937
  logger7.warn(`Unclear boolean response: ${response}, defaulting to false`);
2893
2938
  return false;
2894
2939
  }
2895
- if (await _shouldUnmute(state)) {
2940
+ if (state && await _shouldUnmute(state)) {
2896
2941
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
2897
2942
  }
2898
2943
  const room = await runtime.getRoom(message.roomId);
2944
+ if (!room) {
2945
+ logger7.warn(`Room not found: ${message.roomId}`);
2946
+ return false;
2947
+ }
2899
2948
  await runtime.createMemory(
2900
2949
  {
2901
2950
  entityId: message.entityId,
@@ -3071,6 +3120,22 @@ var updateEntityAction = {
3071
3120
  },
3072
3121
  handler: async (runtime, message, state, _options, callback, responses) => {
3073
3122
  try {
3123
+ if (!state) {
3124
+ logger8.error("State is required for the updateEntity action");
3125
+ throw new Error("State is required for the updateEntity action");
3126
+ }
3127
+ if (!callback) {
3128
+ logger8.error("State is required for the updateEntity action");
3129
+ throw new Error("Callback is required for the updateEntity action");
3130
+ }
3131
+ if (!responses) {
3132
+ logger8.error("Responses are required for the updateEntity action");
3133
+ throw new Error("Responses are required for the updateEntity action");
3134
+ }
3135
+ if (!message) {
3136
+ logger8.error("Message is required for the updateEntity action");
3137
+ throw new Error("Message is required for the updateEntity action");
3138
+ }
3074
3139
  for (const response of responses) {
3075
3140
  await callback(response.content);
3076
3141
  }
@@ -3133,7 +3198,8 @@ var updateEntityAction = {
3133
3198
  data: componentData,
3134
3199
  agentId,
3135
3200
  roomId: message.roomId,
3136
- sourceEntityId
3201
+ sourceEntityId,
3202
+ createdAt: existingComponent.createdAt
3137
3203
  });
3138
3204
  await callback({
3139
3205
  text: `I've updated the ${componentType} information for ${entity.names[0]}.`,
@@ -3149,7 +3215,8 @@ var updateEntityAction = {
3149
3215
  data: componentData,
3150
3216
  agentId,
3151
3217
  roomId: message.roomId,
3152
- sourceEntityId
3218
+ sourceEntityId,
3219
+ createdAt: Date.now()
3153
3220
  });
3154
3221
  await callback({
3155
3222
  text: `I've added new ${componentType} information for ${entity.names[0]}.`,
@@ -3159,7 +3226,7 @@ var updateEntityAction = {
3159
3226
  }
3160
3227
  } catch (error) {
3161
3228
  logger8.error(`Error in updateEntity handler: ${error}`);
3162
- await callback({
3229
+ await callback?.({
3163
3230
  text: "There was an error processing the entity information.",
3164
3231
  actions: ["UPDATE_ENTITY_ERROR"],
3165
3232
  source: message.content.source
@@ -3300,23 +3367,27 @@ function resolveEntity(entityId, entities) {
3300
3367
  }
3301
3368
  let entity;
3302
3369
  entity = entities.find((a2) => a2.id === entityId);
3303
- if (entity) {
3370
+ if (entity?.id) {
3304
3371
  return entity.id;
3305
3372
  }
3306
- entity = entities.find((a2) => a2.id.includes(entityId));
3307
- if (entity) {
3373
+ entity = entities.find((a2) => a2.id?.includes(entityId));
3374
+ if (entity?.id) {
3308
3375
  return entity.id;
3309
3376
  }
3310
3377
  entity = entities.find(
3311
3378
  (a2) => a2.names.some((n2) => n2.toLowerCase().includes(entityId.toLowerCase()))
3312
3379
  );
3313
- if (entity) {
3380
+ if (entity?.id) {
3314
3381
  return entity.id;
3315
3382
  }
3316
3383
  throw new Error(`Could not resolve entityId "${entityId}" to a valid UUID`);
3317
3384
  }
3318
3385
  async function handler(runtime, message, state) {
3319
3386
  const { agentId, roomId } = message;
3387
+ if (!agentId || !roomId) {
3388
+ logger9.warn("Missing agentId or roomId in message", message);
3389
+ return;
3390
+ }
3320
3391
  const [existingRelationships, entities, knownFacts] = await Promise.all([
3321
3392
  runtime.getRelationships({
3322
3393
  entityId: message.entityId
@@ -3331,7 +3402,7 @@ async function handler(runtime, message, state) {
3331
3402
  ]);
3332
3403
  const prompt = composePrompt4({
3333
3404
  state: {
3334
- ...state.values,
3405
+ ...state?.values || {},
3335
3406
  knownFacts: formatFacts(knownFacts),
3336
3407
  roomType: message.content.channelType,
3337
3408
  entitiesInRoom: JSON.stringify(entities),
@@ -3411,7 +3482,10 @@ async function handler(runtime, message, state) {
3411
3482
  });
3412
3483
  }
3413
3484
  }
3414
- await runtime.setCache(`${message.roomId}-reflection-last-processed`, message.id);
3485
+ await runtime.setCache(
3486
+ `${message.roomId}-reflection-last-processed`,
3487
+ message?.id || ""
3488
+ );
3415
3489
  return reflection;
3416
3490
  } catch (error) {
3417
3491
  logger9.error("Error in reflection handler:", error);
@@ -3866,7 +3940,7 @@ var characterProvider = {
3866
3940
  () => Math.random().toString(36).substring(2, 8)
3867
3941
  );
3868
3942
  return example.map((message2) => {
3869
- let messageString = `${message2.name}: ${message2.content.text}${message2.content.action || message2.content.actions ? ` (actions: ${message2.content.action || message2.content.actions.join(", ")})` : ""}`;
3943
+ let messageString = `${message2.name}: ${message2.content.text}${message2.content.action || message2.content.actions ? ` (actions: ${message2.content.action || message2.content.actions?.join(", ")})` : ""}`;
3870
3944
  exampleNames.forEach((name, index) => {
3871
3945
  const placeholder = `{{name${index + 1}}}`;
3872
3946
  messageString = messageString.replaceAll(placeholder, name);
@@ -3880,7 +3954,7 @@ var characterProvider = {
3880
3954
  ) : "";
3881
3955
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
3882
3956
  const isPostFormat = room?.type === ChannelType4.FEED || room?.type === ChannelType4.THREAD;
3883
- const postDirections = character?.style?.all?.length > 0 || character?.style?.post?.length > 0 ? addHeader4(
3957
+ const postDirections = character?.style?.all?.length && character?.style?.all?.length > 0 || character?.style?.post?.length && character?.style?.post?.length > 0 ? addHeader4(
3884
3958
  `# Post Directions for ${character.name}`,
3885
3959
  (() => {
3886
3960
  const all = character?.style?.all || [];
@@ -3888,7 +3962,7 @@ var characterProvider = {
3888
3962
  return [...all, ...post].join("\n");
3889
3963
  })()
3890
3964
  ) : "";
3891
- const messageDirections = character?.style?.all?.length > 0 || character?.style?.chat?.length > 0 ? addHeader4(
3965
+ const messageDirections = character?.style?.all?.length && character?.style?.all?.length > 0 || character?.style?.chat?.length && character?.style?.chat?.length > 0 ? addHeader4(
3892
3966
  `# Message Directions for ${character.name}`,
3893
3967
  (() => {
3894
3968
  const all = character?.style?.all || [];
@@ -3980,7 +4054,7 @@ var choiceProvider = {
3980
4054
  const options = task.metadata.options;
3981
4055
  options.forEach((option) => {
3982
4056
  if (typeof option === "string") {
3983
- const description = task.metadata?.options.find((o) => o.name === option)?.description || "";
4057
+ const description = task.metadata?.options?.find((o) => o.name === option)?.description || "";
3984
4058
  output += ` - \`${option}\` ${description ? `- ${description}` : ""}
3985
4059
  `;
3986
4060
  } else {
@@ -4115,7 +4189,7 @@ function formatEvaluatorExamples(evaluators) {
4115
4189
  const placeholder = `{{name${index + 1}}}`;
4116
4190
  messageString = messageString.replaceAll(placeholder, name);
4117
4191
  });
4118
- return messageString + (message.content.action || message.content.actions ? ` (${message.content.action || message.content.actions.join(", ")})` : "");
4192
+ return messageString + (message.content.action || message.content.actions ? ` (${message.content.action || message.content.actions?.join(", ")})` : "");
4119
4193
  }).join("\n");
4120
4194
  return `Prompt:
4121
4195
  ${formattedPrompt}
@@ -4164,6 +4238,7 @@ var evaluatorsProvider = {
4164
4238
 
4165
4239
  // src/providers/facts.ts
4166
4240
  import { ModelType as ModelType12 } from "@elizaos/core";
4241
+ import { logger as logger12 } from "@elizaos/core";
4167
4242
  function formatFacts2(facts) {
4168
4243
  return facts.reverse().map((fact) => fact.content.text).join("\n");
4169
4244
  }
@@ -4172,59 +4247,72 @@ var factsProvider = {
4172
4247
  description: "Key facts that the agent knows",
4173
4248
  dynamic: true,
4174
4249
  get: async (runtime, message, _state) => {
4175
- const recentMessages = await runtime.getMemories({
4176
- tableName: "messages",
4177
- roomId: message.roomId,
4178
- count: 10,
4179
- unique: false
4180
- });
4181
- const last5Messages = recentMessages.slice(-5).map((message2) => message2.content.text).join("\n");
4182
- const embedding = await runtime.useModel(ModelType12.TEXT_EMBEDDING, {
4183
- text: last5Messages
4184
- });
4185
- const [relevantFacts, recentFactsData] = await Promise.all([
4186
- runtime.searchMemories({
4187
- tableName: "facts",
4188
- embedding,
4189
- roomId: message.roomId,
4190
- worldId: message.worldId,
4191
- count: 6,
4192
- query: message.content.text
4193
- }),
4194
- runtime.searchMemories({
4195
- embedding,
4196
- query: message.content.text,
4197
- tableName: "facts",
4250
+ try {
4251
+ const recentMessages = await runtime.getMemories({
4252
+ tableName: "messages",
4198
4253
  roomId: message.roomId,
4199
- entityId: message.entityId,
4200
- count: 6
4201
- })
4202
- ]);
4203
- const allFacts = [...relevantFacts, ...recentFactsData].filter(
4204
- (fact, index, self) => index === self.findIndex((t) => t.id === fact.id)
4205
- );
4206
- if (allFacts.length === 0) {
4254
+ count: 10,
4255
+ unique: false
4256
+ });
4257
+ const last5Messages = recentMessages.slice(-5).map((message2) => message2.content.text).join("\n");
4258
+ const embedding = await runtime.useModel(ModelType12.TEXT_EMBEDDING, {
4259
+ text: last5Messages
4260
+ });
4261
+ const [relevantFacts, recentFactsData] = await Promise.all([
4262
+ runtime.searchMemories({
4263
+ tableName: "facts",
4264
+ embedding,
4265
+ roomId: message.roomId,
4266
+ worldId: message.worldId,
4267
+ count: 6,
4268
+ query: message.content.text
4269
+ }),
4270
+ runtime.searchMemories({
4271
+ embedding,
4272
+ query: message.content.text,
4273
+ tableName: "facts",
4274
+ roomId: message.roomId,
4275
+ entityId: message.entityId,
4276
+ count: 6
4277
+ })
4278
+ ]);
4279
+ const allFacts = [...relevantFacts, ...recentFactsData].filter(
4280
+ (fact, index, self) => index === self.findIndex((t) => t.id === fact.id)
4281
+ );
4282
+ if (allFacts.length === 0) {
4283
+ return {
4284
+ values: {
4285
+ facts: ""
4286
+ },
4287
+ data: {
4288
+ facts: allFacts
4289
+ },
4290
+ text: "No facts available."
4291
+ };
4292
+ }
4293
+ const formattedFacts = formatFacts2(allFacts);
4294
+ const text = "Key facts that {{agentName}} knows:\n{{formattedFacts}}".replace("{{agentName}}", runtime.character.name).replace("{{formattedFacts}}", formattedFacts);
4207
4295
  return {
4208
4296
  values: {
4209
- facts: ""
4297
+ facts: formattedFacts
4210
4298
  },
4211
4299
  data: {
4212
4300
  facts: allFacts
4213
4301
  },
4214
- text: ""
4302
+ text
4303
+ };
4304
+ } catch (error) {
4305
+ logger12.error("Error in factsProvider:", error);
4306
+ return {
4307
+ values: {
4308
+ facts: ""
4309
+ },
4310
+ data: {
4311
+ facts: []
4312
+ },
4313
+ text: "Error retrieving facts."
4215
4314
  };
4216
4315
  }
4217
- const formattedFacts = formatFacts2(allFacts);
4218
- const text = "Key facts that {{agentName}} knows:\n{{formattedFacts}}".replace("{{agentName}}", runtime.character.name).replace("{{formattedFacts}}", formattedFacts);
4219
- return {
4220
- values: {
4221
- facts: formattedFacts
4222
- },
4223
- data: {
4224
- facts: allFacts
4225
- },
4226
- text
4227
- };
4228
4316
  }
4229
4317
  };
4230
4318
 
@@ -4294,7 +4382,8 @@ import {
4294
4382
  ChannelType as ChannelType5,
4295
4383
  formatMessages,
4296
4384
  formatPosts,
4297
- getEntityDetails as getEntityDetails3
4385
+ getEntityDetails as getEntityDetails3,
4386
+ logger as logger13
4298
4387
  } from "@elizaos/core";
4299
4388
  var getRecentInteractions = async (runtime, sourceEntityId, targetEntityId, excludeRoomId) => {
4300
4389
  const rooms = await runtime.getRoomsForParticipants([sourceEntityId, targetEntityId]);
@@ -4310,120 +4399,158 @@ var recentMessagesProvider = {
4310
4399
  description: "Recent messages, interactions and other memories",
4311
4400
  position: 100,
4312
4401
  get: async (runtime, message) => {
4313
- const { roomId } = message;
4314
- const conversationLength = runtime.getConversationLength();
4315
- const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
4316
- getEntityDetails3({ runtime, roomId }),
4317
- runtime.getRoom(roomId),
4318
- runtime.getMemories({
4319
- tableName: "messages",
4320
- roomId,
4321
- count: conversationLength,
4322
- unique: false
4323
- }),
4324
- message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
4325
- ]);
4326
- const isPostFormat = room?.type === ChannelType5.FEED || room?.type === ChannelType5.THREAD;
4327
- const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([
4328
- formatMessages({
4329
- messages: recentMessagesData,
4330
- entities: entitiesData
4331
- }),
4332
- formatPosts({
4333
- messages: recentMessagesData,
4334
- entities: entitiesData,
4335
- conversationHeader: false
4336
- })
4337
- ]);
4338
- const recentPosts = formattedRecentPosts && formattedRecentPosts.length > 0 ? addHeader9("# Posts in Thread", formattedRecentPosts) : "";
4339
- const metaData = message.metadata;
4340
- const senderName = metaData?.entityName || "unknown";
4341
- const receivedMessageContent = message.content.text;
4342
- const receivedMessageHeader = addHeader9(
4343
- "# Received Message",
4344
- `${senderName}: ${receivedMessageContent}`
4345
- );
4346
- const focusHeader = addHeader9(
4347
- "# \u26A1 Focus your response",
4348
- `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.`
4349
- );
4350
- const recentMessages = formattedRecentMessages && formattedRecentMessages.length > 0 ? addHeader9("# Conversation Messages", formattedRecentMessages) : "";
4351
- const interactionEntityMap = /* @__PURE__ */ new Map();
4352
- if (recentInteractionsData.length > 0) {
4353
- const uniqueEntityIds = [
4354
- ...new Set(
4355
- recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId)
4356
- )
4357
- ];
4358
- const uniqueEntityIdSet = new Set(uniqueEntityIds);
4359
- const entitiesDataIdSet = /* @__PURE__ */ new Set();
4360
- entitiesData.forEach((entity) => {
4361
- if (uniqueEntityIdSet.has(entity.id)) {
4362
- interactionEntityMap.set(entity.id, entity);
4363
- entitiesDataIdSet.add(entity.id);
4364
- }
4365
- });
4366
- const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
4367
- if (remainingEntityIds.length > 0) {
4368
- const entities = await Promise.all(
4369
- remainingEntityIds.map((entityId) => runtime.getEntityById(entityId))
4370
- );
4371
- entities.forEach((entity, index) => {
4372
- if (entity) {
4373
- interactionEntityMap.set(remainingEntityIds[index], entity);
4402
+ try {
4403
+ const { roomId } = message;
4404
+ const conversationLength = runtime.getConversationLength();
4405
+ const [entitiesData, room, recentMessagesData, recentInteractionsData] = await Promise.all([
4406
+ getEntityDetails3({ runtime, roomId }),
4407
+ runtime.getRoom(roomId),
4408
+ runtime.getMemories({
4409
+ tableName: "messages",
4410
+ roomId,
4411
+ count: conversationLength,
4412
+ unique: false
4413
+ }),
4414
+ message.entityId !== runtime.agentId ? getRecentInteractions(runtime, message.entityId, runtime.agentId, roomId) : Promise.resolve([])
4415
+ ]);
4416
+ const isPostFormat = room?.type ? room.type === ChannelType5.FEED || room.type === ChannelType5.THREAD : false;
4417
+ const [formattedRecentMessages, formattedRecentPosts] = await Promise.all([
4418
+ formatMessages({
4419
+ messages: recentMessagesData,
4420
+ entities: entitiesData
4421
+ }),
4422
+ formatPosts({
4423
+ messages: recentMessagesData,
4424
+ entities: entitiesData,
4425
+ conversationHeader: false
4426
+ })
4427
+ ]);
4428
+ const recentPosts = formattedRecentPosts && formattedRecentPosts.length > 0 ? addHeader9("# Posts in Thread", formattedRecentPosts) : "";
4429
+ const recentMessages = formattedRecentMessages && formattedRecentMessages.length > 0 ? addHeader9("# Conversation Messages", formattedRecentMessages) : "";
4430
+ if (!recentPosts && !recentMessages && recentMessagesData.length === 0 && !message.content.text) {
4431
+ return {
4432
+ data: {
4433
+ recentMessages: [],
4434
+ recentInteractions: []
4435
+ },
4436
+ values: {
4437
+ recentPosts: "",
4438
+ recentMessages: "",
4439
+ recentMessageInteractions: "",
4440
+ recentPostInteractions: "",
4441
+ recentInteractions: ""
4442
+ },
4443
+ text: "No recent messages available"
4444
+ };
4445
+ }
4446
+ const metaData = message.metadata;
4447
+ const senderName = metaData?.entityName || "unknown";
4448
+ const receivedMessageContent = message.content.text;
4449
+ const hasReceivedMessage = !!receivedMessageContent?.trim();
4450
+ const receivedMessageHeader = hasReceivedMessage ? addHeader9("# Received Message", `${senderName}: ${receivedMessageContent}`) : "";
4451
+ const focusHeader = hasReceivedMessage ? addHeader9(
4452
+ "# Focus your response",
4453
+ `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.`
4454
+ ) : "";
4455
+ const interactionEntityMap = /* @__PURE__ */ new Map();
4456
+ if (recentInteractionsData.length > 0) {
4457
+ const uniqueEntityIds = [
4458
+ ...new Set(
4459
+ recentInteractionsData.map((message2) => message2.entityId).filter((id) => id !== runtime.agentId)
4460
+ )
4461
+ ];
4462
+ const uniqueEntityIdSet = new Set(uniqueEntityIds);
4463
+ const entitiesDataIdSet = /* @__PURE__ */ new Set();
4464
+ entitiesData.forEach((entity) => {
4465
+ if (uniqueEntityIdSet.has(entity.id)) {
4466
+ interactionEntityMap.set(entity.id, entity);
4467
+ entitiesDataIdSet.add(entity.id);
4374
4468
  }
4375
4469
  });
4470
+ const remainingEntityIds = uniqueEntityIds.filter((id) => !entitiesDataIdSet.has(id));
4471
+ if (remainingEntityIds.length > 0) {
4472
+ const entities = await Promise.all(
4473
+ remainingEntityIds.map((entityId) => runtime.getEntityById(entityId))
4474
+ );
4475
+ entities.forEach((entity, index) => {
4476
+ if (entity) {
4477
+ interactionEntityMap.set(remainingEntityIds[index], entity);
4478
+ }
4479
+ });
4480
+ }
4376
4481
  }
4377
- }
4378
- const getRecentMessageInteractions = async (recentInteractionsData2) => {
4379
- const formattedInteractions = recentInteractionsData2.map((message2) => {
4380
- const isSelf = message2.entityId === runtime.agentId;
4381
- let sender;
4382
- if (isSelf) {
4383
- sender = runtime.character.name;
4384
- } else {
4385
- sender = interactionEntityMap.get(message2.entityId)?.metadata?.username || "unknown";
4482
+ const getRecentMessageInteractions = async (recentInteractionsData2) => {
4483
+ const formattedInteractions = recentInteractionsData2.map((message2) => {
4484
+ const isSelf = message2.entityId === runtime.agentId;
4485
+ let sender;
4486
+ if (isSelf) {
4487
+ sender = runtime.character.name;
4488
+ } else {
4489
+ sender = interactionEntityMap.get(message2.entityId)?.metadata?.username || "unknown";
4490
+ }
4491
+ return `${sender}: ${message2.content.text}`;
4492
+ });
4493
+ return formattedInteractions.join("\n");
4494
+ };
4495
+ const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
4496
+ const combinedEntities = [...entities];
4497
+ const actorIds = new Set(entities.map((entity) => entity.id));
4498
+ for (const [id, entity] of interactionEntityMap.entries()) {
4499
+ if (!actorIds.has(id)) {
4500
+ combinedEntities.push(entity);
4501
+ }
4386
4502
  }
4387
- return `${sender}: ${message2.content.text}`;
4388
- });
4389
- return formattedInteractions.join("\n");
4390
- };
4391
- const getRecentPostInteractions = async (recentInteractionsData2, entities) => {
4392
- const combinedEntities = [...entities];
4393
- const actorIds = new Set(entities.map((entity) => entity.id));
4394
- for (const [id, entity] of interactionEntityMap.entries()) {
4395
- if (!actorIds.has(id)) {
4396
- combinedEntities.push(entity);
4397
- }
4398
- }
4399
- const formattedInteractions = formatPosts({
4400
- messages: recentInteractionsData2,
4401
- entities: combinedEntities,
4402
- conversationHeader: true
4403
- });
4404
- return formattedInteractions;
4405
- };
4406
- const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
4407
- getRecentMessageInteractions(recentInteractionsData),
4408
- getRecentPostInteractions(recentInteractionsData, entitiesData)
4409
- ]);
4410
- const data = {
4411
- recentMessages: recentMessagesData,
4412
- recentInteractions: recentInteractionsData
4413
- };
4414
- const values = {
4415
- recentPosts,
4416
- recentMessages,
4417
- recentMessageInteractions,
4418
- recentPostInteractions,
4419
- recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions
4420
- };
4421
- const text = [isPostFormat ? recentPosts : recentMessages + receivedMessageHeader + focusHeader].filter(Boolean).join("\n\n");
4422
- return {
4423
- data,
4424
- values,
4425
- text
4426
- };
4503
+ const formattedInteractions = formatPosts({
4504
+ messages: recentInteractionsData2,
4505
+ entities: combinedEntities,
4506
+ conversationHeader: true
4507
+ });
4508
+ return formattedInteractions;
4509
+ };
4510
+ const [recentMessageInteractions, recentPostInteractions] = await Promise.all([
4511
+ getRecentMessageInteractions(recentInteractionsData),
4512
+ getRecentPostInteractions(recentInteractionsData, entitiesData)
4513
+ ]);
4514
+ const data = {
4515
+ recentMessages: recentMessagesData,
4516
+ recentInteractions: recentInteractionsData
4517
+ };
4518
+ const values = {
4519
+ recentPosts,
4520
+ recentMessages,
4521
+ recentMessageInteractions,
4522
+ recentPostInteractions,
4523
+ recentInteractions: isPostFormat ? recentPostInteractions : recentMessageInteractions
4524
+ };
4525
+ const text = [
4526
+ isPostFormat ? recentPosts : recentMessages,
4527
+ // Only add received message and focus headers if there are messages or a current message to process
4528
+ recentMessages || recentPosts || message.content.text ? receivedMessageHeader : "",
4529
+ recentMessages || recentPosts || message.content.text ? focusHeader : ""
4530
+ ].filter(Boolean).join("\n\n");
4531
+ return {
4532
+ data,
4533
+ values,
4534
+ text
4535
+ };
4536
+ } catch (error) {
4537
+ logger13.error("Error in recentMessagesProvider:", error);
4538
+ return {
4539
+ data: {
4540
+ recentMessages: [],
4541
+ recentInteractions: []
4542
+ },
4543
+ values: {
4544
+ recentPosts: "",
4545
+ recentMessages: "",
4546
+ recentMessageInteractions: "",
4547
+ recentPostInteractions: "",
4548
+ recentInteractions: ""
4549
+ },
4550
+ text: "Error retrieving recent messages."
4551
+ // Or 'No recent messages available' as the test expects
4552
+ };
4553
+ }
4427
4554
  }
4428
4555
  };
4429
4556
 
@@ -4512,7 +4639,7 @@ ${formattedRelationships}`
4512
4639
  import {
4513
4640
  ChannelType as ChannelType6,
4514
4641
  createUniqueUuid as createUniqueUuid2,
4515
- logger as logger12
4642
+ logger as logger14
4516
4643
  } from "@elizaos/core";
4517
4644
  var roleProvider = {
4518
4645
  name: "ROLES",
@@ -4537,106 +4664,108 @@ var roleProvider = {
4537
4664
  if (!serverId) {
4538
4665
  throw new Error("No server ID found");
4539
4666
  }
4540
- try {
4541
- logger12.info(`Using server ID: ${serverId}`);
4542
- const worldId = createUniqueUuid2(runtime, serverId);
4543
- const world = await runtime.getWorld(worldId);
4544
- if (!world || !world.metadata?.ownership?.ownerId) {
4545
- logger12.info(
4546
- `No ownership data found for server ${serverId}, initializing empty role hierarchy`
4547
- );
4548
- return {
4549
- data: {
4550
- roles: []
4551
- },
4552
- values: {
4553
- roles: "No role information available for this server."
4554
- },
4555
- text: "No role information available for this server."
4556
- };
4557
- }
4558
- const roles = world.metadata.roles || {};
4559
- if (Object.keys(roles).length === 0) {
4560
- logger12.info(`No roles found for server ${serverId}`);
4561
- return {
4562
- data: {
4563
- roles: []
4564
- },
4565
- values: {
4566
- roles: "No role information available for this server."
4567
- }
4568
- };
4569
- }
4570
- logger12.info(`Found ${Object.keys(roles).length} roles`);
4571
- const owners = [];
4572
- const admins = [];
4573
- const members = [];
4574
- for (const entityId of Object.keys(roles)) {
4575
- const userRole = roles[entityId];
4576
- const user = await runtime.getEntityById(entityId);
4577
- const name = user.metadata[room.source]?.name;
4578
- const username = user.metadata[room.source]?.username;
4579
- const names = user.names;
4580
- if (owners.some((owner) => owner.username === username) || admins.some((admin) => admin.username === username) || members.some((member) => member.username === username)) {
4581
- continue;
4582
- }
4583
- switch (userRole) {
4584
- case "OWNER":
4585
- owners.push({ name, username, names });
4586
- break;
4587
- case "ADMIN":
4588
- admins.push({ name, username, names });
4589
- break;
4590
- default:
4591
- members.push({ name, username, names });
4592
- break;
4593
- }
4594
- }
4595
- let response = "# Server Role Hierarchy\n\n";
4596
- if (owners.length > 0) {
4597
- response += "## Owners\n";
4598
- owners.forEach((owner) => {
4599
- response += `${owner.name} (${owner.names.join(", ")})
4600
- `;
4601
- });
4602
- response += "\n";
4603
- }
4604
- if (admins.length > 0) {
4605
- response += "## Administrators\n";
4606
- admins.forEach((admin) => {
4607
- response += `${admin.name} (${admin.names.join(", ")}) (${admin.username})
4608
- `;
4609
- });
4610
- response += "\n";
4611
- }
4612
- if (members.length > 0) {
4613
- response += "## Members\n";
4614
- members.forEach((member) => {
4615
- response += `${member.name} (${member.names.join(", ")}) (${member.username})
4616
- `;
4617
- });
4618
- }
4667
+ logger14.info(`Using server ID: ${serverId}`);
4668
+ const worldId = createUniqueUuid2(runtime, serverId);
4669
+ const world = await runtime.getWorld(worldId);
4670
+ if (!world || !world.metadata?.ownership?.ownerId) {
4671
+ logger14.info(
4672
+ `No ownership data found for server ${serverId}, initializing empty role hierarchy`
4673
+ );
4619
4674
  return {
4620
4675
  data: {
4621
- roles: response
4676
+ roles: []
4622
4677
  },
4623
4678
  values: {
4624
- roles: response
4679
+ roles: "No role information available for this server."
4625
4680
  },
4626
- text: response
4681
+ text: "No role information available for this server."
4627
4682
  };
4628
- } catch (error) {
4629
- logger12.error("Error in role provider:", error);
4683
+ }
4684
+ const roles = world.metadata.roles || {};
4685
+ if (Object.keys(roles).length === 0) {
4686
+ logger14.info(`No roles found for server ${serverId}`);
4630
4687
  return {
4631
4688
  data: {
4632
4689
  roles: []
4633
4690
  },
4634
4691
  values: {
4635
- roles: "There was an error retrieving role information."
4692
+ roles: "No role information available for this server."
4693
+ }
4694
+ };
4695
+ }
4696
+ logger14.info(`Found ${Object.keys(roles).length} roles`);
4697
+ const owners = [];
4698
+ const admins = [];
4699
+ const members = [];
4700
+ for (const entityId of Object.keys(roles)) {
4701
+ const userRole = roles[entityId];
4702
+ const user = await runtime.getEntityById(entityId);
4703
+ const name = user?.metadata?.[room.source]?.name;
4704
+ const username = user?.metadata?.[room.source]?.username;
4705
+ const names = user?.names;
4706
+ if (owners.some((owner) => owner.username === username) || admins.some((admin) => admin.username === username) || members.some((member) => member.username === username)) {
4707
+ continue;
4708
+ }
4709
+ if (!name || !username || !names) {
4710
+ logger14.warn(`User ${entityId} has no name or username, skipping`);
4711
+ continue;
4712
+ }
4713
+ switch (userRole) {
4714
+ case "OWNER":
4715
+ owners.push({ name, username, names });
4716
+ break;
4717
+ case "ADMIN":
4718
+ admins.push({ name, username, names });
4719
+ break;
4720
+ default:
4721
+ members.push({ name, username, names });
4722
+ break;
4723
+ }
4724
+ }
4725
+ let response = "# Server Role Hierarchy\n\n";
4726
+ if (owners.length > 0) {
4727
+ response += "## Owners\n";
4728
+ owners.forEach((owner) => {
4729
+ response += `${owner.name} (${owner.names.join(", ")})
4730
+ `;
4731
+ });
4732
+ response += "\n";
4733
+ }
4734
+ if (admins.length > 0) {
4735
+ response += "## Administrators\n";
4736
+ admins.forEach((admin) => {
4737
+ response += `${admin.name} (${admin.names.join(", ")}) (${admin.username})
4738
+ `;
4739
+ });
4740
+ response += "\n";
4741
+ }
4742
+ if (members.length > 0) {
4743
+ response += "## Members\n";
4744
+ members.forEach((member) => {
4745
+ response += `${member.name} (${member.names.join(", ")}) (${member.username})
4746
+ `;
4747
+ });
4748
+ }
4749
+ if (owners.length === 0 && admins.length === 0 && members.length === 0) {
4750
+ return {
4751
+ data: {
4752
+ roles: []
4753
+ },
4754
+ values: {
4755
+ roles: "No role information available for this server."
4636
4756
  },
4637
- text: "There was an error retrieving role information."
4757
+ text: "No role information available for this server."
4638
4758
  };
4639
4759
  }
4760
+ return {
4761
+ data: {
4762
+ roles: response
4763
+ },
4764
+ values: {
4765
+ roles: response
4766
+ },
4767
+ text: response
4768
+ };
4640
4769
  }
4641
4770
  };
4642
4771
 
@@ -4645,7 +4774,7 @@ import {
4645
4774
  ChannelType as ChannelType7,
4646
4775
  findWorldsForOwner as findWorldsForOwner2,
4647
4776
  getWorldSettings as getWorldSettings2,
4648
- logger as logger13
4777
+ logger as logger15
4649
4778
  } from "@elizaos/core";
4650
4779
  var formatSettingValue = (setting, isOnboarding) => {
4651
4780
  if (setting.value === null) return "Not set";
@@ -4672,13 +4801,13 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4672
4801
  };
4673
4802
  }).filter(Boolean);
4674
4803
  const requiredUnconfigured = formattedSettings.filter(
4675
- (s) => s.required && !s.configured
4804
+ (s) => s?.required && !s.configured
4676
4805
  ).length;
4677
4806
  if (isOnboarding) {
4678
4807
  const settingsList = formattedSettings.map((s) => {
4679
- const label = s.required ? "(Required)" : "(Optional)";
4680
- return `${s.key}: ${s.value} ${label}
4681
- (${s.name}) ${s.usageDescription}`;
4808
+ const label = s?.required ? "(Required)" : "(Optional)";
4809
+ return `${s?.key}: ${s?.value} ${label}
4810
+ (${s?.name}) ${s?.usageDescription}`;
4682
4811
  }).join("\n\n");
4683
4812
  const validKeys = `Valid setting keys: ${Object.keys(worldSettings).join(", ")}`;
4684
4813
  const commonInstructions = `Instructions for ${runtime.character.name}:
@@ -4688,7 +4817,7 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4688
4817
  - 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.
4689
4818
  - Answer setting-related questions using only the name, description, and value from the list.`;
4690
4819
  if (requiredUnconfigured > 0) {
4691
- return `# PRIORITY TASK: Onboarding with ${state.senderName}
4820
+ return `# PRIORITY TASK: Onboarding with ${state?.senderName}
4692
4821
 
4693
4822
  ${runtime.character.name} needs to help the user configure ${requiredUnconfigured} required settings:
4694
4823
 
@@ -4712,11 +4841,11 @@ function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
4712
4841
 
4713
4842
  ${requiredUnconfigured > 0 ? `IMPORTANT!: ${requiredUnconfigured} required settings still need configuration. ${runtime.character.name} should get onboarded with the OWNER as soon as possible.
4714
4843
 
4715
- ` : "All required settings are configured.\n\n"}${formattedSettings.map((s) => `### ${s.name}
4716
- **Value:** ${s.value}
4717
- **Description:** ${s.description}`).join("\n\n")}`;
4844
+ ` : "All required settings are configured.\n\n"}${formattedSettings.map((s) => `### ${s?.name}
4845
+ **Value:** ${s?.value}
4846
+ **Description:** ${s?.description}`).join("\n\n")}`;
4718
4847
  } catch (error) {
4719
- logger13.error(`Error generating status message: ${error}`);
4848
+ logger15.error(`Error generating status message: ${error}`);
4720
4849
  return "Error generating configuration status.";
4721
4850
  }
4722
4851
  }
@@ -4729,11 +4858,11 @@ var settingsProvider = {
4729
4858
  runtime.getRoom(message.roomId),
4730
4859
  findWorldsForOwner2(runtime, message.entityId)
4731
4860
  ]).catch((error) => {
4732
- logger13.error(`Error fetching initial data: ${error}`);
4861
+ logger15.error(`Error fetching initial data: ${error}`);
4733
4862
  throw new Error("Failed to retrieve room or user world information");
4734
4863
  });
4735
4864
  if (!room) {
4736
- logger13.error("No room found for settings provider");
4865
+ logger15.error("No room found for settings provider");
4737
4866
  return {
4738
4867
  data: {
4739
4868
  settings: []
@@ -4745,7 +4874,7 @@ var settingsProvider = {
4745
4874
  };
4746
4875
  }
4747
4876
  if (!room.worldId) {
4748
- logger13.debug("No world found for settings provider -- settings provider will be skipped");
4877
+ logger15.debug("No world found for settings provider -- settings provider will be skipped");
4749
4878
  return {
4750
4879
  data: {
4751
4880
  settings: []
@@ -4758,42 +4887,42 @@ var settingsProvider = {
4758
4887
  }
4759
4888
  const type = room.type;
4760
4889
  const isOnboarding = type === ChannelType7.DM;
4761
- let world;
4762
- let serverId;
4763
- let worldSettings;
4890
+ let world = null;
4891
+ let serverId = void 0;
4892
+ let worldSettings = null;
4764
4893
  if (isOnboarding) {
4765
- world = userWorlds.find((world2) => world2.metadata.settings);
4894
+ world = userWorlds?.find((world2) => world2.metadata?.settings);
4766
4895
  if (!world) {
4767
- logger13.error("No world found for user during onboarding");
4896
+ logger15.error("No world found for user during onboarding");
4768
4897
  throw new Error("No server ownership found for onboarding");
4769
4898
  }
4770
4899
  serverId = world.serverId;
4771
4900
  try {
4772
4901
  worldSettings = await getWorldSettings2(runtime, serverId);
4773
4902
  } catch (error) {
4774
- logger13.error(`Error fetching world settings: ${error}`);
4903
+ logger15.error(`Error fetching world settings: ${error}`);
4775
4904
  throw new Error(`Failed to retrieve settings for server ${serverId}`);
4776
4905
  }
4777
4906
  } else {
4778
4907
  try {
4779
4908
  world = await runtime.getWorld(room.worldId);
4780
4909
  if (!world) {
4781
- logger13.error(`No world found for room ${room.worldId}`);
4910
+ logger15.error(`No world found for room ${room.worldId}`);
4782
4911
  throw new Error(`No world found for room ${room.worldId}`);
4783
4912
  }
4784
4913
  serverId = world.serverId;
4785
4914
  if (serverId) {
4786
4915
  worldSettings = await getWorldSettings2(runtime, serverId);
4787
4916
  } else {
4788
- logger13.error(`No server ID found for world ${room.worldId}`);
4917
+ logger15.error(`No server ID found for world ${room.worldId}`);
4789
4918
  }
4790
4919
  } catch (error) {
4791
- logger13.error(`Error processing world data: ${error}`);
4920
+ logger15.error(`Error processing world data: ${error}`);
4792
4921
  throw new Error("Failed to process world information");
4793
4922
  }
4794
4923
  }
4795
4924
  if (!serverId) {
4796
- logger13.info(
4925
+ logger15.info(
4797
4926
  `No server ownership found for user ${message.entityId} after recovery attempt`
4798
4927
  );
4799
4928
  return isOnboarding ? {
@@ -4815,7 +4944,7 @@ var settingsProvider = {
4815
4944
  };
4816
4945
  }
4817
4946
  if (!worldSettings) {
4818
- logger13.info(`No settings state found for server ${serverId}`);
4947
+ logger15.info(`No settings state found for server ${serverId}`);
4819
4948
  return isOnboarding ? {
4820
4949
  data: {
4821
4950
  settings: []
@@ -4845,7 +4974,7 @@ var settingsProvider = {
4845
4974
  text: output
4846
4975
  };
4847
4976
  } catch (error) {
4848
- logger13.error(`Critical error in settings provider: ${error}`);
4977
+ logger15.error(`Critical error in settings provider: ${error}`);
4849
4978
  return {
4850
4979
  data: {
4851
4980
  settings: []
@@ -4884,7 +5013,7 @@ var timeProvider = {
4884
5013
 
4885
5014
  // src/providers/world.ts
4886
5015
  import {
4887
- logger as logger14,
5016
+ logger as logger16,
4888
5017
  addHeader as addHeader10,
4889
5018
  ChannelType as ChannelType8
4890
5019
  } from "@elizaos/core";
@@ -4894,10 +5023,10 @@ var worldProvider = {
4894
5023
  dynamic: true,
4895
5024
  get: async (runtime, message) => {
4896
5025
  try {
4897
- logger14.debug("\u{1F310} World provider activated for roomId:", message.roomId);
5026
+ logger16.debug("\u{1F310} World provider activated for roomId:", message.roomId);
4898
5027
  const currentRoom = await runtime.getRoom(message.roomId);
4899
5028
  if (!currentRoom) {
4900
- logger14.warn(`World provider: Room not found for roomId ${message.roomId}`);
5029
+ logger16.warn(`World provider: Room not found for roomId ${message.roomId}`);
4901
5030
  return {
4902
5031
  data: {
4903
5032
  world: {
@@ -4907,11 +5036,22 @@ var worldProvider = {
4907
5036
  text: "Unable to retrieve world information - room not found"
4908
5037
  };
4909
5038
  }
4910
- logger14.debug(`\u{1F310} World provider: Found room "${currentRoom.name}" (${currentRoom.type})`);
5039
+ logger16.debug(`\u{1F310} World provider: Found room "${currentRoom.name}" (${currentRoom.type})`);
4911
5040
  const worldId = currentRoom.worldId;
5041
+ if (!worldId) {
5042
+ logger16.warn(`World provider: World ID not found for roomId ${message.roomId}`);
5043
+ return {
5044
+ data: {
5045
+ world: {
5046
+ info: "Unable to retrieve world information - world ID not found"
5047
+ }
5048
+ },
5049
+ text: "Unable to retrieve world information - world ID not found"
5050
+ };
5051
+ }
4912
5052
  const world = await runtime.getWorld(worldId);
4913
5053
  if (!world) {
4914
- logger14.warn(`World provider: World not found for worldId ${worldId}`);
5054
+ logger16.warn(`World provider: World not found for worldId ${worldId}`);
4915
5055
  return {
4916
5056
  data: {
4917
5057
  world: {
@@ -4921,11 +5061,11 @@ var worldProvider = {
4921
5061
  text: "Unable to retrieve world information - world not found"
4922
5062
  };
4923
5063
  }
4924
- logger14.debug(`\u{1F310} World provider: Found world "${world.name}" (ID: ${world.id})`);
5064
+ logger16.debug(`\u{1F310} World provider: Found world "${world.name}" (ID: ${world.id})`);
4925
5065
  const worldRooms = await runtime.getRooms(worldId);
4926
- logger14.debug(`\u{1F310} World provider: Found ${worldRooms.length} rooms in world "${world.name}"`);
5066
+ logger16.debug(`\u{1F310} World provider: Found ${worldRooms.length} rooms in world "${world.name}"`);
4927
5067
  const participants = await runtime.getParticipantsForRoom(message.roomId);
4928
- logger14.debug(
5068
+ logger16.debug(
4929
5069
  `\u{1F310} World provider: Found ${participants.length} participants in room "${currentRoom.name}"`
4930
5070
  );
4931
5071
  const channelsByType = {
@@ -4937,6 +5077,10 @@ var worldProvider = {
4937
5077
  other: []
4938
5078
  };
4939
5079
  for (const room of worldRooms) {
5080
+ if (!room?.id || !room.name) {
5081
+ logger16.warn(`World provider: Room ID or name is missing for room ${room.id}`);
5082
+ continue;
5083
+ }
4940
5084
  const roomInfo = {
4941
5085
  id: room.id,
4942
5086
  name: room.name,
@@ -5003,14 +5147,14 @@ var worldProvider = {
5003
5147
  worldInfo: worldInfoText
5004
5148
  };
5005
5149
  const formattedText = addHeader10("# World Information", worldInfoText);
5006
- logger14.debug("\u{1F310} World provider completed successfully");
5150
+ logger16.debug("\u{1F310} World provider completed successfully");
5007
5151
  return {
5008
5152
  data,
5009
5153
  values,
5010
5154
  text: formattedText
5011
5155
  };
5012
5156
  } catch (error) {
5013
- logger14.error(
5157
+ logger16.error(
5014
5158
  `Error in world provider: ${error instanceof Error ? error.message : String(error)}`
5015
5159
  );
5016
5160
  return {
@@ -5032,7 +5176,7 @@ import {
5032
5176
  EventType,
5033
5177
  Service,
5034
5178
  createUniqueUuid as createUniqueUuid3,
5035
- logger as logger15
5179
+ logger as logger17
5036
5180
  } from "@elizaos/core";
5037
5181
  var ScenarioService = class _ScenarioService extends Service {
5038
5182
  /**
@@ -5076,7 +5220,7 @@ var ScenarioService = class _ScenarioService extends Service {
5076
5220
  startTime: Date.now(),
5077
5221
  completed: false
5078
5222
  });
5079
- logger15.debug("Evaluator started", data);
5223
+ logger17.debug("[Bootstrap] Evaluator started", data);
5080
5224
  return Promise.resolve();
5081
5225
  });
5082
5226
  this.runtime.registerEvent(
@@ -5087,7 +5231,7 @@ var ScenarioService = class _ScenarioService extends Service {
5087
5231
  evaluator.completed = true;
5088
5232
  evaluator.error = data.error;
5089
5233
  }
5090
- logger15.debug("Evaluator completed", data);
5234
+ logger17.debug("[Bootstrap] Evaluator completed", data);
5091
5235
  return Promise.resolve();
5092
5236
  }
5093
5237
  );
@@ -5168,7 +5312,8 @@ var ScenarioService = class _ScenarioService extends Service {
5168
5312
  source: "scenario",
5169
5313
  type: ChannelType9.GROUP,
5170
5314
  channelId: roomId,
5171
- serverId: worldId
5315
+ serverId: worldId,
5316
+ worldId
5172
5317
  });
5173
5318
  return roomId;
5174
5319
  }
@@ -5268,7 +5413,7 @@ var ScenarioService = class _ScenarioService extends Service {
5268
5413
 
5269
5414
  // src/services/task.ts
5270
5415
  import {
5271
- logger as logger16,
5416
+ logger as logger18,
5272
5417
  Service as Service2,
5273
5418
  ServiceType
5274
5419
  } from "@elizaos/core";
@@ -5296,21 +5441,21 @@ var TaskService = class _TaskService extends Service2 {
5296
5441
  this.runtime.registerTaskWorker({
5297
5442
  name: "REPEATING_TEST_TASK",
5298
5443
  validate: async (_runtime, _message, _state) => {
5299
- logger16.debug("Validating repeating test task");
5444
+ logger18.debug("[Bootstrap] Validating repeating test task");
5300
5445
  return true;
5301
5446
  },
5302
5447
  execute: async (_runtime, _options) => {
5303
- logger16.debug("Executing repeating test task");
5448
+ logger18.debug("[Bootstrap] Executing repeating test task");
5304
5449
  }
5305
5450
  });
5306
5451
  this.runtime.registerTaskWorker({
5307
5452
  name: "ONETIME_TEST_TASK",
5308
5453
  validate: async (_runtime, _message, _state) => {
5309
- logger16.debug("Validating one-time test task");
5454
+ logger18.debug("[Bootstrap] Validating one-time test task");
5310
5455
  return true;
5311
5456
  },
5312
5457
  execute: async (_runtime, _options) => {
5313
- logger16.debug("Executing one-time test task");
5458
+ logger18.debug("[Bootstrap] Executing one-time test task");
5314
5459
  }
5315
5460
  });
5316
5461
  const tasks = await this.runtime.getTasksByName("REPEATING_TEST_TASK");
@@ -5347,7 +5492,7 @@ var TaskService = class _TaskService extends Service2 {
5347
5492
  try {
5348
5493
  await this.checkTasks();
5349
5494
  } catch (error) {
5350
- logger16.error("Error checking tasks:", error);
5495
+ logger18.error("[Bootstrap] Error checking tasks:", error);
5351
5496
  }
5352
5497
  }, this.TICK_INTERVAL);
5353
5498
  }
@@ -5376,7 +5521,7 @@ var TaskService = class _TaskService extends Service2 {
5376
5521
  continue;
5377
5522
  }
5378
5523
  } catch (error) {
5379
- logger16.error(`Error validating task ${task.name}:`, error);
5524
+ logger18.error(`[Bootstrap] Error validating task ${task.name}:`, error);
5380
5525
  continue;
5381
5526
  }
5382
5527
  }
@@ -5416,22 +5561,22 @@ var TaskService = class _TaskService extends Service2 {
5416
5561
  await this.executeTask(task);
5417
5562
  continue;
5418
5563
  }
5419
- if (task.metadata.updatedAt === task.metadata.createdAt) {
5564
+ if (task.metadata?.updatedAt === task.metadata?.createdAt) {
5420
5565
  if (task.tags?.includes("immediate")) {
5421
- logger16.debug("immediately running task", task.name);
5566
+ logger18.debug("[Bootstrap] Immediately running task", task.name);
5422
5567
  await this.executeTask(task);
5423
5568
  continue;
5424
5569
  }
5425
5570
  }
5426
5571
  if (now - taskStartTime >= updateIntervalMs) {
5427
- logger16.debug(
5428
- `Executing task ${task.name} - interval of ${updateIntervalMs}ms has elapsed`
5572
+ logger18.debug(
5573
+ `[Bootstrap] Executing task ${task.name} - interval of ${updateIntervalMs}ms has elapsed`
5429
5574
  );
5430
5575
  await this.executeTask(task);
5431
5576
  }
5432
5577
  }
5433
5578
  } catch (error) {
5434
- logger16.error("Error checking tasks:", error);
5579
+ logger18.error("[Bootstrap] Error checking tasks:", error);
5435
5580
  }
5436
5581
  }
5437
5582
  /**
@@ -5441,13 +5586,13 @@ var TaskService = class _TaskService extends Service2 {
5441
5586
  */
5442
5587
  async executeTask(task) {
5443
5588
  try {
5444
- if (!task) {
5445
- logger16.debug(`Task ${task.id} not found`);
5589
+ if (!task || !task.id) {
5590
+ logger18.debug(`[Bootstrap] Task not found`);
5446
5591
  return;
5447
5592
  }
5448
5593
  const worker = this.runtime.getTaskWorker(task.name);
5449
5594
  if (!worker) {
5450
- logger16.debug(`No worker found for task type: ${task.name}`);
5595
+ logger18.debug(`[Bootstrap] No worker found for task type: ${task.name}`);
5451
5596
  return;
5452
5597
  }
5453
5598
  if (task.tags?.includes("repeat")) {
@@ -5457,16 +5602,20 @@ var TaskService = class _TaskService extends Service2 {
5457
5602
  updatedAt: Date.now()
5458
5603
  }
5459
5604
  });
5460
- logger16.debug(`Updated repeating task ${task.name} (${task.id}) with new timestamp`);
5605
+ logger18.debug(
5606
+ `[Bootstrap] Updated repeating task ${task.name} (${task.id}) with new timestamp`
5607
+ );
5461
5608
  }
5462
- logger16.debug(`Executing task ${task.name} (${task.id})`);
5609
+ logger18.debug(`[Bootstrap] Executing task ${task.name} (${task.id})`);
5463
5610
  await worker.execute(this.runtime, task.metadata || {}, task);
5464
5611
  if (!task.tags?.includes("repeat")) {
5465
5612
  await this.runtime.deleteTask(task.id);
5466
- logger16.debug(`Deleted non-repeating task ${task.name} (${task.id}) after execution`);
5613
+ logger18.debug(
5614
+ `[Bootstrap] Deleted non-repeating task ${task.name} (${task.id}) after execution`
5615
+ );
5467
5616
  }
5468
5617
  } catch (error) {
5469
- logger16.error(`Error executing task ${task.id}:`, error);
5618
+ logger18.error(`[Bootstrap] Error executing task ${task.id}:`, error);
5470
5619
  }
5471
5620
  }
5472
5621
  /**
@@ -5516,6 +5665,7 @@ var messageReceivedHandler = async ({
5516
5665
  callback,
5517
5666
  onComplete
5518
5667
  }) => {
5668
+ logger19.info(`[Bootstrap] Message received from ${message.entityId} in room ${message.roomId}`);
5519
5669
  const responseId = v4_default();
5520
5670
  if (!latestResponseIds.has(runtime.agentId)) {
5521
5671
  latestResponseIds.set(runtime.agentId, /* @__PURE__ */ new Map());
@@ -5538,7 +5688,7 @@ var messageReceivedHandler = async ({
5538
5688
  source: "messageHandler"
5539
5689
  });
5540
5690
  const timeoutDuration = 60 * 60 * 1e3;
5541
- let timeoutId;
5691
+ let timeoutId = void 0;
5542
5692
  const timeoutPromise = new Promise((_, reject) => {
5543
5693
  timeoutId = setTimeout(async () => {
5544
5694
  await runtime.emitEvent(EventType2.RUN_TIMEOUT, {
@@ -5560,15 +5710,20 @@ var messageReceivedHandler = async ({
5560
5710
  const processingPromise = (async () => {
5561
5711
  try {
5562
5712
  if (message.entityId === runtime.agentId) {
5713
+ logger19.debug(`[Bootstrap] Skipping message from self (${runtime.agentId})`);
5563
5714
  throw new Error("Message is from the agent itself");
5564
5715
  }
5716
+ logger19.debug(
5717
+ `[Bootstrap] Processing message: ${truncateToCompleteSentence(message.content.text || "", 50)}...`
5718
+ );
5719
+ logger19.debug("[Bootstrap] Saving message to memory and embeddings");
5565
5720
  await Promise.all([
5566
5721
  runtime.addEmbeddingToMemory(message),
5567
5722
  runtime.createMemory(message, "messages")
5568
5723
  ]);
5569
5724
  const agentUserState = await runtime.getParticipantUserState(message.roomId, runtime.agentId);
5570
5725
  if (agentUserState === "MUTED" && !message.content.text?.toLowerCase().includes(runtime.character.name.toLowerCase())) {
5571
- logger17.debug("Ignoring muted room");
5726
+ logger19.debug(`[Bootstrap] Ignoring muted room ${message.roomId}`);
5572
5727
  return;
5573
5728
  }
5574
5729
  let state = await runtime.composeState(message, [
@@ -5579,26 +5734,25 @@ var messageReceivedHandler = async ({
5579
5734
  "RECENT_MESSAGES"
5580
5735
  ]);
5581
5736
  const room = await runtime.getRoom(message.roomId);
5582
- const shouldSkipShouldRespond = room?.type === ChannelType10.DM || room?.type === ChannelType10.VOICE_DM || room?.type === ChannelType10.SELF;
5737
+ const shouldSkipShouldRespond = room?.type === ChannelType10.DM || room?.type === ChannelType10.VOICE_DM || room?.type === ChannelType10.SELF || room?.type === ChannelType10.API;
5583
5738
  let shouldRespond = true;
5584
5739
  if (!shouldSkipShouldRespond) {
5585
5740
  const shouldRespondPrompt = composePromptFromState9({
5586
5741
  state,
5587
5742
  template: runtime.character.templates?.shouldRespondTemplate || shouldRespondTemplate
5588
5743
  });
5589
- logger17.debug(
5590
- `*** Should Respond Prompt for ${runtime.character.name} ***
5591
- `,
5592
- shouldRespondPrompt
5744
+ logger19.debug(
5745
+ `[Bootstrap] Evaluating response for ${runtime.character.name}
5746
+ Prompt: ${shouldRespondPrompt}`
5593
5747
  );
5594
5748
  const response = await runtime.useModel(ModelType13.TEXT_SMALL, {
5595
5749
  prompt: shouldRespondPrompt
5596
5750
  });
5597
- logger17.debug(`*** Should Respond Response for ${runtime.character.name} ***
5598
- `, response);
5599
- logger17.debug(`*** Raw Response Type: ${typeof response} ***`);
5751
+ logger19.debug(`[Bootstrap] Response evaluation for ${runtime.character.name}:
5752
+ ${response}`);
5753
+ logger19.debug(`[Bootstrap] Response type: ${typeof response}`);
5600
5754
  const responseObject = parseKeyValueXml(response);
5601
- logger17.debug("*** Parsed XML Response Object ***", responseObject);
5755
+ logger19.debug("[Bootstrap] Parsed response:", responseObject);
5602
5756
  shouldRespond = responseObject?.action && responseObject.action === "RESPOND";
5603
5757
  } else {
5604
5758
  shouldRespond = true;
@@ -5617,11 +5771,12 @@ var messageReceivedHandler = async ({
5617
5771
  let response = await runtime.useModel(ModelType13.TEXT_LARGE, {
5618
5772
  prompt
5619
5773
  });
5620
- logger17.debug("*** Raw LLM Response ***\n", response);
5774
+ logger19.debug("[Bootstrap] *** Raw LLM Response ***\n", response);
5621
5775
  const parsedXml = parseKeyValueXml(response);
5622
- logger17.debug("*** Parsed XML Content ***\n", parsedXml);
5776
+ logger19.debug("[Bootstrap] *** Parsed XML Content ***\n", parsedXml);
5623
5777
  if (parsedXml) {
5624
5778
  responseContent = {
5779
+ ...parsedXml,
5625
5780
  thought: parsedXml.thought || "",
5626
5781
  actions: parsedXml.actions || ["IGNORE"],
5627
5782
  providers: parsedXml.providers || [],
@@ -5633,17 +5788,19 @@ var messageReceivedHandler = async ({
5633
5788
  }
5634
5789
  retries++;
5635
5790
  if (!responseContent?.thought || !responseContent?.actions) {
5636
- logger17.warn("*** Missing required fields (thought or actions), retrying... ***");
5791
+ logger19.warn(
5792
+ "[Bootstrap] *** Missing required fields (thought or actions), retrying... ***"
5793
+ );
5637
5794
  }
5638
5795
  }
5639
5796
  const currentResponseId = agentResponses.get(message.roomId);
5640
5797
  if (currentResponseId !== responseId) {
5641
- logger17.info(
5798
+ logger19.info(
5642
5799
  `Response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
5643
5800
  );
5644
5801
  return;
5645
5802
  }
5646
- if (responseContent) {
5803
+ if (responseContent && message.id) {
5647
5804
  responseContent.inReplyTo = createUniqueUuid4(runtime, message.id);
5648
5805
  const responseMesssage = {
5649
5806
  id: asUUID(v4_default()),
@@ -5659,24 +5816,28 @@ var messageReceivedHandler = async ({
5659
5816
  if (agentResponses.size === 0) {
5660
5817
  latestResponseIds.delete(runtime.agentId);
5661
5818
  }
5662
- if (responseContent?.providers.length > 0) {
5663
- state = await runtime.composeState(message, null, [...responseContent?.providers]);
5819
+ if (responseContent?.providers?.length && responseContent?.providers?.length > 0) {
5820
+ state = await runtime.composeState(message, responseContent?.providers || []);
5664
5821
  }
5665
- if (responseContent && responseContent.simple && responseContent.text && (responseContent.actions.length === 0 || responseContent.actions.length === 1 && responseContent.actions[0].toUpperCase() === "REPLY")) {
5822
+ if (responseContent && responseContent.simple && responseContent.text && (responseContent.actions?.length === 0 || responseContent.actions?.length === 1 && responseContent.actions[0].toUpperCase() === "REPLY")) {
5666
5823
  await callback(responseContent);
5667
5824
  } else {
5668
5825
  await runtime.processActions(message, responseMessages, state, callback);
5669
5826
  }
5670
5827
  await runtime.evaluate(message, state, shouldRespond, callback, responseMessages);
5671
5828
  } else {
5672
- logger17.debug("Agent decided not to respond (shouldRespond is false).");
5829
+ logger19.debug("[Bootstrap] Agent decided not to respond (shouldRespond is false).");
5673
5830
  const currentResponseId = agentResponses.get(message.roomId);
5674
5831
  if (currentResponseId !== responseId) {
5675
- logger17.info(
5832
+ logger19.info(
5676
5833
  `Ignore response discarded - newer message being processed for agent: ${runtime.agentId}, room: ${message.roomId}`
5677
5834
  );
5678
5835
  return;
5679
5836
  }
5837
+ if (!message.id) {
5838
+ logger19.error("[Bootstrap] Message ID is missing, cannot create ignore response.");
5839
+ return;
5840
+ }
5680
5841
  const ignoreContent = {
5681
5842
  thought: "Agent decided not to respond to this message.",
5682
5843
  actions: ["IGNORE"],
@@ -5695,7 +5856,7 @@ var messageReceivedHandler = async ({
5695
5856
  createdAt: Date.now()
5696
5857
  };
5697
5858
  await runtime.createMemory(ignoreMemory, "messages");
5698
- logger17.debug("Saved ignore response to memory", { memoryId: ignoreMemory.id });
5859
+ logger19.debug("[Bootstrap] Saved ignore response to memory", { memoryId: ignoreMemory.id });
5699
5860
  agentResponses.delete(message.roomId);
5700
5861
  if (agentResponses.size === 0) {
5701
5862
  latestResponseIds.delete(runtime.agentId);
@@ -5723,13 +5884,12 @@ var messageReceivedHandler = async ({
5723
5884
  roomId: message.roomId,
5724
5885
  entityId: message.entityId,
5725
5886
  startTime,
5726
- status: "completed",
5887
+ status: "error",
5727
5888
  endTime: Date.now(),
5728
5889
  duration: Date.now() - startTime,
5729
5890
  error: error.message,
5730
5891
  source: "messageHandler"
5731
5892
  });
5732
- throw error;
5733
5893
  }
5734
5894
  })();
5735
5895
  try {
@@ -5746,10 +5906,10 @@ var reactionReceivedHandler = async ({
5746
5906
  await runtime.createMemory(message, "messages");
5747
5907
  } catch (error) {
5748
5908
  if (error.code === "23505") {
5749
- logger17.warn("Duplicate reaction memory, skipping");
5909
+ logger19.warn("[Bootstrap] Duplicate reaction memory, skipping");
5750
5910
  return;
5751
5911
  }
5752
- logger17.error("Error in reaction handler:", error);
5912
+ logger19.error("[Bootstrap] Error in reaction handler:", error);
5753
5913
  }
5754
5914
  };
5755
5915
  var postGeneratedHandler = async ({
@@ -5760,7 +5920,7 @@ var postGeneratedHandler = async ({
5760
5920
  roomId,
5761
5921
  source
5762
5922
  }) => {
5763
- logger17.info("Generating new post...");
5923
+ logger19.info("[Bootstrap] Generating new post...");
5764
5924
  await runtime.ensureWorldExists({
5765
5925
  id: worldId,
5766
5926
  name: `${runtime.character.name}'s Feed`,
@@ -5787,10 +5947,10 @@ var postGeneratedHandler = async ({
5787
5947
  type: "message"
5788
5948
  }
5789
5949
  };
5790
- let state = await runtime.composeState(message, null, [
5950
+ let state = await runtime.composeState(message, [
5791
5951
  "PROVIDERS",
5792
5952
  "CHARACTER",
5793
- //'RECENT_MESSAGES',
5953
+ "RECENT_MESSAGES",
5794
5954
  "ENTITIES"
5795
5955
  ]);
5796
5956
  const entity = await runtime.getEntityById(runtime.agentId);
@@ -5822,10 +5982,10 @@ var postGeneratedHandler = async ({
5822
5982
  }
5823
5983
  retries++;
5824
5984
  if (!responseContent?.thought || !responseContent?.actions) {
5825
- logger17.warn("*** Missing required fields, retrying... ***");
5985
+ logger19.warn("[Bootstrap] *** Missing required fields, retrying... ***");
5826
5986
  }
5827
5987
  }
5828
- state = await runtime.composeState(message, responseContent.providers);
5988
+ state = await runtime.composeState(message, responseContent?.providers);
5829
5989
  const postPrompt = composePromptFromState9({
5830
5990
  state,
5831
5991
  template: runtime.character.templates?.postCreationTemplate || postCreationTemplate
@@ -5835,7 +5995,10 @@ var postGeneratedHandler = async ({
5835
5995
  });
5836
5996
  const parsedXmlResponse = parseKeyValueXml(xmlResponseText);
5837
5997
  if (!parsedXmlResponse) {
5838
- logger17.error("Failed to parse XML response for post creation. Raw response:", xmlResponseText);
5998
+ logger19.error(
5999
+ "[Bootstrap] Failed to parse XML response for post creation. Raw response:",
6000
+ xmlResponseText
6001
+ );
5839
6002
  return;
5840
6003
  }
5841
6004
  function cleanupPostText(text) {
@@ -5851,7 +6014,7 @@ var postGeneratedHandler = async ({
5851
6014
  if (RM) {
5852
6015
  for (const m of RM.data.recentMessages) {
5853
6016
  if (cleanedText === m.content.text) {
5854
- logger17.log("we've already recently posted that, retrying", cleanedText);
6017
+ logger19.log("[Bootstrap] Already recently posted that, retrying", cleanedText);
5855
6018
  postGeneratedHandler({
5856
6019
  runtime,
5857
6020
  callback,
@@ -5869,7 +6032,7 @@ var postGeneratedHandler = async ({
5869
6032
  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;
5870
6033
  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;
5871
6034
  if (oaiRefusalRegex.test(cleanedText) || anthropicRefusalRegex.test(cleanedText) || googleRefusalRegex.test(cleanedText) || generalRefusalRegex.test(cleanedText)) {
5872
- logger17.log("got prompt moderation refusal, retrying", cleanedText);
6035
+ logger19.log("[Bootstrap] Got prompt moderation refusal, retrying", cleanedText);
5873
6036
  postGeneratedHandler({
5874
6037
  runtime,
5875
6038
  callback,
@@ -5897,15 +6060,15 @@ var postGeneratedHandler = async ({
5897
6060
  }
5898
6061
  ];
5899
6062
  for (const message2 of responseMessages) {
5900
- await callback(message2.content);
6063
+ await callback?.(message2.content);
5901
6064
  }
5902
6065
  };
5903
6066
  var syncSingleUser = async (entityId, runtime, serverId, channelId, type, source) => {
5904
6067
  try {
5905
6068
  const entity = await runtime.getEntityById(entityId);
5906
- logger17.info(`Syncing user: ${entity?.metadata[source]?.username || entityId}`);
6069
+ logger19.info(`[Bootstrap] Syncing user: ${entity?.metadata?.[source]?.username || entityId}`);
5907
6070
  if (!channelId) {
5908
- logger17.warn(`Cannot sync user ${entity?.id} without a valid channelId`);
6071
+ logger19.warn(`[Bootstrap] Cannot sync user ${entity?.id} without a valid channelId`);
5909
6072
  return;
5910
6073
  }
5911
6074
  const roomId = createUniqueUuid4(runtime, channelId);
@@ -5913,17 +6076,19 @@ var syncSingleUser = async (entityId, runtime, serverId, channelId, type, source
5913
6076
  await runtime.ensureConnection({
5914
6077
  entityId,
5915
6078
  roomId,
5916
- userName: entity?.metadata[source].username || entityId,
5917
- name: entity?.metadata[source].name || entity?.metadata[source].username || `User${entityId}`,
6079
+ userName: entity?.metadata?.[source].username || entityId,
6080
+ name: entity?.metadata?.[source].name || entity?.metadata?.[source].username || `User${entityId}`,
5918
6081
  source,
5919
6082
  channelId,
5920
6083
  serverId,
5921
6084
  type,
5922
6085
  worldId
5923
6086
  });
5924
- logger17.success(`Successfully synced user: ${entity?.id}`);
6087
+ logger19.success(`[Bootstrap] Successfully synced user: ${entity?.id}`);
5925
6088
  } catch (error) {
5926
- logger17.error(`Error syncing user: ${error instanceof Error ? error.message : String(error)}`);
6089
+ logger19.error(
6090
+ `[Bootstrap] Error syncing user: ${error instanceof Error ? error.message : String(error)}`
6091
+ );
5927
6092
  }
5928
6093
  };
5929
6094
  var handleServerSync = async ({
@@ -5934,7 +6099,7 @@ var handleServerSync = async ({
5934
6099
  source,
5935
6100
  onComplete
5936
6101
  }) => {
5937
- logger17.debug(`Handling server sync event for server: ${world.name}`);
6102
+ logger19.debug(`[Bootstrap] Handling server sync event for server: ${world.name}`);
5938
6103
  try {
5939
6104
  await runtime.ensureWorldExists({
5940
6105
  id: world.id,
@@ -5963,14 +6128,22 @@ var handleServerSync = async ({
5963
6128
  for (let i2 = 0; i2 < entities.length; i2 += batchSize) {
5964
6129
  const entityBatch = entities.slice(i2, i2 + batchSize);
5965
6130
  const firstRoomUserIsIn = rooms.length > 0 ? rooms[0] : null;
6131
+ if (!firstRoomUserIsIn) {
6132
+ logger19.warn(`[Bootstrap] No rooms found for syncing users`);
6133
+ continue;
6134
+ }
5966
6135
  await Promise.all(
5967
6136
  entityBatch.map(async (entity) => {
5968
6137
  try {
6138
+ if (!entity?.id) {
6139
+ logger19.warn(`[Bootstrap] No entity ID found for syncing users`);
6140
+ return;
6141
+ }
5969
6142
  await runtime.ensureConnection({
5970
6143
  entityId: entity.id,
5971
6144
  roomId: firstRoomUserIsIn.id,
5972
- userName: entity.metadata[source].username,
5973
- name: entity.metadata[source].name,
6145
+ userName: entity.metadata?.[source].username,
6146
+ name: entity.metadata?.[source].name,
5974
6147
  source,
5975
6148
  channelId: firstRoomUserIsIn.channelId,
5976
6149
  serverId: world.serverId,
@@ -5978,7 +6151,7 @@ var handleServerSync = async ({
5978
6151
  worldId: world.id
5979
6152
  });
5980
6153
  } catch (err) {
5981
- logger17.warn(`Failed to sync user ${entity.metadata.username}: ${err}`);
6154
+ logger19.warn(`[Bootstrap] Failed to sync user ${entity.metadata?.username}: ${err}`);
5982
6155
  }
5983
6156
  })
5984
6157
  );
@@ -5987,10 +6160,10 @@ var handleServerSync = async ({
5987
6160
  }
5988
6161
  }
5989
6162
  }
5990
- logger17.debug(`Successfully synced standardized world structure for ${world.name}`);
6163
+ logger19.debug(`Successfully synced standardized world structure for ${world.name}`);
5991
6164
  onComplete?.();
5992
6165
  } catch (error) {
5993
- logger17.error(
6166
+ logger19.error(
5994
6167
  `Error processing standardized server data: ${error instanceof Error ? error.message : String(error)}`
5995
6168
  );
5996
6169
  }
@@ -6001,7 +6174,7 @@ var controlMessageHandler = async ({
6001
6174
  source
6002
6175
  }) => {
6003
6176
  try {
6004
- logger17.debug(
6177
+ logger19.debug(
6005
6178
  `[controlMessageHandler] Processing control message: ${message.payload.action} for room ${message.roomId}`
6006
6179
  );
6007
6180
  const serviceNames = Array.from(runtime.getAllServices().keys());
@@ -6019,22 +6192,26 @@ var controlMessageHandler = async ({
6019
6192
  roomId: message.roomId
6020
6193
  }
6021
6194
  });
6022
- logger17.debug(
6195
+ logger19.debug(
6023
6196
  `[controlMessageHandler] Control message ${message.payload.action} sent successfully`
6024
6197
  );
6025
6198
  } else {
6026
- logger17.error("[controlMessageHandler] WebSocket service does not have sendMessage method");
6199
+ logger19.error("[controlMessageHandler] WebSocket service does not have sendMessage method");
6027
6200
  }
6028
6201
  } else {
6029
- logger17.error("[controlMessageHandler] No WebSocket service found to send control message");
6202
+ logger19.error("[controlMessageHandler] No WebSocket service found to send control message");
6030
6203
  }
6031
6204
  } catch (error) {
6032
- logger17.error(`[controlMessageHandler] Error processing control message: ${error}`);
6205
+ logger19.error(`[controlMessageHandler] Error processing control message: ${error}`);
6033
6206
  }
6034
6207
  };
6035
6208
  var events = {
6036
6209
  [EventType2.MESSAGE_RECEIVED]: [
6037
6210
  async (payload) => {
6211
+ if (!payload.callback) {
6212
+ logger19.error("No callback provided for message");
6213
+ return;
6214
+ }
6038
6215
  await messageReceivedHandler({
6039
6216
  runtime: payload.runtime,
6040
6217
  message: payload.message,
@@ -6045,6 +6222,10 @@ var events = {
6045
6222
  ],
6046
6223
  [EventType2.VOICE_MESSAGE_RECEIVED]: [
6047
6224
  async (payload) => {
6225
+ if (!payload.callback) {
6226
+ logger19.error("No callback provided for voice message");
6227
+ return;
6228
+ }
6048
6229
  await messageReceivedHandler({
6049
6230
  runtime: payload.runtime,
6050
6231
  message: payload.message,
@@ -6067,7 +6248,7 @@ var events = {
6067
6248
  ],
6068
6249
  [EventType2.MESSAGE_SENT]: [
6069
6250
  async (payload) => {
6070
- logger17.debug(`Message sent: ${payload.message.content.text}`);
6251
+ logger19.debug(`[Bootstrap] Message sent: ${payload.message.content.text}`);
6071
6252
  }
6072
6253
  ],
6073
6254
  [EventType2.WORLD_JOINED]: [
@@ -6082,6 +6263,18 @@ var events = {
6082
6263
  ],
6083
6264
  [EventType2.ENTITY_JOINED]: [
6084
6265
  async (payload) => {
6266
+ if (!payload.worldId) {
6267
+ logger19.error("[Bootstrap] No callback provided for entity joined");
6268
+ return;
6269
+ }
6270
+ if (!payload.roomId) {
6271
+ logger19.error("[Bootstrap] No roomId provided for entity joined");
6272
+ return;
6273
+ }
6274
+ if (!payload.metadata?.type) {
6275
+ logger19.error("[Bootstrap] No type provided for entity joined");
6276
+ return;
6277
+ }
6085
6278
  await syncSingleUser(
6086
6279
  payload.entityId,
6087
6280
  payload.runtime,
@@ -6104,32 +6297,36 @@ var events = {
6104
6297
  };
6105
6298
  await payload.runtime.updateEntity(entity);
6106
6299
  }
6107
- logger17.info(`User ${payload.entityId} left world ${payload.worldId}`);
6300
+ logger19.info(`[Bootstrap] User ${payload.entityId} left world ${payload.worldId}`);
6108
6301
  } catch (error) {
6109
- logger17.error(`Error handling user left: ${error.message}`);
6302
+ logger19.error(`[Bootstrap] Error handling user left: ${error.message}`);
6110
6303
  }
6111
6304
  }
6112
6305
  ],
6113
6306
  [EventType2.ACTION_STARTED]: [
6114
6307
  async (payload) => {
6115
- logger17.debug(`Action started: ${payload.actionName} (${payload.actionId})`);
6308
+ logger19.debug(`[Bootstrap] Action started: ${payload.actionName} (${payload.actionId})`);
6116
6309
  }
6117
6310
  ],
6118
6311
  [EventType2.ACTION_COMPLETED]: [
6119
6312
  async (payload) => {
6120
6313
  const status = payload.error ? `failed: ${payload.error.message}` : "completed";
6121
- logger17.debug(`Action ${status}: ${payload.actionName} (${payload.actionId})`);
6314
+ logger19.debug(`[Bootstrap] Action ${status}: ${payload.actionName} (${payload.actionId})`);
6122
6315
  }
6123
6316
  ],
6124
6317
  [EventType2.EVALUATOR_STARTED]: [
6125
6318
  async (payload) => {
6126
- logger17.debug(`Evaluator started: ${payload.evaluatorName} (${payload.evaluatorId})`);
6319
+ logger19.debug(
6320
+ `[Bootstrap] Evaluator started: ${payload.evaluatorName} (${payload.evaluatorId})`
6321
+ );
6127
6322
  }
6128
6323
  ],
6129
6324
  [EventType2.EVALUATOR_COMPLETED]: [
6130
6325
  async (payload) => {
6131
6326
  const status = payload.error ? `failed: ${payload.error.message}` : "completed";
6132
- logger17.debug(`Evaluator ${status}: ${payload.evaluatorName} (${payload.evaluatorId})`);
6327
+ logger19.debug(
6328
+ `[Bootstrap] Evaluator ${status}: ${payload.evaluatorName} (${payload.evaluatorId})`
6329
+ );
6133
6330
  }
6134
6331
  ],
6135
6332
  CONTROL_MESSAGE: [controlMessageHandler]
@@ -6151,6 +6348,7 @@ var bootstrapPlugin = {
6151
6348
  updateRoleAction,
6152
6349
  updateSettingsAction
6153
6350
  ],
6351
+ // this is jank, these events are not valid
6154
6352
  events,
6155
6353
  evaluators: [reflectionEvaluator],
6156
6354
  providers: [