@elizaos/plugin-commands 2.0.0-alpha.3 → 2.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
2
  import {
3
- logger
3
+ logger as logger3
4
4
  } from "@elizaos/core";
5
5
 
6
6
  // src/registry.ts
@@ -286,21 +286,39 @@ var DEFAULT_COMMANDS = [
286
286
  requiresElevated: true
287
287
  }
288
288
  ];
289
- var commands = [...DEFAULT_COMMANDS];
290
- var aliasMap = null;
289
+ var runtimeStores = new Map;
290
+ var fallbackStore = {
291
+ commands: DEFAULT_COMMANDS.map((c) => ({ ...c })),
292
+ aliasMap: null
293
+ };
294
+ var activeStore = fallbackStore;
295
+ function initForRuntime(agentId) {
296
+ const store = {
297
+ commands: DEFAULT_COMMANDS.map((c) => ({ ...c })),
298
+ aliasMap: null
299
+ };
300
+ runtimeStores.set(agentId, store);
301
+ activeStore = store;
302
+ }
303
+ function useRuntime(agentId) {
304
+ const store = runtimeStores.get(agentId);
305
+ if (store) {
306
+ activeStore = store;
307
+ }
308
+ }
291
309
  function getCommands() {
292
- return [...commands];
310
+ return [...activeStore.commands];
293
311
  }
294
312
  function getEnabledCommands() {
295
- return commands.filter((cmd) => cmd.enabled !== false);
313
+ return activeStore.commands.filter((cmd) => cmd.enabled !== false);
296
314
  }
297
315
  function getCommandsByCategory(category) {
298
- return commands.filter((cmd) => cmd.category === category && cmd.enabled !== false);
316
+ return activeStore.commands.filter((cmd) => cmd.category === category && cmd.enabled !== false);
299
317
  }
300
318
  function registerCommand(command) {
301
- commands = commands.filter((c) => c.key !== command.key);
302
- commands.push(command);
303
- aliasMap = null;
319
+ activeStore.commands = activeStore.commands.filter((c) => c.key !== command.key);
320
+ activeStore.commands.push(command);
321
+ activeStore.aliasMap = null;
304
322
  }
