@elizaos/plugin-bootstrap 1.6.5 → 1.7.0-beta.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
@@ -83,7 +83,7 @@ import {
83
83
  ChannelType as ChannelType9,
84
84
  composePromptFromState as composePromptFromState10,
85
85
  ContentType as ContentType2,
86
- createUniqueUuid as createUniqueUuid3,
86
+ createUniqueUuid,
87
87
  EventType as EventType2,
88
88
  imageDescriptionTemplate,
89
89
  logger as logger16,
@@ -189,7 +189,7 @@ var generateImageAction = {
189
189
  prompt
190
190
  });
191
191
  const parsedXml = parseKeyValueXml(promptResponse);
192
- const imagePrompt = parsedXml?.prompt || "Unable to generate descriptive prompt for image";
192
+ const imagePrompt = typeof parsedXml?.prompt === "string" ? parsedXml.prompt : "Unable to generate descriptive prompt for image";
193
193
  const imageResponse = await runtime.useModel(ModelType.IMAGE, {
194
194
  prompt: imagePrompt
195
195
  });
@@ -223,7 +223,7 @@ var generateImageAction = {
223
223
  if (extension2 && ["png", "jpg", "jpeg", "gif", "webp", "bmp"].includes(extension2)) {
224
224
  return extension2;
225
225
  }
226
- } catch (e) {}
226
+ } catch (_e) {}
227
227
  return "png";
228
228
  };
229
229
  const extension = getFileExtension(imageUrl);
@@ -243,7 +243,9 @@ var generateImageAction = {
243
243
  actions: ["GENERATE_IMAGE"],
244
244
  text: imagePrompt
245
245
  };
