UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

1,064 lines (1,063 loc) 27.8 kB
import { c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js"; import { l as normalizeStringEntries } from "./string-normalization-WNUDCpXX.js"; import { a as listThinkingLevels, l as BASE_THINKING_LEVELS } from "./thinking-OG7pb4lf.js"; import { r as getActivePluginChannelRegistryVersionFromState } from "./runtime-channel-state-D79Ax0is.js"; import { r as listLoadedChannelPlugins } from "./registry-loaded-C3DZQnLP.js"; //#region src/auto-reply/commands-args.ts /** Argument serializers for command definitions that expose structured values. */ function normalizeArgValue(value) { if (value == null) return; let text; if (typeof value === "string") text = normalizeOptionalString(value) ?? ""; else if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") text = normalizeOptionalString(String(value)) ?? ""; else if (typeof value === "symbol") text = normalizeOptionalString(value.toString()) ?? ""; else if (typeof value === "function") text = normalizeOptionalString(value.toString()) ?? ""; else text = JSON.stringify(value); return text ? text : void 0; } function formatActionArgs(values, params) { const action = normalizeOptionalLowercaseString(normalizeArgValue(values.action)); const path = normalizeArgValue(values.path); const value = normalizeArgValue(values.value); if (!action) return; const knownAction = params.formatKnownAction(action, path); if (knownAction) return knownAction; return formatSetUnsetArgAction(action, { path, value }); } const formatConfigArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => { if (action === "show" || action === "get") return path ? `${action} ${path}` : action; } }); const formatMcpArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => { if (action === "show" || action === "get") return path ? `${action} ${path}` : action; } }); const formatPluginsArgs = (values) => formatActionArgs(values, { formatKnownAction: (action, path) => { if (action === "list") return "list"; if (action === "show" || action === "get") return path ? `${action} ${path}` : action; if (action === "enable" || action === "disable") return path ? `${action} ${path}` : action; } }); const formatDebugArgs = (values) => formatActionArgs(values, { formatKnownAction: (action) => { if (action === "show" || action === "reset") return action; } }); function formatSetUnsetArgAction(action, params) { if (action === "unset") return params.path ? `${action} ${params.path}` : action; if (action === "set") { if (!params.path) return action; if (!params.value) return `${action} ${params.path}`; return `${action} ${params.path}=${params.value}`; } return action; } const formatQueueArgs = (values) => { const mode = normalizeArgValue(values.mode); const debounce = normalizeArgValue(values.debounce); const cap = normalizeArgValue(values.cap); const drop = normalizeArgValue(values.drop); const parts = []; if (mode) parts.push(mode); if (debounce) parts.push(`debounce:${debounce}`); if (cap) parts.push(`cap:${cap}`); if (drop) parts.push(`drop:${drop}`); return parts.length > 0 ? parts.join(" ") : void 0; }; const formatExecArgs = (values) => { const host = normalizeArgValue(values.host); const security = normalizeArgValue(values.security); const ask = normalizeArgValue(values.ask); const node = normalizeArgValue(values.node); const parts = []; if (host) parts.push(`host=${host}`); if (security) parts.push(`security=${security}`); if (ask) parts.push(`ask=${ask}`); if (node) parts.push(`node=${node}`); return parts.length > 0 ? parts.join(" ") : void 0; }; /** Command-specific serializers used when rebuilding slash-command text from parsed args. */ const COMMAND_ARG_FORMATTERS = { config: formatConfigArgs, mcp: formatMcpArgs, plugins: formatPluginsArgs, debug: formatDebugArgs, queue: formatQueueArgs, exec: formatExecArgs }; //#endregion //#region src/auto-reply/commands-registry.shared.ts /** Shared command registry builders used by browser-safe and runtime command lists. */ const BROWSER_SAFE_THINKING_LEVELS = [ ...BASE_THINKING_LEVELS, "xhigh", "adaptive", "max" ]; /** Defines one command with normalized aliases, scope, and argument parsing defaults. */ function defineChatCommand(command) { const aliases = (command.textAliases ?? (command.textAlias ? [command.textAlias] : [])).map((alias) => alias.trim()).filter(Boolean); const scope = command.scope ?? (command.nativeName ? aliases.length ? "both" : "native" : "text"); const acceptsArgs = command.acceptsArgs ?? Boolean(command.args?.length); const argsParsing = command.argsParsing ?? (command.args?.length ? "positional" : "none"); return { key: command.key, nativeName: command.nativeName, nativeAliases: command.nativeAliases ? normalizeStringEntries(command.nativeAliases) : void 0, description: command.description, acceptsArgs, args: command.args, argsParsing, formatArgs: command.formatArgs, argsMenu: command.argsMenu, textAliases: aliases, scope, category: command.category, tier: command.tier }; } function registerAlias(commands, key, ...aliases) { const command = commands.find((entry) => entry.key === key); if (!command) throw new Error(`registerAlias: unknown command key: ${key}`); const existing = /* @__PURE__ */ new Set(); for (const alias of command.textAliases) { const lowered = normalizeOptionalLowercaseString(alias); if (lowered) existing.add(lowered); } for (const alias of aliases) { const trimmed = alias.trim(); if (!trimmed) continue; const lowered = normalizeOptionalLowercaseString(trimmed); if (!lowered) continue; if (existing.has(lowered)) continue; existing.add(lowered); command.textAliases.push(trimmed); } } /** Validates command registry uniqueness and text/native surface invariants. */ function assertCommandRegistry(commands) { const keys = /* @__PURE__ */ new Set(); const nativeNames = /* @__PURE__ */ new Set(); const textAliases = /* @__PURE__ */ new Set(); for (const command of commands) { if (keys.has(command.key)) throw new Error(`Duplicate command key: ${command.key}`); keys.add(command.key); const nativeName = command.nativeName?.trim(); if (command.scope === "text") { if (nativeName) throw new Error(`Text-only command has native name: ${command.key}`); if (command.nativeAliases?.length) throw new Error(`Text-only command has native aliases: ${command.key}`); if (command.textAliases.length === 0) throw new Error(`Text-only command missing text alias: ${command.key}`); } else if (!nativeName) throw new Error(`Native command missing native name: ${command.key}`); else for (const alias of [nativeName, ...command.nativeAliases ?? []]) { const nativeKey = normalizeOptionalLowercaseString(alias) ?? ""; if (nativeNames.has(nativeKey)) throw new Error(`Duplicate native command: ${alias}`); nativeNames.add(nativeKey); } if (command.scope === "native" && command.textAliases.length > 0) throw new Error(`Native-only command has text aliases: ${command.key}`); for (const alias of command.textAliases) { if (!alias.startsWith("/")) throw new Error(`Command alias missing leading '/': ${alias}`); const aliasKey = normalizeOptionalLowercaseString(alias) ?? ""; if (textAliases.has(aliasKey)) throw new Error(`Duplicate command alias: ${alias}`); textAliases.add(aliasKey); } } } /** Builds the built-in command list with context-aware thinking choices. */ function buildBuiltinChatCommands(params = {}) { const configuredThinkingLevels = params.listThinkingLevels ?? (() => BROWSER_SAFE_THINKING_LEVELS); const listThinkingLevelChoices = (provider, model, catalog) => { return ["default", ...configuredThinkingLevels(provider, model, catalog).filter((level) => level !== "default")]; }; const commands = [ defineChatCommand({ key: "help", nativeName: "help", description: "Show available commands.", textAlias: "/help", category: "status", tier: "essential" }), defineChatCommand({ key: "commands", nativeName: "commands", description: "List all slash commands.", textAlias: "/commands", category: "status", tier: "power" }), defineChatCommand({ key: "tools", nativeName: "tools", description: "List available runtime tools.", textAlias: "/tools", category: "status", args: [{ name: "mode", description: "compact or verbose", type: "string", choices: ["compact", "verbose"] }], argsMenu: "auto", tier: "standard" }), defineChatCommand({ key: "skill", nativeName: "skill", description: "Run a skill by name.", textAlias: "/skill", category: "tools", tier: "standard", args: [{ name: "name", description: "Skill name", type: "string", required: true }, { name: "input", description: "Skill input", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "status", nativeName: "status", description: "Show current status.", textAlias: "/status", category: "status", tier: "essential" }), defineChatCommand({ key: "goal", nativeName: "goal", description: "Show or control the current goal.", textAlias: "/goal", category: "status", tier: "standard", acceptsArgs: true, args: [{ name: "action", description: "status, start, pause, resume, complete, block, clear", type: "string", choices: [ "status", "start", "pause", "resume", "complete", "block", "clear" ] }, { name: "text", description: "Goal objective or note", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "diagnostics", nativeName: "diagnostics", description: "Explain Gateway diagnostics and Codex feedback upload options.", textAlias: "/diagnostics", acceptsArgs: true, category: "status", tier: "standard", args: [{ name: "note", description: "Optional note for Codex feedback upload", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "crestodian", description: "Run the Crestodian setup and repair helper.", textAlias: "/crestodian", acceptsArgs: true, scope: "text", category: "management", tier: "essential" }), defineChatCommand({ key: "tasks", nativeName: "tasks", description: "List background tasks for this session.", textAlias: "/tasks", category: "status", tier: "standard" }), defineChatCommand({ key: "allowlist", description: "List/add/remove allowlist entries.", textAlias: "/allowlist", acceptsArgs: true, scope: "text", category: "management", tier: "power" }), defineChatCommand({ key: "approve", nativeName: "approve", description: "Approve or deny exec requests.", textAlias: "/approve", acceptsArgs: true, category: "management", tier: "power" }), defineChatCommand({ key: "context", nativeName: "context", description: "Explain how context is built and used.", textAlias: "/context", acceptsArgs: true, category: "status", tier: "standard" }), defineChatCommand({ key: "btw", nativeName: "btw", nativeAliases: ["side"], description: "Ask a side question without changing future session context.", textAliases: ["/btw", "/side"], acceptsArgs: true, category: "tools", tier: "standard" }), defineChatCommand({ key: "export-session", nativeName: "export-session", description: "Export current session to HTML file with full system prompt.", textAliases: ["/export-session", "/export"], acceptsArgs: true, category: "status", tier: "essential", args: [{ name: "path", description: "Output path (default: workspace)", type: "string", required: false }] }), defineChatCommand({ key: "export-trajectory", nativeName: "export-trajectory", description: "Export a JSONL trajectory bundle for the active session.", textAliases: ["/export-trajectory", "/trajectory"], acceptsArgs: true, category: "status", tier: "essential", args: [{ name: "path", description: "Output directory (default: workspace)", type: "string", required: false }] }), defineChatCommand({ key: "tts", nativeName: "tts", description: "Control text-to-speech (TTS).", textAlias: "/tts", category: "media", tier: "standard", args: [{ name: "action", description: "TTS action", type: "string", choices: [ { value: "on", label: "On" }, { value: "off", label: "Off" }, { value: "status", label: "Status" }, { value: "provider", label: "Provider" }, { value: "limit", label: "Limit" }, { value: "summary", label: "Summary" }, { value: "audio", label: "Audio" }, { value: "help", label: "Help" } ] }, { name: "value", description: "Provider, limit, or text", type: "string", captureRemaining: true }], argsMenu: { arg: "action", title: "TTS Actions:\n• On – Enable TTS for responses\n• Off – Disable TTS\n• Status – Show current settings\n• Provider – Show or set the voice provider\n• Limit – Set max characters for TTS\n• Summary – Toggle AI summary for long texts\n• Audio – Generate TTS from custom text\n• Help – Show usage guide" } }), defineChatCommand({ key: "whoami", nativeName: "whoami", description: "Show your sender id.", textAlias: "/whoami", category: "status", tier: "power" }), defineChatCommand({ key: "session", nativeName: "session", description: "Manage session-level settings (for example /session idle).", textAlias: "/session", category: "session", tier: "power", args: [{ name: "action", description: "idle | max-age", type: "string", choices: ["idle", "max-age"] }, { name: "value", description: "Duration (24h, 90m) or off", type: "string", captureRemaining: true }], argsMenu: "auto" }), defineChatCommand({ key: "subagents", nativeName: "subagents", description: "Inspect subagent runs for this session.", textAlias: "/subagents", category: "management", tier: "standard", args: [ { name: "action", description: "list | log | info", type: "string", choices: [ "list", "log", "info" ] }, { name: "target", description: "Run id, index, or session key", type: "string" }, { name: "value", description: "Additional input (limit/message)", type: "string", captureRemaining: true } ], argsMenu: "auto" }), defineChatCommand({ key: "acp", nativeName: "acp", description: "Manage ACP sessions and runtime options.", textAlias: "/acp", category: "management", tier: "power", args: [{ name: "action", description: "Action to run", type: "string", preferAutocomplete: true, choices: [ "spawn", "cancel", "steer", "close", "sessions", "status", "set-mode", "set", "cwd", "permissions", "timeout", "model", "reset-options", "doctor", "install", "help" ] }, { name: "value", description: "Action arguments", type: "string", captureRemaining: true }], argsMenu: "auto" }), defineChatCommand({ key: "focus", nativeName: "focus", description: "Bind this thread (Discord) or topic/conversation (Telegram) to a session target.", textAlias: "/focus", category: "management", tier: "power", args: [{ name: "target", description: "Subagent label/index or session key/id/label", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "unfocus", nativeName: "unfocus", description: "Remove the current thread (Discord) or topic/conversation (Telegram) binding.", textAlias: "/unfocus", category: "management", tier: "power" }), defineChatCommand({ key: "agents", nativeName: "agents", description: "List thread-bound agents for this session.", textAlias: "/agents", category: "management", tier: "standard" }), defineChatCommand({ key: "steer", nativeName: "steer", description: "Send guidance to the active run in this session.", textAlias: "/steer", category: "management", tier: "standard", args: [{ name: "message", description: "Steering message", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "config", nativeName: "config", description: "Show or set config values.", textAlias: "/config", category: "management", tier: "power", args: [ { name: "action", description: "show | get | set | unset", type: "string", choices: [ "show", "get", "set", "unset" ] }, { name: "path", description: "Config path", type: "string" }, { name: "value", description: "Value for set", type: "string", captureRemaining: true } ], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.config }), defineChatCommand({ key: "mcp", nativeName: "mcp", description: "Show or set OpenClaw MCP servers.", textAlias: "/mcp", category: "management", tier: "power", args: [ { name: "action", description: "show | get | set | unset", type: "string", choices: [ "show", "get", "set", "unset" ] }, { name: "path", description: "MCP server name", type: "string" }, { name: "value", description: "JSON config for set", type: "string", captureRemaining: true } ], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.mcp }), defineChatCommand({ key: "plugins", nativeName: "plugins", description: "List, show, enable, or disable plugins.", textAliases: ["/plugins", "/plugin"], category: "management", tier: "power", args: [{ name: "action", description: "list | show | get | enable | disable", type: "string", choices: [ "list", "show", "get", "enable", "disable" ] }, { name: "path", description: "Plugin id or name", type: "string" }], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.plugins }), defineChatCommand({ key: "debug", nativeName: "debug", description: "Set runtime debug overrides.", textAlias: "/debug", category: "management", tier: "power", args: [ { name: "action", description: "show | reset | set | unset", type: "string", choices: [ "show", "reset", "set", "unset" ] }, { name: "path", description: "Debug path", type: "string" }, { name: "value", description: "Value for set", type: "string", captureRemaining: true } ], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.debug }), defineChatCommand({ key: "usage", nativeName: "usage", description: "Usage footer or cost summary.", textAlias: "/usage", category: "options", tier: "standard", args: [{ name: "mode", description: "off, tokens, full, or cost", type: "string", choices: [ "off", "tokens", "full", "cost" ] }], argsMenu: "auto" }), defineChatCommand({ key: "stop", nativeName: "stop", description: "Stop the current run.", textAlias: "/stop", category: "session", tier: "essential" }), defineChatCommand({ key: "restart", nativeName: "restart", description: "Restart OpenClaw.", textAlias: "/restart", category: "tools", tier: "power" }), defineChatCommand({ key: "activation", nativeName: "activation", description: "Set group activation mode.", textAlias: "/activation", category: "management", tier: "power", args: [{ name: "mode", description: "mention or always", type: "string", choices: ["mention", "always"] }], argsMenu: "auto" }), defineChatCommand({ key: "send", nativeName: "send", description: "Set send policy.", textAlias: "/send", category: "management", tier: "power", args: [{ name: "mode", description: "on, off, or inherit", type: "string", choices: [ "on", "off", "inherit" ] }], argsMenu: "auto" }), defineChatCommand({ key: "reset", nativeName: "reset", description: "Reset the current session.", textAlias: "/reset", acceptsArgs: true, category: "session", tier: "essential" }), defineChatCommand({ key: "new", nativeName: "new", description: "Start a new session.", textAlias: "/new", acceptsArgs: true, category: "session", tier: "essential" }), defineChatCommand({ key: "compact", nativeName: "compact", description: "Compact the session context.", textAlias: "/compact", category: "session", tier: "essential", args: [{ name: "instructions", description: "Extra compaction instructions", type: "string", captureRemaining: true }] }), defineChatCommand({ key: "think", nativeName: "think", description: "Set thinking level.", textAlias: "/think", category: "options", tier: "essential", args: [{ name: "level", description: "Thinking level", type: "string", choices: ({ provider, model, catalog }) => listThinkingLevelChoices(provider, model, catalog) }], argsMenu: "auto" }), defineChatCommand({ key: "verbose", nativeName: "verbose", description: "Toggle verbose mode.", textAlias: "/verbose", category: "options", tier: "standard", args: [{ name: "mode", description: "on, off, or full", type: "string", choices: [ "on", "off", "full" ] }] }), defineChatCommand({ key: "trace", nativeName: "trace", description: "Toggle plugin trace lines.", textAlias: "/trace", category: "options", tier: "power", args: [{ name: "mode", description: "on, off, or raw", type: "string", choices: [ "on", "off", "raw" ] }], argsMenu: "auto" }), defineChatCommand({ key: "fast", nativeName: "fast", description: "Toggle fast mode.", textAlias: "/fast", category: "options", tier: "standard", args: [{ name: "mode", description: "status, on, off, or default", type: "string", choices: [ "status", "on", "off", "default" ] }], argsMenu: "auto" }), defineChatCommand({ key: "reasoning", nativeName: "reasoning", description: "Toggle reasoning visibility.", textAlias: "/reasoning", category: "options", tier: "standard", args: [{ name: "mode", description: "on, off, or stream", type: "string", choices: [ "on", "off", "stream" ] }], argsMenu: "auto" }), defineChatCommand({ key: "elevated", nativeName: "elevated", description: "Toggle elevated mode.", textAlias: "/elevated", category: "options", tier: "power", args: [{ name: "mode", description: "on, off, ask, or full", type: "string", choices: [ "on", "off", "ask", "full" ] }], argsMenu: "auto" }), defineChatCommand({ key: "exec", nativeName: "exec", description: "Set exec defaults for this session.", textAlias: "/exec", category: "options", tier: "power", args: [ { name: "host", description: "sandbox, gateway, or node", type: "string", choices: [ "sandbox", "gateway", "node" ] }, { name: "security", description: "deny, allowlist, or full", type: "string", choices: [ "deny", "allowlist", "full" ] }, { name: "ask", description: "off, on-miss, or always", type: "string", choices: [ "off", "on-miss", "always" ] }, { name: "node", description: "Node id or name", type: "string" } ], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.exec }), defineChatCommand({ key: "model", nativeName: "model", description: "Show or set the model.", textAlias: "/model", category: "options", tier: "essential", args: [{ name: "model", description: "Model id (provider/model or id)", type: "string" }] }), defineChatCommand({ key: "models", nativeName: "models", description: "List model providers/models.", textAlias: "/models", tier: "standard", argsParsing: "none", acceptsArgs: true, category: "options" }), defineChatCommand({ key: "queue", nativeName: "queue", description: "Adjust queue settings.", textAlias: "/queue", category: "options", tier: "power", args: [ { name: "mode", description: "queue mode", type: "string", choices: [ "steer", "followup", "collect", "interrupt" ] }, { name: "debounce", description: "debounce duration (e.g. 500ms, 2s)", type: "string" }, { name: "cap", description: "queue cap", type: "number" }, { name: "drop", description: "drop policy", type: "string", choices: [ "old", "new", "summarize" ] } ], argsParsing: "none", formatArgs: COMMAND_ARG_FORMATTERS.queue }), defineChatCommand({ key: "bash", description: "Run host shell commands (host-only).", textAlias: "/bash", scope: "text", category: "tools", tier: "power", args: [{ name: "command", description: "Shell command", type: "string", captureRemaining: true }] }) ]; registerAlias(commands, "whoami", "/id"); registerAlias(commands, "think", "/thinking", "/t"); registerAlias(commands, "verbose", "/v"); registerAlias(commands, "reasoning", "/reason"); registerAlias(commands, "elevated", "/elev"); registerAlias(commands, "steer", "/tell"); assertCommandRegistry(commands); return commands; } //#endregion //#region src/auto-reply/commands-registry.data.ts /** Built-in and channel-derived command registry data for auto-reply commands. */ function supportsNativeCommands(plugin) { return plugin.capabilities?.nativeCommands === true; } function defineDockCommand(plugin) { return defineChatCommand({ key: `dock:${plugin.id}`, nativeName: `dock_${plugin.id}`, description: `Switch to ${plugin.id} for replies.`, textAliases: [`/dock-${plugin.id}`, `/dock_${plugin.id}`], category: "docks" }); } let cachedCommands = null; let cachedRegistryVersion = -1; function buildChatCommands() { const commands = [...buildBuiltinChatCommands({ listThinkingLevels }), ...listLoadedChannelPlugins().filter(supportsNativeCommands).map((plugin) => defineDockCommand(plugin))]; assertCommandRegistry(commands); return commands; } /** Returns the current command registry, including dynamic dock commands for native surfaces. */ function getChatCommands() { const registryVersion = getActivePluginChannelRegistryVersionFromState(); if (cachedCommands && registryVersion === cachedRegistryVersion) return cachedCommands; const commands = buildChatCommands(); cachedCommands = commands; cachedRegistryVersion = registryVersion; return commands; } //#endregion export { getChatCommands as t };