@elizaos/plugin-commands 2.0.0-beta.1 → 2.0.3-beta.3
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/LICENSE +21 -0
- package/README.md +83 -0
- package/auto-enable.ts +1 -1
- package/dist/cjs/index.cjs +959 -24
- package/dist/cjs/index.cjs.map +17 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +959 -24
- package/dist/index.js.map +17 -6
- package/dist/src/actions/command-actions.d.ts +17 -0
- package/dist/src/actions/command-actions.d.ts.map +1 -0
- package/dist/src/actions/command-settings.d.ts +35 -0
- package/dist/src/actions/command-settings.d.ts.map +1 -0
- package/dist/src/actions/dispatch.d.ts +54 -0
- package/dist/src/actions/dispatch.d.ts.map +1 -0
- package/dist/src/actions/handlers.d.ts +26 -0
- package/dist/src/actions/handlers.d.ts.map +1 -0
- package/dist/src/actions/index.d.ts +19 -0
- package/dist/src/actions/index.d.ts.map +1 -0
- package/dist/src/actions/shortcuts.d.ts +41 -0
- package/dist/src/actions/shortcuts.d.ts.map +1 -0
- package/dist/src/connector-bridge.d.ts +128 -0
- package/dist/src/connector-bridge.d.ts.map +1 -0
- package/dist/src/connector-catalog.d.ts +71 -0
- package/dist/src/connector-catalog.d.ts.map +1 -0
- package/dist/src/index.d.ts +68 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/navigation-commands.d.ts +28 -0
- package/dist/src/navigation-commands.d.ts.map +1 -0
- package/dist/src/parser.d.ts +32 -0
- package/dist/src/parser.d.ts.map +1 -0
- package/dist/src/registry.d.ts +66 -0
- package/dist/src/registry.d.ts.map +1 -0
- package/dist/src/serialize.d.ts +30 -0
- package/dist/src/serialize.d.ts.map +1 -0
- package/dist/src/settings-sections.d.ts +32 -0
- package/dist/src/settings-sections.d.ts.map +1 -0
- package/dist/src/types.d.ts +175 -0
- package/dist/src/types.d.ts.map +1 -0
- package/package.json +27 -16
- package/registry-entry.json +63 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -42,27 +42,60 @@ __export(exports_src, {
|
|
|
42
42
|
useRuntime: () => useRuntime,
|
|
43
43
|
unregisterCommand: () => unregisterCommand,
|
|
44
44
|
startsWithCommand: () => startsWithCommand,
|
|
45
|
+
setCommandSetting: () => setCommandSetting,
|
|
46
|
+
serializeCommand: () => serializeCommand,
|
|
47
|
+
runCommand: () => runCommand,
|
|
48
|
+
resolveSettingsSection: () => resolveSettingsSection,
|
|
49
|
+
resolveConnectorCommandAuth: () => resolveConnectorCommandAuth,
|
|
50
|
+
resolveCommand: () => resolveCommand,
|
|
45
51
|
resetCommands: () => resetCommands,
|
|
46
52
|
registerCommands: () => registerCommands,
|
|
47
53
|
registerCommand: () => registerCommand,
|
|
48
54
|
parseCommand: () => parseCommand,
|
|
49
55
|
normalizeCommandBody: () => normalizeCommandBody,
|
|
56
|
+
navigationCommandDefinitions: () => navigationCommandDefinitions,
|
|
57
|
+
naturalShortcuts: () => naturalShortcuts,
|
|
50
58
|
isElevated: () => isElevated,
|
|
59
|
+
isDeterministicCommand: () => isDeterministicCommand,
|
|
51
60
|
isCommandOnly: () => isCommandOnly,
|
|
52
61
|
isAuthorized: () => isAuthorized,
|
|
53
62
|
initForRuntime: () => initForRuntime,
|
|
54
63
|
hasCommand: () => hasCommand,
|
|
64
|
+
getSettingsSections: () => getSettingsSections,
|
|
65
|
+
getSettingsSectionChoices: () => getSettingsSectionChoices,
|
|
66
|
+
getEnabledCommandsForRuntime: () => getEnabledCommandsForRuntime,
|
|
55
67
|
getEnabledCommands: () => getEnabledCommands,
|
|
68
|
+
getConnectorCommands: () => getConnectorCommands,
|
|
69
|
+
getCommandsForRuntime: () => getCommandsForRuntime,
|
|
70
|
+
getCommandsByCategoryForRuntime: () => getCommandsByCategoryForRuntime,
|
|
56
71
|
getCommandsByCategory: () => getCommandsByCategory,
|
|
57
72
|
getCommands: () => getCommands,
|
|
73
|
+
getCommandSettings: () => getCommandSettings,
|
|
74
|
+
getCatalogCommands: () => getCatalogCommands,
|
|
75
|
+
gateConnectorCommandByName: () => gateConnectorCommandByName,
|
|
76
|
+
gateConnectorCommand: () => gateConnectorCommand,
|
|
58
77
|
formatCommandResult: () => formatCommandResult,
|
|
78
|
+
findCommandByKeyForRuntime: () => findCommandByKeyForRuntime,
|
|
59
79
|
findCommandByKey: () => findCommandByKey,
|
|
80
|
+
findCommandByAliasForRuntime: () => findCommandByAliasForRuntime,
|
|
60
81
|
findCommandByAlias: () => findCommandByAlias,
|
|
61
82
|
extractCommand: () => extractCommand,
|
|
83
|
+
explicitCommandShortcuts: () => explicitCommandShortcuts,
|
|
84
|
+
dispatchCommandMessage: () => dispatchCommandMessage,
|
|
62
85
|
detectCommand: () => detectCommand,
|
|
63
86
|
default: () => src_default,
|
|
87
|
+
createCommandShortcuts: () => createCommandShortcuts,
|
|
88
|
+
createCommandActions: () => createCommandActions,
|
|
64
89
|
commandsPlugin: () => commandsPlugin,
|
|
65
|
-
|
|
90
|
+
commandVisibleForView: () => commandVisibleForView,
|
|
91
|
+
commandVisibleForSurface: () => commandVisibleForSurface,
|
|
92
|
+
commandShortcuts: () => commandShortcuts,
|
|
93
|
+
commandRegistryProvider: () => commandRegistryProvider,
|
|
94
|
+
commandActions: () => commandActions,
|
|
95
|
+
clearCommandSettings: () => clearCommandSettings,
|
|
96
|
+
DETERMINISTIC_COMMAND_KEYS: () => DETERMINISTIC_COMMAND_KEYS,
|
|
97
|
+
DEFAULT_COMMANDS: () => DEFAULT_COMMANDS,
|
|
98
|
+
COMMAND_SETTING_CHOICES: () => COMMAND_SETTING_CHOICES
|
|
66
99
|
});
|
|
67
100
|
module.exports = __toCommonJS(exports_src);
|
|
68
101
|
var import_core = require("@elizaos/core");
|
|
@@ -161,6 +194,7 @@ var DEFAULT_COMMANDS = [
|
|
|
161
194
|
scope: "both",
|
|
162
195
|
category: "session",
|
|
163
196
|
acceptsArgs: true,
|
|
197
|
+
requiresAuth: true,
|
|
164
198
|
args: [
|
|
165
199
|
{ name: "instructions", description: "Optional compaction instructions" }
|
|
166
200
|
]
|
|
@@ -216,7 +250,13 @@ var DEFAULT_COMMANDS = [
|
|
|
216
250
|
scope: "both",
|
|
217
251
|
category: "options",
|
|
218
252
|
acceptsArgs: true,
|
|
219
|
-
args: [
|
|
253
|
+
args: [
|
|
254
|
+
{
|
|
255
|
+
name: "model",
|
|
256
|
+
description: "provider/model or alias",
|
|
257
|
+
dynamicChoices: "models"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
220
260
|
},
|
|
221
261
|
{
|
|
222
262
|
key: "models",
|
|
@@ -331,6 +371,15 @@ var DEFAULT_COMMANDS = [
|
|
|
331
371
|
}
|
|
332
372
|
]
|
|
333
373
|
},
|
|
374
|
+
{
|
|
375
|
+
key: "transcribe",
|
|
376
|
+
nativeName: "transcribe",
|
|
377
|
+
description: "Toggle long-form transcription mode (record-only; agent stays silent until an exit phrase)",
|
|
378
|
+
textAliases: ["/transcribe", "/transcription", "/dictate"],
|
|
379
|
+
scope: "both",
|
|
380
|
+
category: "media",
|
|
381
|
+
acceptsArgs: false
|
|
382
|
+
},
|
|
334
383
|
{
|
|
335
384
|
key: "bash",
|
|
336
385
|
nativeName: "bash",
|
|
@@ -365,10 +414,7 @@ function initForRuntime(agentId) {
|
|
|
365
414
|
activeStore = store;
|
|
366
415
|
}
|
|
367
416
|
function useRuntime(agentId) {
|
|
368
|
-
|
|
369
|
-
if (store) {
|
|
370
|
-
activeStore = store;
|
|
371
|
-
}
|
|
417
|
+
activeStore = storeForRuntime(agentId);
|
|
372
418
|
}
|
|
373
419
|
function getCommands() {
|
|
374
420
|
return [...activeStore.commands];
|
|
@@ -427,12 +473,55 @@ function startsWithCommand(text) {
|
|
|
427
473
|
if (normalized === alias) {
|
|
428
474
|
return command;
|
|
429
475
|
}
|
|
430
|
-
|
|
476
|
+
const remainder = normalized.slice(alias.length);
|
|
477
|
+
if (normalized.startsWith(alias) && /^[\s:]/.test(remainder)) {
|
|
431
478
|
return command;
|
|
432
479
|
}
|
|
433
480
|
}
|
|
434
481
|
return;
|
|
435
482
|
}
|
|
483
|
+
function storeForRuntime(agentId) {
|
|
484
|
+
if (!agentId)
|
|
485
|
+
return fallbackStore;
|
|
486
|
+
return runtimeStores.get(agentId) ?? fallbackStore;
|
|
487
|
+
}
|
|
488
|
+
function getEnabledCommandsFromStore(store) {
|
|
489
|
+
return store.commands.filter((cmd) => cmd.enabled !== false);
|
|
490
|
+
}
|
|
491
|
+
function getCommandsByCategoryFromStore(store, category) {
|
|
492
|
+
return store.commands.filter((cmd) => cmd.category === category && cmd.enabled !== false);
|
|
493
|
+
}
|
|
494
|
+
function getAliasMapForStore(store) {
|
|
495
|
+
if (store.aliasMap)
|
|
496
|
+
return store.aliasMap;
|
|
497
|
+
store.aliasMap = new Map;
|
|
498
|
+
for (const command of store.commands) {
|
|
499
|
+
if (command.enabled === false)
|
|
500
|
+
continue;
|
|
501
|
+
for (const alias of command.textAliases) {
|
|
502
|
+
const normalized = alias.toLowerCase().trim();
|
|
503
|
+
if (!store.aliasMap.has(normalized)) {
|
|
504
|
+
store.aliasMap.set(normalized, command);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return store.aliasMap;
|
|
509
|
+
}
|
|
510
|
+
function getCommandsForRuntime(agentId) {
|
|
511
|
+
return [...storeForRuntime(agentId).commands];
|
|
512
|
+
}
|
|
513
|
+
function getEnabledCommandsForRuntime(agentId) {
|
|
514
|
+
return getEnabledCommandsFromStore(storeForRuntime(agentId));
|
|
515
|
+
}
|
|
516
|
+
function getCommandsByCategoryForRuntime(category, agentId) {
|
|
517
|
+
return getCommandsByCategoryFromStore(storeForRuntime(agentId), category);
|
|
518
|
+
}
|
|
519
|
+
function findCommandByAliasForRuntime(alias, agentId) {
|
|
520
|
+
return getAliasMapForStore(storeForRuntime(agentId)).get(alias.toLowerCase().trim());
|
|
521
|
+
}
|
|
522
|
+
function findCommandByKeyForRuntime(key, agentId) {
|
|
523
|
+
return storeForRuntime(agentId).commands.find((c) => c.key === key);
|
|
524
|
+
}
|
|
436
525
|
|
|
437
526
|
// src/parser.ts
|
|
438
527
|
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -471,7 +560,8 @@ function parseCommand(text, definition) {
|
|
|
471
560
|
matchedAlias = alias;
|
|
472
561
|
break;
|
|
473
562
|
}
|
|
474
|
-
|
|
563
|
+
const remainder = trimmed.slice(alias.length);
|
|
564
|
+
if (trimmed.toLowerCase().startsWith(normalized) && /^[\s:]/.test(remainder)) {
|
|
475
565
|
matchedAlias = alias;
|
|
476
566
|
break;
|
|
477
567
|
}
|
|
@@ -484,12 +574,15 @@ function parseCommand(text, definition) {
|
|
|
484
574
|
rawArgs = rawArgs.slice(1).trim();
|
|
485
575
|
}
|
|
486
576
|
const args = parseArgs(rawArgs, definition);
|
|
487
|
-
|
|
577
|
+
const parsed = {
|
|
488
578
|
key: definition.key,
|
|
489
579
|
canonical: definition.textAliases[0] ?? `/${definition.key}`,
|
|
490
|
-
args
|
|
491
|
-
rawArgs: rawArgs || undefined
|
|
580
|
+
args
|
|
492
581
|
};
|
|
582
|
+
if (rawArgs) {
|
|
583
|
+
parsed.rawArgs = rawArgs;
|
|
584
|
+
}
|
|
585
|
+
return parsed;
|
|
493
586
|
}
|
|
494
587
|
function parseArgs(rawArgs, definition) {
|
|
495
588
|
if (!rawArgs || !definition.acceptsArgs) {
|
|
@@ -502,13 +595,13 @@ function parseArgs(rawArgs, definition) {
|
|
|
502
595
|
const args = [];
|
|
503
596
|
const argDefs = definition.args ?? [];
|
|
504
597
|
const tokens = tokenize(rawArgs);
|
|
505
|
-
for (
|
|
598
|
+
for (const [i, token] of tokens.entries()) {
|
|
506
599
|
const argDef = argDefs[i];
|
|
507
600
|
if (argDef?.captureRemaining) {
|
|
508
601
|
args.push(tokens.slice(i).join(" "));
|
|
509
602
|
break;
|
|
510
603
|
}
|
|
511
|
-
args.push(
|
|
604
|
+
args.push(token);
|
|
512
605
|
}
|
|
513
606
|
return args;
|
|
514
607
|
}
|
|
@@ -517,8 +610,7 @@ function tokenize(input) {
|
|
|
517
610
|
let current = "";
|
|
518
611
|
let inQuote = false;
|
|
519
612
|
let quoteChar = "";
|
|
520
|
-
for (
|
|
521
|
-
const char = input[i];
|
|
613
|
+
for (const char of input) {
|
|
522
614
|
if (inQuote) {
|
|
523
615
|
if (char === quoteChar) {
|
|
524
616
|
inQuote = false;
|
|
@@ -552,7 +644,7 @@ function normalizeCommandBody(text, botMention) {
|
|
|
552
644
|
const mentionPattern = new RegExp(`^@${escapeRegExp(botMention)}\\s*`, "i");
|
|
553
645
|
normalized = normalized.replace(mentionPattern, "");
|
|
554
646
|
}
|
|
555
|
-
normalized = normalized.replace(/^(
|
|
647
|
+
normalized = normalized.replace(/^([/!][^\s:]+):\s*/, "$1 ");
|
|
556
648
|
return normalized.trim();
|
|
557
649
|
}
|
|
558
650
|
function isCommandOnly(text) {
|
|
@@ -577,6 +669,849 @@ function extractCommand(text) {
|
|
|
577
669
|
return { command, remainingText: command.rawArgs };
|
|
578
670
|
}
|
|
579
671
|
|
|
672
|
+
// src/actions/command-settings.ts
|
|
673
|
+
var COMMAND_SETTING_CHOICES = {
|
|
674
|
+
thinking: ["off", "minimal", "low", "medium", "high", "xhigh"],
|
|
675
|
+
verbose: ["off", "on", "full"],
|
|
676
|
+
reasoning: ["off", "on", "stream"],
|
|
677
|
+
queue: ["steer", "followup", "collect", "interrupt"],
|
|
678
|
+
elevated: ["off", "on", "ask", "full"],
|
|
679
|
+
model: null,
|
|
680
|
+
tts: ["on", "off"]
|
|
681
|
+
};
|
|
682
|
+
function cacheKey(roomId) {
|
|
683
|
+
return `command-settings:${roomId}`;
|
|
684
|
+
}
|
|
685
|
+
async function clearCommandSettings(runtime, roomId) {
|
|
686
|
+
return runtime.deleteCache(cacheKey(roomId));
|
|
687
|
+
}
|
|
688
|
+
async function getCommandSettings(runtime, roomId) {
|
|
689
|
+
const stored = await runtime.getCache(cacheKey(roomId));
|
|
690
|
+
return stored ?? {};
|
|
691
|
+
}
|
|
692
|
+
async function setCommandSetting(runtime, roomId, key, rawValue) {
|
|
693
|
+
const value = rawValue.trim().toLowerCase();
|
|
694
|
+
const choices = COMMAND_SETTING_CHOICES[key];
|
|
695
|
+
if (choices && !choices.includes(value)) {
|
|
696
|
+
return {
|
|
697
|
+
error: `Invalid ${key} value "${rawValue}". Choose one of: ${choices.join(", ")}.`
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
const normalized = choices ? value : rawValue.trim();
|
|
701
|
+
const current = await getCommandSettings(runtime, roomId);
|
|
702
|
+
await runtime.setCache(cacheKey(roomId), {
|
|
703
|
+
...current,
|
|
704
|
+
[key]: normalized
|
|
705
|
+
});
|
|
706
|
+
return { value: normalized };
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// src/actions/handlers.ts
|
|
710
|
+
var DETERMINISTIC_COMMAND_KEYS = [
|
|
711
|
+
"help",
|
|
712
|
+
"commands",
|
|
713
|
+
"status",
|
|
714
|
+
"whoami",
|
|
715
|
+
"context",
|
|
716
|
+
"reset",
|
|
717
|
+
"new",
|
|
718
|
+
"compact",
|
|
719
|
+
"models",
|
|
720
|
+
"usage",
|
|
721
|
+
"think",
|
|
722
|
+
"verbose",
|
|
723
|
+
"reasoning",
|
|
724
|
+
"queue",
|
|
725
|
+
"elevated",
|
|
726
|
+
"model",
|
|
727
|
+
"tts"
|
|
728
|
+
];
|
|
729
|
+
var DETERMINISTIC_KEYS = new Set(DETERMINISTIC_COMMAND_KEYS);
|
|
730
|
+
function isDeterministicCommand(key) {
|
|
731
|
+
return DETERMINISTIC_KEYS.has(key);
|
|
732
|
+
}
|
|
733
|
+
var CATEGORY_ORDER = [
|
|
734
|
+
"status",
|
|
735
|
+
"session",
|
|
736
|
+
"options",
|
|
737
|
+
"media",
|
|
738
|
+
"management",
|
|
739
|
+
"tools",
|
|
740
|
+
"docks",
|
|
741
|
+
"skills"
|
|
742
|
+
];
|
|
743
|
+
var OPTION_COMMANDS = {
|
|
744
|
+
think: { key: "thinking", label: "Thinking" },
|
|
745
|
+
verbose: { key: "verbose", label: "Verbose" },
|
|
746
|
+
reasoning: { key: "reasoning", label: "Reasoning" },
|
|
747
|
+
queue: { key: "queue", label: "Queue mode" },
|
|
748
|
+
elevated: { key: "elevated", label: "Elevated mode" },
|
|
749
|
+
model: { key: "model", label: "Model" },
|
|
750
|
+
tts: { key: "tts", label: "TTS" }
|
|
751
|
+
};
|
|
752
|
+
function reply(text) {
|
|
753
|
+
return { handled: true, reply: text, shouldContinue: false };
|
|
754
|
+
}
|
|
755
|
+
function authError() {
|
|
756
|
+
return reply("This command requires authorization.");
|
|
757
|
+
}
|
|
758
|
+
function formatCommandList(agentId) {
|
|
759
|
+
const lines = [];
|
|
760
|
+
for (const category of CATEGORY_ORDER) {
|
|
761
|
+
const commands = getCommandsByCategoryForRuntime(category, agentId);
|
|
762
|
+
if (commands.length === 0)
|
|
763
|
+
continue;
|
|
764
|
+
lines.push(`**${category}**`);
|
|
765
|
+
for (const command of commands) {
|
|
766
|
+
const alias = command.textAliases[0] ?? `/${command.key}`;
|
|
767
|
+
const auth = command.requiresAuth ? " (requires auth)" : "";
|
|
768
|
+
lines.push(` ${alias} — ${command.description}${auth}`);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return lines.join(`
|
|
772
|
+
`);
|
|
773
|
+
}
|
|
774
|
+
function resolveModelLabel(runtime) {
|
|
775
|
+
const fromSetting = runtime.getSetting("LARGE_MODEL") ?? runtime.getSetting("ANTHROPIC_LARGE_MODEL") ?? runtime.getSetting("OPENAI_LARGE_MODEL");
|
|
776
|
+
if (typeof fromSetting === "string" && fromSetting.trim()) {
|
|
777
|
+
return fromSetting.trim();
|
|
778
|
+
}
|
|
779
|
+
const fromCharacter = runtime.character?.settings?.model;
|
|
780
|
+
if (typeof fromCharacter === "string" && fromCharacter.trim()) {
|
|
781
|
+
return fromCharacter.trim();
|
|
782
|
+
}
|
|
783
|
+
return "default";
|
|
784
|
+
}
|
|
785
|
+
async function countRoomMessages(runtime, roomId) {
|
|
786
|
+
if (typeof runtime.countMemories !== "function")
|
|
787
|
+
return null;
|
|
788
|
+
try {
|
|
789
|
+
return await runtime.countMemories({
|
|
790
|
+
roomIds: [roomId],
|
|
791
|
+
tableName: "messages",
|
|
792
|
+
unique: false
|
|
793
|
+
});
|
|
794
|
+
} catch {
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
async function clearRoomMessages(runtime, roomId) {
|
|
799
|
+
const before = await countRoomMessages(runtime, roomId);
|
|
800
|
+
if (typeof runtime.deleteAllMemories !== "function")
|
|
801
|
+
return null;
|
|
802
|
+
await runtime.deleteAllMemories([roomId], "messages");
|
|
803
|
+
return before;
|
|
804
|
+
}
|
|
805
|
+
function findAction(runtime, name) {
|
|
806
|
+
return runtime.actions?.find((action) => action.name === name);
|
|
807
|
+
}
|
|
808
|
+
async function runCompactAction(runtime, message, callback) {
|
|
809
|
+
const action = findAction(runtime, "COMPACT_CONVERSATION");
|
|
810
|
+
if (!action || !message) {
|
|
811
|
+
return reply("Conversation compaction is not available in this runtime.");
|
|
812
|
+
}
|
|
813
|
+
const result = await action.handler(runtime, message, undefined, undefined, callback);
|
|
814
|
+
if (result?.text && result.text.trim().length > 0)
|
|
815
|
+
return reply(result.text);
|
|
816
|
+
return reply("Conversation compaction completed.");
|
|
817
|
+
}
|
|
818
|
+
async function setOptionCommand(runtime, roomId, parsed, option) {
|
|
819
|
+
const rawValue = parsed.rawArgs?.trim() ?? parsed.args[0]?.trim() ?? "";
|
|
820
|
+
if (!rawValue) {
|
|
821
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
822
|
+
const current = option.key === "model" ? settings.model ?? resolveModelLabel(runtime) : settings[option.key] ?? "default";
|
|
823
|
+
return reply(`${option.label} is ${current}.`);
|
|
824
|
+
}
|
|
825
|
+
const result = await setCommandSetting(runtime, roomId, option.key, rawValue);
|
|
826
|
+
if ("error" in result)
|
|
827
|
+
return reply(result.error);
|
|
828
|
+
return reply(`${option.label} set to ${result.value}.`);
|
|
829
|
+
}
|
|
830
|
+
async function runCommand(runtime, parsed, context) {
|
|
831
|
+
const agentId = runtime.agentId;
|
|
832
|
+
useRuntime(agentId);
|
|
833
|
+
const definition = findCommandByKeyForRuntime(parsed.key, agentId);
|
|
834
|
+
if (definition?.requiresAuth && !context.isAuthorized)
|
|
835
|
+
return authError();
|
|
836
|
+
if (definition?.requiresElevated && !context.isElevated) {
|
|
837
|
+
return reply("This command requires elevated permissions.");
|
|
838
|
+
}
|
|
839
|
+
const roomId = context.roomId;
|
|
840
|
+
switch (parsed.key) {
|
|
841
|
+
case "help":
|
|
842
|
+
case "commands":
|
|
843
|
+
return reply(`Available commands:
|
|
844
|
+
${formatCommandList(agentId)}`);
|
|
845
|
+
case "status": {
|
|
846
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
847
|
+
const messageCount = await countRoomMessages(runtime, roomId);
|
|
848
|
+
const lines = [
|
|
849
|
+
`Agent: ${runtime.character?.name ?? runtime.agentId}`,
|
|
850
|
+
`Model: ${settings.model ?? resolveModelLabel(runtime)}`,
|
|
851
|
+
`Thinking: ${settings.thinking ?? "default"}`,
|
|
852
|
+
`Reasoning: ${settings.reasoning ?? "default"}`,
|
|
853
|
+
`Verbose: ${settings.verbose ?? "default"}`,
|
|
854
|
+
`Queue: ${settings.queue ?? "default"}`,
|
|
855
|
+
`TTS: ${settings.tts ?? "default"}`,
|
|
856
|
+
messageCount === null ? null : `Messages: ${messageCount}`,
|
|
857
|
+
`Commands enabled: ${getEnabledCommandsForRuntime(agentId).length}`
|
|
858
|
+
].filter(Boolean);
|
|
859
|
+
return reply(lines.join(`
|
|
860
|
+
`));
|
|
861
|
+
}
|
|
862
|
+
case "whoami": {
|
|
863
|
+
const who = context.senderName ?? context.senderId ?? "you";
|
|
864
|
+
return reply(`You are ${who}.
|
|
865
|
+
Authorized: ${context.isAuthorized ? "yes" : "no"}
|
|
866
|
+
Elevated: ${context.isElevated ? "yes" : "no"}`);
|
|
867
|
+
}
|
|
868
|
+
case "context": {
|
|
869
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
870
|
+
const lines = [
|
|
871
|
+
`Room: ${roomId}`,
|
|
872
|
+
context.channelId ? `Channel: ${context.channelId}` : null,
|
|
873
|
+
`Active settings: ${describeSettings(settings)}`
|
|
874
|
+
].filter(Boolean);
|
|
875
|
+
return reply(lines.join(`
|
|
876
|
+
`));
|
|
877
|
+
}
|
|
878
|
+
case "models":
|
|
879
|
+
return reply(`Current model: ${resolveModelLabel(runtime)}`);
|
|
880
|
+
case "usage": {
|
|
881
|
+
const usage = await runtime.getCache(`token-usage:${roomId}`);
|
|
882
|
+
if (!usage?.totalTokens) {
|
|
883
|
+
return reply("No token usage recorded for this conversation yet.");
|
|
884
|
+
}
|
|
885
|
+
return reply(`Token usage — prompt: ${usage.promptTokens ?? 0}, completion: ${usage.completionTokens ?? 0}, total: ${usage.totalTokens}.`);
|
|
886
|
+
}
|
|
887
|
+
case "think":
|
|
888
|
+
case "verbose":
|
|
889
|
+
case "reasoning":
|
|
890
|
+
case "queue":
|
|
891
|
+
case "elevated":
|
|
892
|
+
case "model":
|
|
893
|
+
case "tts":
|
|
894
|
+
return setOptionCommand(runtime, roomId, parsed, OPTION_COMMANDS[parsed.key]);
|
|
895
|
+
case "reset": {
|
|
896
|
+
await clearCommandSettings(runtime, roomId);
|
|
897
|
+
const deleted = await clearRoomMessages(runtime, roomId);
|
|
898
|
+
if (deleted === null) {
|
|
899
|
+
return reply("Reset command settings for this room. Message history is unchanged because memory deletion is unavailable.");
|
|
900
|
+
}
|
|
901
|
+
return reply(`Reset this room: cleared command settings and ${deleted} message(s).`);
|
|
902
|
+
}
|
|
903
|
+
case "new":
|
|
904
|
+
await clearCommandSettings(runtime, roomId);
|
|
905
|
+
return reply("Started a new conversation context for this room.");
|
|
906
|
+
case "compact":
|
|
907
|
+
return runCompactAction(runtime, context.message, context.callback);
|
|
908
|
+
default:
|
|
909
|
+
return { handled: false, shouldContinue: true };
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
function describeSettings(settings) {
|
|
913
|
+
const entries = Object.entries(settings).filter(([, v]) => v);
|
|
914
|
+
if (entries.length === 0)
|
|
915
|
+
return "none";
|
|
916
|
+
return entries.map(([k, v]) => `${k}=${v}`).join(", ");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// src/actions/dispatch.ts
|
|
920
|
+
function buildContext(message, options) {
|
|
921
|
+
const content = message.content;
|
|
922
|
+
const context = {
|
|
923
|
+
senderId: message.entityId,
|
|
924
|
+
isAuthorized: options.isAuthorized ?? false,
|
|
925
|
+
isElevated: options.isElevated ?? false,
|
|
926
|
+
roomId: message.roomId,
|
|
927
|
+
message
|
|
928
|
+
};
|
|
929
|
+
if (options.senderName)
|
|
930
|
+
context.senderName = options.senderName;
|
|
931
|
+
if (options.callback)
|
|
932
|
+
context.callback = options.callback;
|
|
933
|
+
const channelId = content.channelId ?? content.source;
|
|
934
|
+
if (channelId)
|
|
935
|
+
context.channelId = channelId;
|
|
936
|
+
return context;
|
|
937
|
+
}
|
|
938
|
+
async function resolveCommand(runtime, message, options = {}) {
|
|
939
|
+
const text = message.content.text ?? "";
|
|
940
|
+
if (!hasCommand(text))
|
|
941
|
+
return { handled: false };
|
|
942
|
+
const detection = detectCommand(text);
|
|
943
|
+
if (!detection.isCommand || !detection.command)
|
|
944
|
+
return { handled: false };
|
|
945
|
+
const parsed = detection.command;
|
|
946
|
+
const definition = findCommandByKeyForRuntime(parsed.key, runtime.agentId);
|
|
947
|
+
if (definition?.target && definition.target.kind !== "agent") {
|
|
948
|
+
return { handled: false, command: parsed };
|
|
949
|
+
}
|
|
950
|
+
const deterministicOnly = options.deterministicOnly ?? options.gateSafeOnly ?? true;
|
|
951
|
+
if (deterministicOnly && !isDeterministicCommand(parsed.key)) {
|
|
952
|
+
return { handled: false, command: parsed };
|
|
953
|
+
}
|
|
954
|
+
const result = await runCommand(runtime, parsed, buildContext(message, options));
|
|
955
|
+
if (!result.handled)
|
|
956
|
+
return { handled: false, command: parsed };
|
|
957
|
+
const dispatched = { handled: true, command: parsed };
|
|
958
|
+
if (result.reply !== undefined)
|
|
959
|
+
dispatched.reply = result.reply;
|
|
960
|
+
return dispatched;
|
|
961
|
+
}
|
|
962
|
+
async function dispatchCommandMessage(runtime, message, callback, options = {}) {
|
|
963
|
+
const result = await resolveCommand(runtime, message, options);
|
|
964
|
+
if (!result.handled || result.reply === undefined)
|
|
965
|
+
return false;
|
|
966
|
+
await callback({ text: result.reply, source: "command" });
|
|
967
|
+
return true;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/actions/command-actions.ts
|
|
971
|
+
var OWNER_SOURCES = new Set([
|
|
972
|
+
"client_chat",
|
|
973
|
+
"gui",
|
|
974
|
+
"tui",
|
|
975
|
+
"direct",
|
|
976
|
+
"dashboard"
|
|
977
|
+
]);
|
|
978
|
+
function resolveTrust(message) {
|
|
979
|
+
const source = message.content.source;
|
|
980
|
+
const trusted = !source || OWNER_SOURCES.has(source);
|
|
981
|
+
return { isAuthorized: trusted, isElevated: trusted };
|
|
982
|
+
}
|
|
983
|
+
function buildAction(key, _nativeName, description, aliases) {
|
|
984
|
+
return {
|
|
985
|
+
name: `${key.toUpperCase()}_COMMAND`,
|
|
986
|
+
description,
|
|
987
|
+
similes: aliases,
|
|
988
|
+
suppressEarlyReply: true,
|
|
989
|
+
suppressPostActionContinuation: true,
|
|
990
|
+
validate: async (_runtime, message) => {
|
|
991
|
+
const text = message.content.text ?? "";
|
|
992
|
+
if (!hasCommand(text))
|
|
993
|
+
return false;
|
|
994
|
+
const detection = detectCommand(text);
|
|
995
|
+
return detection.isCommand && detection.command?.key === key;
|
|
996
|
+
},
|
|
997
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
998
|
+
const result = await resolveCommand(runtime, message, {
|
|
999
|
+
...resolveTrust(message),
|
|
1000
|
+
deterministicOnly: true,
|
|
1001
|
+
...callback ? { callback } : {}
|
|
1002
|
+
});
|
|
1003
|
+
if (!result.handled || result.reply === undefined) {
|
|
1004
|
+
return { success: false };
|
|
1005
|
+
}
|
|
1006
|
+
if (callback) {
|
|
1007
|
+
await callback({ text: result.reply, source: "command" });
|
|
1008
|
+
}
|
|
1009
|
+
return { success: true, text: result.reply };
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
function createCommandActions(commandKeys) {
|
|
1014
|
+
const actions = [];
|
|
1015
|
+
for (const key of commandKeys) {
|
|
1016
|
+
if (!isDeterministicCommand(key))
|
|
1017
|
+
continue;
|
|
1018
|
+
const definition = findCommandByKey(key);
|
|
1019
|
+
if (!definition)
|
|
1020
|
+
continue;
|
|
1021
|
+
if (definition.target && definition.target.kind !== "agent")
|
|
1022
|
+
continue;
|
|
1023
|
+
actions.push(buildAction(key, definition.nativeName ?? key, definition.description, definition.textAliases));
|
|
1024
|
+
}
|
|
1025
|
+
return actions;
|
|
1026
|
+
}
|
|
1027
|
+
// src/actions/shortcuts.ts
|
|
1028
|
+
function createCommandShortcuts(commandKeys = DETERMINISTIC_COMMAND_KEYS) {
|
|
1029
|
+
const shortcuts = [];
|
|
1030
|
+
for (const key of commandKeys) {
|
|
1031
|
+
const definition = findCommandByKey(key);
|
|
1032
|
+
if (!definition)
|
|
1033
|
+
continue;
|
|
1034
|
+
if (definition.target && definition.target.kind !== "agent")
|
|
1035
|
+
continue;
|
|
1036
|
+
shortcuts.push({
|
|
1037
|
+
id: `cmd:${key}`,
|
|
1038
|
+
kind: "explicit",
|
|
1039
|
+
aliases: definition.textAliases,
|
|
1040
|
+
target: { kind: "action", name: `${key.toUpperCase()}_COMMAND` }
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
return shortcuts;
|
|
1044
|
+
}
|
|
1045
|
+
var explicitCommandShortcuts = createCommandShortcuts();
|
|
1046
|
+
var naturalShortcuts = [
|
|
1047
|
+
{
|
|
1048
|
+
id: "nl:commands",
|
|
1049
|
+
kind: "natural",
|
|
1050
|
+
patterns: [
|
|
1051
|
+
{
|
|
1052
|
+
regex: /^what commands (?:can i (?:use|run)|are (?:there|available)|do you (?:have|support))$/u
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
regex: /^(?:show|list|give|tell)(?: me)?(?: a list of| the list of| all(?: of)?| the| your| available)* commands$/u
|
|
1056
|
+
},
|
|
1057
|
+
{ regex: /^what are(?: all)?(?: the| your| available)* commands$/u }
|
|
1058
|
+
],
|
|
1059
|
+
target: { kind: "action", name: "COMMANDS_COMMAND" },
|
|
1060
|
+
requiresAction: "COMMANDS_COMMAND",
|
|
1061
|
+
confidence: 0.95
|
|
1062
|
+
}
|
|
1063
|
+
];
|
|
1064
|
+
var commandShortcuts = [
|
|
1065
|
+
...explicitCommandShortcuts,
|
|
1066
|
+
...naturalShortcuts
|
|
1067
|
+
];
|
|
1068
|
+
|
|
1069
|
+
// src/actions/index.ts
|
|
1070
|
+
var commandActions = createCommandActions([
|
|
1071
|
+
...DETERMINISTIC_COMMAND_KEYS
|
|
1072
|
+
]);
|
|
1073
|
+
// src/connector-bridge.ts
|
|
1074
|
+
function resolveConnectorCommandAuth(agentId, name) {
|
|
1075
|
+
const definition = findCommandByKeyForRuntime(name, agentId);
|
|
1076
|
+
return {
|
|
1077
|
+
requiresAuth: definition?.requiresAuth ?? false,
|
|
1078
|
+
requiresElevated: definition?.requiresElevated ?? false
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
function gateConnectorCommand(requirements, sender) {
|
|
1082
|
+
if (requirements.requiresAuth && !sender.isAuthorized) {
|
|
1083
|
+
return {
|
|
1084
|
+
allowed: false,
|
|
1085
|
+
reply: "This command requires authorization. Pair your account or ask an owner to run it."
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
if (requirements.requiresElevated && !sender.isElevated) {
|
|
1089
|
+
return {
|
|
1090
|
+
allowed: false,
|
|
1091
|
+
reply: "This command requires elevated permissions."
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
return { allowed: true };
|
|
1095
|
+
}
|
|
1096
|
+
function gateConnectorCommandByName(agentId, name, sender) {
|
|
1097
|
+
return gateConnectorCommand(resolveConnectorCommandAuth(agentId, name), sender);
|
|
1098
|
+
}
|
|
1099
|
+
// src/settings-sections.ts
|
|
1100
|
+
var SETTINGS_SECTIONS = [
|
|
1101
|
+
{
|
|
1102
|
+
id: "ai-model",
|
|
1103
|
+
label: "AI Model & Providers",
|
|
1104
|
+
aliases: ["model", "models", "providers", "provider", "llm"]
|
|
1105
|
+
},
|
|
1106
|
+
{ id: "general", label: "General", aliases: ["basics"] },
|
|
1107
|
+
{ id: "agent", label: "Agent", aliases: ["character", "persona"] },
|
|
1108
|
+
{ id: "voice", label: "Voice", aliases: ["audio", "tts", "speech"] },
|
|
1109
|
+
{ id: "connectors", label: "Connectors", aliases: ["integrations"] },
|
|
1110
|
+
{ id: "skills", label: "Skills" },
|
|
1111
|
+
{ id: "memory", label: "Memory", aliases: ["knowledge"] },
|
|
1112
|
+
{ id: "permissions", label: "Permissions", aliases: ["security", "access"] },
|
|
1113
|
+
{ id: "billing", label: "Billing", aliases: ["plan", "subscription"] },
|
|
1114
|
+
{ id: "appearance", label: "Appearance", aliases: ["theme", "display"] },
|
|
1115
|
+
{ id: "notifications", label: "Notifications", aliases: ["alerts"] },
|
|
1116
|
+
{ id: "advanced", label: "Advanced", aliases: ["developer", "debug"] }
|
|
1117
|
+
];
|
|
1118
|
+
var lookup = null;
|
|
1119
|
+
function getLookup() {
|
|
1120
|
+
if (lookup)
|
|
1121
|
+
return lookup;
|
|
1122
|
+
const map = new Map;
|
|
1123
|
+
for (const section of SETTINGS_SECTIONS) {
|
|
1124
|
+
map.set(section.id, section);
|
|
1125
|
+
for (const alias of section.aliases ?? []) {
|
|
1126
|
+
map.set(alias, section);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
lookup = map;
|
|
1130
|
+
return map;
|
|
1131
|
+
}
|
|
1132
|
+
function getSettingsSections() {
|
|
1133
|
+
return [...SETTINGS_SECTIONS];
|
|
1134
|
+
}
|
|
1135
|
+
function getSettingsSectionChoices() {
|
|
1136
|
+
return SETTINGS_SECTIONS.map((section) => section.id);
|
|
1137
|
+
}
|
|
1138
|
+
function resolveSettingsSection(raw) {
|
|
1139
|
+
const normalized = raw.trim().toLowerCase();
|
|
1140
|
+
if (!normalized)
|
|
1141
|
+
return;
|
|
1142
|
+
return getLookup().get(normalized)?.id;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// src/navigation-commands.ts
|
|
1146
|
+
var IN_APP_SURFACES = ["gui", "tui"];
|
|
1147
|
+
var NAVIGATE_COMMANDS = [
|
|
1148
|
+
{
|
|
1149
|
+
key: "settings",
|
|
1150
|
+
nativeName: "settings",
|
|
1151
|
+
description: "Open agent settings",
|
|
1152
|
+
textAliases: ["/settings"],
|
|
1153
|
+
scope: "both",
|
|
1154
|
+
category: "docks",
|
|
1155
|
+
icon: "settings",
|
|
1156
|
+
target: { kind: "navigate", path: "/settings", tab: "settings" },
|
|
1157
|
+
acceptsArgs: true,
|
|
1158
|
+
args: [
|
|
1159
|
+
{
|
|
1160
|
+
name: "section",
|
|
1161
|
+
description: "Settings section to open",
|
|
1162
|
+
required: false,
|
|
1163
|
+
choices: getSettingsSectionChoices(),
|
|
1164
|
+
dynamicChoices: "settings-sections"
|
|
1165
|
+
}
|
|
1166
|
+
]
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
1169
|
+
key: "chat",
|
|
1170
|
+
nativeName: "chat",
|
|
1171
|
+
description: "Return to the chat",
|
|
1172
|
+
textAliases: ["/chat"],
|
|
1173
|
+
scope: "both",
|
|
1174
|
+
category: "docks",
|
|
1175
|
+
icon: "message-circle",
|
|
1176
|
+
target: { kind: "navigate", path: "/chat", tab: "chat" }
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
key: "views",
|
|
1180
|
+
nativeName: "views",
|
|
1181
|
+
description: "Open the agent's views",
|
|
1182
|
+
textAliases: ["/views"],
|
|
1183
|
+
scope: "both",
|
|
1184
|
+
category: "docks",
|
|
1185
|
+
icon: "layout-grid",
|
|
1186
|
+
target: { kind: "navigate", path: "/views", tab: "views" },
|
|
1187
|
+
acceptsArgs: true,
|
|
1188
|
+
args: [
|
|
1189
|
+
{
|
|
1190
|
+
name: "view",
|
|
1191
|
+
description: "View to open",
|
|
1192
|
+
required: false,
|
|
1193
|
+
dynamicChoices: "views"
|
|
1194
|
+
}
|
|
1195
|
+
]
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
key: "orchestrator",
|
|
1199
|
+
nativeName: "orchestrator",
|
|
1200
|
+
description: "Open the agent orchestrator",
|
|
1201
|
+
textAliases: ["/orchestrator"],
|
|
1202
|
+
scope: "both",
|
|
1203
|
+
category: "docks",
|
|
1204
|
+
icon: "workflow",
|
|
1205
|
+
target: { kind: "navigate", path: "/orchestrator", viewId: "orchestrator" }
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
key: "character",
|
|
1209
|
+
nativeName: "character",
|
|
1210
|
+
description: "Open the character editor",
|
|
1211
|
+
textAliases: ["/character"],
|
|
1212
|
+
scope: "both",
|
|
1213
|
+
category: "docks",
|
|
1214
|
+
icon: "user",
|
|
1215
|
+
target: { kind: "navigate", path: "/character", tab: "character" }
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
key: "knowledge",
|
|
1219
|
+
nativeName: "knowledge",
|
|
1220
|
+
description: "Open the knowledge base",
|
|
1221
|
+
textAliases: ["/knowledge"],
|
|
1222
|
+
scope: "both",
|
|
1223
|
+
category: "docks",
|
|
1224
|
+
icon: "book-open",
|
|
1225
|
+
target: {
|
|
1226
|
+
kind: "navigate",
|
|
1227
|
+
path: "/character/documents",
|
|
1228
|
+
tab: "documents"
|
|
1229
|
+
}
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
key: "wallet",
|
|
1233
|
+
nativeName: "wallet",
|
|
1234
|
+
description: "Open the wallet & inventory",
|
|
1235
|
+
textAliases: ["/wallet"],
|
|
1236
|
+
scope: "both",
|
|
1237
|
+
category: "docks",
|
|
1238
|
+
icon: "wallet",
|
|
1239
|
+
target: { kind: "navigate", path: "/wallet", tab: "inventory" }
|
|
1240
|
+
},
|
|
1241
|
+
{
|
|
1242
|
+
key: "automations",
|
|
1243
|
+
nativeName: "automations",
|
|
1244
|
+
description: "Open automations",
|
|
1245
|
+
textAliases: ["/automations"],
|
|
1246
|
+
scope: "both",
|
|
1247
|
+
category: "docks",
|
|
1248
|
+
icon: "zap",
|
|
1249
|
+
target: { kind: "navigate", path: "/automations", tab: "automations" }
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
key: "tasks",
|
|
1253
|
+
nativeName: "tasks",
|
|
1254
|
+
description: "Open tasks",
|
|
1255
|
+
textAliases: ["/tasks"],
|
|
1256
|
+
scope: "both",
|
|
1257
|
+
category: "docks",
|
|
1258
|
+
icon: "check-square",
|
|
1259
|
+
target: { kind: "navigate", path: "/apps/tasks", tab: "tasks" }
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
key: "skills",
|
|
1263
|
+
nativeName: "skills",
|
|
1264
|
+
description: "Open the skills library",
|
|
1265
|
+
textAliases: ["/skills"],
|
|
1266
|
+
scope: "both",
|
|
1267
|
+
category: "docks",
|
|
1268
|
+
icon: "sparkles",
|
|
1269
|
+
target: { kind: "navigate", path: "/apps/skills", tab: "skills" }
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
key: "plugins",
|
|
1273
|
+
nativeName: "plugins",
|
|
1274
|
+
description: "Open installed plugins",
|
|
1275
|
+
textAliases: ["/plugins"],
|
|
1276
|
+
scope: "both",
|
|
1277
|
+
category: "docks",
|
|
1278
|
+
icon: "plug",
|
|
1279
|
+
target: { kind: "navigate", path: "/apps/plugins", tab: "plugins" }
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
key: "logs",
|
|
1283
|
+
nativeName: "logs",
|
|
1284
|
+
description: "Open the logs",
|
|
1285
|
+
textAliases: ["/logs"],
|
|
1286
|
+
scope: "both",
|
|
1287
|
+
category: "docks",
|
|
1288
|
+
icon: "scroll-text",
|
|
1289
|
+
target: { kind: "navigate", path: "/apps/logs", tab: "logs" }
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
key: "database",
|
|
1293
|
+
nativeName: "database",
|
|
1294
|
+
description: "Open the database browser",
|
|
1295
|
+
textAliases: ["/database"],
|
|
1296
|
+
scope: "both",
|
|
1297
|
+
category: "docks",
|
|
1298
|
+
icon: "database",
|
|
1299
|
+
target: { kind: "navigate", path: "/apps/database", tab: "database" }
|
|
1300
|
+
}
|
|
1301
|
+
];
|
|
1302
|
+
var CLIENT_COMMANDS = [
|
|
1303
|
+
{
|
|
1304
|
+
key: "clear",
|
|
1305
|
+
nativeName: "clear",
|
|
1306
|
+
description: "Clear the current chat",
|
|
1307
|
+
textAliases: ["/clear"],
|
|
1308
|
+
scope: "both",
|
|
1309
|
+
category: "docks",
|
|
1310
|
+
icon: "eraser",
|
|
1311
|
+
surfaces: IN_APP_SURFACES,
|
|
1312
|
+
target: { kind: "client", clientAction: "clear-chat" }
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
key: "fullscreen",
|
|
1316
|
+
nativeName: "fullscreen",
|
|
1317
|
+
description: "Toggle full-screen chat",
|
|
1318
|
+
textAliases: ["/fullscreen"],
|
|
1319
|
+
scope: "both",
|
|
1320
|
+
category: "docks",
|
|
1321
|
+
icon: "maximize",
|
|
1322
|
+
surfaces: IN_APP_SURFACES,
|
|
1323
|
+
target: { kind: "client", clientAction: "toggle-fullscreen" }
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
key: "transcribe",
|
|
1327
|
+
nativeName: "transcribe",
|
|
1328
|
+
description: "Toggle long-form transcription mode (record-only; agent stays silent until an exit phrase)",
|
|
1329
|
+
textAliases: ["/transcribe"],
|
|
1330
|
+
scope: "both",
|
|
1331
|
+
category: "docks",
|
|
1332
|
+
icon: "mic",
|
|
1333
|
+
surfaces: IN_APP_SURFACES,
|
|
1334
|
+
target: { kind: "client", clientAction: "toggle-transcription" }
|
|
1335
|
+
}
|
|
1336
|
+
];
|
|
1337
|
+
var VIEW_SCOPED_COMMANDS = [
|
|
1338
|
+
{
|
|
1339
|
+
key: "calendar-add",
|
|
1340
|
+
nativeName: "calendar-add",
|
|
1341
|
+
description: "Add a calendar event (in the calendar view)",
|
|
1342
|
+
textAliases: ["/calendar-add"],
|
|
1343
|
+
scope: "both",
|
|
1344
|
+
category: "docks",
|
|
1345
|
+
icon: "calendar-plus",
|
|
1346
|
+
surfaces: IN_APP_SURFACES,
|
|
1347
|
+
views: ["calendar"],
|
|
1348
|
+
target: { kind: "agent" },
|
|
1349
|
+
acceptsArgs: true,
|
|
1350
|
+
args: [{ name: "event", description: "What to schedule", required: false }]
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
key: "todos-add",
|
|
1354
|
+
nativeName: "todos-add",
|
|
1355
|
+
description: "Add a to-do (in the todos view)",
|
|
1356
|
+
textAliases: ["/todos-add"],
|
|
1357
|
+
scope: "both",
|
|
1358
|
+
category: "docks",
|
|
1359
|
+
icon: "list-plus",
|
|
1360
|
+
surfaces: IN_APP_SURFACES,
|
|
1361
|
+
views: ["todos"],
|
|
1362
|
+
target: { kind: "agent" },
|
|
1363
|
+
acceptsArgs: true,
|
|
1364
|
+
args: [{ name: "task", description: "What to do", required: false }]
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
key: "todos-done",
|
|
1368
|
+
nativeName: "todos-done",
|
|
1369
|
+
description: "Complete a to-do (in the todos view)",
|
|
1370
|
+
textAliases: ["/todos-done"],
|
|
1371
|
+
scope: "both",
|
|
1372
|
+
category: "docks",
|
|
1373
|
+
icon: "check",
|
|
1374
|
+
surfaces: IN_APP_SURFACES,
|
|
1375
|
+
views: ["todos"],
|
|
1376
|
+
target: { kind: "agent" },
|
|
1377
|
+
acceptsArgs: true,
|
|
1378
|
+
args: [
|
|
1379
|
+
{ name: "task", description: "Which to-do to complete", required: false }
|
|
1380
|
+
]
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
key: "documents-search",
|
|
1384
|
+
nativeName: "documents-search",
|
|
1385
|
+
description: "Search the knowledge base (in the documents view)",
|
|
1386
|
+
textAliases: ["/documents-search"],
|
|
1387
|
+
scope: "both",
|
|
1388
|
+
category: "docks",
|
|
1389
|
+
icon: "search",
|
|
1390
|
+
surfaces: IN_APP_SURFACES,
|
|
1391
|
+
views: ["documents"],
|
|
1392
|
+
target: { kind: "agent" },
|
|
1393
|
+
acceptsArgs: true,
|
|
1394
|
+
args: [
|
|
1395
|
+
{ name: "query", description: "What to search for", required: false }
|
|
1396
|
+
]
|
|
1397
|
+
}
|
|
1398
|
+
];
|
|
1399
|
+
function navigationCommandDefinitions() {
|
|
1400
|
+
return [...NAVIGATE_COMMANDS, ...CLIENT_COMMANDS, ...VIEW_SCOPED_COMMANDS];
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
// src/serialize.ts
|
|
1404
|
+
var DEFAULT_TARGET = { kind: "agent" };
|
|
1405
|
+
function commandVisibleForSurface(surfaces, surface) {
|
|
1406
|
+
if (!surface)
|
|
1407
|
+
return true;
|
|
1408
|
+
if (!surfaces || surfaces.length === 0)
|
|
1409
|
+
return true;
|
|
1410
|
+
return surfaces.includes(surface);
|
|
1411
|
+
}
|
|
1412
|
+
function serializeArg(arg) {
|
|
1413
|
+
const serialized = {
|
|
1414
|
+
name: arg.name,
|
|
1415
|
+
description: arg.description
|
|
1416
|
+
};
|
|
1417
|
+
if (arg.required)
|
|
1418
|
+
serialized.required = true;
|
|
1419
|
+
if (arg.captureRemaining)
|
|
1420
|
+
serialized.captureRemaining = true;
|
|
1421
|
+
if (arg.dynamicChoices)
|
|
1422
|
+
serialized.dynamicChoices = arg.dynamicChoices;
|
|
1423
|
+
if (Array.isArray(arg.choices) && arg.choices.length > 0) {
|
|
1424
|
+
serialized.choices = arg.choices;
|
|
1425
|
+
}
|
|
1426
|
+
return serialized;
|
|
1427
|
+
}
|
|
1428
|
+
function serializeCommand(command, options = {}) {
|
|
1429
|
+
const args = (command.args ?? []).map(serializeArg);
|
|
1430
|
+
const serialized = {
|
|
1431
|
+
key: command.key,
|
|
1432
|
+
nativeName: command.nativeName ?? command.key,
|
|
1433
|
+
description: command.description,
|
|
1434
|
+
textAliases: command.textAliases,
|
|
1435
|
+
scope: command.scope,
|
|
1436
|
+
acceptsArgs: command.acceptsArgs ?? args.length > 0,
|
|
1437
|
+
args,
|
|
1438
|
+
requiresAuth: command.requiresAuth ?? false,
|
|
1439
|
+
requiresElevated: command.requiresElevated ?? false,
|
|
1440
|
+
target: command.target ?? DEFAULT_TARGET,
|
|
1441
|
+
source: options.source ?? "builtin"
|
|
1442
|
+
};
|
|
1443
|
+
if (command.category)
|
|
1444
|
+
serialized.category = command.category;
|
|
1445
|
+
if (command.surfaces && command.surfaces.length > 0) {
|
|
1446
|
+
serialized.surfaces = command.surfaces;
|
|
1447
|
+
}
|
|
1448
|
+
if (command.icon)
|
|
1449
|
+
serialized.icon = command.icon;
|
|
1450
|
+
if (command.views && command.views.length > 0) {
|
|
1451
|
+
serialized.views = command.views;
|
|
1452
|
+
}
|
|
1453
|
+
return serialized;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/connector-catalog.ts
|
|
1457
|
+
var KNOWN_SURFACES = new Set([
|
|
1458
|
+
"gui",
|
|
1459
|
+
"tui",
|
|
1460
|
+
"discord",
|
|
1461
|
+
"telegram"
|
|
1462
|
+
]);
|
|
1463
|
+
function commandVisibleForView(views, activeViewId) {
|
|
1464
|
+
if (!views || views.length === 0)
|
|
1465
|
+
return true;
|
|
1466
|
+
if (!activeViewId)
|
|
1467
|
+
return false;
|
|
1468
|
+
return views.includes(activeViewId);
|
|
1469
|
+
}
|
|
1470
|
+
function isConnectorScoped(command) {
|
|
1471
|
+
return command.scope !== "text";
|
|
1472
|
+
}
|
|
1473
|
+
function commandName(command) {
|
|
1474
|
+
return command.nativeName ?? command.key;
|
|
1475
|
+
}
|
|
1476
|
+
function unifiedDefinitions(agentId) {
|
|
1477
|
+
const agentCommands = agentId ? getEnabledCommandsForRuntime(agentId) : DEFAULT_COMMANDS.filter((command) => command.enabled !== false);
|
|
1478
|
+
const agent = agentCommands.filter(isConnectorScoped);
|
|
1479
|
+
const navigation = navigationCommandDefinitions();
|
|
1480
|
+
const navigationNames = new Set(navigation.map(commandName));
|
|
1481
|
+
const agentOnly = agent.filter((command) => !navigationNames.has(commandName(command)));
|
|
1482
|
+
return [...agentOnly, ...navigation];
|
|
1483
|
+
}
|
|
1484
|
+
function normalizeSurface(surface) {
|
|
1485
|
+
return KNOWN_SURFACES.has(surface) ? surface : null;
|
|
1486
|
+
}
|
|
1487
|
+
function visibleDefinitions(surface, activeViewId, agentId) {
|
|
1488
|
+
const normalized = normalizeSurface(surface);
|
|
1489
|
+
return unifiedDefinitions(agentId).filter((command) => commandVisibleForSurface(command.surfaces, normalized)).filter((command) => commandVisibleForView(command.views, activeViewId));
|
|
1490
|
+
}
|
|
1491
|
+
function mapDefinitionArg(arg) {
|
|
1492
|
+
return {
|
|
1493
|
+
name: arg.name,
|
|
1494
|
+
description: arg.description,
|
|
1495
|
+
required: arg.required ?? false,
|
|
1496
|
+
choices: Array.isArray(arg.choices) ? arg.choices : []
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function toConnectorCommand(command) {
|
|
1500
|
+
return {
|
|
1501
|
+
name: commandName(command),
|
|
1502
|
+
description: command.description,
|
|
1503
|
+
target: command.target ?? { kind: "agent" },
|
|
1504
|
+
options: (command.args ?? []).map(mapDefinitionArg),
|
|
1505
|
+
...command.views && command.views.length > 0 ? { views: command.views } : {}
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
function getConnectorCommands(surface, options = {}) {
|
|
1509
|
+
return visibleDefinitions(surface, options.activeViewId, options.agentId).map(toConnectorCommand);
|
|
1510
|
+
}
|
|
1511
|
+
function getCatalogCommands(surface, options = {}) {
|
|
1512
|
+
return visibleDefinitions(surface, options.activeViewId, options.agentId).map((command) => serializeCommand(command, options.source ? { source: options.source } : {}));
|
|
1513
|
+
}
|
|
1514
|
+
|
|
580
1515
|
// src/index.ts
|
|
581
1516
|
var commandRegistryProvider = {
|
|
582
1517
|
name: "COMMAND_REGISTRY",
|
|
@@ -588,10 +1523,9 @@ var commandRegistryProvider = {
|
|
|
588
1523
|
cacheStable: true,
|
|
589
1524
|
cacheScope: "agent",
|
|
590
1525
|
async get(runtime, message, _state) {
|
|
591
|
-
|
|
592
|
-
const text = message.content?.text ?? "";
|
|
1526
|
+
const text = message.content.text ?? "";
|
|
593
1527
|
const isCommand = hasCommand(text);
|
|
594
|
-
const commands =
|
|
1528
|
+
const commands = getEnabledCommandsForRuntime(runtime.agentId);
|
|
595
1529
|
if (isCommand) {
|
|
596
1530
|
const commandList = commands.map((cmd) => {
|
|
597
1531
|
const auth = cmd.requiresAuth ? " (requires auth)" : "";
|
|
@@ -643,14 +1577,15 @@ var commandsPlugin = {
|
|
|
643
1577
|
name: "commands",
|
|
644
1578
|
description: "Chat command system with /help, /status, /reset, etc.",
|
|
645
1579
|
providers: [commandRegistryProvider],
|
|
1580
|
+
actions: commandActions,
|
|
1581
|
+
shortcuts: commandShortcuts,
|
|
646
1582
|
autoEnable: {
|
|
647
1583
|
shouldEnable: (_env, config) => {
|
|
648
|
-
const f = config
|
|
1584
|
+
const f = config.features?.commands;
|
|
649
1585
|
return f === true || typeof f === "object" && f !== null && f.enabled !== false;
|
|
650
1586
|
}
|
|
651
1587
|
},
|
|
652
1588
|
config: {
|
|
653
|
-
COMMANDS_ENABLED: "true",
|
|
654
1589
|
COMMANDS_CONFIG_ENABLED: "false",
|
|
655
1590
|
COMMANDS_DEBUG_ENABLED: "false",
|
|
656
1591
|
COMMANDS_BASH_ENABLED: "false",
|
|
@@ -685,8 +1620,8 @@ var commandsPlugin = {
|
|
|
685
1620
|
if (detection.command?.key !== "think") {
|
|
686
1621
|
throw new Error(`Expected key 'think', got '${detection.command?.key}'`);
|
|
687
1622
|
}
|
|
688
|
-
if (detection.command
|
|
689
|
-
throw new Error(`Expected arg 'high', got '${detection.command
|
|
1623
|
+
if (detection.command.args[0] !== "high") {
|
|
1624
|
+
throw new Error(`Expected arg 'high', got '${detection.command.args[0]}'`);
|
|
690
1625
|
}
|
|
691
1626
|
import_core.logger.success("Command argument parsing works correctly");
|
|
692
1627
|
}
|
|
@@ -819,4 +1754,4 @@ var commandsPlugin = {
|
|
|
819
1754
|
};
|
|
820
1755
|
var src_default = commandsPlugin;
|
|
821
1756
|
|
|
822
|
-
//# debugId=
|
|
1757
|
+
//# debugId=D816A7531DE8F68364756E2164756E21
|