305
323
  function registerCommands(newCommands) {
306
324
  for (const command of newCommands) {
@@ -308,35 +326,35 @@ function registerCommands(newCommands) {
308
326
  }
309
327
  }
310
328
  function unregisterCommand(key) {
311
- commands = commands.filter((c) => c.key !== key);
312
- aliasMap = null;
329
+ activeStore.commands = activeStore.commands.filter((c) => c.key !== key);
330
+ activeStore.aliasMap = null;
313
331
  }
314
332
  function resetCommands() {
315
- commands = [...DEFAULT_COMMANDS];
316
- aliasMap = null;
333
+ activeStore.commands = DEFAULT_COMMANDS.map((c) => ({ ...c }));
334
+ activeStore.aliasMap = null;
317
335
  }
318
336
  function getAliasMap() {
319
- if (aliasMap)
320
- return aliasMap;
321
- aliasMap = new Map;
322
- for (const command of commands) {
337
+ if (activeStore.aliasMap)
338
+ return activeStore.aliasMap;
339
+ activeStore.aliasMap = new Map;
340
+ for (const command of activeStore.commands) {
323
341
  if (command.enabled === false)
324
342
  continue;
325
343
  for (const alias of command.textAliases) {
326
344
  const normalized = alias.toLowerCase().trim();
327
- if (!aliasMap.has(normalized)) {
328
- aliasMap.set(normalized, command);
345
+ if (!activeStore.aliasMap.has(normalized)) {
346
+ activeStore.aliasMap.set(normalized, command);
329
347
  }
330
348
  }
331
349
  }
332
- return aliasMap;
350
+ return activeStore.aliasMap;
333
351
  }
334
352
  function findCommandByAlias(alias) {
335
353
  const map = getAliasMap();
336
354
  return map.get(alias.toLowerCase().trim());
337
355
  }
338
356
  function findCommandByKey(key) {
339
- return commands.find((c) => c.key === key);
357
+ return activeStore.commands.find((c) => c.key === key);
340
358
  }
341
359
  function startsWithCommand(text) {
342
360
  const map = getAliasMap();
@@ -498,18 +516,18 @@ function extractCommand(text) {
498
516
  // src/actions/commands-list.ts
499
517
  var commandsListAction = {
500
518
  name: "COMMANDS_LIST",
501
- description: "List all available commands with their aliases",
502
- similes: ["/commands", "/cmds", "list all commands"],
519
+ description: "List all available commands with their aliases. Only activates for /commands or /cmds slash commands.",
520
+ similes: ["/commands", "/cmds"],
503
521
  async validate(runtime, message) {
504
522
  const text = message.content?.text ?? "";
505
523
  const detection = detectCommand(text);
506
524
  return detection.isCommand && detection.command?.key === "commands";
507
525
  },
508
526
  async handler(runtime, message, state, options, callback) {
509
- const commands2 = getEnabledCommands();
510
- const lines = [`**Commands (${commands2.length}):**
527
+ const commands = getEnabledCommands();
528
+ const lines = [`**Commands (${commands.length}):**
511
529
  `];
512
- for (const cmd of commands2) {
530
+ for (const cmd of commands) {
513
531
  const aliases = cmd.textAliases.join(", ");
514
532
  const authNote = cmd.requiresAuth ? " [auth]" : "";
515
533
  const elevatedNote = cmd.requiresElevated ? " [elevated]" : "";
@@ -521,7 +539,7 @@ var commandsListAction = {
521
539
  return {
522
540
  success: true,
523
541
  text: replyText,
524
- data: { commandCount: commands2.length }
542
+ data: { commandCount: commands.length }
525
543
  };
526
544
  },
527
545
  examples: [
@@ -541,7 +559,7 @@ var commandsListAction = {
541
559
  };
542
560
 
543
561
  // src/actions/help.ts
544
- function formatCommandList(commands2) {
562
+ function formatCommandList(commands) {
545
563
  const lines = [`**Available Commands:**
546
564
  `];
547
565
  const categories = [
@@ -553,7 +571,7 @@ function formatCommandList(commands2) {
553
571
  { key: "tools", name: "Tools" }
554
572
  ];
555
573
  for (const cat of categories) {
556
- const catCommands = commands2.filter((c) => c.category === cat.key);
574
+ const catCommands = commands.filter((c) => c.category === cat.key);
557
575
  if (catCommands.length === 0)
558
576
  continue;
559
577
  lines.push(`
@@ -563,7 +581,7 @@ function formatCommandList(commands2) {
563
581
  lines.push(`• ${aliases} - ${cmd.description}`);
564
582
  }
565
583
  }
566
- const uncategorized = commands2.filter((c) => !c.category);
584
+ const uncategorized = commands.filter((c) => !c.category);
567
585
  if (uncategorized.length > 0) {
568
586
  lines.push(`
569
587
  **Other:**`);
@@ -577,21 +595,21 @@ function formatCommandList(commands2) {
577
595
  }
578
596
  var helpAction = {
579
597
  name: "HELP_COMMAND",
580
- description: "Show available commands and their descriptions",
581
- similes: ["/help", "/h", "/?", "help", "show help", "list commands"],
598
+ description: "Show available commands and their descriptions. Only activates for /help, /h, or /? slash commands.",
599
+ similes: ["/help", "/h", "/?"],
582
600
  async validate(runtime, message) {
583
601
  const text = message.content?.text ?? "";
584
602
  const detection = detectCommand(text);
585
603
  return detection.isCommand && detection.command?.key === "help";
586
604
  },
587
605
  async handler(runtime, message, state, options, callback) {
588
- const commands2 = getEnabledCommands();
589
- const helpText = formatCommandList(commands2);
606
+ const commands = getEnabledCommands();
607
+ const helpText = formatCommandList(commands);
590
608
  await callback?.({ text: helpText });
591
609
  return {
592
610
  success: true,
593
611
  text: helpText,
594
- data: { commandCount: commands2.length }
612
+ data: { commandCount: commands.length }
595
613
  };
596
614
  },
597
615
  examples: [
@@ -623,10 +641,31 @@ var helpAction = {
623
641
  };
624
642
 
625
643
  // src/actions/models.ts
644
+ import { ModelType, logger } from "@elizaos/core";
645
+ function describeModelType(modelType) {
646
+ const descriptions = {
647
+ [ModelType.TEXT_SMALL]: "Text (Small)",
648
+ [ModelType.TEXT_LARGE]: "Text (Large)",
649
+ [ModelType.TEXT_REASONING_SMALL]: "Reasoning (Small)",
650
+ [ModelType.TEXT_REASONING_LARGE]: "Reasoning (Large)",
651
+ [ModelType.TEXT_COMPLETION]: "Text Completion",
652
+ [ModelType.TEXT_EMBEDDING]: "Embedding",
653
+ [ModelType.IMAGE]: "Image Generation",
654
+ [ModelType.IMAGE_DESCRIPTION]: "Image Description",
655
+ [ModelType.TRANSCRIPTION]: "Transcription",
656
+ [ModelType.TEXT_TO_SPEECH]: "Text-to-Speech",
657
+ [ModelType.AUDIO]: "Audio",
658
+ [ModelType.VIDEO]: "Video",
659
+ [ModelType.OBJECT_SMALL]: "Object (Small)",
660
+ [ModelType.OBJECT_LARGE]: "Object (Large)",
661
+ [ModelType.RESEARCH]: "Research"
662
+ };
663
+ return descriptions[modelType] ?? modelType;
664
+ }
626
665
  var modelsAction = {
627
666
  name: "MODELS_COMMAND",
628
- description: "List available AI models and providers",
629
- similes: ["/models", "list models", "show models", "available models"],
667
+ description: "List available AI models and providers. Only activates for /models slash command.",
668
+ similes: ["/models"],
630
669
  async validate(runtime, message) {
631
670
  const text = message.content?.text ?? "";
632
671
  const detection = detectCommand(text);
@@ -635,37 +674,41 @@ var modelsAction = {
635
674
  async handler(runtime, message, state, options, callback) {
636
675
  const lines = [`**Available Models:**
637
676
  `];
638
- const providers = [
639
- {
640
- name: "Anthropic",
641
- models: [
642
- "claude-3-opus",
643
- "claude-3-sonnet",
644
- "claude-3-haiku",
645
- "claude-3.5-sonnet"
646
- ]
647
- },
648
- {
649
- name: "OpenAI",
650
- models: [
651
- "gpt-4o",
652
- "gpt-4o-mini",
653
- "gpt-4-turbo",
654
- "gpt-4",
655
- "gpt-3.5-turbo"
656
- ]
657
- },
658
- {
659
- name: "Google",
660
- models: ["gemini-pro", "gemini-pro-vision", "gemini-ultra"]
677
+ try {
678
+ const registeredTypes = [];
679
+ const seen = new Set;
680
+ for (const modelType of Object.values(ModelType)) {
681
+ if (seen.has(modelType))
682
+ continue;
683
+ seen.add(modelType);
684
+ try {
685
+ const handler = runtime.getModel(modelType);
686
+ if (handler) {
687
+ registeredTypes.push(modelType);
688
+ }
689
+ } catch {}
661
690
  }
662
- ];
663
- for (const provider of providers) {
664
- lines.push(`
665
- **${provider.name}:**`);
666
- for (const model of provider.models) {
667
- lines.push(`• ${provider.name.toLowerCase()}/${model}`);
691
+ if (registeredTypes.length > 0) {
692
+ lines.push("**Registered Model Types:**");
693
+ for (const modelType of registeredTypes) {
694
+ lines.push(`• ${describeModelType(modelType)} (\`${modelType}\`)`);
695
+ }
696
+ } else {
697
+ lines.push("No model handlers are currently registered.");
698
+ }
699
+ const modelProvider = runtime.getSetting("MODEL_PROVIDER");
700
+ const modelName = runtime.getSetting("MODEL_NAME");
701
+ if (modelProvider || modelName) {
702
+ lines.push(`
703
+ **Current Configuration:**`);
704
+ if (modelProvider)
705
+ lines.push(`• Provider: ${modelProvider}`);
706
+ if (modelName)
707
+ lines.push(`• Model: ${modelName}`);
668
708
  }
709
+ } catch (err) {
710
+ logger.warn({ src: "plugin-commands", err }, "Error querying runtime models");
711
+ lines.push("Unable to query available models.");
669
712
  }
670
713
  lines.push(`
671
714
 
@@ -675,8 +718,7 @@ _Use /model <provider/model> to switch models._`);
675
718
  await callback?.({ text: replyText });
676
719
  return {
677
720
  success: true,
678
- text: replyText,
679
- data: { providers }
721
+ text: replyText
680
722
  };
681
723
  },
682
724
  examples: [
@@ -685,11 +727,7 @@ _Use /model <provider/model> to switch models._`);
685
727
  {
686
728
  user: "assistant",
687
729
  content: {
688
- text: `**Available Models:**
689
-
690
- **Anthropic:**
691
- • anthropic/claude-3-opus
692
- • anthropic/claude-3-sonnet...`
730
+ text: "**Available Models:**\n\n**Registered Model Types:**\n• Text (Large) (`text_large`)\n• Text (Small) (`text_small`)..."
693
731
  }
694
732
  }
695
733
  ]
@@ -700,7 +738,7 @@ _Use /model <provider/model> to switch models._`);
700
738
  async function buildStatusReport(runtime, roomId) {
701
739
  const lines = [`**Session Status:**
702
740
  `];
703
- lines.push(`**Agent:** ${runtime.agentId}`);
741
+ lines.push(`**Agent:** ${runtime.character.name ?? runtime.agentId}`);
704
742
  lines.push(`**Room:** ${roomId}`);
705
743
  try {
706
744
  const directiveService = runtime.getService("directive-parser");
@@ -720,13 +758,20 @@ async function buildStatusReport(runtime, roomId) {
720
758
  }
721
759
  }
722
760
  } catch {}
761
+ try {
762
+ const tasks = await runtime.getTasks({ roomId });
763
+ if (tasks.length > 0) {
764
+ lines.push(`
765
+ **Tasks:** ${tasks.length} pending`);
766
+ }
767
+ } catch {}
723
768
  return lines.join(`
724
769
  `);
725
770
  }
726
771
  var statusAction = {
727
772
  name: "STATUS_COMMAND",
728
- description: "Show current session status, model, and settings",
729
- similes: ["/status", "/s", "status", "show status", "what's my status"],
773
+ description: "Show session directive settings via /status slash command. Only activates for /status or /s prefix.",
774
+ similes: ["/status", "/s"],
730
775
  async validate(runtime, message) {
731
776
  const text = message.content?.text ?? "";
732
777
  const detection = detectCommand(text);
@@ -748,7 +793,7 @@ var statusAction = {
748
793
  content: {
749
794
  text: `**Session Status:**
750
795
 
751
- **Agent:** agent-123
796
+ **Agent:** Eliza
752
797
  **Room:** room-456
753
798
 
754
799
  **Directives:**
@@ -760,10 +805,11 @@ var statusAction = {
760
805
  };
761
806
 
762
807
  // src/actions/stop.ts
808
+ import { EventType, logger as logger2 } from "@elizaos/core";
763
809
  var stopAction = {
764
810
  name: "STOP_COMMAND",
765
- description: "Stop current operation or abort running tasks",
766
- similes: ["/stop", "/abort", "/cancel", "stop", "abort", "cancel"],
811
+ description: "Stop current operation or abort running tasks. Triggered by /stop, /abort, or /cancel slash commands only.",
812
+ similes: ["/stop", "/abort", "/cancel"],
767
813
  async validate(runtime, message) {
768
814
  const text = message.content?.text ?? "";
769
815
  const detection = detectCommand(text);
@@ -771,12 +817,22 @@ var stopAction = {
771
817
  },
772
818
  async handler(runtime, message, state, options, callback) {
773
819
  try {
774
- await runtime.emitEvent?.("ABORT_REQUESTED", {
775
- roomId: message.roomId,
776
- userId: message.userId,
777
- requestedAt: Date.now()
820
+ await runtime.emitEvent(EventType.HOOK_COMMAND_STOP, {
821
+ runtime,
822
+ sessionKey: message.roomId,
823
+ messages: [],
824
+ timestamp: new Date,
825
+ context: {
826
+ entityId: message.entityId,
827
+ source: message.content?.source
828
+ },
829
+ command: "stop",
830
+ senderId: message.entityId,
831
+ commandSource: message.content?.source
778
832
  });
779
- } catch {}
833
+ } catch (err) {
834
+ logger2.warn({ src: "plugin-commands", err }, "Failed to emit HOOK_COMMAND_STOP event");
835
+ }
780
836
  const replyText = "✓ Stop requested. Current operations will be cancelled.";
781
837
  await callback?.({ text: replyText });
782
838
  return {
@@ -812,28 +868,44 @@ var commandRegistryProvider = {
812
868
  description: "Available chat commands and their descriptions",
813
869
  dynamic: true,
814
870
  async get(runtime, message, _state) {
815
- const commands2 = getEnabledCommands();
816
- const commandList = commands2.map((cmd) => {
817
- const auth = cmd.requiresAuth ? " (requires auth)" : "";
818
- return `- ${cmd.textAliases[0]}: ${cmd.description}${auth}`;
819
- });
820
- return {
821
- text: `Available commands:
871
+ useRuntime(runtime.agentId);
872
+ const text = message.content?.text ?? "";
873
+ const isCommand = hasCommand(text);
874
+ const commands = getEnabledCommands();
875
+ if (isCommand) {
876
+ const commandList = commands.map((cmd) => {
877
+ const auth = cmd.requiresAuth ? " (requires auth)" : "";
878
+ return `- ${cmd.textAliases[0]}: ${cmd.description}${auth}`;
879
+ });
880
+ return {
881
+ text: `The user sent a slash command. Available commands:
822
882
  ${commandList.join(`
823
- `)}`,
883
+ `)}
884
+
885
+ IMPORTANT: This is a slash command — respond by executing the matching command action, not with conversational text.`,
886
+ values: {
887
+ commandCount: commands.length,
888
+ isCommand: true,
889
+ hasElevatedCommands: commands.some((c) => c.requiresElevated)
890
+ },
891
+ data: { commands, isCommand: true }
892
+ };
893
+ }
894
+ return {
895
+ text: "",
824
896
  values: {
825
- commandCount: commands2.length,
826
- hasElevatedCommands: commands2.some((c) => c.requiresElevated)
897
+ commandCount: commands.length,
898
+ isCommand: false
827
899
  },
828
- data: { commands: commands2 }
900
+ data: { isCommand: false }
829
901
  };
830
902
  }
831
903
  };
832
904
  function formatCommandResult(result) {
833
905
  if (result.error) {
834
- return `❌ Error: ${result.error}`;
906
+ return `Error: ${result.error}`;
835
907
  }
836
- return result.reply ?? "Command executed";
908
+ return result.reply ?? "Command executed";
837
909
  }
838
910
  function isAuthorized(context, command) {
839
911
  if (!command.requiresAuth) {
@@ -881,7 +953,7 @@ var commandsPlugin = {
881
953
  if (hasCommand("hello world")) {
882
954
  throw new Error("Should not detect plain text as command");
883
955
  }
884
- logger.success("Command prefix detection works correctly");
956
+ logger3.success("Command prefix detection works correctly");
885
957
  }
886
958
  },
887
959
  {
@@ -897,7 +969,7 @@ var commandsPlugin = {
897
969
  if (detection.command?.args[0] !== "high") {
898
970
  throw new Error(`Expected arg 'high', got '${detection.command?.args[0]}'`);
899
971
  }
900
- logger.success("Command argument parsing works correctly");
972
+ logger3.success("Command argument parsing works correctly");
901
973
  }
902
974
  },
903
975
  {
@@ -911,7 +983,7 @@ var commandsPlugin = {
911
983
  if (normalized2 !== "/help") {
912
984
  throw new Error(`Expected '/help', got '${normalized2}'`);
913
985
  }
914
- logger.success("Command normalization works correctly");
986
+ logger3.success("Command normalization works correctly");
915
987
  }
916
988
  },
917
989
  {
@@ -924,7 +996,7 @@ var commandsPlugin = {
924
996
  if (cmd.key !== "help") {
925
997
  throw new Error(`Expected key 'help', got '${cmd.key}'`);
926
998
  }
927
- logger.success("Command alias lookup works correctly");
999
+ logger3.success("Command alias lookup works correctly");
928
1000
  }
929
1001
  },
930
1002
  {
@@ -937,7 +1009,7 @@ var commandsPlugin = {
937
1009
  if (cmd.key !== "status") {
938
1010
  throw new Error(`Expected key 'status', got '${cmd.key}'`);
939
1011
  }
940
- logger.success("Command key lookup works correctly");
1012
+ logger3.success("Command key lookup works correctly");
941
1013
  }
942
1014
  }
943
1015
  ]
@@ -948,16 +1020,16 @@ var commandsPlugin = {
948
1020
  {
949
1021
  name: "Get enabled commands",
950
1022
  fn: async (_runtime) => {
951
- const commands2 = getEnabledCommands();
952
- if (commands2.length === 0) {
1023
+ const commands = getEnabledCommands();
1024
+ if (commands.length === 0) {
953
1025
  throw new Error("Should have enabled commands");
954
1026
  }
955
- const hasHelp = commands2.some((c) => c.key === "help");
956
- const hasStatus = commands2.some((c) => c.key === "status");
957
- if (!hasHelp || !hasStatus) {
1027
+ const cmdHelp = commands.some((c) => c.key === "help");
1028
+ const cmdStatus = commands.some((c) => c.key === "status");
1029
+ if (!cmdHelp || !cmdStatus) {
958
1030
  throw new Error("Should have help and status commands");
959
1031
  }
960
- logger.success("Command registry works correctly");
1032
+ logger3.success("Command registry works correctly");
961
1033
  }
962
1034
  },
963
1035
  {
@@ -979,7 +1051,7 @@ var commandsPlugin = {
979
1051
  if (notFound) {
980
1052
  throw new Error("Should not find unregistered command");
981
1053
  }
982
- logger.success("Custom command registration works correctly");
1054
+ logger3.success("Custom command registration works correctly");
983
1055
  }
984
1056
  },
985
1057
  {
@@ -993,17 +1065,19 @@ var commandsPlugin = {
993
1065
  if (!allStatus) {
994
1066
  throw new Error("All returned commands should be in status category");
995
1067
  }
996
- logger.success("Command categorization works correctly");
1068
+ logger3.success("Command categorization works correctly");
997
1069
  }
998
1070
  }
999
1071
  ]
1000
1072
  }
1001
1073
  ],
1002
1074
  async init(config, runtime) {
1003
- logger.log("[plugin-commands] Initializing command system");
1075
+ logger3.log("[plugin-commands] Initializing command system");
1076
+ initForRuntime(runtime.agentId);
1004
1077
  const configEnabled = config.COMMANDS_CONFIG_ENABLED === "true";
1005
1078
  const debugEnabled = config.COMMANDS_DEBUG_ENABLED === "true";
1006
1079
  const bashEnabled = config.COMMANDS_BASH_ENABLED === "true";
1080
+ const restartEnabled = config.COMMANDS_RESTART_ENABLED !== "false";
1007
1081
  const configCmd = findCommandByKey("config");
1008
1082
  if (configCmd) {
1009
1083
  configCmd.enabled = configEnabled;
@@ -1016,12 +1090,17 @@ var commandsPlugin = {
1016
1090
  if (bashCmd) {
1017
1091
  bashCmd.enabled = bashEnabled;
1018
1092
  }
1093
+ const restartCmd = findCommandByKey("restart");
1094
+ if (restartCmd) {
1095
+ restartCmd.enabled = restartEnabled;
1096
+ }
1019
1097
  const enabledCount = getEnabledCommands().length;
1020
- logger.log(`[plugin-commands] ${enabledCount} commands enabled`);
1098
+ logger3.log(`[plugin-commands] ${enabledCount} commands enabled for agent ${runtime.agentId}`);
1021
1099
  }
1022
1100
  };
1023
1101
  var src_default = commandsPlugin;
1024
1102
  export {
1103
+ useRuntime,
1025
1104
  unregisterCommand,
1026
1105
  startsWithCommand,
1027
1106
  resetCommands,
@@ -1032,6 +1111,7 @@ export {
1032
1111
  isElevated,
1033
1112
  isCommandOnly,
1034
1113
  isAuthorized,
1114
+ initForRuntime,
1035
1115
  hasCommand,
1036
1116
  getEnabledCommands,
1037
1117
  getCommandsByCategory,
@@ -1046,4 +1126,4 @@ export {
1046
1126
  commandRegistryProvider
1047
1127
  };
1048
1128
 
1049
- //# debugId=4D1F6605A437A12664756E2164756E21
1129
+ //# debugId=C6086C11EDA7A75E64756E2164756E21