246
- await callback(responseContent);
246
+ if (callback) {
247
+ await callback(responseContent);
248
+ }
247
249
  return {
248
250
  text: "Generated image",
249
251
  values: {
@@ -405,11 +407,6 @@ var choiceAction = {
405
407
  roomId: message.roomId,
406
408
  tags: ["AWAITING_CHOICE"]
407
409
  });
408
- const room2 = state.data.room ?? await runtime.getRoom(message.roomId);
409
- const userRole2 = await getUserServerRole(runtime, message.entityId, room2.messageServerId);
410
- if (userRole2 !== "OWNER" && userRole2 !== "ADMIN") {
411
- return false;
412
- }
413
410
  return pendingTasks && pendingTasks.length > 0 && pendingTasks.some((task) => task.metadata?.options);
414
411
  } catch (error) {
415
412
  logger2.error({
@@ -485,7 +482,7 @@ ${task.options?.map((opt) => `- ${opt.name}: ${opt.description}`).join(`
485
482
  stopSequences: []
486
483
  });
487
484
  const parsed = parseKeyValueXml2(result);
488
- const { taskId, selectedOption } = parsed;
485
+ const { taskId, selectedOption } = parsed || {};
489
486
  if (taskId && selectedOption) {
490
487
  const taskMap = new Map(formattedTasks.map((task) => [task.taskId, task]));
491
488
  const taskInfo = taskMap.get(taskId);
@@ -749,7 +746,6 @@ var followRoomAction = {
749
746
  template: shouldFollowTemplate
750
747
  });
751
748
  const response = await runtime.useModel(ModelType3.TEXT_SMALL, {
752
- runtime,
753
749
  prompt: shouldFollowPrompt,
754
750
  stopSequences: []
755
751
  });
@@ -791,6 +787,14 @@ var followRoomAction = {
791
787
  }
792
788
  const shouldFollow = await _shouldFollow(state);
793
789
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
790
+ if (!room) {
791
+ return {
792
+ text: "Could not find room to follow",
793
+ values: { success: false, error: "ROOM_NOT_FOUND" },
794
+ data: { actionName: "FOLLOW_ROOM", error: "Room not found" },
795
+ success: false
796
+ };
797
+ }
794
798
  if (shouldFollow) {
795
799
  try {
796
800
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, "FOLLOWED");
@@ -1407,7 +1411,6 @@ var muteRoomAction = {
1407
1411
  template: shouldMuteTemplate
1408
1412
  });
1409
1413
  const response = await runtime.useModel(ModelType4.TEXT_SMALL, {
1410
- runtime,
1411
1414
  prompt: shouldMutePrompt,
1412
1415
  stopSequences: []
1413
1416
  });
@@ -1448,6 +1451,14 @@ var muteRoomAction = {
1448
1451
  }
1449
1452
  const shouldMute = await _shouldMute(state);
1450
1453
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
1454
+ if (!room) {
1455
+ return {
1456
+ text: "Could not find room to mute",
1457
+ values: { success: false, error: "ROOM_NOT_FOUND" },
1458
+ data: { actionName: "MUTE_ROOM", error: "Room not found" },
1459
+ success: false
1460
+ };
1461
+ }
1451
1462
  if (shouldMute) {
1452
1463
  try {
1453
1464
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, "MUTED");
@@ -1783,7 +1794,7 @@ var replyTemplate = `# Task: Generate dialog for the character {{agentName}}.
1783
1794
 
1784
1795
  # Instructions: Write the next message for {{agentName}}.
1785
1796
  "thought" should be a short description of what the agent is thinking about and planning.
1786
- "message" should be the next message for {{agentName}} which they will send to the conversation.
1797
+ "text" should be the next message for {{agentName}} which they will send to the conversation.
1787
1798
 
1788
1799
  IMPORTANT CODE BLOCK FORMATTING RULES:
1789
1800
  - If {{agentName}} includes code examples, snippets, or multi-line code in the response, ALWAYS wrap the code with \`\`\` fenced code blocks (specify the language if known, e.g., \`\`\`python).
@@ -1791,13 +1802,13 @@ IMPORTANT CODE BLOCK FORMATTING RULES:
1791
1802
  - If including inline code (short single words or function names), use single backticks (\`) as appropriate.
1792
1803
  - This ensures the user sees clearly formatted and copyable code when relevant.
1793
1804
 
1794
- Do NOT include any thinking, reasoning, or <think> sections in your response.
1805
+ Do NOT include any thinking, reasoning, or <think> sections in your response.
1795
1806
  Go directly to the XML response format without any preamble or explanation.
1796
1807
 
1797
1808
  Respond using XML format like this:
1798
1809
  <response>
1799
1810
  <thought>Your thought here</thought>
1800
- <message>Your message here</message>
1811
+ <text>Your message here</text>
1801
1812
  </response>
1802
1813
 
1803
1814
  IMPORTANT: Your response must ONLY contain the <response></response> XML block above. Do not include any text, thinking, or reasoning before or after this XML block. Start your response immediately with <response> and end with </response>.`;
@@ -1833,12 +1844,16 @@ var replyAction = {
1833
1844
  prompt
1834
1845
  });
1835
1846
  const parsedXml = parseKeyValueXml3(response);
1847
+ const thought = typeof parsedXml?.thought === "string" ? parsedXml.thought : "";
1848
+ const text = typeof parsedXml?.text === "string" ? parsedXml.text : "";
1836
1849
  const responseContent = {
1837
- thought: parsedXml?.thought || "",
1838
- text: parsedXml?.message || "",
1850
+ thought,
1851
+ text,
1839
1852
  actions: ["REPLY"]
1840
1853
  };
1841
- await callback(responseContent);
1854
+ if (callback) {
1855
+ await callback(responseContent);
1856
+ }
1842
1857
  return {
1843
1858
  text: `Generated reply: ${responseContent.text}`,
1844
1859
  values: {
@@ -1846,12 +1861,12 @@ var replyAction = {
1846
1861
  responded: true,
1847
1862
  lastReply: responseContent.text,
1848
1863
  lastReplyTime: Date.now(),
1849
- thoughtProcess: parsedXml?.thought
1864
+ thoughtProcess: thought
1850
1865
  },
1851
1866
  data: {
1852
1867
  actionName: "REPLY",
1853
1868
  response: responseContent,
1854
- thought: parsedXml?.thought,
1869
+ thought,
1855
1870
  messageGenerated: true
1856
1871
  },
1857
1872
  success: true
@@ -1951,8 +1966,9 @@ import {
1951
1966
  parseKeyValueXml as parseKeyValueXml4
1952
1967
  } from "@elizaos/core";
1953
1968
  var canModifyRole = (currentRole, targetRole, newRole) => {
1954
- if (targetRole === currentRole)
1969
+ if (targetRole === currentRole) {
1955
1970
  return false;
1971
+ }
1956
1972
  switch (currentRole) {
1957
1973
  case Role.OWNER:
1958
1974
  return true;
@@ -2063,7 +2079,7 @@ IMPORTANT: Your response must ONLY contain the <response></response> XML block a
2063
2079
  let assignments = [];
2064
2080
  if (parsedXml?.assignments?.assignment) {
2065
2081
  const assignmentArray = Array.isArray(parsedXml.assignments.assignment) ? parsedXml.assignments.assignment : [parsedXml.assignments.assignment];
2066
- assignments = assignmentArray.map((a) => ({
2082
+ assignments = assignmentArray.filter((a) => !!a.entityId).map((a) => ({
2067
2083
  entityId: a.entityId,
2068
2084
  newRole: a.newRole
2069
2085
  }));
@@ -2091,7 +2107,7 @@ IMPORTANT: Your response must ONLY contain the <response></response> XML block a
2091
2107
  const successfulUpdates = [];
2092
2108
  const failedUpdates = [];
2093
2109
  for (const assignment of assignments) {
2094
- let targetEntity = entities.find((e) => e.id === assignment.entityId);
2110
+ const targetEntity = entities.find((e) => e.id === assignment.entityId);
2095
2111
  if (!targetEntity) {
2096
2112
  logger6.error({
2097
2113
  src: "plugin:bootstrap:action:update_role",
@@ -2345,6 +2361,14 @@ var sendMessageAction = {
2345
2361
  }
2346
2362
  const sourceEntityId = message.entityId;
2347
2363
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
2364
+ if (!room) {
2365
+ return {
2366
+ text: "Could not find room",
2367
+ values: { success: false, error: "ROOM_NOT_FOUND" },
2368
+ data: { actionName: "SEND_MESSAGE", error: "Room not found" },
2369
+ success: false
2370
+ };
2371
+ }
2348
2372
  const worldId = room.worldId;
2349
2373
  const targetPrompt = composePromptFromState5({
2350
2374
  state,
@@ -2424,7 +2448,8 @@ var sendMessageAction = {
2424
2448
  success: false
2425
2449
  };
2426
2450
  }
2427
- const sendDirectMessage = runtime.getService(source)?.sendDirectMessage;
2451
+ const service = runtime.getService(source);
2452
+ const sendDirectMessage = service?.sendDirectMessage;
2428
2453
  if (!sendDirectMessage) {
2429
2454
  await callback({
2430
2455
  text: "I couldn't find the user you want me to send a message to. Could you please provide more details about who they are?",
@@ -2449,7 +2474,10 @@ var sendMessageAction = {
2449
2474
  };
2450
2475
  }
2451
2476
  try {
2452
- await sendDirectMessage(runtime, targetEntity.id, source, message.content.text, worldId);
2477
+ await sendDirectMessage(targetEntity.id, {
2478
+ text: message.content.text,
2479
+ source: message.content.source
2480
+ });
2453
2481
  await callback({
2454
2482
  text: `Message sent to ${targetEntity.names[0]} on ${source}.`,
2455
2483
  actions: ["SEND_MESSAGE"],
@@ -2496,7 +2524,7 @@ var sendMessageAction = {
2496
2524
  },
2497
2525
  data: {
2498
2526
  actionName: "SEND_MESSAGE",
2499
- error: error.message,
2527
+ error: error instanceof Error ? error.message : String(error),
2500
2528
  targetType: "user",
2501
2529
  targetId: targetEntity.id,
2502
2530
  source
@@ -2506,9 +2534,17 @@ var sendMessageAction = {
2506
2534
  };
2507
2535
  }
2508
2536
  } else if (targetData.targetType === "room") {
2537
+ if (!worldId) {
2538
+ return {
2539
+ text: "Could not determine world for room lookup",
2540
+ values: { success: false, error: "NO_WORLD_ID" },
2541
+ data: { actionName: "SEND_MESSAGE", error: "No world ID available" },
2542
+ success: false
2543
+ };
2544
+ }
2509
2545
  const rooms = await runtime.getRooms(worldId);
2510
2546
  const targetRoom = rooms.find((r) => {
2511
- return r.name?.toLowerCase() === targetData.identifiers.roomName?.toLowerCase();
2547
+ return r.name?.toLowerCase() === targetData.identifiers?.roomName?.toLowerCase();
2512
2548
  });
2513
2549
  if (!targetRoom) {
2514
2550
  await callback({
@@ -2522,19 +2558,20 @@ var sendMessageAction = {
2522
2558
  success: false,
2523
2559
  error: "ROOM_NOT_FOUND",
2524
2560
  targetType: "room",
2525
- roomName: targetData.identifiers.roomName
2561
+ roomName: targetData.identifiers?.roomName
2526
2562
  },
2527
2563
  data: {
2528
2564
  actionName: "SEND_MESSAGE",
2529
2565
  error: "Could not find target room",
2530
2566
  targetType: "room",
2531
- roomName: targetData.identifiers.roomName,
2567
+ roomName: targetData.identifiers?.roomName,
2532
2568
  source
2533
2569
  },
2534
2570
  success: false
2535
2571
  };
2536
2572
  }
2537
- const sendRoomMessage = runtime.getService(source)?.sendRoomMessage;
2573
+ const service = runtime.getService(source);
2574
+ const sendRoomMessage = service?.sendRoomMessage;
2538
2575
  if (!sendRoomMessage) {
2539
2576
  await callback({
2540
2577
  text: "I couldn't find the room you want me to send a message to. Could you please specify the exact room name?",
@@ -2559,7 +2596,10 @@ var sendMessageAction = {
2559
2596
  };
2560
2597
  }
2561
2598
  try {
2562
- await sendRoomMessage(runtime, targetRoom.id, source, message.content.text, worldId);
2599
+ await sendRoomMessage(targetRoom.id, {
2600
+ text: message.content.text,
2601
+ source: message.content.source
2602
+ });
2563
2603
  await callback({
2564
2604
  text: `Message sent to ${targetRoom.name} on ${source}.`,
2565
2605
  actions: ["SEND_MESSAGE"],
@@ -2606,7 +2646,7 @@ var sendMessageAction = {
2606
2646
  },
2607
2647
  data: {
2608
2648
  actionName: "SEND_MESSAGE",
2609
- error: error.message,
2649
+ error: error instanceof Error ? error.message : String(error),
2610
2650
  targetType: "room",
2611
2651
  targetId: targetRoom.id,
2612
2652
  targetName: targetRoom.name,
@@ -2625,7 +2665,7 @@ var sendMessageAction = {
2625
2665
  },
2626
2666
  data: {
2627
2667
  actionName: "SEND_MESSAGE",
2628
- error: "Unknown target type: " + targetData.targetType
2668
+ error: `Unknown target type: ${targetData.targetType}`
2629
2669
  },
2630
2670
  success: false
2631
2671
  };
@@ -2708,11 +2748,13 @@ import {
2708
2748
  ChannelType as ChannelType2,
2709
2749
  composePrompt as composePrompt3,
2710
2750
  composePromptFromState as composePromptFromState6,
2711
- createUniqueUuid,
2712
2751
  findWorldsForOwner,
2752
+ getSalt,
2713
2753
  logger as logger8,
2714
2754
  ModelType as ModelType8,
2715
- parseKeyValueXml as parseKeyValueXml6
2755
+ parseKeyValueXml as parseKeyValueXml6,
2756
+ saltWorldSettings,
2757
+ unsaltWorldSettings
2716
2758
  } from "@elizaos/core";
2717
2759
 
2718
2760
  // ../../node_modules/dedent/dist/dedent.mjs
@@ -2914,14 +2956,14 @@ var completionTemplate = `# Task: Generate a response for settings completion
2914
2956
  Write a natural, conversational response that {{agentName}} would send about the successful completion of settings.
2915
2957
  Include the actions array ["ONBOARDING_COMPLETE"] in your response.
2916
2958
  ${messageCompletionFooter}`;
2917
- async function getWorldSettings(runtime, serverId) {
2959
+ async function getWorldSettings(runtime, worldId) {
2918
2960
  try {
2919
- const worldId = createUniqueUuid(runtime, serverId);
2920
2961
  const world = await runtime.getWorld(worldId);
2921
2962
  if (!world || !world.metadata?.settings) {
2922
2963
  return null;
2923
2964
  }
2924
- return world.metadata.settings;
2965
+ const salt = getSalt();
2966
+ return unsaltWorldSettings(world.metadata.settings, salt);
2925
2967
  } catch (error) {
2926
2968
  logger8.error({
2927
2969
  src: "plugin:bootstrap:action:settings",
@@ -2931,18 +2973,19 @@ async function getWorldSettings(runtime, serverId) {
2931
2973
  return null;
2932
2974
  }
2933
2975
  }
2934
- async function updateWorldSettings(runtime, serverId, worldSettings) {
2976
+ async function updateWorldSettings(runtime, worldId, worldSettings) {
2935
2977
  try {
2936
- const worldId = createUniqueUuid(runtime, serverId);
2937
2978
  const world = await runtime.getWorld(worldId);
2938
2979
  if (!world) {
2939
- logger8.error({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, serverId }, "No world found for server");
2980
+ logger8.error({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, worldId }, "No world found");
2940
2981
  return false;
2941
2982
  }
2942
2983
  if (!world.metadata) {
2943
2984
  world.metadata = {};
2944
2985
  }
2945
- world.metadata.settings = worldSettings;
2986
+ const salt = getSalt();
2987
+ const saltedSettings = saltWorldSettings(worldSettings, salt);
2988
+ world.metadata.settings = saltedSettings;
2946
2989
  await runtime.updateWorld(world);
2947
2990
  return true;
2948
2991
  } catch (error) {
@@ -2968,8 +3011,9 @@ function categorizeSettings(worldSettings) {
2968
3011
  const requiredUnconfigured = [];
2969
3012
  const optionalUnconfigured = [];
2970
3013
  for (const [key, setting] of Object.entries(worldSettings)) {
2971
- if (key.startsWith("_"))
3014
+ if (key.startsWith("_")) {
2972
3015
  continue;
3016
+ }
2973
3017
  const typedSetting = setting;
2974
3018
  if (typedSetting.value !== null) {
2975
3019
  configured.push([key, typedSetting]);
@@ -3047,7 +3091,7 @@ async function extractSettingValues(runtime, _message, state, worldSettings) {
3047
3091
  return [];
3048
3092
  }
3049
3093
  }
3050
- async function processSettingUpdates(runtime, serverId, worldSettings, updates) {
3094
+ async function processSettingUpdates(runtime, worldId, worldSettings, updates) {
3051
3095
  if (!updates.length) {
3052
3096
  return { updatedAny: false, messages: [] };
3053
3097
  }
@@ -3057,8 +3101,9 @@ async function processSettingUpdates(runtime, serverId, worldSettings, updates)
3057
3101
  const updatedState = { ...worldSettings };
3058
3102
  for (const update of updates) {
3059
3103
  const setting = updatedState[update.key];
3060
- if (!setting)
3104
+ if (!setting) {
3061
3105
  continue;
3106
+ }
3062
3107
  if (setting.dependsOn?.length) {
3063
3108
  const dependenciesMet = setting.dependsOn.every((dep) => updatedState[dep]?.value !== null);
3064
3109
  if (!dependenciesMet) {
@@ -3080,11 +3125,11 @@ async function processSettingUpdates(runtime, serverId, worldSettings, updates)
3080
3125
  }
3081
3126
  }
3082
3127
  if (updatedAny) {
3083
- const saved = await updateWorldSettings(runtime, serverId, updatedState);
3128
+ const saved = await updateWorldSettings(runtime, worldId, updatedState);
3084
3129
  if (!saved) {
3085
3130
  throw new Error("Failed to save updated state to world metadata");
3086
3131
  }
3087
- const savedState = await getWorldSettings(runtime, serverId);
3132
+ const savedState = await getWorldSettings(runtime, worldId);
3088
3133
  if (!savedState) {
3089
3134
  throw new Error("Failed to verify state save");
3090
3135
  }
@@ -3478,32 +3523,12 @@ var updateSettingsAction = {
3478
3523
  success: false
3479
3524
  };
3480
3525
  }
3481
- const serverId = serverOwnership?.messageServerId;
3482
- logger8.info({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, serverId }, "Using server ID");
3483
- if (!serverId) {
3484
- logger8.error({
3485
- src: "plugin:bootstrap:action:settings",
3486
- agentId: runtime.agentId,
3487
- entityId: message.entityId
3488
- }, "No server ID found for user in handler");
3489
- await generateErrorResponse(runtime, state, callback);
3490
- return {
3491
- text: "No server ID found",
3492
- values: {
3493
- success: false,
3494
- error: "NO_SERVER_ID"
3495
- },
3496
- data: {
3497
- actionName: "UPDATE_SETTINGS",
3498
- error: "No server ID found",
3499
- entityId: message.entityId
3500
- },
3501
- success: false
3502
- };
3503
- }
3504
- const worldSettings = await getWorldSettings(runtime, serverId);
3526
+ const worldId = serverOwnership.id;
3527
+ logger8.info({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, worldId }, "Using world ID");
3528
+ const rawSettings = serverOwnership.metadata?.settings;
3529
+ const worldSettings = rawSettings ? unsaltWorldSettings(rawSettings, getSalt()) : undefined;
3505
3530
  if (!worldSettings) {
3506
- logger8.error({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, serverId }, "No settings state found for server in handler");
3531
+ logger8.error({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId, worldId }, "No settings state found for world in handler");
3507
3532
  await generateErrorResponse(runtime, state, callback);
3508
3533
  return {
3509
3534
  text: "No settings state found",
@@ -3513,8 +3538,8 @@ var updateSettingsAction = {
3513
3538
  },
3514
3539
  data: {
3515
3540
  actionName: "UPDATE_SETTINGS",
3516
- error: "No settings state found for server",
3517
- serverId
3541
+ error: "No settings state found for world",
3542
+ worldId
3518
3543
  },
3519
3544
  success: false
3520
3545
  };
@@ -3530,14 +3555,14 @@ var updateSettingsAction = {
3530
3555
  agentId: runtime.agentId,
3531
3556
  count: extractedSettings.length
3532
3557
  }, "Extracted settings");
3533
- const updateResults = await processSettingUpdates(runtime, serverId, worldSettings, extractedSettings);
3558
+ const updateResults = await processSettingUpdates(runtime, worldId, worldSettings, extractedSettings);
3534
3559
  if (updateResults.updatedAny) {
3535
3560
  logger8.info({
3536
3561
  src: "plugin:bootstrap:action:settings",
3537
3562
  agentId: runtime.agentId,
3538
3563
  messages: updateResults.messages
3539
3564
  }, "Successfully updated settings");
3540
- const updatedWorldSettings = await getWorldSettings(runtime, serverId);
3565
+ const updatedWorldSettings = await getWorldSettings(runtime, worldId);
3541
3566
  if (!updatedWorldSettings) {
3542
3567
  logger8.error({ src: "plugin:bootstrap:action:settings", agentId: runtime.agentId }, "Failed to retrieve updated settings state");
3543
3568
  await generateErrorResponse(runtime, state, callback);
@@ -3550,7 +3575,7 @@ var updateSettingsAction = {
3550
3575
  data: {
3551
3576
  actionName: "UPDATE_SETTINGS",
3552
3577
  error: "Failed to retrieve updated settings state",
3553
- serverId
3578
+ worldId
3554
3579
  },
3555
3580
  success: false
3556
3581
  };
@@ -3559,14 +3584,14 @@ var updateSettingsAction = {
3559
3584
  const { requiredUnconfigured } = categorizeSettings(updatedWorldSettings);
3560
3585
  const allConfigured = requiredUnconfigured.length === 0;
3561
3586
  return {
3562
- text: `Settings updated successfully`,
3587
+ text: "Settings updated successfully",
3563
3588
  values: {
3564
3589
  success: true,
3565
3590
  settingsUpdated: extractedSettings.length,
3566
3591
  updatedSettings: extractedSettings.map((s) => s.key),
3567
3592
  remainingRequired: requiredUnconfigured.length,
3568
3593
  allConfigured,
3569
- serverId
3594
+ worldId
3570
3595
  },
3571
3596
  data: {
3572
3597
  actionName: "UPDATE_SETTINGS",
@@ -3574,7 +3599,7 @@ var updateSettingsAction = {
3574
3599
  messages: updateResults.messages,
3575
3600
  remainingRequired: requiredUnconfigured.map(([key, _]) => key),
3576
3601
  allConfigured,
3577
- serverId
3602
+ worldId
3578
3603
  },
3579
3604
  success: true
3580
3605
  };
@@ -3588,13 +3613,13 @@ var updateSettingsAction = {
3588
3613
  success: false,
3589
3614
  error: "NO_UPDATES",
3590
3615
  remainingRequired: requiredUnconfigured.length,
3591
- serverId
3616
+ worldId
3592
3617
  },
3593
3618
  data: {
3594
3619
  actionName: "UPDATE_SETTINGS",
3595
3620
  error: "No valid settings found in message",
3596
3621
  remainingRequired: requiredUnconfigured.map(([key, _]) => key),
3597
- serverId
3622
+ worldId
3598
3623
  },
3599
3624
  success: false
3600
3625
  };
@@ -3840,6 +3865,14 @@ var unfollowRoomAction = {
3840
3865
  try {
3841
3866
  await runtime.setParticipantUserState(message.roomId, runtime.agentId, null);
3842
3867
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
3868
+ if (!room) {
3869
+ return {
3870
+ text: "Could not find room to unfollow",
3871
+ values: { success: false, error: "ROOM_NOT_FOUND" },
3872
+ data: { actionName: "UNFOLLOW_ROOM", error: "Room not found" },
3873
+ success: false
3874
+ };
3875
+ }
3843
3876
  await runtime.createMemory({
3844
3877
  entityId: message.entityId,
3845
3878
  agentId: message.agentId,
@@ -4210,7 +4243,6 @@ var unmuteRoomAction = {
4210
4243
  template: shouldUnmuteTemplate
4211
4244
  });
4212
4245
  const response = await runtime.useModel(ModelType10.TEXT_SMALL, {
4213
- runtime,
4214
4246
  prompt: shouldUnmutePrompt,
4215
4247
  stopSequences: []
4216
4248
  });
@@ -4585,6 +4617,14 @@ var updateEntityAction = {
4585
4617
  const sourceEntityId = message.entityId;
4586
4618
  const agentId = runtime.agentId;
4587
4619
  const room = state.data.room ?? await runtime.getRoom(message.roomId);
4620
+ if (!room || !room.worldId) {
4621
+ return {
4622
+ text: "Could not find room or world",
4623
+ values: { success: false, error: "ROOM_NOT_FOUND" },
4624
+ data: { actionName: "UPDATE_CONTACT", error: "Room or world not found" },
4625
+ success: false
4626
+ };
4627
+ }
4588
4628
  const worldId = room.worldId;
4589
4629
  const entity = await findEntityByName2(runtime, message, state);
4590
4630
  if (!entity) {
@@ -4615,18 +4655,12 @@ var updateEntityAction = {
4615
4655
  prompt,
4616
4656
  stopSequences: []
4617
4657
  });
4618
- let parsedResult;
4619
- try {
4620
- parsedResult = parseKeyValueXml7(result);
4621
- if (!parsedResult || !parsedResult.source || !parsedResult.data) {
4622
- throw new Error("Invalid response format - missing source or data");
4623
- }
4624
- } catch (error) {
4658
+ const parsedResult = parseKeyValueXml7(result);
4659
+ if (!parsedResult?.source || !parsedResult?.data) {
4625
4660
  logger10.error({
4626
4661
  src: "plugin:bootstrap:action:update_entity",
4627
- agentId: runtime.agentId,
4628
- error: error instanceof Error ? error.message : String(error)
4629
- }, "Failed to parse component data");
4662
+ agentId: runtime.agentId
4663
+ }, "Failed to parse component data - missing source or data");
4630
4664
  await callback({
4631
4665
  text: "I couldn't properly understand the component information. Please try again with more specific information.",
4632
4666
  actions: ["UPDATE_ENTITY_ERROR"],
@@ -4640,10 +4674,9 @@ var updateEntityAction = {
4640
4674
  },
4641
4675
  data: {
4642
4676
  actionName: "UPDATE_CONTACT",
4643
- error: error.message
4677
+ error: "Invalid response format - missing source or data"
4644
4678
  },
4645
- success: false,
4646
- error
4679
+ success: false
4647
4680
  };
4648
4681
  }
4649
4682
  const componentType = parsedResult.source.toLowerCase();
@@ -4953,7 +4986,7 @@ async function handler(runtime, message, state) {
4953
4986
  if (reflection.facts.fact) {
4954
4987
  factsArray = Array.isArray(reflection.facts.fact) ? reflection.facts.fact : [reflection.facts.fact];
4955
4988
  }
4956
- const newFacts = factsArray.filter((fact) => fact && typeof fact === "object" && fact.already_known === "false" && fact.in_bio === "false" && fact.claim && typeof fact.claim === "string" && fact.claim.trim() !== "") || [];
4989
+ const newFacts = factsArray.filter((fact) => fact != null && fact.already_known === "false" && fact.in_bio === "false" && typeof fact.claim === "string" && fact.claim.trim() !== "");
4957
4990
  await Promise.all(newFacts.map(async (fact) => {
4958
4991
  const factMemory = {
4959
4992
  id: asUUID(v4_default()),
@@ -4973,6 +5006,10 @@ async function handler(runtime, message, state) {
4973
5006
  relationshipsArray = Array.isArray(reflection.relationships.relationship) ? reflection.relationships.relationship : [reflection.relationships.relationship];
4974
5007
  }
4975
5008
  for (const relationship of relationshipsArray) {
5009
+ if (!relationship.sourceEntityId || !relationship.targetEntityId) {
5010
+ console.warn("Skipping relationship with missing entity IDs:", relationship);
5011
+ continue;
5012
+ }
4976
5013
  let sourceId;
4977
5014
  let targetId;
4978
5015
  try {
@@ -5305,8 +5342,9 @@ var actionStateProvider = {
5305
5342
  Output: ${result.text}`;
5306
5343
  }
5307
5344
  if (result.error) {
5345
+ const errorMsg = result.error instanceof Error ? result.error.message : result.error;
5308
5346
  resultText += `
5309
- Error: ${result.error}`;
5347
+ Error: ${errorMsg}`;
5310
5348
  }
5311
5349
  if (result.values && Object.keys(result.values).length > 0) {
5312
5350
  const values = Object.entries(result.values).map(([key, value]) => ` - ${key}: ${JSON.stringify(value)}`).join(`
@@ -5325,9 +5363,14 @@ ${values}`;
5325
5363
  }
5326
5364
  let memoryText = "";
5327
5365
  if (Object.keys(workingMemory).length > 0) {
5328
- const memoryEntries = Object.entries(workingMemory).sort((a, b) => (b[1].timestamp || 0) - (a[1].timestamp || 0)).slice(0, 10).map(([key, value]) => {
5329
- if (value.actionName && value.result) {
5330
- return `**${value.actionName}**: ${value.result.text || JSON.stringify(value.result.data)}`;
5366
+ const memoryEntries = Object.entries(workingMemory).sort((a, b) => {
5367
+ const aTimestamp = a[1] && typeof a[1] === "object" && "timestamp" in a[1] && typeof a[1].timestamp === "number" ? a[1].timestamp : 0;
5368
+ const bTimestamp = b[1] && typeof b[1] === "object" && "timestamp" in b[1] && typeof b[1].timestamp === "number" ? b[1].timestamp : 0;
5369
+ return bTimestamp - aTimestamp;
5370
+ }).slice(0, 10).map(([key, value]) => {
5371
+ const valueObj = value && typeof value === "object" ? value : null;
5372
+ if (valueObj?.actionName && valueObj.result) {
5373
+ return `**${valueObj.actionName}**: ${valueObj.result.text || JSON.stringify(valueObj.result.data)}`;
5331
5374
  }
5332
5375
  return `**${key}**: ${JSON.stringify(value)}`;
5333
5376
  }).join(`
@@ -5371,8 +5414,9 @@ ${values}`;
5371
5414
  const planStep = mem.content?.planStep || "";
5372
5415
  const text = mem.content?.text || "";
5373
5416
  let memText = ` - ${actionName} (${status})`;
5374
- if (planStep)
5417
+ if (planStep) {
5375
5418
  memText += ` [${planStep}]`;
5419
+ }
5376
5420
  if (text && text !== `Executed action: ${actionName}`) {
5377
5421
  memText += `: ${text}`;
5378
5422
  }
@@ -6094,8 +6138,9 @@ var recentMessagesProvider = {
6094
6138
  const text2 = mem.content?.text || "";
6095
6139
  const error = mem.content?.error || "";
6096
6140
  let memText = ` - ${actionName} (${status})`;
6097
- if (planStep)
6141
+ if (planStep) {
6098
6142
  memText += ` [${planStep}]`;
6143
+ }
6099
6144
  if (error) {
6100
6145
  memText += `: Error - ${error}`;
6101
6146
  } else if (text2 && text2 !== `Executed action: ${actionName}`) {
@@ -6335,7 +6380,6 @@ ${formattedRelationships}`
6335
6380
  // src/providers/roles.ts
6336
6381
  import {
6337
6382
  ChannelType as ChannelType6,
6338
- createUniqueUuid as createUniqueUuid2,
6339
6383
  logger as logger13
6340
6384
  } from "@elizaos/core";
6341
6385
  var roleProvider = {
@@ -6357,15 +6401,14 @@ var roleProvider = {
6357
6401
  text: "No access to role information in DMs, the role provider is only available in group scenarios."
6358
6402
  };
6359
6403
  }
6360
- const serverId = room.messageServerId;
6361
- if (!serverId) {
6362
- throw new Error("No server ID found");
6404
+ const worldId = room.worldId;
6405
+ if (!worldId) {
6406
+ throw new Error("No world ID found for room");
6363
6407
  }
6364
- logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, serverId }, "Using server ID");
6365
- const worldId = createUniqueUuid2(runtime, serverId);
6408
+ logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, worldId }, "Using world ID");
6366
6409
  const world = await runtime.getWorld(worldId);
6367
6410
  if (!world || !world.metadata?.ownership?.ownerId) {
6368
- logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, serverId }, "No ownership data found for server, initializing empty role hierarchy");
6411
+ logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, worldId }, "No ownership data found for world, initializing empty role hierarchy");
6369
6412
  return {
6370
6413
  data: {
6371
6414
  roles: []
@@ -6378,7 +6421,7 @@ var roleProvider = {
6378
6421
  }
6379
6422
  const roles = world.metadata.roles || {};
6380
6423
  if (Object.keys(roles).length === 0) {
6381
- logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, serverId }, "No roles found for server");
6424
+ logger13.info({ src: "plugin:bootstrap:provider:roles", agentId: runtime.agentId, worldId }, "No roles found for world");
6382
6425
  return {
6383
6426
  data: {
6384
6427
  roles: []
@@ -6479,21 +6522,25 @@ var roleProvider = {
6479
6522
  import {
6480
6523
  ChannelType as ChannelType7,
6481
6524
  findWorldsForOwner as findWorldsForOwner2,
6482
- getWorldSettings as getWorldSettings2,
6483
- logger as logger14
6525
+ getSalt as getSalt2,
6526
+ logger as logger14,
6527
+ unsaltWorldSettings as unsaltWorldSettings2
6484
6528
  } from "@elizaos/core";
6485
6529
  var formatSettingValue = (setting, isOnboarding) => {
6486
- if (setting.value === null)
6530
+ if (setting.value === null) {
6487
6531
  return "Not set";
6488
- if (setting.secret && !isOnboarding)
6532
+ }
6533
+ if (setting.secret && !isOnboarding) {
6489
6534
  return "****************";
6535
+ }
6490
6536
  return String(setting.value);
6491
6537
  };
6492
6538
  function generateStatusMessage(runtime, worldSettings, isOnboarding, state) {
6493
6539
  try {
6494
6540
  const formattedSettings = Object.entries(worldSettings).map(([key, setting]) => {
6495
- if (typeof setting !== "object" || !setting.name)
6541
+ if (typeof setting !== "object" || !setting.name) {
6496
6542
  return null;
6543
+ }
6497
6544
  const description = setting.description || "";
6498
6545
  const usageDescription = setting.usageDescription || "";
6499
6546
  if (setting.visibleIf && !setting.visibleIf(worldSettings)) {
@@ -6631,18 +6678,9 @@ var settingsProvider = {
6631
6678
  throw new Error("No server ownership found for onboarding");
6632
6679
  }
6633
6680
  serverId = world.messageServerId;
6634
- if (serverId) {
6635
- try {
6636
- worldSettings = await getWorldSettings2(runtime, serverId);
6637
- } catch (error) {
6638
- logger14.error({
6639
- src: "plugin:bootstrap:provider:settings",
6640
- agentId: runtime.agentId,
6641
- serverId,
6642
- error: error instanceof Error ? error.message : String(error)
6643
- }, "Error fetching world settings");
6644
- throw new Error(`Failed to retrieve settings for server ${serverId}`);
6645
- }
6681
+ if (world.metadata?.settings) {
6682
+ const salt = getSalt2();
6683
+ worldSettings = unsaltWorldSettings2(world.metadata.settings, salt);
6646
6684
  }
6647
6685
  } else {
6648
6686
  try {
@@ -6656,14 +6694,15 @@ var settingsProvider = {
6656
6694
  throw new Error(`No world found for room ${room.worldId}`);
6657
6695
  }
6658
6696
  serverId = world.messageServerId;
6659
- if (serverId) {
6660
- worldSettings = await getWorldSettings2(runtime, serverId);
6661
- } else {
6662
- logger14.error({
6697
+ if (world.metadata?.settings) {
6698
+ const salt = getSalt2();
6699
+ worldSettings = unsaltWorldSettings2(world.metadata.settings, salt);
6700
+ } else if (!serverId) {
6701
+ logger14.debug({
6663
6702
  src: "plugin:bootstrap:provider:settings",
6664
6703
  agentId: runtime.agentId,
6665
6704
  worldId: room.worldId
6666
- }, "No server ID found for world");
6705
+ }, "No server ID or settings found for world");
6667
6706
  }
6668
6707
  } catch (error) {
6669
6708
  logger14.error({
@@ -7274,8 +7313,9 @@ class EmbeddingGenerationService extends Service2 {
7274
7313
  itemsWithIndex.sort((a, b) => {
7275
7314
  const priorityOrder = { low: 0, normal: 1, high: 2 };
7276
7315
  const priorityDiff = priorityOrder[a.item.priority] - priorityOrder[b.item.priority];
7277
- if (priorityDiff !== 0)
7316
+ if (priorityDiff !== 0) {
7278
7317
  return priorityDiff;
7318
+ }
7279
7319
  return a.item.addedAt - b.item.addedAt;
7280
7320
  });
7281
7321
  const indicesToRemove = new Set(itemsWithIndex.slice(0, Math.min(itemsToRemove, itemsWithIndex.length)).map(({ originalIndex }) => originalIndex));
@@ -7293,8 +7333,9 @@ class EmbeddingGenerationService extends Service2 {
7293
7333
  if (queueItem.priority === "high") {
7294
7334
  let insertIndex = 0;
7295
7335
  for (let i = 0;i < this.queue.length; i++) {
7296
- if (this.queue[i].priority !== "high")
7336
+ if (this.queue[i].priority !== "high") {
7297
7337
  break;
7338
+ }
7298
7339
  insertIndex = i + 1;
7299
7340
  }
7300
7341
  this.queue.splice(insertIndex, 0, queueItem);
@@ -7540,8 +7581,9 @@ async function processAttachments(attachments, runtime) {
7540
7581
  let imageUrl = url;
7541
7582
  if (!isRemote) {
7542
7583
  const res = await fetch(url);
7543
- if (!res.ok)
7584
+ if (!res.ok) {
7544
7585
  throw new Error(`Failed to fetch image: ${res.statusText}`);
7586
+ }
7545
7587
  const arrayBuffer = await res.arrayBuffer();
7546
7588
  const buffer = Buffer.from(arrayBuffer);
7547
7589
  const contentType = res.headers.get("content-type") || "application/octet-stream";
@@ -7555,9 +7597,9 @@ async function processAttachments(attachments, runtime) {
7555
7597
  if (typeof response === "string") {
7556
7598
  const parsedXml = parseKeyValueXml9(response);
7557
7599
  if (parsedXml && (parsedXml.description || parsedXml.text)) {
7558
- processedAttachment.description = parsedXml.description || "";
7559
- processedAttachment.title = parsedXml.title || "Image";
7560
- processedAttachment.text = parsedXml.text || parsedXml.description || "";
7600
+ processedAttachment.description = parsedXml.description ?? "";
7601
+ processedAttachment.title = parsedXml.title ?? "Image";
7602
+ processedAttachment.text = parsedXml.text ?? parsedXml.description ?? "";
7561
7603
  runtime.logger.debug({
7562
7604
  src: "plugin:bootstrap",
7563
7605
  agentId: runtime.agentId,
@@ -7602,8 +7644,9 @@ async function processAttachments(attachments, runtime) {
7602
7644
  }
7603
7645
  } else if (attachment.contentType === ContentType2.DOCUMENT && !attachment.text) {
7604
7646
  const res = await fetch(url);
7605
- if (!res.ok)
7647
+ if (!res.ok) {
7606
7648
  throw new Error(`Failed to fetch document: ${res.statusText}`);
7649
+ }
7607
7650
  const contentType = res.headers.get("content-type") || "";
7608
7651
  const isPlainText = contentType.startsWith("text/plain");
7609
7652
  if (isPlainText) {
@@ -7638,8 +7681,9 @@ function shouldRespond(runtime, message, room, mentionContext) {
7638
7681
  return { shouldRespond: false, skipEvaluation: true, reason: "no room context" };
7639
7682
  }
7640
7683
  function normalizeEnvList(value) {
7641
- if (!value || typeof value !== "string")
7684
+ if (!value || typeof value !== "string") {
7642
7685
  return [];
7686
+ }
7643
7687
  const cleaned = value.trim().replace(/^[\[]|[\]]$/g, "");
7644
7688
  return cleaned.split(",").map((v) => v.trim()).filter(Boolean);
7645
7689
  }
@@ -7680,7 +7724,8 @@ var reactionReceivedHandler = async ({
7680
7724
  try {
7681
7725
  await runtime.createMemory(message, "messages");
7682
7726
  } catch (error) {
7683
- if (error.code === "23505") {
7727
+ const isDuplicateKeyError = error instanceof Error && "code" in error && error.code === "23505";
7728
+ if (isDuplicateKeyError) {
7684
7729
  runtime.logger.warn({ src: "plugin:bootstrap", agentId: runtime.agentId }, "Duplicate reaction memory, skipping");
7685
7730
  return;
7686
7731
  }
@@ -7716,7 +7761,7 @@ var postGeneratedHandler = async ({
7716
7761
  worldId
7717
7762
  });
7718
7763
  const message = {
7719
- id: createUniqueUuid3(runtime, `tweet-${Date.now()}`),
7764
+ id: createUniqueUuid(runtime, `tweet-${Date.now()}`),
7720
7765
  entityId: runtime.agentId,
7721
7766
  agentId: runtime.agentId,
7722
7767
  roomId,
@@ -7733,8 +7778,9 @@ var postGeneratedHandler = async ({
7733
7778
  "ENTITIES"
7734
7779
  ]);
7735
7780
  const entity = await runtime.getEntityById(runtime.agentId);
7736
- if (entity?.metadata?.twitter?.userName || entity?.metadata?.userName) {
7737
- state.values.twitterUserName = entity?.metadata?.twitter?.userName || entity?.metadata?.userName;
7781
+ const metadata = entity?.metadata;
7782
+ if (metadata?.twitter?.userName || metadata?.userName) {
7783
+ state.values.twitterUserName = metadata.twitter?.userName || metadata.userName;
7738
7784
  }
7739
7785
  const prompt = composePromptFromState10({
7740
7786
  state,
@@ -7749,12 +7795,14 @@ var postGeneratedHandler = async ({
7749
7795
  });
7750
7796
  const parsedXml = parseKeyValueXml9(response);
7751
7797
  if (parsedXml) {
7798
+ const actionsRaw = parsedXml.actions;
7799
+ const providersRaw = parsedXml.providers;
7752
7800
  responseContent = {
7753
- thought: parsedXml.thought || "",
7754
- actions: parsedXml.actions || ["IGNORE"],
7755
- providers: parsedXml.providers || [],
7756
- text: parsedXml.text || "",
7757
- simple: parsedXml.simple || false
7801
+ thought: parsedXml.thought ?? "",
7802
+ actions: Array.isArray(actionsRaw) ? actionsRaw : actionsRaw ? [actionsRaw] : ["IGNORE"],
7803
+ providers: Array.isArray(providersRaw) ? providersRaw : providersRaw ? [providersRaw] : [],
7804
+ text: parsedXml.text ?? "",
7805
+ simple: parsedXml.simple ?? false
7758
7806
  };
7759
7807
  } else {
7760
7808
  responseContent = null;
@@ -7787,9 +7835,9 @@ var postGeneratedHandler = async ({
7787
7835
  $2`);
7788
7836
  return cleanedText2;
7789
7837
  }
7790
- const cleanedText = cleanupPostText(parsedXmlResponse.post || "");
7838
+ const cleanedText = cleanupPostText(parsedXmlResponse.post ?? "");
7791
7839
  const RM = state.data?.providers?.RECENT_MESSAGES;
7792
- if (RM) {
7840
+ if (RM?.data?.recentMessages) {
7793
7841
  for (const m of RM.data.recentMessages) {
7794
7842
  if (cleanedText === m.content.text) {
7795
7843
  runtime.logger.info({ src: "plugin:bootstrap", agentId: runtime.agentId, cleanedText }, "Already recently posted that, retrying");
@@ -7830,7 +7878,7 @@ $2`);
7830
7878
  text: cleanedText,
7831
7879
  source,
7832
7880
  channelType: ChannelType9.FEED,
7833
- thought: parsedXmlResponse.thought || "",
7881
+ thought: parsedXmlResponse.thought ?? "",
7834
7882
  type: "post"
7835
7883
  },
7836
7884
  roomId: message.roomId,
@@ -7854,8 +7902,8 @@ var syncSingleUser = async (entityId, runtime, messageServerId, channelId, type,
7854
7902
  runtime.logger.warn({ src: "plugin:bootstrap", agentId: runtime.agentId, entityId: entity?.id }, "Cannot sync user without a valid channelId");
7855
7903
  return;
7856
7904
  }
7857
- const roomId = createUniqueUuid3(runtime, channelId);
7858
- const worldId = createUniqueUuid3(runtime, messageServerId);
7905
+ const roomId = createUniqueUuid(runtime, channelId);
7906
+ const worldId = createUniqueUuid(runtime, messageServerId);
7859
7907
  const worldMetadata = type === ChannelType9.DM ? {
7860
7908
  ownership: {
7861
7909
  ownerId: entityId
@@ -7933,10 +7981,7 @@ var handleServerSync = async ({
7933
7981
  }, "Error processing standardized server data");
7934
7982
  }
7935
7983
  };
7936
- var controlMessageHandler = async ({
7937
- runtime,
7938
- message
7939
- }) => {
7984
+ var controlMessageHandler = async ({ runtime, message }) => {
7940
7985
  try {
7941
7986
  runtime.logger.debug({
7942
7987
  src: "plugin:bootstrap",
@@ -8017,7 +8062,12 @@ var events = {
8017
8062
  payload.runtime.logger.error({ src: "plugin:bootstrap", agentId: payload.runtime.agentId }, "No type provided for entity joined");
8018
8063
  return;
8019
8064
  }
8020
- await syncSingleUser(payload.entityId, payload.runtime, payload.worldId, payload.roomId, payload.metadata.type, payload.source);
8065
+ const channelType = payload.metadata?.type;
8066
+ if (typeof channelType !== "string") {
8067
+ payload.runtime.logger.warn("Missing channel type in entity payload");
8068
+ return;
8069
+ }
8070
+ await syncSingleUser(payload.entityId, payload.runtime, payload.worldId, payload.roomId, channelType, payload.source);
8021
8071
  }
8022
8072
  ],
8023
8073
  [EventType2.ENTITY_LEFT]: [
@@ -8228,7 +8278,15 @@ var events = {
8228
8278
  }
8229
8279
  }
8230
8280
  ],
8231
- CONTROL_MESSAGE: [controlMessageHandler]
8281
+ [EventType2.CONTROL_MESSAGE]: [
8282
+ async (payload) => {
8283
+ if (!payload.message) {
8284
+ payload.runtime.logger.warn({ src: "plugin:bootstrap" }, "CONTROL_MESSAGE received without message property");
8285
+ return;
8286
+ }
8287
+ await controlMessageHandler(payload);
8288
+ }
8289
+ ]
8232
8290
  };
8233
8291
  var bootstrapPlugin = {
8234
8292
  name: "bootstrap",
@@ -8310,5 +8368,5 @@ export {
8310
8368
  actionStateProvider
8311
8369
  };
8312
8370
 
8313
- //# debugId=F550F36B3F910A4364756E2164756E21
8371
+ //# debugId=A60B9416692989D164756E2164756E21
8314
8372
  //# sourceMappingURL=index.js.map