perf(auto-reply): avoid skill scans for inline directives

This commit is contained in:
Peter Steinberger
2026-02-15 19:18:20 +00:00
parent 38f430e133
commit 8fdde0429e
4 changed files with 219 additions and 62 deletions

View File

@@ -11,12 +11,52 @@ import { createOpenClawTools } from "../../agents/openclaw-tools.js";
import { getChannelDock } from "../../channels/dock.js";
import { logVerbose } from "../../globals.js";
import { resolveGatewayMessageChannel } from "../../utils/message-channel.js";
import { listChatCommands } from "../commands-registry.js";
import { listSkillCommandsForWorkspace, resolveSkillCommandInvocation } from "../skill-commands.js";
import { getAbortMemory } from "./abort.js";
import { buildStatusReply, handleCommands } from "./commands.js";
import { isDirectiveOnly } from "./directive-handling.js";
import { extractInlineSimpleCommand } from "./reply-inline.js";
const builtinSlashCommands = (() => {
const reserved = new Set<string>();
for (const command of listChatCommands()) {
if (command.nativeName) {
reserved.add(command.nativeName.toLowerCase());
}
for (const alias of command.textAliases) {
const trimmed = alias.trim();
if (!trimmed.startsWith("/")) {
continue;
}
reserved.add(trimmed.slice(1).toLowerCase());
}
}
for (const name of [
"think",
"verbose",
"reasoning",
"elevated",
"exec",
"model",
"status",
"queue",
]) {
reserved.add(name);
}
return reserved;
})();
function resolveSlashCommandName(commandBodyNormalized: string): string | null {
const trimmed = commandBodyNormalized.trim();
if (!trimmed.startsWith("/")) {
return null;
}
const match = trimmed.match(/^\/([^\s:]+)(?::|\s|$)/);
const name = match?.[1]?.trim().toLowerCase() ?? "";
return name ? name : null;
}
export type InlineActionResult =
| { kind: "reply"; reply: ReplyPayload | ReplyPayload[] | undefined }
| {
@@ -135,7 +175,12 @@ export async function handleInlineActions(params: {
let directives = initialDirectives;
let cleanedBody = initialCleanedBody;
const shouldLoadSkillCommands = command.commandBodyNormalized.startsWith("/");
const slashCommandName = resolveSlashCommandName(command.commandBodyNormalized);
const shouldLoadSkillCommands =
allowTextCommands &&
slashCommandName !== null &&
// `/skill …` needs the full skill command list.
(slashCommandName === "skill" || !builtinSlashCommands.has(slashCommandName));
const skillCommands =
shouldLoadSkillCommands && params.skillCommands
? params.skillCommands