@elizaos/plugin-commands 2.0.0-alpha.9 → 2.0.11-beta.7
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 +24 -0
- package/package.json +115 -97
- package/dist/cjs/index.cjs +0 -1214
- package/dist/cjs/index.cjs.map +0 -17
- package/dist/index.js +0 -1176
- package/dist/index.js.map +0 -17
package/dist/index.js
DELETED
|
@@ -1,1176 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
import {
|
|
3
|
-
logger as logger3
|
|
4
|
-
} from "@elizaos/core";
|
|
5
|
-
|
|
6
|
-
// src/registry.ts
|
|
7
|
-
var DEFAULT_COMMANDS = [
|
|
8
|
-
{
|
|
9
|
-
key: "help",
|
|
10
|
-
nativeName: "help",
|
|
11
|
-
description: "Show available commands",
|
|
12
|
-
textAliases: ["/help", "/h", "/?"],
|
|
13
|
-
scope: "both",
|
|
14
|
-
category: "status",
|
|
15
|
-
acceptsArgs: false
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
key: "commands",
|
|
19
|
-
nativeName: "commands",
|
|
20
|
-
description: "List all commands",
|
|
21
|
-
textAliases: ["/commands", "/cmds"],
|
|
22
|
-
scope: "both",
|
|
23
|
-
category: "status",
|
|
24
|
-
acceptsArgs: false
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
key: "status",
|
|
28
|
-
nativeName: "status",
|
|
29
|
-
description: "Show current session status",
|
|
30
|
-
textAliases: ["/status", "/s"],
|
|
31
|
-
scope: "both",
|
|
32
|
-
category: "status",
|
|
33
|
-
acceptsArgs: false
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
key: "context",
|
|
37
|
-
nativeName: "context",
|
|
38
|
-
description: "Show current context information",
|
|
39
|
-
textAliases: ["/context", "/ctx"],
|
|
40
|
-
scope: "both",
|
|
41
|
-
category: "status",
|
|
42
|
-
acceptsArgs: true,
|
|
43
|
-
args: [{ name: "mode", description: "Output mode (list, detail, json)" }]
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
key: "whoami",
|
|
47
|
-
nativeName: "whoami",
|
|
48
|
-
description: "Show your identity information",
|
|
49
|
-
textAliases: ["/whoami", "/who"],
|
|
50
|
-
scope: "both",
|
|
51
|
-
category: "status",
|
|
52
|
-
acceptsArgs: false
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
key: "stop",
|
|
56
|
-
nativeName: "stop",
|
|
57
|
-
description: "Stop current operation",
|
|
58
|
-
textAliases: ["/stop", "/abort", "/cancel"],
|
|
59
|
-
scope: "both",
|
|
60
|
-
category: "session",
|
|
61
|
-
acceptsArgs: false
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
key: "restart",
|
|
65
|
-
nativeName: "restart",
|
|
66
|
-
description: "Restart the session",
|
|
67
|
-
textAliases: ["/restart"],
|
|
68
|
-
scope: "both",
|
|
69
|
-
category: "session",
|
|
70
|
-
acceptsArgs: false,
|
|
71
|
-
requiresAuth: true
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
key: "reset",
|
|
75
|
-
nativeName: "reset",
|
|
76
|
-
description: "Reset session state",
|
|
77
|
-
textAliases: ["/reset"],
|
|
78
|
-
scope: "both",
|
|
79
|
-
category: "session",
|
|
80
|
-
acceptsArgs: false,
|
|
81
|
-
requiresAuth: true
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
key: "new",
|
|
85
|
-
nativeName: "new",
|
|
86
|
-
description: "Start a new conversation",
|
|
87
|
-
textAliases: ["/new"],
|
|
88
|
-
scope: "both",
|
|
89
|
-
category: "session",
|
|
90
|
-
acceptsArgs: false
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
key: "compact",
|
|
94
|
-
nativeName: "compact",
|
|
95
|
-
description: "Compact conversation history",
|
|
96
|
-
textAliases: ["/compact"],
|
|
97
|
-
scope: "both",
|
|
98
|
-
category: "session",
|
|
99
|
-
acceptsArgs: true,
|
|
100
|
-
args: [
|
|
101
|
-
{ name: "instructions", description: "Optional compaction instructions" }
|
|
102
|
-
]
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
key: "think",
|
|
106
|
-
nativeName: "think",
|
|
107
|
-
description: "Set thinking level",
|
|
108
|
-
textAliases: ["/think", "/thinking", "/t"],
|
|
109
|
-
scope: "both",
|
|
110
|
-
category: "options",
|
|
111
|
-
acceptsArgs: true,
|
|
112
|
-
args: [
|
|
113
|
-
{ name: "level", description: "off, minimal, low, medium, high, xhigh" }
|
|
114
|
-
]
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
key: "verbose",
|
|
118
|
-
nativeName: "verbose",
|
|
119
|
-
description: "Set verbose output level",
|
|
120
|
-
textAliases: ["/verbose", "/v"],
|
|
121
|
-
scope: "both",
|
|
122
|
-
category: "options",
|
|
123
|
-
acceptsArgs: true,
|
|
124
|
-
args: [{ name: "level", description: "off, on, full" }]
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
key: "reasoning",
|
|
128
|
-
nativeName: "reasoning",
|
|
129
|
-
description: "Set reasoning visibility",
|
|
130
|
-
textAliases: ["/reasoning", "/reason"],
|
|
131
|
-
scope: "both",
|
|
132
|
-
category: "options",
|
|
133
|
-
acceptsArgs: true,
|
|
134
|
-
args: [{ name: "level", description: "off, on, stream" }]
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
key: "elevated",
|
|
138
|
-
nativeName: "elevated",
|
|
139
|
-
description: "Set elevated permission mode",
|
|
140
|
-
textAliases: ["/elevated", "/elev"],
|
|
141
|
-
scope: "both",
|
|
142
|
-
category: "options",
|
|
143
|
-
acceptsArgs: true,
|
|
144
|
-
args: [{ name: "level", description: "off, on, ask, full" }],
|
|
145
|
-
requiresAuth: true
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
key: "model",
|
|
149
|
-
nativeName: "model",
|
|
150
|
-
description: "Set or show current model",
|
|
151
|
-
textAliases: ["/model", "/m"],
|
|
152
|
-
scope: "both",
|
|
153
|
-
category: "options",
|
|
154
|
-
acceptsArgs: true,
|
|
155
|
-
args: [{ name: "model", description: "provider/model or alias" }]
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
key: "models",
|
|
159
|
-
nativeName: "models",
|
|
160
|
-
description: "List available models",
|
|
161
|
-
textAliases: ["/models"],
|
|
162
|
-
scope: "both",
|
|
163
|
-
category: "options",
|
|
164
|
-
acceptsArgs: false
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
key: "usage",
|
|
168
|
-
nativeName: "usage",
|
|
169
|
-
description: "Show token usage",
|
|
170
|
-
textAliases: ["/usage"],
|
|
171
|
-
scope: "both",
|
|
172
|
-
category: "options",
|
|
173
|
-
acceptsArgs: false
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
key: "queue",
|
|
177
|
-
nativeName: "queue",
|
|
178
|
-
description: "Set queue mode",
|
|
179
|
-
textAliases: ["/queue", "/q"],
|
|
180
|
-
scope: "both",
|
|
181
|
-
category: "options",
|
|
182
|
-
acceptsArgs: true,
|
|
183
|
-
args: [
|
|
184
|
-
{
|
|
185
|
-
name: "mode",
|
|
186
|
-
description: "steer, followup, collect, interrupt, or options"
|
|
187
|
-
}
|
|
188
|
-
]
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
key: "allowlist",
|
|
192
|
-
nativeName: "allowlist",
|
|
193
|
-
description: "Manage sender allowlist",
|
|
194
|
-
textAliases: ["/allowlist", "/allow"],
|
|
195
|
-
scope: "both",
|
|
196
|
-
category: "management",
|
|
197
|
-
acceptsArgs: true,
|
|
198
|
-
args: [
|
|
199
|
-
{ name: "action", description: "list, add, remove" },
|
|
200
|
-
{ name: "value", description: "sender to add/remove" }
|
|
201
|
-
],
|
|
202
|
-
requiresAuth: true
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
key: "approve",
|
|
206
|
-
nativeName: "approve",
|
|
207
|
-
description: "Approve or deny a pending action",
|
|
208
|
-
textAliases: ["/approve"],
|
|
209
|
-
scope: "both",
|
|
210
|
-
category: "management",
|
|
211
|
-
acceptsArgs: true,
|
|
212
|
-
args: [
|
|
213
|
-
{ name: "id", description: "Approval ID", required: true },
|
|
214
|
-
{ name: "action", description: "allow-once, allow-always, deny" }
|
|
215
|
-
],
|
|
216
|
-
requiresAuth: true
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
key: "subagents",
|
|
220
|
-
nativeName: "subagents",
|
|
221
|
-
description: "Manage subagents",
|
|
222
|
-
textAliases: ["/subagents", "/sub"],
|
|
223
|
-
scope: "both",
|
|
224
|
-
category: "management",
|
|
225
|
-
acceptsArgs: true,
|
|
226
|
-
args: [{ name: "action", description: "list, stop, log, info, send" }],
|
|
227
|
-
requiresAuth: true
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
key: "config",
|
|
231
|
-
nativeName: "config",
|
|
232
|
-
description: "View or set configuration",
|
|
233
|
-
textAliases: ["/config", "/cfg"],
|
|
234
|
-
scope: "both",
|
|
235
|
-
category: "management",
|
|
236
|
-
acceptsArgs: true,
|
|
237
|
-
args: [
|
|
238
|
-
{ name: "key", description: "Configuration key" },
|
|
239
|
-
{ name: "value", description: "Value to set" }
|
|
240
|
-
],
|
|
241
|
-
requiresAuth: true,
|
|
242
|
-
enabled: false
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
key: "debug",
|
|
246
|
-
nativeName: "debug",
|
|
247
|
-
description: "Debug information",
|
|
248
|
-
textAliases: ["/debug"],
|
|
249
|
-
scope: "both",
|
|
250
|
-
category: "management",
|
|
251
|
-
acceptsArgs: true,
|
|
252
|
-
requiresAuth: true,
|
|
253
|
-
enabled: false
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
key: "tts",
|
|
257
|
-
nativeName: "tts",
|
|
258
|
-
description: "Text-to-speech settings",
|
|
259
|
-
textAliases: ["/tts", "/voice"],
|
|
260
|
-
scope: "both",
|
|
261
|
-
category: "media",
|
|
262
|
-
acceptsArgs: true,
|
|
263
|
-
args: [
|
|
264
|
-
{
|
|
265
|
-
name: "action",
|
|
266
|
-
description: "on, off, status, provider, limit, audio"
|
|
267
|
-
}
|
|
268
|
-
]
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
key: "bash",
|
|
272
|
-
nativeName: "bash",
|
|
273
|
-
description: "Execute shell command",
|
|
274
|
-
textAliases: ["/bash", "/sh", "/!"],
|
|
275
|
-
scope: "text",
|
|
276
|
-
category: "tools",
|
|
277
|
-
acceptsArgs: true,
|
|
278
|
-
args: [
|
|
279
|
-
{
|
|
280
|
-
name: "command",
|
|
281
|
-
description: "Shell command to execute",
|
|
282
|
-
captureRemaining: true
|
|
283
|
-
}
|
|
284
|
-
],
|
|
285
|
-
requiresAuth: true,
|
|
286
|
-
requiresElevated: true
|
|
287
|
-
}
|
|
288
|
-
];
|
|
289
|
-
var runtimeStores = new Map;
|
|
290
|
-
var fallbackStore = {
|
|
291
|
-
commands: DEFAULT_COMMANDS.map((c) => ({ ...c })),
|
|
292
|
-
aliasMap: null
|
|
293
|
-
};
|
|
294
|
-
var activeStore = fallbackStore;
|
|
295
|
-
function initForRuntime(agentId) {
|
|
296
|
-
const store = {
|
|
297
|
-
commands: DEFAULT_COMMANDS.map((c) => ({ ...c })),
|
|
298
|
-
aliasMap: null
|
|
299
|
-
};
|
|
300
|
-
runtimeStores.set(agentId, store);
|
|
301
|
-
activeStore = store;
|
|
302
|
-
}
|
|
303
|
-
function useRuntime(agentId) {
|
|
304
|
-
const store = runtimeStores.get(agentId);
|
|
305
|
-
if (store) {
|
|
306
|
-
activeStore = store;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
function getCommands() {
|
|
310
|
-
return [...activeStore.commands];
|
|
311
|
-
}
|
|
312
|
-
function getEnabledCommands() {
|
|
313
|
-
return activeStore.commands.filter((cmd) => cmd.enabled !== false);
|
|
314
|
-
}
|
|
315
|
-
function getCommandsByCategory(category) {
|
|
316
|
-
return activeStore.commands.filter((cmd) => cmd.category === category && cmd.enabled !== false);
|
|
317
|
-
}
|
|
318
|
-
function registerCommand(command) {
|
|
319
|
-
activeStore.commands = activeStore.commands.filter((c) => c.key !== command.key);
|
|
320
|
-
activeStore.commands.push(command);
|
|
321
|
-
activeStore.aliasMap = null;
|
|
322
|
-
}
|
|
323
|
-
function registerCommands(newCommands) {
|
|
324
|
-
for (const command of newCommands) {
|
|
325
|
-
registerCommand(command);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
function unregisterCommand(key) {
|
|
329
|
-
activeStore.commands = activeStore.commands.filter((c) => c.key !== key);
|
|
330
|
-
activeStore.aliasMap = null;
|
|
331
|
-
}
|
|
332
|
-
function resetCommands() {
|
|
333
|
-
activeStore.commands = DEFAULT_COMMANDS.map((c) => ({ ...c }));
|
|
334
|
-
activeStore.aliasMap = null;
|
|
335
|
-
}
|
|
336
|
-
function getAliasMap() {
|
|
337
|
-
if (activeStore.aliasMap)
|
|
338
|
-
return activeStore.aliasMap;
|
|
339
|
-
activeStore.aliasMap = new Map;
|
|
340
|
-
for (const command of activeStore.commands) {
|
|
341
|
-
if (command.enabled === false)
|
|
342
|
-
continue;
|
|
343
|
-
for (const alias of command.textAliases) {
|
|
344
|
-
const normalized = alias.toLowerCase().trim();
|
|
345
|
-
if (!activeStore.aliasMap.has(normalized)) {
|
|
346
|
-
activeStore.aliasMap.set(normalized, command);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
return activeStore.aliasMap;
|
|
351
|
-
}
|
|
352
|
-
function findCommandByAlias(alias) {
|
|
353
|
-
const map = getAliasMap();
|
|
354
|
-
return map.get(alias.toLowerCase().trim());
|
|
355
|
-
}
|
|
356
|
-
function findCommandByKey(key) {
|
|
357
|
-
return activeStore.commands.find((c) => c.key === key);
|
|
358
|
-
}
|
|
359
|
-
function startsWithCommand(text) {
|
|
360
|
-
const map = getAliasMap();
|
|
361
|
-
const normalized = text.toLowerCase().trim();
|
|
362
|
-
for (const [alias, command] of map) {
|
|
363
|
-
if (normalized === alias) {
|
|
364
|
-
return command;
|
|
365
|
-
}
|
|
366
|
-
if (normalized.startsWith(`${alias} `) || normalized.startsWith(`${alias}:`)) {
|
|
367
|
-
return command;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// src/parser.ts
|
|
374
|
-
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
375
|
-
function hasCommand(text) {
|
|
376
|
-
if (!text)
|
|
377
|
-
return false;
|
|
378
|
-
const trimmed = text.trim();
|
|
379
|
-
if (!trimmed.startsWith("/") && !trimmed.startsWith("!"))
|
|
380
|
-
return false;
|
|
381
|
-
return Boolean(startsWithCommand(trimmed));
|
|
382
|
-
}
|
|
383
|
-
function detectCommand(text) {
|
|
384
|
-
if (!text) {
|
|
385
|
-
return { isCommand: false };
|
|
386
|
-
}
|
|
387
|
-
const trimmed = text.trim();
|
|
388
|
-
if (!trimmed.startsWith("/") && !trimmed.startsWith("!")) {
|
|
389
|
-
return { isCommand: false };
|
|
390
|
-
}
|
|
391
|
-
const command = startsWithCommand(trimmed);
|
|
392
|
-
if (!command) {
|
|
393
|
-
return { isCommand: false };
|
|
394
|
-
}
|
|
395
|
-
const parsed = parseCommand(trimmed, command);
|
|
396
|
-
if (!parsed) {
|
|
397
|
-
return { isCommand: false };
|
|
398
|
-
}
|
|
399
|
-
return { isCommand: true, command: parsed };
|
|
400
|
-
}
|
|
401
|
-
function parseCommand(text, definition) {
|
|
402
|
-
const trimmed = text.trim();
|
|
403
|
-
let matchedAlias = null;
|
|
404
|
-
for (const alias of definition.textAliases) {
|
|
405
|
-
const normalized = alias.toLowerCase();
|
|
406
|
-
if (trimmed.toLowerCase() === normalized) {
|
|
407
|
-
matchedAlias = alias;
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
if (trimmed.toLowerCase().startsWith(`${normalized} `) || trimmed.toLowerCase().startsWith(`${normalized}:`)) {
|
|
411
|
-
matchedAlias = alias;
|
|
412
|
-
break;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (!matchedAlias) {
|
|
416
|
-
return null;
|
|
417
|
-
}
|
|
418
|
-
let rawArgs = trimmed.slice(matchedAlias.length).trim();
|
|
419
|
-
if (rawArgs.startsWith(":")) {
|
|
420
|
-
rawArgs = rawArgs.slice(1).trim();
|
|
421
|
-
}
|
|
422
|
-
const args = parseArgs(rawArgs, definition);
|
|
423
|
-
return {
|
|
424
|
-
key: definition.key,
|
|
425
|
-
canonical: definition.textAliases[0] ?? `/${definition.key}`,
|
|
426
|
-
args,
|
|
427
|
-
rawArgs: rawArgs || undefined
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
function parseArgs(rawArgs, definition) {
|
|
431
|
-
if (!rawArgs || !definition.acceptsArgs) {
|
|
432
|
-
return [];
|
|
433
|
-
}
|
|
434
|
-
const parsing = definition.argsParsing ?? "positional";
|
|
435
|
-
if (parsing === "none") {
|
|
436
|
-
return rawArgs ? [rawArgs] : [];
|
|
437
|
-
}
|
|
438
|
-
const args = [];
|
|
439
|
-
const argDefs = definition.args ?? [];
|
|
440
|
-
const tokens = tokenize(rawArgs);
|
|
441
|
-
for (let i = 0;i < tokens.length; i++) {
|
|
442
|
-
const argDef = argDefs[i];
|
|
443
|
-
if (argDef?.captureRemaining) {
|
|
444
|
-
args.push(tokens.slice(i).join(" "));
|
|
445
|
-
break;
|
|
446
|
-
}
|
|
447
|
-
args.push(tokens[i]);
|
|
448
|
-
}
|
|
449
|
-
return args;
|
|
450
|
-
}
|
|
451
|
-
function tokenize(input) {
|
|
452
|
-
const tokens = [];
|
|
453
|
-
let current = "";
|
|
454
|
-
let inQuote = false;
|
|
455
|
-
let quoteChar = "";
|
|
456
|
-
for (let i = 0;i < input.length; i++) {
|
|
457
|
-
const char = input[i];
|
|
458
|
-
if (inQuote) {
|
|
459
|
-
if (char === quoteChar) {
|
|
460
|
-
inQuote = false;
|
|
461
|
-
if (current) {
|
|
462
|
-
tokens.push(current);
|
|
463
|
-
current = "";
|
|
464
|
-
}
|
|
465
|
-
} else {
|
|
466
|
-
current += char;
|
|
467
|
-
}
|
|
468
|
-
} else if (char === '"' || char === "'") {
|
|
469
|
-
inQuote = true;
|
|
470
|
-
quoteChar = char;
|
|
471
|
-
} else if (/\s/.test(char)) {
|
|
472
|
-
if (current) {
|
|
473
|
-
tokens.push(current);
|
|
474
|
-
current = "";
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
current += char;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
if (current) {
|
|
481
|
-
tokens.push(current);
|
|
482
|
-
}
|
|
483
|
-
return tokens;
|
|
484
|
-
}
|
|
485
|
-
function normalizeCommandBody(text, botMention) {
|
|
486
|
-
let normalized = text.trim();
|
|
487
|
-
if (botMention) {
|
|
488
|
-
const mentionPattern = new RegExp(`^@${escapeRegExp(botMention)}\\s*`, "i");
|
|
489
|
-
normalized = normalized.replace(mentionPattern, "");
|
|
490
|
-
}
|
|
491
|
-
normalized = normalized.replace(/^(\/\w+):\s*/, "$1 ");
|
|
492
|
-
return normalized.trim();
|
|
493
|
-
}
|
|
494
|
-
function isCommandOnly(text) {
|
|
495
|
-
const detection = detectCommand(text);
|
|
496
|
-
if (!detection.isCommand || !detection.command) {
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
if (!detection.command.rawArgs) {
|
|
500
|
-
return true;
|
|
501
|
-
}
|
|
502
|
-
return detection.command.rawArgs.trim().length === 0;
|
|
503
|
-
}
|
|
504
|
-
function extractCommand(text) {
|
|
505
|
-
const detection = detectCommand(text);
|
|
506
|
-
if (!detection.isCommand || !detection.command) {
|
|
507
|
-
return null;
|
|
508
|
-
}
|
|
509
|
-
const { command } = detection;
|
|
510
|
-
if (!command.rawArgs) {
|
|
511
|
-
return { command, remainingText: "" };
|
|
512
|
-
}
|
|
513
|
-
return { command, remainingText: command.rawArgs };
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// src/actions/commands-list.ts
|
|
517
|
-
var commandsListAction = {
|
|
518
|
-
name: "COMMANDS_LIST",
|
|
519
|
-
description: "List all available commands with their aliases. Only activates for /commands or /cmds slash commands.",
|
|
520
|
-
similes: ["/commands", "/cmds"],
|
|
521
|
-
validate: async (runtime, message) => {
|
|
522
|
-
const textRaw = message.content?.text ?? "";
|
|
523
|
-
const text = textRaw.toLowerCase();
|
|
524
|
-
const hasKeyword = text.includes("/commands") || text.includes("/cmds") || text.includes("commands");
|
|
525
|
-
const hasRegex = /^(?:\/|!)\s*(?:commands|cmds)\b/i.test(textRaw);
|
|
526
|
-
const hasContext = Boolean(runtime?.agentId || message?.roomId || message?.content);
|
|
527
|
-
const hasInput = textRaw.trim().length > 0;
|
|
528
|
-
if (!(hasKeyword && hasRegex && hasContext && hasInput)) {
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
531
|
-
const detection = detectCommand(textRaw);
|
|
532
|
-
return detection.isCommand && detection.command?.key === "commands";
|
|
533
|
-
},
|
|
534
|
-
async handler(_runtime, _message, _state, _options, callback) {
|
|
535
|
-
const commands = getEnabledCommands();
|
|
536
|
-
const lines = [`**Commands (${commands.length}):**
|
|
537
|
-
`];
|
|
538
|
-
for (const cmd of commands) {
|
|
539
|
-
const aliases = cmd.textAliases.join(", ");
|
|
540
|
-
const authNote = cmd.requiresAuth ? " [auth]" : "";
|
|
541
|
-
const elevatedNote = cmd.requiresElevated ? " [elevated]" : "";
|
|
542
|
-
lines.push(`• **${cmd.key}**: ${aliases}${authNote}${elevatedNote}`);
|
|
543
|
-
}
|
|
544
|
-
const replyText = lines.join(`
|
|
545
|
-
`);
|
|
546
|
-
await callback?.({ text: replyText });
|
|
547
|
-
return {
|
|
548
|
-
success: true,
|
|
549
|
-
text: replyText,
|
|
550
|
-
data: { commandCount: commands.length }
|
|
551
|
-
};
|
|
552
|
-
},
|
|
553
|
-
examples: [
|
|
554
|
-
[
|
|
555
|
-
{ name: "user", content: { text: "/commands" } },
|
|
556
|
-
{
|
|
557
|
-
name: "assistant",
|
|
558
|
-
content: {
|
|
559
|
-
text: `**Commands (15):**
|
|
560
|
-
|
|
561
|
-
• **help**: /help, /h, /?
|
|
562
|
-
• **status**: /status, /s...`
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
]
|
|
566
|
-
]
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
// src/actions/help.ts
|
|
570
|
-
function formatCommandList(commands) {
|
|
571
|
-
const lines = [`**Available Commands:**
|
|
572
|
-
`];
|
|
573
|
-
const categories = [
|
|
574
|
-
{ key: "status", name: "Status" },
|
|
575
|
-
{ key: "session", name: "Session" },
|
|
576
|
-
{ key: "options", name: "Options" },
|
|
577
|
-
{ key: "management", name: "Management" },
|
|
578
|
-
{ key: "media", name: "Media" },
|
|
579
|
-
{ key: "tools", name: "Tools" }
|
|
580
|
-
];
|
|
581
|
-
for (const cat of categories) {
|
|
582
|
-
const catCommands = commands.filter((c) => c.category === cat.key);
|
|
583
|
-
if (catCommands.length === 0)
|
|
584
|
-
continue;
|
|
585
|
-
lines.push(`
|
|
586
|
-
**${cat.name}:**`);
|
|
587
|
-
for (const cmd of catCommands) {
|
|
588
|
-
const aliases = cmd.textAliases.slice(0, 2).join(", ");
|
|
589
|
-
lines.push(`• ${aliases} - ${cmd.description}`);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
const uncategorized = commands.filter((c) => !c.category);
|
|
593
|
-
if (uncategorized.length > 0) {
|
|
594
|
-
lines.push(`
|
|
595
|
-
**Other:**`);
|
|
596
|
-
for (const cmd of uncategorized) {
|
|
597
|
-
const aliases = cmd.textAliases.slice(0, 2).join(", ");
|
|
598
|
-
lines.push(`• ${aliases} - ${cmd.description}`);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
return lines.join(`
|
|
602
|
-
`);
|
|
603
|
-
}
|
|
604
|
-
var helpAction = {
|
|
605
|
-
name: "HELP_COMMAND",
|
|
606
|
-
description: "Show available commands and their descriptions. Only activates for /help, /h, or /? slash commands.",
|
|
607
|
-
similes: ["/help", "/h", "/?"],
|
|
608
|
-
validate: async (runtime, message) => {
|
|
609
|
-
const textRaw = message.content?.text ?? "";
|
|
610
|
-
const text = textRaw.toLowerCase();
|
|
611
|
-
const hasKeyword = text.includes("/help") || text.includes("/h") || text.includes("/?");
|
|
612
|
-
const hasRegex = /^(?:\/|!)\s*(?:help|h|\?)(?:\s|$|:)/i.test(textRaw);
|
|
613
|
-
const hasContext = Boolean(runtime?.agentId || message?.roomId || message?.content);
|
|
614
|
-
const hasInput = textRaw.trim().length > 0;
|
|
615
|
-
if (!(hasKeyword && hasRegex && hasContext && hasInput)) {
|
|
616
|
-
return false;
|
|
617
|
-
}
|
|
618
|
-
const detection = detectCommand(textRaw);
|
|
619
|
-
return detection.isCommand && detection.command?.key === "help";
|
|
620
|
-
},
|
|
621
|
-
async handler(_runtime, message, _state, _options, callback) {
|
|
622
|
-
const detection = detectCommand(message?.content?.text ?? "");
|
|
623
|
-
if (!detection.isCommand || detection.command?.key !== "help") {
|
|
624
|
-
return { success: false, text: "" };
|
|
625
|
-
}
|
|
626
|
-
const commands = getEnabledCommands();
|
|
627
|
-
const helpText = formatCommandList(commands);
|
|
628
|
-
await callback?.({ text: helpText });
|
|
629
|
-
return {
|
|
630
|
-
success: true,
|
|
631
|
-
text: helpText,
|
|
632
|
-
data: { commandCount: commands.length }
|
|
633
|
-
};
|
|
634
|
-
},
|
|
635
|
-
examples: [
|
|
636
|
-
[
|
|
637
|
-
{ name: "user", content: { text: "/help" } },
|
|
638
|
-
{
|
|
639
|
-
name: "assistant",
|
|
640
|
-
content: {
|
|
641
|
-
text: `**Available Commands:**
|
|
642
|
-
|
|
643
|
-
**Status:**
|
|
644
|
-
• /help - Show available commands...`
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
],
|
|
648
|
-
[
|
|
649
|
-
{ name: "user", content: { text: "/?" } },
|
|
650
|
-
{
|
|
651
|
-
name: "assistant",
|
|
652
|
-
content: {
|
|
653
|
-
text: `**Available Commands:**
|
|
654
|
-
|
|
655
|
-
**Status:**
|
|
656
|
-
• /help - Show available commands...`
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
]
|
|
660
|
-
]
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
// src/actions/models.ts
|
|
664
|
-
import { logger, ModelType } from "@elizaos/core";
|
|
665
|
-
function describeModelType(modelType) {
|
|
666
|
-
const descriptions = {
|
|
667
|
-
[ModelType.TEXT_SMALL]: "Text (Small)",
|
|
668
|
-
[ModelType.TEXT_LARGE]: "Text (Large)",
|
|
669
|
-
[ModelType.TEXT_REASONING_SMALL]: "Reasoning (Small)",
|
|
670
|
-
[ModelType.TEXT_REASONING_LARGE]: "Reasoning (Large)",
|
|
671
|
-
[ModelType.TEXT_COMPLETION]: "Text Completion",
|
|
672
|
-
[ModelType.TEXT_EMBEDDING]: "Embedding",
|
|
673
|
-
[ModelType.IMAGE]: "Image Generation",
|
|
674
|
-
[ModelType.IMAGE_DESCRIPTION]: "Image Description",
|
|
675
|
-
[ModelType.TRANSCRIPTION]: "Transcription",
|
|
676
|
-
[ModelType.TEXT_TO_SPEECH]: "Text-to-Speech",
|
|
677
|
-
[ModelType.AUDIO]: "Audio",
|
|
678
|
-
[ModelType.VIDEO]: "Video",
|
|
679
|
-
[ModelType.OBJECT_SMALL]: "Object (Small)",
|
|
680
|
-
[ModelType.OBJECT_LARGE]: "Object (Large)",
|
|
681
|
-
[ModelType.RESEARCH]: "Research"
|
|
682
|
-
};
|
|
683
|
-
return descriptions[modelType] ?? modelType;
|
|
684
|
-
}
|
|
685
|
-
var modelsAction = {
|
|
686
|
-
name: "MODELS_COMMAND",
|
|
687
|
-
description: "List available AI models and providers. Only activates for /models slash command.",
|
|
688
|
-
similes: ["/models"],
|
|
689
|
-
validate: async (runtime, message) => {
|
|
690
|
-
const textRaw = message.content?.text ?? "";
|
|
691
|
-
const text = textRaw.toLowerCase();
|
|
692
|
-
const hasKeyword = text.includes("/models") || text.includes("models");
|
|
693
|
-
const hasRegex = /^(?:\/|!)\s*models\b/i.test(textRaw);
|
|
694
|
-
const hasContext = Boolean(runtime?.agentId || message?.roomId || message?.content);
|
|
695
|
-
const hasInput = textRaw.trim().length > 0;
|
|
696
|
-
if (!(hasKeyword && hasRegex && hasContext && hasInput)) {
|
|
697
|
-
return false;
|
|
698
|
-
}
|
|
699
|
-
const detection = detectCommand(textRaw);
|
|
700
|
-
return detection.isCommand && detection.command?.key === "models";
|
|
701
|
-
},
|
|
702
|
-
async handler(runtime, _message, _state, _options, callback) {
|
|
703
|
-
const lines = [`**Available Models:**
|
|
704
|
-
`];
|
|
705
|
-
try {
|
|
706
|
-
const registeredTypes = [];
|
|
707
|
-
const seen = new Set;
|
|
708
|
-
for (const modelType of Object.values(ModelType)) {
|
|
709
|
-
if (seen.has(modelType))
|
|
710
|
-
continue;
|
|
711
|
-
seen.add(modelType);
|
|
712
|
-
try {
|
|
713
|
-
const handler = runtime.getModel(modelType);
|
|
714
|
-
if (handler) {
|
|
715
|
-
registeredTypes.push(modelType);
|
|
716
|
-
}
|
|
717
|
-
} catch {}
|
|
718
|
-
}
|
|
719
|
-
if (registeredTypes.length > 0) {
|
|
720
|
-
lines.push("**Registered Model Types:**");
|
|
721
|
-
for (const modelType of registeredTypes) {
|
|
722
|
-
lines.push(`• ${describeModelType(modelType)} (\`${modelType}\`)`);
|
|
723
|
-
}
|
|
724
|
-
} else {
|
|
725
|
-
lines.push("No model handlers are currently registered.");
|
|
726
|
-
}
|
|
727
|
-
const modelProvider = runtime.getSetting("MODEL_PROVIDER");
|
|
728
|
-
const modelName = runtime.getSetting("MODEL_NAME");
|
|
729
|
-
if (modelProvider || modelName) {
|
|
730
|
-
lines.push(`
|
|
731
|
-
**Current Configuration:**`);
|
|
732
|
-
if (modelProvider)
|
|
733
|
-
lines.push(`• Provider: ${modelProvider}`);
|
|
734
|
-
if (modelName)
|
|
735
|
-
lines.push(`• Model: ${modelName}`);
|
|
736
|
-
}
|
|
737
|
-
} catch (err) {
|
|
738
|
-
logger.warn({ src: "plugin-commands", err }, "Error querying runtime models");
|
|
739
|
-
lines.push("Unable to query available models.");
|
|
740
|
-
}
|
|
741
|
-
lines.push(`
|
|
742
|
-
|
|
743
|
-
_Use /model <provider/model> to switch models._`);
|
|
744
|
-
const replyText = lines.join(`
|
|
745
|
-
`);
|
|
746
|
-
await callback?.({ text: replyText });
|
|
747
|
-
return {
|
|
748
|
-
success: true,
|
|
749
|
-
text: replyText
|
|
750
|
-
};
|
|
751
|
-
},
|
|
752
|
-
examples: [
|
|
753
|
-
[
|
|
754
|
-
{ name: "user", content: { text: "/models" } },
|
|
755
|
-
{
|
|
756
|
-
name: "assistant",
|
|
757
|
-
content: {
|
|
758
|
-
text: "**Available Models:**\n\n**Registered Model Types:**\n• Text (Large) (`text_large`)\n• Text (Small) (`text_small`)..."
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
]
|
|
762
|
-
]
|
|
763
|
-
};
|
|
764
|
-
|
|
765
|
-
// src/actions/status.ts
|
|
766
|
-
async function buildStatusReport(runtime, roomId) {
|
|
767
|
-
const lines = [`**Session Status:**
|
|
768
|
-
`];
|
|
769
|
-
lines.push(`**Agent:** ${runtime.character.name ?? runtime.agentId}`);
|
|
770
|
-
lines.push(`**Room:** ${roomId}`);
|
|
771
|
-
try {
|
|
772
|
-
const directiveService = runtime.getService("directive-parser");
|
|
773
|
-
if (directiveService) {
|
|
774
|
-
const state = directiveService.getSessionState?.(roomId);
|
|
775
|
-
if (state) {
|
|
776
|
-
lines.push(`
|
|
777
|
-
**Directives:**`);
|
|
778
|
-
lines.push(`• Thinking: ${state.thinking}`);
|
|
779
|
-
lines.push(`• Verbose: ${state.verbose}`);
|
|
780
|
-
lines.push(`• Reasoning: ${state.reasoning}`);
|
|
781
|
-
lines.push(`• Elevated: ${state.elevated}`);
|
|
782
|
-
if (state.model?.provider || state.model?.model) {
|
|
783
|
-
const modelStr = state.model.provider ? `${state.model.provider}/${state.model.model}` : state.model.model;
|
|
784
|
-
lines.push(`• Model: ${modelStr}`);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
} catch {}
|
|
789
|
-
try {
|
|
790
|
-
const tasks = await runtime.getTasks({
|
|
791
|
-
roomId,
|
|
792
|
-
agentIds: [runtime.agentId]
|
|
793
|
-
});
|
|
794
|
-
if (tasks.length > 0) {
|
|
795
|
-
lines.push(`
|
|
796
|
-
**Tasks:** ${tasks.length} pending`);
|
|
797
|
-
}
|
|
798
|
-
} catch {}
|
|
799
|
-
return lines.join(`
|
|
800
|
-
`);
|
|
801
|
-
}
|
|
802
|
-
var statusAction = {
|
|
803
|
-
name: "STATUS_COMMAND",
|
|
804
|
-
description: "Show session directive settings via /status slash command. Only activates for /status or /s prefix.",
|
|
805
|
-
similes: ["/status", "/s"],
|
|
806
|
-
validate: async (runtime, message) => {
|
|
807
|
-
const textRaw = message.content?.text ?? "";
|
|
808
|
-
const text = textRaw.toLowerCase();
|
|
809
|
-
const hasKeyword = text.includes("/status") || text.includes("/s") || text.includes("status");
|
|
810
|
-
const hasRegex = /^(?:\/|!)\s*(?:status|s)\b/i.test(textRaw);
|
|
811
|
-
const hasContext = Boolean(runtime?.agentId || message?.roomId || message?.content);
|
|
812
|
-
const hasInput = textRaw.trim().length > 0;
|
|
813
|
-
if (!(hasKeyword && hasRegex && hasContext && hasInput)) {
|
|
814
|
-
return false;
|
|
815
|
-
}
|
|
816
|
-
const detection = detectCommand(textRaw);
|
|
817
|
-
return detection.isCommand && detection.command?.key === "status";
|
|
818
|
-
},
|
|
819
|
-
async handler(runtime, message, _state, _options, callback) {
|
|
820
|
-
const statusText = await buildStatusReport(runtime, message.roomId);
|
|
821
|
-
await callback?.({ text: statusText });
|
|
822
|
-
return {
|
|
823
|
-
success: true,
|
|
824
|
-
text: statusText
|
|
825
|
-
};
|
|
826
|
-
},
|
|
827
|
-
examples: [
|
|
828
|
-
[
|
|
829
|
-
{ name: "user", content: { text: "/status" } },
|
|
830
|
-
{
|
|
831
|
-
name: "assistant",
|
|
832
|
-
content: {
|
|
833
|
-
text: `**Session Status:**
|
|
834
|
-
|
|
835
|
-
**Agent:** Eliza
|
|
836
|
-
**Room:** room-456
|
|
837
|
-
|
|
838
|
-
**Directives:**
|
|
839
|
-
• Thinking: low...`
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
]
|
|
843
|
-
]
|
|
844
|
-
};
|
|
845
|
-
|
|
846
|
-
// src/actions/stop.ts
|
|
847
|
-
import { EventType, logger as logger2 } from "@elizaos/core";
|
|
848
|
-
var stopAction = {
|
|
849
|
-
name: "STOP_COMMAND",
|
|
850
|
-
description: "Stop current operation or abort running tasks. Triggered by /stop, /abort, or /cancel slash commands only.",
|
|
851
|
-
similes: ["/stop", "/abort", "/cancel"],
|
|
852
|
-
validate: async (runtime, message) => {
|
|
853
|
-
const textRaw = message.content?.text ?? "";
|
|
854
|
-
const text = textRaw.toLowerCase();
|
|
855
|
-
const hasKeyword = text.includes("/stop") || text.includes("/abort") || text.includes("/cancel") || text.includes("stop");
|
|
856
|
-
const hasRegex = /^(?:\/|!)\s*(?:stop|abort|cancel)\b/i.test(textRaw);
|
|
857
|
-
const hasContext = Boolean(runtime?.agentId || message?.roomId || message?.content);
|
|
858
|
-
const hasInput = textRaw.trim().length > 0;
|
|
859
|
-
if (!(hasKeyword && hasRegex && hasContext && hasInput)) {
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
const detection = detectCommand(textRaw);
|
|
863
|
-
return detection.isCommand && ["stop", "abort", "cancel"].includes(detection.command?.key ?? "");
|
|
864
|
-
},
|
|
865
|
-
async handler(runtime, message, _state, _options, callback) {
|
|
866
|
-
try {
|
|
867
|
-
await runtime.emitEvent(EventType.HOOK_COMMAND_STOP, {
|
|
868
|
-
runtime,
|
|
869
|
-
sessionKey: message.roomId,
|
|
870
|
-
messages: [],
|
|
871
|
-
timestamp: new Date,
|
|
872
|
-
context: {
|
|
873
|
-
entityId: message.entityId,
|
|
874
|
-
source: message.content?.source
|
|
875
|
-
},
|
|
876
|
-
command: "stop",
|
|
877
|
-
senderId: message.entityId,
|
|
878
|
-
commandSource: message.content?.source
|
|
879
|
-
});
|
|
880
|
-
} catch (err) {
|
|
881
|
-
logger2.warn({ src: "plugin-commands", err }, "Failed to emit HOOK_COMMAND_STOP event");
|
|
882
|
-
}
|
|
883
|
-
const replyText = "✓ Stop requested. Current operations will be cancelled.";
|
|
884
|
-
await callback?.({ text: replyText });
|
|
885
|
-
return {
|
|
886
|
-
success: true,
|
|
887
|
-
text: replyText
|
|
888
|
-
};
|
|
889
|
-
},
|
|
890
|
-
examples: [
|
|
891
|
-
[
|
|
892
|
-
{ name: "user", content: { text: "/stop" } },
|
|
893
|
-
{
|
|
894
|
-
name: "assistant",
|
|
895
|
-
content: {
|
|
896
|
-
text: "✓ Stop requested. Current operations will be cancelled."
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
],
|
|
900
|
-
[
|
|
901
|
-
{ name: "user", content: { text: "/abort" } },
|
|
902
|
-
{
|
|
903
|
-
name: "assistant",
|
|
904
|
-
content: {
|
|
905
|
-
text: "✓ Stop requested. Current operations will be cancelled."
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
]
|
|
909
|
-
]
|
|
910
|
-
};
|
|
911
|
-
|
|
912
|
-
// src/index.ts
|
|
913
|
-
var commandRegistryProvider = {
|
|
914
|
-
name: "COMMAND_REGISTRY",
|
|
915
|
-
description: "Available chat commands and their descriptions",
|
|
916
|
-
dynamic: true,
|
|
917
|
-
async get(runtime, message, _state) {
|
|
918
|
-
useRuntime(runtime.agentId);
|
|
919
|
-
const text = message.content?.text ?? "";
|
|
920
|
-
const isCommand = hasCommand(text);
|
|
921
|
-
const commands = getEnabledCommands();
|
|
922
|
-
if (isCommand) {
|
|
923
|
-
const commandList = commands.map((cmd) => {
|
|
924
|
-
const auth = cmd.requiresAuth ? " (requires auth)" : "";
|
|
925
|
-
return `- ${cmd.textAliases[0]}: ${cmd.description}${auth}`;
|
|
926
|
-
});
|
|
927
|
-
return {
|
|
928
|
-
text: `The user sent a slash command. Available commands:
|
|
929
|
-
${commandList.join(`
|
|
930
|
-
`)}
|
|
931
|
-
|
|
932
|
-
IMPORTANT: This is a slash command — respond by executing the matching command action, not with conversational text.`,
|
|
933
|
-
values: {
|
|
934
|
-
commandCount: commands.length,
|
|
935
|
-
isCommand: true,
|
|
936
|
-
hasElevatedCommands: commands.some((c) => c.requiresElevated)
|
|
937
|
-
},
|
|
938
|
-
data: { commands, isCommand: true }
|
|
939
|
-
};
|
|
940
|
-
}
|
|
941
|
-
return {
|
|
942
|
-
text: "",
|
|
943
|
-
values: {
|
|
944
|
-
commandCount: commands.length,
|
|
945
|
-
isCommand: false
|
|
946
|
-
},
|
|
947
|
-
data: { isCommand: false }
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
function formatCommandResult(result) {
|
|
952
|
-
if (result.error) {
|
|
953
|
-
return `Error: ${result.error}`;
|
|
954
|
-
}
|
|
955
|
-
return result.reply ?? "Command executed";
|
|
956
|
-
}
|
|
957
|
-
function isAuthorized(context, command) {
|
|
958
|
-
if (!command.requiresAuth) {
|
|
959
|
-
return true;
|
|
960
|
-
}
|
|
961
|
-
return context.isAuthorized;
|
|
962
|
-
}
|
|
963
|
-
function isElevated(context, command) {
|
|
964
|
-
if (!command.requiresElevated) {
|
|
965
|
-
return true;
|
|
966
|
-
}
|
|
967
|
-
return context.isElevated;
|
|
968
|
-
}
|
|
969
|
-
var commandsPlugin = {
|
|
970
|
-
name: "commands",
|
|
971
|
-
description: "Chat command system with /help, /status, /reset, etc.",
|
|
972
|
-
providers: [commandRegistryProvider],
|
|
973
|
-
actions: [
|
|
974
|
-
helpAction,
|
|
975
|
-
statusAction,
|
|
976
|
-
stopAction,
|
|
977
|
-
modelsAction,
|
|
978
|
-
commandsListAction
|
|
979
|
-
],
|
|
980
|
-
config: {
|
|
981
|
-
COMMANDS_ENABLED: "true",
|
|
982
|
-
COMMANDS_CONFIG_ENABLED: "false",
|
|
983
|
-
COMMANDS_DEBUG_ENABLED: "false",
|
|
984
|
-
COMMANDS_BASH_ENABLED: "false",
|
|
985
|
-
COMMANDS_RESTART_ENABLED: "true"
|
|
986
|
-
},
|
|
987
|
-
tests: [
|
|
988
|
-
{
|
|
989
|
-
name: "command-detection",
|
|
990
|
-
tests: [
|
|
991
|
-
{
|
|
992
|
-
name: "Detect command prefix",
|
|
993
|
-
fn: async (_runtime) => {
|
|
994
|
-
if (!hasCommand("/help")) {
|
|
995
|
-
throw new Error("Should detect /help command");
|
|
996
|
-
}
|
|
997
|
-
if (!hasCommand("/status test")) {
|
|
998
|
-
throw new Error("Should detect /status with args");
|
|
999
|
-
}
|
|
1000
|
-
if (hasCommand("hello world")) {
|
|
1001
|
-
throw new Error("Should not detect plain text as command");
|
|
1002
|
-
}
|
|
1003
|
-
logger3.success("Command prefix detection works correctly");
|
|
1004
|
-
}
|
|
1005
|
-
},
|
|
1006
|
-
{
|
|
1007
|
-
name: "Parse command with args",
|
|
1008
|
-
fn: async (_runtime) => {
|
|
1009
|
-
const detection = detectCommand("/think:high");
|
|
1010
|
-
if (!detection.isCommand) {
|
|
1011
|
-
throw new Error("Should detect think command");
|
|
1012
|
-
}
|
|
1013
|
-
if (detection.command?.key !== "think") {
|
|
1014
|
-
throw new Error(`Expected key 'think', got '${detection.command?.key}'`);
|
|
1015
|
-
}
|
|
1016
|
-
if (detection.command?.args[0] !== "high") {
|
|
1017
|
-
throw new Error(`Expected arg 'high', got '${detection.command?.args[0]}'`);
|
|
1018
|
-
}
|
|
1019
|
-
logger3.success("Command argument parsing works correctly");
|
|
1020
|
-
}
|
|
1021
|
-
},
|
|
1022
|
-
{
|
|
1023
|
-
name: "Normalize command body",
|
|
1024
|
-
fn: async (_runtime) => {
|
|
1025
|
-
const normalized1 = normalizeCommandBody("/status: test");
|
|
1026
|
-
if (normalized1 !== "/status test") {
|
|
1027
|
-
throw new Error(`Expected '/status test', got '${normalized1}'`);
|
|
1028
|
-
}
|
|
1029
|
-
const normalized2 = normalizeCommandBody("@bot /help", "bot");
|
|
1030
|
-
if (normalized2 !== "/help") {
|
|
1031
|
-
throw new Error(`Expected '/help', got '${normalized2}'`);
|
|
1032
|
-
}
|
|
1033
|
-
logger3.success("Command normalization works correctly");
|
|
1034
|
-
}
|
|
1035
|
-
},
|
|
1036
|
-
{
|
|
1037
|
-
name: "Find command by alias",
|
|
1038
|
-
fn: async (_runtime) => {
|
|
1039
|
-
const cmd = findCommandByAlias("/h");
|
|
1040
|
-
if (!cmd) {
|
|
1041
|
-
throw new Error("Should find help command by /h alias");
|
|
1042
|
-
}
|
|
1043
|
-
if (cmd.key !== "help") {
|
|
1044
|
-
throw new Error(`Expected key 'help', got '${cmd.key}'`);
|
|
1045
|
-
}
|
|
1046
|
-
logger3.success("Command alias lookup works correctly");
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
name: "Find command by key",
|
|
1051
|
-
fn: async (_runtime) => {
|
|
1052
|
-
const cmd = findCommandByKey("status");
|
|
1053
|
-
if (!cmd) {
|
|
1054
|
-
throw new Error("Should find status command by key");
|
|
1055
|
-
}
|
|
1056
|
-
if (cmd.key !== "status") {
|
|
1057
|
-
throw new Error(`Expected key 'status', got '${cmd.key}'`);
|
|
1058
|
-
}
|
|
1059
|
-
logger3.success("Command key lookup works correctly");
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
]
|
|
1063
|
-
},
|
|
1064
|
-
{
|
|
1065
|
-
name: "command-registry",
|
|
1066
|
-
tests: [
|
|
1067
|
-
{
|
|
1068
|
-
name: "Get enabled commands",
|
|
1069
|
-
fn: async (_runtime) => {
|
|
1070
|
-
const commands = getEnabledCommands();
|
|
1071
|
-
if (commands.length === 0) {
|
|
1072
|
-
throw new Error("Should have enabled commands");
|
|
1073
|
-
}
|
|
1074
|
-
const cmdHelp = commands.some((c) => c.key === "help");
|
|
1075
|
-
const cmdStatus = commands.some((c) => c.key === "status");
|
|
1076
|
-
if (!cmdHelp || !cmdStatus) {
|
|
1077
|
-
throw new Error("Should have help and status commands");
|
|
1078
|
-
}
|
|
1079
|
-
logger3.success("Command registry works correctly");
|
|
1080
|
-
}
|
|
1081
|
-
},
|
|
1082
|
-
{
|
|
1083
|
-
name: "Register custom command",
|
|
1084
|
-
fn: async (_runtime) => {
|
|
1085
|
-
const customCmd = {
|
|
1086
|
-
key: "test-custom",
|
|
1087
|
-
description: "Test custom command",
|
|
1088
|
-
textAliases: ["/test-custom", "/tc"],
|
|
1089
|
-
scope: "text"
|
|
1090
|
-
};
|
|
1091
|
-
registerCommand(customCmd);
|
|
1092
|
-
const found = findCommandByKey("test-custom");
|
|
1093
|
-
if (!found) {
|
|
1094
|
-
throw new Error("Should find registered custom command");
|
|
1095
|
-
}
|
|
1096
|
-
unregisterCommand("test-custom");
|
|
1097
|
-
const notFound = findCommandByKey("test-custom");
|
|
1098
|
-
if (notFound) {
|
|
1099
|
-
throw new Error("Should not find unregistered command");
|
|
1100
|
-
}
|
|
1101
|
-
logger3.success("Custom command registration works correctly");
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
{
|
|
1105
|
-
name: "Get commands by category",
|
|
1106
|
-
fn: async (_runtime) => {
|
|
1107
|
-
const statusCommands = getCommandsByCategory("status");
|
|
1108
|
-
if (statusCommands.length === 0) {
|
|
1109
|
-
throw new Error("Should have status category commands");
|
|
1110
|
-
}
|
|
1111
|
-
const allStatus = statusCommands.every((c) => c.category === "status");
|
|
1112
|
-
if (!allStatus) {
|
|
1113
|
-
throw new Error("All returned commands should be in status category");
|
|
1114
|
-
}
|
|
1115
|
-
logger3.success("Command categorization works correctly");
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
]
|
|
1119
|
-
}
|
|
1120
|
-
],
|
|
1121
|
-
async init(config, runtime) {
|
|
1122
|
-
logger3.log("[plugin-commands] Initializing command system");
|
|
1123
|
-
initForRuntime(runtime.agentId);
|
|
1124
|
-
const configEnabled = config.COMMANDS_CONFIG_ENABLED === "true";
|
|
1125
|
-
const debugEnabled = config.COMMANDS_DEBUG_ENABLED === "true";
|
|
1126
|
-
const bashEnabled = config.COMMANDS_BASH_ENABLED === "true";
|
|
1127
|
-
const restartEnabled = config.COMMANDS_RESTART_ENABLED !== "false";
|
|
1128
|
-
const configCmd = findCommandByKey("config");
|
|
1129
|
-
if (configCmd) {
|
|
1130
|
-
configCmd.enabled = configEnabled;
|
|
1131
|
-
}
|
|
1132
|
-
const debugCmd = findCommandByKey("debug");
|
|
1133
|
-
if (debugCmd) {
|
|
1134
|
-
debugCmd.enabled = debugEnabled;
|
|
1135
|
-
}
|
|
1136
|
-
const bashCmd = findCommandByKey("bash");
|
|
1137
|
-
if (bashCmd) {
|
|
1138
|
-
bashCmd.enabled = bashEnabled;
|
|
1139
|
-
}
|
|
1140
|
-
const restartCmd = findCommandByKey("restart");
|
|
1141
|
-
if (restartCmd) {
|
|
1142
|
-
restartCmd.enabled = restartEnabled;
|
|
1143
|
-
}
|
|
1144
|
-
const enabledCount = getEnabledCommands().length;
|
|
1145
|
-
logger3.log(`[plugin-commands] ${enabledCount} commands enabled for agent ${runtime.agentId}`);
|
|
1146
|
-
}
|
|
1147
|
-
};
|
|
1148
|
-
var src_default = commandsPlugin;
|
|
1149
|
-
export {
|
|
1150
|
-
useRuntime,
|
|
1151
|
-
unregisterCommand,
|
|
1152
|
-
startsWithCommand,
|
|
1153
|
-
resetCommands,
|
|
1154
|
-
registerCommands,
|
|
1155
|
-
registerCommand,
|
|
1156
|
-
parseCommand,
|
|
1157
|
-
normalizeCommandBody,
|
|
1158
|
-
isElevated,
|
|
1159
|
-
isCommandOnly,
|
|
1160
|
-
isAuthorized,
|
|
1161
|
-
initForRuntime,
|
|
1162
|
-
hasCommand,
|
|
1163
|
-
getEnabledCommands,
|
|
1164
|
-
getCommandsByCategory,
|
|
1165
|
-
getCommands,
|
|
1166
|
-
formatCommandResult,
|
|
1167
|
-
findCommandByKey,
|
|
1168
|
-
findCommandByAlias,
|
|
1169
|
-
extractCommand,
|
|
1170
|
-
detectCommand,
|
|
1171
|
-
src_default as default,
|
|
1172
|
-
commandsPlugin,
|
|
1173
|
-
commandRegistryProvider
|
|
1174
|
-
};
|
|
1175
|
-
|
|
1176
|
-
//# debugId=24A386E734B88BB864756E2164756E21
|