@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/index.js
CHANGED
|
@@ -97,6 +97,7 @@ var DEFAULT_COMMANDS = [
|
|
|
97
97
|
scope: "both",
|
|
98
98
|
category: "session",
|
|
99
99
|
acceptsArgs: true,
|
|
100
|
+
requiresAuth: true,
|
|
100
101
|
args: [
|
|
101
102
|
{ name: "instructions", description: "Optional compaction instructions" }
|
|
102
103
|
]
|
|
@@ -152,7 +153,13 @@ var DEFAULT_COMMANDS = [
|
|
|
152
153
|
scope: "both",
|
|
153
154
|
category: "options",
|
|
154
155
|
acceptsArgs: true,
|
|
155
|
-
args: [
|
|
156
|
+
args: [
|
|
157
|
+
{
|
|
158
|
+
name: "model",
|
|
159
|
+
description: "provider/model or alias",
|
|
160
|
+
dynamicChoices: "models"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
156
163
|
},
|
|
157
164
|
{
|
|
158
165
|
key: "models",
|
|
@@ -267,6 +274,15 @@ var DEFAULT_COMMANDS = [
|
|
|
267
274
|
}
|
|
268
275
|
]
|
|
269
276
|
},
|
|
277
|
+
{
|
|
278
|
+
key: "transcribe",
|
|
279
|
+
nativeName: "transcribe",
|
|
280
|
+
description: "Toggle long-form transcription mode (record-only; agent stays silent until an exit phrase)",
|
|
281
|
+
textAliases: ["/transcribe", "/transcription", "/dictate"],
|
|
282
|
+
scope: "both",
|
|
283
|
+
category: "media",
|
|
284
|
+
acceptsArgs: false
|
|
285
|
+
},
|
|
270
286
|
{
|
|
271
287
|
key: "bash",
|
|
272
288
|
nativeName: "bash",
|
|
@@ -301,10 +317,7 @@ function initForRuntime(agentId) {
|
|
|
301
317
|
activeStore = store;
|
|
302
318
|
}
|
|
303
319
|
function useRuntime(agentId) {
|
|
304
|
-
|
|
305
|
-
if (store) {
|
|
306
|
-
activeStore = store;
|
|
307
|
-
}
|
|
320
|
+
activeStore = storeForRuntime(agentId);
|
|
308
321
|
}
|
|
309
322
|
function getCommands() {
|
|
310
323
|
return [...activeStore.commands];
|
|
@@ -363,12 +376,55 @@ function startsWithCommand(text) {
|
|
|
363
376
|
if (normalized === alias) {
|
|
364
377
|
return command;
|
|
365
378
|
}
|
|
366
|
-
|
|
379
|
+
const remainder = normalized.slice(alias.length);
|
|
380
|
+
if (normalized.startsWith(alias) && /^[\s:]/.test(remainder)) {
|
|
367
381
|
return command;
|
|
368
382
|
}
|
|
369
383
|
}
|
|
370
384
|
return;
|
|
371
385
|
}
|
|
386
|
+
function storeForRuntime(agentId) {
|
|
387
|
+
if (!agentId)
|
|
388
|
+
return fallbackStore;
|
|
389
|
+
return runtimeStores.get(agentId) ?? fallbackStore;
|
|
390
|
+
}
|
|
391
|
+
function getEnabledCommandsFromStore(store) {
|
|
392
|
+
return store.commands.filter((cmd) => cmd.enabled !== false);
|
|
393
|
+
}
|
|
394
|
+
function getCommandsByCategoryFromStore(store, category) {
|
|
395
|
+
return store.commands.filter((cmd) => cmd.category === category && cmd.enabled !== false);
|
|
396
|
+
}
|
|
397
|
+
function getAliasMapForStore(store) {
|
|
398
|
+
if (store.aliasMap)
|
|
399
|
+
return store.aliasMap;
|
|
400
|
+
store.aliasMap = new Map;
|
|
401
|
+
for (const command of store.commands) {
|
|
402
|
+
if (command.enabled === false)
|
|
403
|
+
continue;
|
|
404
|
+
for (const alias of command.textAliases) {
|
|
405
|
+
const normalized = alias.toLowerCase().trim();
|
|
406
|
+
if (!store.aliasMap.has(normalized)) {
|
|
407
|
+
store.aliasMap.set(normalized, command);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return store.aliasMap;
|
|
412
|
+
}
|
|
413
|
+
function getCommandsForRuntime(agentId) {
|
|
414
|
+
return [...storeForRuntime(agentId).commands];
|
|
415
|
+
}
|
|
416
|
+
function getEnabledCommandsForRuntime(agentId) {
|
|
417
|
+
return getEnabledCommandsFromStore(storeForRuntime(agentId));
|
|
418
|
+
}
|
|
419
|
+
function getCommandsByCategoryForRuntime(category, agentId) {
|
|
420
|
+
return getCommandsByCategoryFromStore(storeForRuntime(agentId), category);
|
|
421
|
+
}
|
|
422
|
+
function findCommandByAliasForRuntime(alias, agentId) {
|
|
423
|
+
return getAliasMapForStore(storeForRuntime(agentId)).get(alias.toLowerCase().trim());
|
|
424
|
+
}
|
|
425
|
+
function findCommandByKeyForRuntime(key, agentId) {
|
|
426
|
+
return storeForRuntime(agentId).commands.find((c) => c.key === key);
|
|
427
|
+
}
|
|
372
428
|
|
|
373
429
|
// src/parser.ts
|
|
374
430
|
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -407,7 +463,8 @@ function parseCommand(text, definition) {
|
|
|
407
463
|
matchedAlias = alias;
|
|
408
464
|
break;
|
|
409
465
|
}
|
|
410
|
-
|
|
466
|
+
const remainder = trimmed.slice(alias.length);
|
|
467
|
+
if (trimmed.toLowerCase().startsWith(normalized) && /^[\s:]/.test(remainder)) {
|
|
411
468
|
matchedAlias = alias;
|
|
412
469
|
break;
|
|
413
470
|
}
|
|
@@ -420,12 +477,15 @@ function parseCommand(text, definition) {
|
|
|
420
477
|
rawArgs = rawArgs.slice(1).trim();
|
|
421
478
|
}
|
|
422
479
|
const args = parseArgs(rawArgs, definition);
|
|
423
|
-
|
|
480
|
+
const parsed = {
|
|
424
481
|
key: definition.key,
|
|
425
482
|
canonical: definition.textAliases[0] ?? `/${definition.key}`,
|
|
426
|
-
args
|
|
427
|
-
rawArgs: rawArgs || undefined
|
|
483
|
+
args
|
|
428
484
|
};
|
|
485
|
+
if (rawArgs) {
|
|
486
|
+
parsed.rawArgs = rawArgs;
|
|
487
|
+
}
|
|
488
|
+
return parsed;
|
|
429
489
|
}
|
|
430
490
|
function parseArgs(rawArgs, definition) {
|
|
431
491
|
if (!rawArgs || !definition.acceptsArgs) {
|
|
@@ -438,13 +498,13 @@ function parseArgs(rawArgs, definition) {
|
|
|
438
498
|
const args = [];
|
|
439
499
|
const argDefs = definition.args ?? [];
|
|
440
500
|
const tokens = tokenize(rawArgs);
|
|
441
|
-
for (
|
|
501
|
+
for (const [i, token] of tokens.entries()) {
|
|
442
502
|
const argDef = argDefs[i];
|
|
443
503
|
if (argDef?.captureRemaining) {
|
|
444
504
|
args.push(tokens.slice(i).join(" "));
|
|
445
505
|
break;
|
|
446
506
|
}
|
|
447
|
-
args.push(
|
|
507
|
+
args.push(token);
|
|
448
508
|
}
|
|
449
509
|
return args;
|
|
450
510
|
}
|
|
@@ -453,8 +513,7 @@ function tokenize(input) {
|
|
|
453
513
|
let current = "";
|
|
454
514
|
let inQuote = false;
|
|
455
515
|
let quoteChar = "";
|
|
456
|
-
for (
|
|
457
|
-
const char = input[i];
|
|
516
|
+
for (const char of input) {
|
|
458
517
|
if (inQuote) {
|
|
459
518
|
if (char === quoteChar) {
|
|
460
519
|
inQuote = false;
|
|
@@ -488,7 +547,7 @@ function normalizeCommandBody(text, botMention) {
|
|
|
488
547
|
const mentionPattern = new RegExp(`^@${escapeRegExp(botMention)}\\s*`, "i");
|
|
489
548
|
normalized = normalized.replace(mentionPattern, "");
|
|
490
549
|
}
|
|
491
|
-
normalized = normalized.replace(/^(
|
|
550
|
+
normalized = normalized.replace(/^([/!][^\s:]+):\s*/, "$1 ");
|
|
492
551
|
return normalized.trim();
|
|
493
552
|
}
|
|
494
553
|
function isCommandOnly(text) {
|
|
@@ -513,6 +572,849 @@ function extractCommand(text) {
|
|
|
513
572
|
return { command, remainingText: command.rawArgs };
|
|
514
573
|
}
|
|
515
574
|
|
|
575
|
+
// src/actions/command-settings.ts
|
|
576
|
+
var COMMAND_SETTING_CHOICES = {
|
|
577
|
+
thinking: ["off", "minimal", "low", "medium", "high", "xhigh"],
|
|
578
|
+
verbose: ["off", "on", "full"],
|
|
579
|
+
reasoning: ["off", "on", "stream"],
|
|
580
|
+
queue: ["steer", "followup", "collect", "interrupt"],
|
|
581
|
+
elevated: ["off", "on", "ask", "full"],
|
|
582
|
+
model: null,
|
|
583
|
+
tts: ["on", "off"]
|
|
584
|
+
};
|
|
585
|
+
function cacheKey(roomId) {
|
|
586
|
+
return `command-settings:${roomId}`;
|
|
587
|
+
}
|
|
588
|
+
async function clearCommandSettings(runtime, roomId) {
|
|
589
|
+
return runtime.deleteCache(cacheKey(roomId));
|
|
590
|
+
}
|
|
591
|
+
async function getCommandSettings(runtime, roomId) {
|
|
592
|
+
const stored = await runtime.getCache(cacheKey(roomId));
|
|
593
|
+
return stored ?? {};
|
|
594
|
+
}
|
|
595
|
+
async function setCommandSetting(runtime, roomId, key, rawValue) {
|
|
596
|
+
const value = rawValue.trim().toLowerCase();
|
|
597
|
+
const choices = COMMAND_SETTING_CHOICES[key];
|
|
598
|
+
if (choices && !choices.includes(value)) {
|
|
599
|
+
return {
|
|
600
|
+
error: `Invalid ${key} value "${rawValue}". Choose one of: ${choices.join(", ")}.`
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
const normalized = choices ? value : rawValue.trim();
|
|
604
|
+
const current = await getCommandSettings(runtime, roomId);
|
|
605
|
+
await runtime.setCache(cacheKey(roomId), {
|
|
606
|
+
...current,
|
|
607
|
+
[key]: normalized
|
|
608
|
+
});
|
|
609
|
+
return { value: normalized };
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// src/actions/handlers.ts
|
|
613
|
+
var DETERMINISTIC_COMMAND_KEYS = [
|
|
614
|
+
"help",
|
|
615
|
+
"commands",
|
|
616
|
+
"status",
|
|
617
|
+
"whoami",
|
|
618
|
+
"context",
|
|
619
|
+
"reset",
|
|
620
|
+
"new",
|
|
621
|
+
"compact",
|
|
622
|
+
"models",
|
|
623
|
+
"usage",
|
|
624
|
+
"think",
|
|
625
|
+
"verbose",
|
|
626
|
+
"reasoning",
|
|
627
|
+
"queue",
|
|
628
|
+
"elevated",
|
|
629
|
+
"model",
|
|
630
|
+
"tts"
|
|
631
|
+
];
|
|
632
|
+
var DETERMINISTIC_KEYS = new Set(DETERMINISTIC_COMMAND_KEYS);
|
|
633
|
+
function isDeterministicCommand(key) {
|
|
634
|
+
return DETERMINISTIC_KEYS.has(key);
|
|
635
|
+
}
|
|
636
|
+
var CATEGORY_ORDER = [
|
|
637
|
+
"status",
|
|
638
|
+
"session",
|
|
639
|
+
"options",
|
|
640
|
+
"media",
|
|
641
|
+
"management",
|
|
642
|
+
"tools",
|
|
643
|
+
"docks",
|
|
644
|
+
"skills"
|
|
645
|
+
];
|
|
646
|
+
var OPTION_COMMANDS = {
|
|
647
|
+
think: { key: "thinking", label: "Thinking" },
|
|
648
|
+
verbose: { key: "verbose", label: "Verbose" },
|
|
649
|
+
reasoning: { key: "reasoning", label: "Reasoning" },
|
|
650
|
+
queue: { key: "queue", label: "Queue mode" },
|
|
651
|
+
elevated: { key: "elevated", label: "Elevated mode" },
|
|
652
|
+
model: { key: "model", label: "Model" },
|
|
653
|
+
tts: { key: "tts", label: "TTS" }
|
|
654
|
+
};
|
|
655
|
+
function reply(text) {
|
|
656
|
+
return { handled: true, reply: text, shouldContinue: false };
|
|
657
|
+
}
|
|
658
|
+
function authError() {
|
|
659
|
+
return reply("This command requires authorization.");
|
|
660
|
+
}
|
|
661
|
+
function formatCommandList(agentId) {
|
|
662
|
+
const lines = [];
|
|
663
|
+
for (const category of CATEGORY_ORDER) {
|
|
664
|
+
const commands = getCommandsByCategoryForRuntime(category, agentId);
|
|
665
|
+
if (commands.length === 0)
|
|
666
|
+
continue;
|
|
667
|
+
lines.push(`**${category}**`);
|
|
668
|
+
for (const command of commands) {
|
|
669
|
+
const alias = command.textAliases[0] ?? `/${command.key}`;
|
|
670
|
+
const auth = command.requiresAuth ? " (requires auth)" : "";
|
|
671
|
+
lines.push(` ${alias} — ${command.description}${auth}`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return lines.join(`
|
|
675
|
+
`);
|
|
676
|
+
}
|
|
677
|
+
function resolveModelLabel(runtime) {
|
|
678
|
+
const fromSetting = runtime.getSetting("LARGE_MODEL") ?? runtime.getSetting("ANTHROPIC_LARGE_MODEL") ?? runtime.getSetting("OPENAI_LARGE_MODEL");
|
|
679
|
+
if (typeof fromSetting === "string" && fromSetting.trim()) {
|
|
680
|
+
return fromSetting.trim();
|
|
681
|
+
}
|
|
682
|
+
const fromCharacter = runtime.character?.settings?.model;
|
|
683
|
+
if (typeof fromCharacter === "string" && fromCharacter.trim()) {
|
|
684
|
+
return fromCharacter.trim();
|
|
685
|
+
}
|
|
686
|
+
return "default";
|
|
687
|
+
}
|
|
688
|
+
async function countRoomMessages(runtime, roomId) {
|
|
689
|
+
if (typeof runtime.countMemories !== "function")
|
|
690
|
+
return null;
|
|
691
|
+
try {
|
|
692
|
+
return await runtime.countMemories({
|
|
693
|
+
roomIds: [roomId],
|
|
694
|
+
tableName: "messages",
|
|
695
|
+
unique: false
|
|
696
|
+
});
|
|
697
|
+
} catch {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
async function clearRoomMessages(runtime, roomId) {
|
|
702
|
+
const before = await countRoomMessages(runtime, roomId);
|
|
703
|
+
if (typeof runtime.deleteAllMemories !== "function")
|
|
704
|
+
return null;
|
|
705
|
+
await runtime.deleteAllMemories([roomId], "messages");
|
|
706
|
+
return before;
|
|
707
|
+
}
|
|
708
|
+
function findAction(runtime, name) {
|
|
709
|
+
return runtime.actions?.find((action) => action.name === name);
|
|
710
|
+
}
|
|
711
|
+
async function runCompactAction(runtime, message, callback) {
|
|
712
|
+
const action = findAction(runtime, "COMPACT_CONVERSATION");
|
|
713
|
+
if (!action || !message) {
|
|
714
|
+
return reply("Conversation compaction is not available in this runtime.");
|
|
715
|
+
}
|
|
716
|
+
const result = await action.handler(runtime, message, undefined, undefined, callback);
|
|
717
|
+
if (result?.text && result.text.trim().length > 0)
|
|
718
|
+
return reply(result.text);
|
|
719
|
+
return reply("Conversation compaction completed.");
|
|
720
|
+
}
|
|
721
|
+
async function setOptionCommand(runtime, roomId, parsed, option) {
|
|
722
|
+
const rawValue = parsed.rawArgs?.trim() ?? parsed.args[0]?.trim() ?? "";
|
|
723
|
+
if (!rawValue) {
|
|
724
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
725
|
+
const current = option.key === "model" ? settings.model ?? resolveModelLabel(runtime) : settings[option.key] ?? "default";
|
|
726
|
+
return reply(`${option.label} is ${current}.`);
|
|
727
|
+
}
|
|
728
|
+
const result = await setCommandSetting(runtime, roomId, option.key, rawValue);
|
|
729
|
+
if ("error" in result)
|
|
730
|
+
return reply(result.error);
|
|
731
|
+
return reply(`${option.label} set to ${result.value}.`);
|
|
732
|
+
}
|
|
733
|
+
async function runCommand(runtime, parsed, context) {
|
|
734
|
+
const agentId = runtime.agentId;
|
|
735
|
+
useRuntime(agentId);
|
|
736
|
+
const definition = findCommandByKeyForRuntime(parsed.key, agentId);
|
|
737
|
+
if (definition?.requiresAuth && !context.isAuthorized)
|
|
738
|
+
return authError();
|
|
739
|
+
if (definition?.requiresElevated && !context.isElevated) {
|
|
740
|
+
return reply("This command requires elevated permissions.");
|
|
741
|
+
}
|
|
742
|
+
const roomId = context.roomId;
|
|
743
|
+
switch (parsed.key) {
|
|
744
|
+
case "help":
|
|
745
|
+
case "commands":
|
|
746
|
+
return reply(`Available commands:
|
|
747
|
+
${formatCommandList(agentId)}`);
|
|
748
|
+
case "status": {
|
|
749
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
750
|
+
const messageCount = await countRoomMessages(runtime, roomId);
|
|
751
|
+
const lines = [
|
|
752
|
+
`Agent: ${runtime.character?.name ?? runtime.agentId}`,
|
|
753
|
+
`Model: ${settings.model ?? resolveModelLabel(runtime)}`,
|
|
754
|
+
`Thinking: ${settings.thinking ?? "default"}`,
|
|
755
|
+
`Reasoning: ${settings.reasoning ?? "default"}`,
|
|
756
|
+
`Verbose: ${settings.verbose ?? "default"}`,
|
|
757
|
+
`Queue: ${settings.queue ?? "default"}`,
|
|
758
|
+
`TTS: ${settings.tts ?? "default"}`,
|
|
759
|
+
messageCount === null ? null : `Messages: ${messageCount}`,
|
|
760
|
+
`Commands enabled: ${getEnabledCommandsForRuntime(agentId).length}`
|
|
761
|
+
].filter(Boolean);
|
|
762
|
+
return reply(lines.join(`
|
|
763
|
+
`));
|
|
764
|
+
}
|
|
765
|
+
case "whoami": {
|
|
766
|
+
const who = context.senderName ?? context.senderId ?? "you";
|
|
767
|
+
return reply(`You are ${who}.
|
|
768
|
+
Authorized: ${context.isAuthorized ? "yes" : "no"}
|
|
769
|
+
Elevated: ${context.isElevated ? "yes" : "no"}`);
|
|
770
|
+
}
|
|
771
|
+
case "context": {
|
|
772
|
+
const settings = await getCommandSettings(runtime, roomId);
|
|
773
|
+
const lines = [
|
|
774
|
+
`Room: ${roomId}`,
|
|
775
|
+
context.channelId ? `Channel: ${context.channelId}` : null,
|
|
776
|
+
`Active settings: ${describeSettings(settings)}`
|
|
777
|
+
].filter(Boolean);
|
|
778
|
+
return reply(lines.join(`
|
|
779
|
+
`));
|
|
780
|
+
}
|
|
781
|
+
case "models":
|
|
782
|
+
return reply(`Current model: ${resolveModelLabel(runtime)}`);
|
|
783
|
+
case "usage": {
|
|
784
|
+
const usage = await runtime.getCache(`token-usage:${roomId}`);
|
|
785
|
+
if (!usage?.totalTokens) {
|
|
786
|
+
return reply("No token usage recorded for this conversation yet.");
|
|
787
|
+
}
|
|
788
|
+
return reply(`Token usage — prompt: ${usage.promptTokens ?? 0}, completion: ${usage.completionTokens ?? 0}, total: ${usage.totalTokens}.`);
|
|
789
|
+
}
|
|
790
|
+
case "think":
|
|
791
|
+
case "verbose":
|
|
792
|
+
case "reasoning":
|
|
793
|
+
case "queue":
|
|
794
|
+
case "elevated":
|
|
795
|
+
case "model":
|
|
796
|
+
case "tts":
|
|
797
|
+
return setOptionCommand(runtime, roomId, parsed, OPTION_COMMANDS[parsed.key]);
|
|
798
|
+
case "reset": {
|
|
799
|
+
await clearCommandSettings(runtime, roomId);
|
|
800
|
+
const deleted = await clearRoomMessages(runtime, roomId);
|
|
801
|
+
if (deleted === null) {
|
|
802
|
+
return reply("Reset command settings for this room. Message history is unchanged because memory deletion is unavailable.");
|
|
803
|
+
}
|
|
804
|
+
return reply(`Reset this room: cleared command settings and ${deleted} message(s).`);
|
|
805
|
+
}
|
|
806
|
+
case "new":
|
|
807
|
+
await clearCommandSettings(runtime, roomId);
|
|
808
|
+
return reply("Started a new conversation context for this room.");
|
|
809
|
+
case "compact":
|
|
810
|
+
return runCompactAction(runtime, context.message, context.callback);
|
|
811
|
+
default:
|
|
812
|
+
return { handled: false, shouldContinue: true };
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
function describeSettings(settings) {
|
|
816
|
+
const entries = Object.entries(settings).filter(([, v]) => v);
|
|
817
|
+
if (entries.length === 0)
|
|
818
|
+
return "none";
|
|
819
|
+
return entries.map(([k, v]) => `${k}=${v}`).join(", ");
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// src/actions/dispatch.ts
|
|
823
|
+
function buildContext(message, options) {
|
|
824
|
+
const content = message.content;
|
|
825
|
+
const context = {
|
|
826
|
+
senderId: message.entityId,
|
|
827
|
+
isAuthorized: options.isAuthorized ?? false,
|
|
828
|
+
isElevated: options.isElevated ?? false,
|
|
829
|
+
roomId: message.roomId,
|
|
830
|
+
message
|
|
831
|
+
};
|
|
832
|
+
if (options.senderName)
|
|
833
|
+
context.senderName = options.senderName;
|
|
834
|
+
if (options.callback)
|
|
835
|
+
context.callback = options.callback;
|
|
836
|
+
const channelId = content.channelId ?? content.source;
|
|
837
|
+
if (channelId)
|
|
838
|
+
context.channelId = channelId;
|
|
839
|
+
return context;
|
|
840
|
+
}
|
|
841
|
+
async function resolveCommand(runtime, message, options = {}) {
|
|
842
|
+
const text = message.content.text ?? "";
|
|
843
|
+
if (!hasCommand(text))
|
|
844
|
+
return { handled: false };
|
|
845
|
+
const detection = detectCommand(text);
|
|
846
|
+
if (!detection.isCommand || !detection.command)
|
|
847
|
+
return { handled: false };
|
|
848
|
+
const parsed = detection.command;
|
|
849
|
+
const definition = findCommandByKeyForRuntime(parsed.key, runtime.agentId);
|
|
850
|
+
if (definition?.target && definition.target.kind !== "agent") {
|
|
851
|
+
return { handled: false, command: parsed };
|
|
852
|
+
}
|
|
853
|
+
const deterministicOnly = options.deterministicOnly ?? options.gateSafeOnly ?? true;
|
|
854
|
+
if (deterministicOnly && !isDeterministicCommand(parsed.key)) {
|
|
855
|
+
return { handled: false, command: parsed };
|
|
856
|
+
}
|
|
857
|
+
const result = await runCommand(runtime, parsed, buildContext(message, options));
|
|
858
|
+
if (!result.handled)
|
|
859
|
+
return { handled: false, command: parsed };
|
|
860
|
+
const dispatched = { handled: true, command: parsed };
|
|
861
|
+
if (result.reply !== undefined)
|
|
862
|
+
dispatched.reply = result.reply;
|
|
863
|
+
return dispatched;
|
|
864
|
+
}
|
|
865
|
+
async function dispatchCommandMessage(runtime, message, callback, options = {}) {
|
|
866
|
+
const result = await resolveCommand(runtime, message, options);
|
|
867
|
+
if (!result.handled || result.reply === undefined)
|
|
868
|
+
return false;
|
|
869
|
+
await callback({ text: result.reply, source: "command" });
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// src/actions/command-actions.ts
|
|
874
|
+
var OWNER_SOURCES = new Set([
|
|
875
|
+
"client_chat",
|
|
876
|
+
"gui",
|
|
877
|
+
"tui",
|
|
878
|
+
"direct",
|
|
879
|
+
"dashboard"
|
|
880
|
+
]);
|
|
881
|
+
function resolveTrust(message) {
|
|
882
|
+
const source = message.content.source;
|
|
883
|
+
const trusted = !source || OWNER_SOURCES.has(source);
|
|
884
|
+
return { isAuthorized: trusted, isElevated: trusted };
|
|
885
|
+
}
|
|
886
|
+
function buildAction(key, _nativeName, description, aliases) {
|
|
887
|
+
return {
|
|
888
|
+
name: `${key.toUpperCase()}_COMMAND`,
|
|
889
|
+
description,
|
|
890
|
+
similes: aliases,
|
|
891
|
+
suppressEarlyReply: true,
|
|
892
|
+
suppressPostActionContinuation: true,
|
|
893
|
+
validate: async (_runtime, message) => {
|
|
894
|
+
const text = message.content.text ?? "";
|
|
895
|
+
if (!hasCommand(text))
|
|
896
|
+
return false;
|
|
897
|
+
const detection = detectCommand(text);
|
|
898
|
+
return detection.isCommand && detection.command?.key === key;
|
|
899
|
+
},
|
|
900
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
901
|
+
const result = await resolveCommand(runtime, message, {
|
|
902
|
+
...resolveTrust(message),
|
|
903
|
+
deterministicOnly: true,
|
|
904
|
+
...callback ? { callback } : {}
|
|
905
|
+
});
|
|
906
|
+
if (!result.handled || result.reply === undefined) {
|
|
907
|
+
return { success: false };
|
|
908
|
+
}
|
|
909
|
+
if (callback) {
|
|
910
|
+
await callback({ text: result.reply, source: "command" });
|
|
911
|
+
}
|
|
912
|
+
return { success: true, text: result.reply };
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function createCommandActions(commandKeys) {
|
|
917
|
+
const actions = [];
|
|
918
|
+
for (const key of commandKeys) {
|
|
919
|
+
if (!isDeterministicCommand(key))
|
|
920
|
+
continue;
|
|
921
|
+
const definition = findCommandByKey(key);
|
|
922
|
+
if (!definition)
|
|
923
|
+
continue;
|
|
924
|
+
if (definition.target && definition.target.kind !== "agent")
|
|
925
|
+
continue;
|
|
926
|
+
actions.push(buildAction(key, definition.nativeName ?? key, definition.description, definition.textAliases));
|
|
927
|
+
}
|
|
928
|
+
return actions;
|
|
929
|
+
}
|
|
930
|
+
// src/actions/shortcuts.ts
|
|
931
|
+
function createCommandShortcuts(commandKeys = DETERMINISTIC_COMMAND_KEYS) {
|
|
932
|
+
const shortcuts = [];
|
|
933
|
+
for (const key of commandKeys) {
|
|
934
|
+
const definition = findCommandByKey(key);
|
|
935
|
+
if (!definition)
|
|
936
|
+
continue;
|
|
937
|
+
if (definition.target && definition.target.kind !== "agent")
|
|
938
|
+
continue;
|
|
939
|
+
shortcuts.push({
|
|
940
|
+
id: `cmd:${key}`,
|
|
941
|
+
kind: "explicit",
|
|
942
|
+
aliases: definition.textAliases,
|
|
943
|
+
target: { kind: "action", name: `${key.toUpperCase()}_COMMAND` }
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
return shortcuts;
|
|
947
|
+
}
|
|
948
|
+
var explicitCommandShortcuts = createCommandShortcuts();
|
|
949
|
+
var naturalShortcuts = [
|
|
950
|
+
{
|
|
951
|
+
id: "nl:commands",
|
|
952
|
+
kind: "natural",
|
|
953
|
+
patterns: [
|
|
954
|
+
{
|
|
955
|
+
regex: /^what commands (?:can i (?:use|run)|are (?:there|available)|do you (?:have|support))$/u
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
regex: /^(?:show|list|give|tell)(?: me)?(?: a list of| the list of| all(?: of)?| the| your| available)* commands$/u
|
|
959
|
+
},
|
|
960
|
+
{ regex: /^what are(?: all)?(?: the| your| available)* commands$/u }
|
|
961
|
+
],
|
|
962
|
+
target: { kind: "action", name: "COMMANDS_COMMAND" },
|
|
963
|
+
requiresAction: "COMMANDS_COMMAND",
|
|
964
|
+
confidence: 0.95
|
|
965
|
+
}
|
|
966
|
+
];
|
|
967
|
+
var commandShortcuts = [
|
|
968
|
+
...explicitCommandShortcuts,
|
|
969
|
+
...naturalShortcuts
|
|
970
|
+
];
|
|
971
|
+
|
|
972
|
+
// src/actions/index.ts
|
|
973
|
+
var commandActions = createCommandActions([
|
|
974
|
+
...DETERMINISTIC_COMMAND_KEYS
|
|
975
|
+
]);
|
|
976
|
+
// src/connector-bridge.ts
|
|
977
|
+
function resolveConnectorCommandAuth(agentId, name) {
|
|
978
|
+
const definition = findCommandByKeyForRuntime(name, agentId);
|
|
979
|
+
return {
|
|
980
|
+
requiresAuth: definition?.requiresAuth ?? false,
|
|
981
|
+
requiresElevated: definition?.requiresElevated ?? false
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
function gateConnectorCommand(requirements, sender) {
|
|
985
|
+
if (requirements.requiresAuth && !sender.isAuthorized) {
|
|
986
|
+
return {
|
|
987
|
+
allowed: false,
|
|
988
|
+
reply: "This command requires authorization. Pair your account or ask an owner to run it."
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
if (requirements.requiresElevated && !sender.isElevated) {
|
|
992
|
+
return {
|
|
993
|
+
allowed: false,
|
|
994
|
+
reply: "This command requires elevated permissions."
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
return { allowed: true };
|
|
998
|
+
}
|
|
999
|
+
function gateConnectorCommandByName(agentId, name, sender) {
|
|
1000
|
+
return gateConnectorCommand(resolveConnectorCommandAuth(agentId, name), sender);
|
|
1001
|
+
}
|
|
1002
|
+
// src/settings-sections.ts
|
|
1003
|
+
var SETTINGS_SECTIONS = [
|
|
1004
|
+
{
|
|
1005
|
+
id: "ai-model",
|
|
1006
|
+
label: "AI Model & Providers",
|
|
1007
|
+
aliases: ["model", "models", "providers", "provider", "llm"]
|
|
1008
|
+
},
|
|
1009
|
+
{ id: "general", label: "General", aliases: ["basics"] },
|
|
1010
|
+
{ id: "agent", label: "Agent", aliases: ["character", "persona"] },
|
|
1011
|
+
{ id: "voice", label: "Voice", aliases: ["audio", "tts", "speech"] },
|
|
1012
|
+
{ id: "connectors", label: "Connectors", aliases: ["integrations"] },
|
|
1013
|
+
{ id: "skills", label: "Skills" },
|
|
1014
|
+
{ id: "memory", label: "Memory", aliases: ["knowledge"] },
|
|
1015
|
+
{ id: "permissions", label: "Permissions", aliases: ["security", "access"] },
|
|
1016
|
+
{ id: "billing", label: "Billing", aliases: ["plan", "subscription"] },
|
|
1017
|
+
{ id: "appearance", label: "Appearance", aliases: ["theme", "display"] },
|
|
1018
|
+
{ id: "notifications", label: "Notifications", aliases: ["alerts"] },
|
|
1019
|
+
{ id: "advanced", label: "Advanced", aliases: ["developer", "debug"] }
|
|
1020
|
+
];
|
|
1021
|
+
var lookup = null;
|
|
1022
|
+
function getLookup() {
|
|
1023
|
+
if (lookup)
|
|
1024
|
+
return lookup;
|
|
1025
|
+
const map = new Map;
|
|
1026
|
+
for (const section of SETTINGS_SECTIONS) {
|
|
1027
|
+
map.set(section.id, section);
|
|
1028
|
+
for (const alias of section.aliases ?? []) {
|
|
1029
|
+
map.set(alias, section);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
lookup = map;
|
|
1033
|
+
return map;
|
|
1034
|
+
}
|
|
1035
|
+
function getSettingsSections() {
|
|
1036
|
+
return [...SETTINGS_SECTIONS];
|
|
1037
|
+
}
|
|
1038
|
+
function getSettingsSectionChoices() {
|
|
1039
|
+
return SETTINGS_SECTIONS.map((section) => section.id);
|
|
1040
|
+
}
|
|
1041
|
+
function resolveSettingsSection(raw) {
|
|
1042
|
+
const normalized = raw.trim().toLowerCase();
|
|
1043
|
+
if (!normalized)
|
|
1044
|
+
return;
|
|
1045
|
+
return getLookup().get(normalized)?.id;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/navigation-commands.ts
|
|
1049
|
+
var IN_APP_SURFACES = ["gui", "tui"];
|
|
1050
|
+
var NAVIGATE_COMMANDS = [
|
|
1051
|
+
{
|
|
1052
|
+
key: "settings",
|
|
1053
|
+
nativeName: "settings",
|
|
1054
|
+
description: "Open agent settings",
|
|
1055
|
+
textAliases: ["/settings"],
|
|
1056
|
+
scope: "both",
|
|
1057
|
+
category: "docks",
|
|
1058
|
+
icon: "settings",
|
|
1059
|
+
target: { kind: "navigate", path: "/settings", tab: "settings" },
|
|
1060
|
+
acceptsArgs: true,
|
|
1061
|
+
args: [
|
|
1062
|
+
{
|
|
1063
|
+
name: "section",
|
|
1064
|
+
description: "Settings section to open",
|
|
1065
|
+
required: false,
|
|
1066
|
+
choices: getSettingsSectionChoices(),
|
|
1067
|
+
dynamicChoices: "settings-sections"
|
|
1068
|
+
}
|
|
1069
|
+
]
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
key: "chat",
|
|
1073
|
+
nativeName: "chat",
|
|
1074
|
+
description: "Return to the chat",
|
|
1075
|
+
textAliases: ["/chat"],
|
|
1076
|
+
scope: "both",
|
|
1077
|
+
category: "docks",
|
|
1078
|
+
icon: "message-circle",
|
|
1079
|
+
target: { kind: "navigate", path: "/chat", tab: "chat" }
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
key: "views",
|
|
1083
|
+
nativeName: "views",
|
|
1084
|
+
description: "Open the agent's views",
|
|
1085
|
+
textAliases: ["/views"],
|
|
1086
|
+
scope: "both",
|
|
1087
|
+
category: "docks",
|
|
1088
|
+
icon: "layout-grid",
|
|
1089
|
+
target: { kind: "navigate", path: "/views", tab: "views" },
|
|
1090
|
+
acceptsArgs: true,
|
|
1091
|
+
args: [
|
|
1092
|
+
{
|
|
1093
|
+
name: "view",
|
|
1094
|
+
description: "View to open",
|
|
1095
|
+
required: false,
|
|
1096
|
+
dynamicChoices: "views"
|
|
1097
|
+
}
|
|
1098
|
+
]
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
key: "orchestrator",
|
|
1102
|
+
nativeName: "orchestrator",
|
|
1103
|
+
description: "Open the agent orchestrator",
|
|
1104
|
+
textAliases: ["/orchestrator"],
|
|
1105
|
+
scope: "both",
|
|
1106
|
+
category: "docks",
|
|
1107
|
+
icon: "workflow",
|
|
1108
|
+
target: { kind: "navigate", path: "/orchestrator", viewId: "orchestrator" }
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
key: "character",
|
|
1112
|
+
nativeName: "character",
|
|
1113
|
+
description: "Open the character editor",
|
|
1114
|
+
textAliases: ["/character"],
|
|
1115
|
+
scope: "both",
|
|
1116
|
+
category: "docks",
|
|
1117
|
+
icon: "user",
|
|
1118
|
+
target: { kind: "navigate", path: "/character", tab: "character" }
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
key: "knowledge",
|
|
1122
|
+
nativeName: "knowledge",
|
|
1123
|
+
description: "Open the knowledge base",
|
|
1124
|
+
textAliases: ["/knowledge"],
|
|
1125
|
+
scope: "both",
|
|
1126
|
+
category: "docks",
|
|
1127
|
+
icon: "book-open",
|
|
1128
|
+
target: {
|
|
1129
|
+
kind: "navigate",
|
|
1130
|
+
path: "/character/documents",
|
|
1131
|
+
tab: "documents"
|
|
1132
|
+
}
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
key: "wallet",
|
|
1136
|
+
nativeName: "wallet",
|
|
1137
|
+
description: "Open the wallet & inventory",
|
|
1138
|
+
textAliases: ["/wallet"],
|
|
1139
|
+
scope: "both",
|
|
1140
|
+
category: "docks",
|
|
1141
|
+
icon: "wallet",
|
|
1142
|
+
target: { kind: "navigate", path: "/wallet", tab: "inventory" }
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
key: "automations",
|
|
1146
|
+
nativeName: "automations",
|
|
1147
|
+
description: "Open automations",
|
|
1148
|
+
textAliases: ["/automations"],
|
|
1149
|
+
scope: "both",
|
|
1150
|
+
category: "docks",
|
|
1151
|
+
icon: "zap",
|
|
1152
|
+
target: { kind: "navigate", path: "/automations", tab: "automations" }
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
key: "tasks",
|
|
1156
|
+
nativeName: "tasks",
|
|
1157
|
+
description: "Open tasks",
|
|
1158
|
+
textAliases: ["/tasks"],
|
|
1159
|
+
scope: "both",
|
|
1160
|
+
category: "docks",
|
|
1161
|
+
icon: "check-square",
|
|
1162
|
+
target: { kind: "navigate", path: "/apps/tasks", tab: "tasks" }
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
key: "skills",
|
|
1166
|
+
nativeName: "skills",
|
|
1167
|
+
description: "Open the skills library",
|
|
1168
|
+
textAliases: ["/skills"],
|
|
1169
|
+
scope: "both",
|
|
1170
|
+
category: "docks",
|
|
1171
|
+
icon: "sparkles",
|
|
1172
|
+
target: { kind: "navigate", path: "/apps/skills", tab: "skills" }
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
key: "plugins",
|
|
1176
|
+
nativeName: "plugins",
|
|
1177
|
+
description: "Open installed plugins",
|
|
1178
|
+
textAliases: ["/plugins"],
|
|
1179
|
+
scope: "both",
|
|
1180
|
+
category: "docks",
|
|
1181
|
+
icon: "plug",
|
|
1182
|
+
target: { kind: "navigate", path: "/apps/plugins", tab: "plugins" }
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
key: "logs",
|
|
1186
|
+
nativeName: "logs",
|
|
1187
|
+
description: "Open the logs",
|
|
1188
|
+
textAliases: ["/logs"],
|
|
1189
|
+
scope: "both",
|
|
1190
|
+
category: "docks",
|
|
1191
|
+
icon: "scroll-text",
|
|
1192
|
+
target: { kind: "navigate", path: "/apps/logs", tab: "logs" }
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
key: "database",
|
|
1196
|
+
nativeName: "database",
|
|
1197
|
+
description: "Open the database browser",
|
|
1198
|
+
textAliases: ["/database"],
|
|
1199
|
+
scope: "both",
|
|
1200
|
+
category: "docks",
|
|
1201
|
+
icon: "database",
|
|
1202
|
+
target: { kind: "navigate", path: "/apps/database", tab: "database" }
|
|
1203
|
+
}
|
|
1204
|
+
];
|
|
1205
|
+
var CLIENT_COMMANDS = [
|
|
1206
|
+
{
|
|
1207
|
+
key: "clear",
|
|
1208
|
+
nativeName: "clear",
|
|
1209
|
+
description: "Clear the current chat",
|
|
1210
|
+
textAliases: ["/clear"],
|
|
1211
|
+
scope: "both",
|
|
1212
|
+
category: "docks",
|
|
1213
|
+
icon: "eraser",
|
|
1214
|
+
surfaces: IN_APP_SURFACES,
|
|
1215
|
+
target: { kind: "client", clientAction: "clear-chat" }
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
key: "fullscreen",
|
|
1219
|
+
nativeName: "fullscreen",
|
|
1220
|
+
description: "Toggle full-screen chat",
|
|
1221
|
+
textAliases: ["/fullscreen"],
|
|
1222
|
+
scope: "both",
|
|
1223
|
+
category: "docks",
|
|
1224
|
+
icon: "maximize",
|
|
1225
|
+
surfaces: IN_APP_SURFACES,
|
|
1226
|
+
target: { kind: "client", clientAction: "toggle-fullscreen" }
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
key: "transcribe",
|
|
1230
|
+
nativeName: "transcribe",
|
|
1231
|
+
description: "Toggle long-form transcription mode (record-only; agent stays silent until an exit phrase)",
|
|
1232
|
+
textAliases: ["/transcribe"],
|
|
1233
|
+
scope: "both",
|
|
1234
|
+
category: "docks",
|
|
1235
|
+
icon: "mic",
|
|
1236
|
+
surfaces: IN_APP_SURFACES,
|
|
1237
|
+
target: { kind: "client", clientAction: "toggle-transcription" }
|
|
1238
|
+
}
|
|
1239
|
+
];
|
|
1240
|
+
var VIEW_SCOPED_COMMANDS = [
|
|
1241
|
+
{
|
|
1242
|
+
key: "calendar-add",
|
|
1243
|
+
nativeName: "calendar-add",
|
|
1244
|
+
description: "Add a calendar event (in the calendar view)",
|
|
1245
|
+
textAliases: ["/calendar-add"],
|
|
1246
|
+
scope: "both",
|
|
1247
|
+
category: "docks",
|
|
1248
|
+
icon: "calendar-plus",
|
|
1249
|
+
surfaces: IN_APP_SURFACES,
|
|
1250
|
+
views: ["calendar"],
|
|
1251
|
+
target: { kind: "agent" },
|
|
1252
|
+
acceptsArgs: true,
|
|
1253
|
+
args: [{ name: "event", description: "What to schedule", required: false }]
|
|
1254
|
+
},
|
|
1255
|
+
{
|
|
1256
|
+
key: "todos-add",
|
|
1257
|
+
nativeName: "todos-add",
|
|
1258
|
+
description: "Add a to-do (in the todos view)",
|
|
1259
|
+
textAliases: ["/todos-add"],
|
|
1260
|
+
scope: "both",
|
|
1261
|
+
category: "docks",
|
|
1262
|
+
icon: "list-plus",
|
|
1263
|
+
surfaces: IN_APP_SURFACES,
|
|
1264
|
+
views: ["todos"],
|
|
1265
|
+
target: { kind: "agent" },
|
|
1266
|
+
acceptsArgs: true,
|
|
1267
|
+
args: [{ name: "task", description: "What to do", required: false }]
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
key: "todos-done",
|
|
1271
|
+
nativeName: "todos-done",
|
|
1272
|
+
description: "Complete a to-do (in the todos view)",
|
|
1273
|
+
textAliases: ["/todos-done"],
|
|
1274
|
+
scope: "both",
|
|
1275
|
+
category: "docks",
|
|
1276
|
+
icon: "check",
|
|
1277
|
+
surfaces: IN_APP_SURFACES,
|
|
1278
|
+
views: ["todos"],
|
|
1279
|
+
target: { kind: "agent" },
|
|
1280
|
+
acceptsArgs: true,
|
|
1281
|
+
args: [
|
|
1282
|
+
{ name: "task", description: "Which to-do to complete", required: false }
|
|
1283
|
+
]
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
key: "documents-search",
|
|
1287
|
+
nativeName: "documents-search",
|
|
1288
|
+
description: "Search the knowledge base (in the documents view)",
|
|
1289
|
+
textAliases: ["/documents-search"],
|
|
1290
|
+
scope: "both",
|
|
1291
|
+
category: "docks",
|
|
1292
|
+
icon: "search",
|
|
1293
|
+
surfaces: IN_APP_SURFACES,
|
|
1294
|
+
views: ["documents"],
|
|
1295
|
+
target: { kind: "agent" },
|
|
1296
|
+
acceptsArgs: true,
|
|
1297
|
+
args: [
|
|
1298
|
+
{ name: "query", description: "What to search for", required: false }
|
|
1299
|
+
]
|
|
1300
|
+
}
|
|
1301
|
+
];
|
|
1302
|
+
function navigationCommandDefinitions() {
|
|
1303
|
+
return [...NAVIGATE_COMMANDS, ...CLIENT_COMMANDS, ...VIEW_SCOPED_COMMANDS];
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// src/serialize.ts
|
|
1307
|
+
var DEFAULT_TARGET = { kind: "agent" };
|
|
1308
|
+
function commandVisibleForSurface(surfaces, surface) {
|
|
1309
|
+
if (!surface)
|
|
1310
|
+
return true;
|
|
1311
|
+
if (!surfaces || surfaces.length === 0)
|
|
1312
|
+
return true;
|
|
1313
|
+
return surfaces.includes(surface);
|
|
1314
|
+
}
|
|
1315
|
+
function serializeArg(arg) {
|
|
1316
|
+
const serialized = {
|
|
1317
|
+
name: arg.name,
|
|
1318
|
+
description: arg.description
|
|
1319
|
+
};
|
|
1320
|
+
if (arg.required)
|
|
1321
|
+
serialized.required = true;
|
|
1322
|
+
if (arg.captureRemaining)
|
|
1323
|
+
serialized.captureRemaining = true;
|
|
1324
|
+
if (arg.dynamicChoices)
|
|
1325
|
+
serialized.dynamicChoices = arg.dynamicChoices;
|
|
1326
|
+
if (Array.isArray(arg.choices) && arg.choices.length > 0) {
|
|
1327
|
+
serialized.choices = arg.choices;
|
|
1328
|
+
}
|
|
1329
|
+
return serialized;
|
|
1330
|
+
}
|
|
1331
|
+
function serializeCommand(command, options = {}) {
|
|
1332
|
+
const args = (command.args ?? []).map(serializeArg);
|
|
1333
|
+
const serialized = {
|
|
1334
|
+
key: command.key,
|
|
1335
|
+
nativeName: command.nativeName ?? command.key,
|
|
1336
|
+
description: command.description,
|
|
1337
|
+
textAliases: command.textAliases,
|
|
1338
|
+
scope: command.scope,
|
|
1339
|
+
acceptsArgs: command.acceptsArgs ?? args.length > 0,
|
|
1340
|
+
args,
|
|
1341
|
+
requiresAuth: command.requiresAuth ?? false,
|
|
1342
|
+
requiresElevated: command.requiresElevated ?? false,
|
|
1343
|
+
target: command.target ?? DEFAULT_TARGET,
|
|
1344
|
+
source: options.source ?? "builtin"
|
|
1345
|
+
};
|
|
1346
|
+
if (command.category)
|
|
1347
|
+
serialized.category = command.category;
|
|
1348
|
+
if (command.surfaces && command.surfaces.length > 0) {
|
|
1349
|
+
serialized.surfaces = command.surfaces;
|
|
1350
|
+
}
|
|
1351
|
+
if (command.icon)
|
|
1352
|
+
serialized.icon = command.icon;
|
|
1353
|
+
if (command.views && command.views.length > 0) {
|
|
1354
|
+
serialized.views = command.views;
|
|
1355
|
+
}
|
|
1356
|
+
return serialized;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
// src/connector-catalog.ts
|
|
1360
|
+
var KNOWN_SURFACES = new Set([
|
|
1361
|
+
"gui",
|
|
1362
|
+
"tui",
|
|
1363
|
+
"discord",
|
|
1364
|
+
"telegram"
|
|
1365
|
+
]);
|
|
1366
|
+
function commandVisibleForView(views, activeViewId) {
|
|
1367
|
+
if (!views || views.length === 0)
|
|
1368
|
+
return true;
|
|
1369
|
+
if (!activeViewId)
|
|
1370
|
+
return false;
|
|
1371
|
+
return views.includes(activeViewId);
|
|
1372
|
+
}
|
|
1373
|
+
function isConnectorScoped(command) {
|
|
1374
|
+
return command.scope !== "text";
|
|
1375
|
+
}
|
|
1376
|
+
function commandName(command) {
|
|
1377
|
+
return command.nativeName ?? command.key;
|
|
1378
|
+
}
|
|
1379
|
+
function unifiedDefinitions(agentId) {
|
|
1380
|
+
const agentCommands = agentId ? getEnabledCommandsForRuntime(agentId) : DEFAULT_COMMANDS.filter((command) => command.enabled !== false);
|
|
1381
|
+
const agent = agentCommands.filter(isConnectorScoped);
|
|
1382
|
+
const navigation = navigationCommandDefinitions();
|
|
1383
|
+
const navigationNames = new Set(navigation.map(commandName));
|
|
1384
|
+
const agentOnly = agent.filter((command) => !navigationNames.has(commandName(command)));
|
|
1385
|
+
return [...agentOnly, ...navigation];
|
|
1386
|
+
}
|
|
1387
|
+
function normalizeSurface(surface) {
|
|
1388
|
+
return KNOWN_SURFACES.has(surface) ? surface : null;
|
|
1389
|
+
}
|
|
1390
|
+
function visibleDefinitions(surface, activeViewId, agentId) {
|
|
1391
|
+
const normalized = normalizeSurface(surface);
|
|
1392
|
+
return unifiedDefinitions(agentId).filter((command) => commandVisibleForSurface(command.surfaces, normalized)).filter((command) => commandVisibleForView(command.views, activeViewId));
|
|
1393
|
+
}
|
|
1394
|
+
function mapDefinitionArg(arg) {
|
|
1395
|
+
return {
|
|
1396
|
+
name: arg.name,
|
|
1397
|
+
description: arg.description,
|
|
1398
|
+
required: arg.required ?? false,
|
|
1399
|
+
choices: Array.isArray(arg.choices) ? arg.choices : []
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
function toConnectorCommand(command) {
|
|
1403
|
+
return {
|
|
1404
|
+
name: commandName(command),
|
|
1405
|
+
description: command.description,
|
|
1406
|
+
target: command.target ?? { kind: "agent" },
|
|
1407
|
+
options: (command.args ?? []).map(mapDefinitionArg),
|
|
1408
|
+
...command.views && command.views.length > 0 ? { views: command.views } : {}
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
function getConnectorCommands(surface, options = {}) {
|
|
1412
|
+
return visibleDefinitions(surface, options.activeViewId, options.agentId).map(toConnectorCommand);
|
|
1413
|
+
}
|
|
1414
|
+
function getCatalogCommands(surface, options = {}) {
|
|
1415
|
+
return visibleDefinitions(surface, options.activeViewId, options.agentId).map((command) => serializeCommand(command, options.source ? { source: options.source } : {}));
|
|
1416
|
+
}
|
|
1417
|
+
|
|
516
1418
|
// src/index.ts
|
|
517
1419
|
var commandRegistryProvider = {
|
|
518
1420
|
name: "COMMAND_REGISTRY",
|
|
@@ -524,10 +1426,9 @@ var commandRegistryProvider = {
|
|
|
524
1426
|
cacheStable: true,
|
|
525
1427
|
cacheScope: "agent",
|
|
526
1428
|
async get(runtime, message, _state) {
|
|
527
|
-
|
|
528
|
-
const text = message.content?.text ?? "";
|
|
1429
|
+
const text = message.content.text ?? "";
|
|
529
1430
|
const isCommand = hasCommand(text);
|
|
530
|
-
const commands =
|
|
1431
|
+
const commands = getEnabledCommandsForRuntime(runtime.agentId);
|
|
531
1432
|
if (isCommand) {
|
|
532
1433
|
const commandList = commands.map((cmd) => {
|
|
533
1434
|
const auth = cmd.requiresAuth ? " (requires auth)" : "";
|
|
@@ -579,14 +1480,15 @@ var commandsPlugin = {
|
|
|
579
1480
|
name: "commands",
|
|
580
1481
|
description: "Chat command system with /help, /status, /reset, etc.",
|
|
581
1482
|
providers: [commandRegistryProvider],
|
|
1483
|
+
actions: commandActions,
|
|
1484
|
+
shortcuts: commandShortcuts,
|
|
582
1485
|
autoEnable: {
|
|
583
1486
|
shouldEnable: (_env, config) => {
|
|
584
|
-
const f = config
|
|
1487
|
+
const f = config.features?.commands;
|
|
585
1488
|
return f === true || typeof f === "object" && f !== null && f.enabled !== false;
|
|
586
1489
|
}
|
|
587
1490
|
},
|
|
588
1491
|
config: {
|
|
589
|
-
COMMANDS_ENABLED: "true",
|
|
590
1492
|
COMMANDS_CONFIG_ENABLED: "false",
|
|
591
1493
|
COMMANDS_DEBUG_ENABLED: "false",
|
|
592
1494
|
COMMANDS_BASH_ENABLED: "false",
|
|
@@ -621,8 +1523,8 @@ var commandsPlugin = {
|
|
|
621
1523
|
if (detection.command?.key !== "think") {
|
|
622
1524
|
throw new Error(`Expected key 'think', got '${detection.command?.key}'`);
|
|
623
1525
|
}
|
|
624
|
-
if (detection.command
|
|
625
|
-
throw new Error(`Expected arg 'high', got '${detection.command
|
|
1526
|
+
if (detection.command.args[0] !== "high") {
|
|
1527
|
+
throw new Error(`Expected arg 'high', got '${detection.command.args[0]}'`);
|
|
626
1528
|
}
|
|
627
1529
|
logger.success("Command argument parsing works correctly");
|
|
628
1530
|
}
|
|
@@ -758,27 +1660,60 @@ export {
|
|
|
758
1660
|
useRuntime,
|
|
759
1661
|
unregisterCommand,
|
|
760
1662
|
startsWithCommand,
|
|
1663
|
+
setCommandSetting,
|
|
1664
|
+
serializeCommand,
|
|
1665
|
+
runCommand,
|
|
1666
|
+
resolveSettingsSection,
|
|
1667
|
+
resolveConnectorCommandAuth,
|
|
1668
|
+
resolveCommand,
|
|
761
1669
|
resetCommands,
|
|
762
1670
|
registerCommands,
|
|
763
1671
|
registerCommand,
|
|
764
1672
|
parseCommand,
|
|
765
1673
|
normalizeCommandBody,
|
|
1674
|
+
navigationCommandDefinitions,
|
|
1675
|
+
naturalShortcuts,
|
|
766
1676
|
isElevated,
|
|
1677
|
+
isDeterministicCommand,
|
|
767
1678
|
isCommandOnly,
|
|
768
1679
|
isAuthorized,
|
|
769
1680
|
initForRuntime,
|
|
770
1681
|
hasCommand,
|
|
1682
|
+
getSettingsSections,
|
|
1683
|
+
getSettingsSectionChoices,
|
|
1684
|
+
getEnabledCommandsForRuntime,
|
|
771
1685
|
getEnabledCommands,
|
|
1686
|
+
getConnectorCommands,
|
|
1687
|
+
getCommandsForRuntime,
|
|
1688
|
+
getCommandsByCategoryForRuntime,
|
|
772
1689
|
getCommandsByCategory,
|
|
773
1690
|
getCommands,
|
|
1691
|
+
getCommandSettings,
|
|
1692
|
+
getCatalogCommands,
|
|
1693
|
+
gateConnectorCommandByName,
|
|
1694
|
+
gateConnectorCommand,
|
|
774
1695
|
formatCommandResult,
|
|
1696
|
+
findCommandByKeyForRuntime,
|
|
775
1697
|
findCommandByKey,
|
|
1698
|
+
findCommandByAliasForRuntime,
|
|
776
1699
|
findCommandByAlias,
|
|
777
1700
|
extractCommand,
|
|
1701
|
+
explicitCommandShortcuts,
|
|
1702
|
+
dispatchCommandMessage,
|
|
778
1703
|
detectCommand,
|
|
779
1704
|
src_default as default,
|
|
1705
|
+
createCommandShortcuts,
|
|
1706
|
+
createCommandActions,
|
|
780
1707
|
commandsPlugin,
|
|
781
|
-
|
|
1708
|
+
commandVisibleForView,
|
|
1709
|
+
commandVisibleForSurface,
|
|
1710
|
+
commandShortcuts,
|
|
1711
|
+
commandRegistryProvider,
|
|
1712
|
+
commandActions,
|
|
1713
|
+
clearCommandSettings,
|
|
1714
|
+
DETERMINISTIC_COMMAND_KEYS,
|
|
1715
|
+
DEFAULT_COMMANDS,
|
|
1716
|
+
COMMAND_SETTING_CHOICES
|
|
782
1717
|
};
|
|
783
1718
|
|
|
784
|
-
//# debugId=
|
|
1719
|
+
//# debugId=0416CA3D9EF6001864756E2164756E21
|