UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

498 lines (497 loc) 17.4 kB
import { t as isTruthyEnvValue } from "./env-Di49gJwo.js"; import { a as getPositiveIntFlagValue, c as hasFlag, i as getFlagValue, k as isValueToken, r as getCommandPositionalsWithRootOptions, s as getVerboseFlag } from "./argv-CnfL__6a.js"; import { t as resolveCliArgvInvocation } from "./argv-invocation-CxGUjPqA.js"; import { t as createLazyImportLoader } from "./lazy-promise-BONnzNfb.js"; import { n as defaultRuntime } from "./runtime-B4lgFmsS.js"; import { i as cliCommandCatalog, r as matchesCommandPath, t as resolveCliCommandPathPolicy } from "./command-path-policy-B0jd3lsl.js"; import { i as parseStrictPositiveIntOrUndefined } from "./helpers-gBVG4H2O.js"; import { n as ensureCliExecutionBootstrap, r as resolveCliExecutionStartupContext, t as applyCliExecutionStartupPresentation } from "./command-execution-startup-Ckkq0X-v.js"; //#region src/cli/program/route-args.ts function parseOptionalFlagValue(argv, name) { const value = getFlagValue(argv, name); if (value === null) return { ok: false }; return { ok: true, value }; } function parseRepeatedFlagValues(argv, name) { const values = []; const args = argv.slice(2); for (let i = 0; i < args.length; i += 1) { const arg = args[i]; if (!arg || arg === "--") break; if (arg === name) { const next = args[i + 1]; if (!isValueToken(next)) return null; values.push(next); i += 1; continue; } if (arg.startsWith(`${name}=`)) { const value = arg.slice(name.length + 1).trim(); if (!value) return null; values.push(value); } } return values; } function parseSinglePositional(argv, params) { const positionals = getCommandPositionalsWithRootOptions(argv, params); if (!positionals || positionals.length !== 1) return null; return positionals[0] ?? null; } /** Parse `openclaw health` flags for the route-first status family. */ function parseHealthRouteArgs(argv) { const timeoutMs = getPositiveIntFlagValue(argv, "--timeout"); if (timeoutMs === null) return null; return { json: hasFlag(argv, "--json"), verbose: getVerboseFlag(argv, { includeDebug: true }), timeoutMs }; } /** Parse `openclaw status` flags without registering the full command tree. */ function parseStatusRouteArgs(argv) { const timeoutMs = getPositiveIntFlagValue(argv, "--timeout"); if (timeoutMs === null) return null; return { json: hasFlag(argv, "--json"), deep: hasFlag(argv, "--deep"), all: hasFlag(argv, "--all"), usage: hasFlag(argv, "--usage"), verbose: getVerboseFlag(argv, { includeDebug: true }), timeoutMs }; } /** Parse `openclaw gateway status` RPC-only flags accepted by the fast route. */ function parseGatewayStatusRouteArgs(argv) { const url = parseOptionalFlagValue(argv, "--url"); if (!url.ok) return null; const token = parseOptionalFlagValue(argv, "--token"); if (!token.ok) return null; const password = parseOptionalFlagValue(argv, "--password"); if (!password.ok) return null; const timeout = parseOptionalFlagValue(argv, "--timeout"); if (!timeout.ok) return null; const ssh = parseOptionalFlagValue(argv, "--ssh"); if (!ssh.ok || ssh.value !== void 0) return null; const sshIdentity = parseOptionalFlagValue(argv, "--ssh-identity"); if (!sshIdentity.ok || sshIdentity.value !== void 0) return null; if (hasFlag(argv, "--ssh-auto")) return null; return { rpc: { url: url.value, token: token.value, password: password.value, timeout: timeout.value }, deep: hasFlag(argv, "--deep"), json: hasFlag(argv, "--json"), requireRpc: hasFlag(argv, "--require-rpc"), probe: !hasFlag(argv, "--no-probe") }; } /** Parse `openclaw sessions` filters for JSON/list route execution. */ function parseSessionsRouteArgs(argv) { const agent = parseOptionalFlagValue(argv, "--agent"); if (!agent.ok) return null; const store = parseOptionalFlagValue(argv, "--store"); if (!store.ok) return null; const active = parseOptionalFlagValue(argv, "--active"); if (!active.ok) return null; const limit = parseOptionalFlagValue(argv, "--limit"); if (!limit.ok) return null; return { json: hasFlag(argv, "--json"), allAgents: hasFlag(argv, "--all-agents"), agent: agent.value, store: store.value, active: active.value, limit: limit.value }; } /** Parse `openclaw agents list` display switches for route-first execution. */ function parseAgentsListRouteArgs(argv) { return { json: hasFlag(argv, "--json"), bindings: hasFlag(argv, "--bindings") }; } /** Parse `openclaw config get <path>` while preserving root option handling. */ function parseConfigGetRouteArgs(argv) { const path = parseSinglePositional(argv, { commandPath: ["config", "get"], booleanFlags: ["--json"] }); if (!path) return null; return { path, json: hasFlag(argv, "--json") }; } /** Parse `openclaw config unset <path>` and its mutation guard flags. */ function parseConfigUnsetRouteArgs(argv) { const path = parseSinglePositional(argv, { commandPath: ["config", "unset"], booleanFlags: [ "--dry-run", "--allow-exec", "--json" ] }); if (!path) return null; return { path, cliOptions: { dryRun: hasFlag(argv, "--dry-run"), allowExec: hasFlag(argv, "--allow-exec"), json: hasFlag(argv, "--json") } }; } /** Parse `openclaw models list` filters for the lightweight model catalog route. */ function parseModelsListRouteArgs(argv) { const provider = parseOptionalFlagValue(argv, "--provider"); if (!provider.ok) return null; return { provider: provider.value, all: hasFlag(argv, "--all"), local: hasFlag(argv, "--local"), json: hasFlag(argv, "--json"), plain: hasFlag(argv, "--plain") }; } /** Parse `openclaw models status` probe controls for the route-first status path. */ function parseModelsStatusRouteArgs(argv) { const probeProvider = parseOptionalFlagValue(argv, "--probe-provider"); if (!probeProvider.ok) return null; const probeTimeout = parseOptionalFlagValue(argv, "--probe-timeout"); if (!probeTimeout.ok) return null; const probeConcurrency = parseOptionalFlagValue(argv, "--probe-concurrency"); if (!probeConcurrency.ok) return null; const probeMaxTokens = parseOptionalFlagValue(argv, "--probe-max-tokens"); if (!probeMaxTokens.ok) return null; const agent = parseOptionalFlagValue(argv, "--agent"); if (!agent.ok) return null; const probeProfileValues = parseRepeatedFlagValues(argv, "--probe-profile"); if (probeProfileValues === null) return null; const probeProfile = probeProfileValues.length === 0 ? void 0 : probeProfileValues.length === 1 ? probeProfileValues[0] : probeProfileValues; return { probeProvider: probeProvider.value, probeTimeout: probeTimeout.value, probeConcurrency: probeConcurrency.value, probeMaxTokens: probeMaxTokens.value, agent: agent.value, probeProfile, json: hasFlag(argv, "--json"), plain: hasFlag(argv, "--plain"), check: hasFlag(argv, "--check"), probe: hasFlag(argv, "--probe") }; } /** Parse `openclaw channels list` display flags for the route-first list path. */ function parseChannelsListRouteArgs(argv) { return { json: hasFlag(argv, "--json"), all: hasFlag(argv, "--all") }; } /** Parse `openclaw channels status` probe flags without full CLI registration. */ function parseChannelsStatusRouteArgs(argv) { const timeout = parseOptionalFlagValue(argv, "--timeout"); const channel = parseOptionalFlagValue(argv, "--channel"); if (!timeout.ok) return null; if (!channel.ok) return null; return { channel: channel.value, json: hasFlag(argv, "--json"), probe: hasFlag(argv, "--probe"), timeout: timeout.value }; } /** Parse JSON-only `openclaw plugins list` flags for plugin inventory output. */ function parsePluginsListRouteArgs(argv) { if (!hasFlag(argv, "--json")) return null; const positionals = getCommandPositionalsWithRootOptions(argv, { commandPath: ["plugins", "list"], booleanFlags: [ "--json", "--enabled", "--verbose" ] }); if (!positionals || positionals.length !== 0) return null; return { json: true, enabled: hasFlag(argv, "--enabled"), verbose: hasFlag(argv, "--verbose") }; } function parseTasksListRouteArgsForCommandPath(argv, commandPath) { if (!hasFlag(argv, "--json")) return null; const positionals = getCommandPositionalsWithRootOptions(argv, { commandPath, booleanFlags: ["--json"], valueFlags: ["--runtime", "--status"] }); if (!positionals || positionals.length !== 0) return null; const runtime = parseOptionalFlagValue(argv, "--runtime"); if (!runtime.ok) return null; const status = parseOptionalFlagValue(argv, "--status"); if (!status.ok) return null; return { json: true, runtime: runtime.value, status: status.value }; } /** Parse both `openclaw tasks --json` and `openclaw tasks list --json` aliases. */ function parseTasksListRouteArgs(argv) { return parseTasksListRouteArgsForCommandPath(argv, ["tasks"]) ?? parseTasksListRouteArgsForCommandPath(argv, ["tasks", "list"]); } /** Parse JSON-only `openclaw tasks audit` filters for the route-first audit path. */ function parseTasksAuditRouteArgs(argv) { if (!hasFlag(argv, "--json")) return null; const positionals = getCommandPositionalsWithRootOptions(argv, { commandPath: ["tasks", "audit"], booleanFlags: ["--json"], valueFlags: [ "--severity", "--code", "--limit" ] }); if (!positionals || positionals.length !== 0) return null; const severity = parseOptionalFlagValue(argv, "--severity"); if (!severity.ok) return null; const code = parseOptionalFlagValue(argv, "--code"); if (!code.ok) return null; const rawLimit = getFlagValue(argv, "--limit"); if (rawLimit === null) return null; const limit = rawLimit === void 0 ? void 0 : parseStrictPositiveIntOrUndefined(rawLimit); if (rawLimit !== void 0 && limit === void 0) return null; return { json: true, severity: severity.value, code: code.value, limit }; } //#endregion //#region src/cli/program/routed-command-definitions.ts function defineRoutedCommand(definition) { return definition; } const configCliLoader = createLazyImportLoader(() => import("./config-cli-DC7j84k_.js")); const agentsListCommandLoader = createLazyImportLoader(() => import("./agents.commands.list-AMLROqTf.js")); const modelsListCommandLoader = createLazyImportLoader(() => import("./list.list-command-BaGs2hLl.js")); const modelsStatusCommandLoader = createLazyImportLoader(() => import("./list.status-command-CGLwk2D-.js")); const tasksJsonCommandLoader = createLazyImportLoader(() => import("./tasks-json-BsF13058.js")); function loadConfigCli() { return configCliLoader.load(); } function loadAgentsListCommand() { return agentsListCommandLoader.load(); } function loadModelsListCommand() { return modelsListCommandLoader.load(); } function loadModelsStatusCommand() { return modelsStatusCommandLoader.load(); } function loadTasksJsonCommand() { return tasksJsonCommandLoader.load(); } /** Route id to lazy parser/runner definition. */ const routedCommandDefinitions = { health: defineRoutedCommand({ parseArgs: parseHealthRouteArgs, runParsedArgs: async (args) => { const { healthCommand } = await import("./health-B9v-C93Q.js"); await healthCommand(args, defaultRuntime); } }), status: defineRoutedCommand({ parseArgs: parseStatusRouteArgs, runParsedArgs: async (args) => { if (args.json) { const { statusJsonCommand } = await import("./status-json-CzgQ8tWi.js"); await statusJsonCommand({ deep: args.deep, all: args.all, usage: args.usage, timeoutMs: args.timeoutMs }, defaultRuntime); return; } const { statusCommand } = await import("./status-BUsX5ajI.js"); await statusCommand(args, defaultRuntime); } }), "gateway-status": defineRoutedCommand({ parseArgs: parseGatewayStatusRouteArgs, runParsedArgs: async (args) => { const { runDaemonStatus } = await import("./status-D6zcQRqq.js"); await runDaemonStatus(args); } }), sessions: defineRoutedCommand({ parseArgs: parseSessionsRouteArgs, runParsedArgs: async (args) => { const { sessionsCommand } = await import("./sessions-DMIMtB8M.js"); await sessionsCommand(args, defaultRuntime); } }), "agents-list": defineRoutedCommand({ parseArgs: parseAgentsListRouteArgs, runParsedArgs: async (args) => { const { agentsListCommand } = await loadAgentsListCommand(); await agentsListCommand(args, defaultRuntime); } }), "config-get": defineRoutedCommand({ parseArgs: parseConfigGetRouteArgs, runParsedArgs: async (args) => { const { runConfigGet } = await loadConfigCli(); await runConfigGet(args); } }), "config-unset": defineRoutedCommand({ parseArgs: parseConfigUnsetRouteArgs, runParsedArgs: async (args) => { const { runConfigUnset } = await loadConfigCli(); await runConfigUnset(args); } }), "models-list": defineRoutedCommand({ parseArgs: parseModelsListRouteArgs, runParsedArgs: async (args) => { const { modelsListCommand } = await loadModelsListCommand(); await modelsListCommand(args, defaultRuntime); } }), "models-status": defineRoutedCommand({ parseArgs: parseModelsStatusRouteArgs, runParsedArgs: async (args) => { const { modelsStatusCommand } = await loadModelsStatusCommand(); await modelsStatusCommand(args, defaultRuntime); } }), "tasks-list": defineRoutedCommand({ parseArgs: parseTasksListRouteArgs, runParsedArgs: async (args) => { const { tasksListJsonCommand } = await loadTasksJsonCommand(); await tasksListJsonCommand(args, defaultRuntime); } }), "tasks-audit": defineRoutedCommand({ parseArgs: parseTasksAuditRouteArgs, runParsedArgs: async (args) => { const { tasksAuditJsonCommand } = await loadTasksJsonCommand(); await tasksAuditJsonCommand(args, defaultRuntime); } }), "channels-list": defineRoutedCommand({ parseArgs: parseChannelsListRouteArgs, runParsedArgs: async (args) => { const { channelsListCommand } = await import("./list-CyAfVw69.js"); await channelsListCommand(args, defaultRuntime); } }), "channels-status": defineRoutedCommand({ parseArgs: parseChannelsStatusRouteArgs, runParsedArgs: async (args) => { const { channelsStatusCommand } = await import("./status-C2M02NJv.js"); await channelsStatusCommand(args, defaultRuntime); } }), "plugins-list": defineRoutedCommand({ parseArgs: parsePluginsListRouteArgs, runParsedArgs: async (args) => { const { runPluginsListCommand } = await import("./plugins-list-command-DTntEbuI.js"); await runPluginsListCommand(args, defaultRuntime); } }) }; //#endregion //#region src/cli/program/route-specs.ts function createCommandLoadPlugins(commandPath) { return (argv) => { const loadPlugins = resolveCliCommandPathPolicy([...commandPath]).loadPlugins; return loadPlugins === "always" || loadPlugins === "text-only" && !hasFlag(argv, "--json"); }; } function createParsedRoute(params) { return { matches: (path) => matchesCommandPath(path, params.entry.commandPath, { exact: params.entry.exact }), canRun: (argv) => Boolean(params.definition.parseArgs(argv)), loadPlugins: params.entry.route?.preloadPlugins ? createCommandLoadPlugins(params.entry.commandPath) : void 0, run: async (argv) => { const args = params.definition.parseArgs(argv); if (!args) return false; await params.definition.runParsedArgs(args); return true; } }; } /** Route specs generated from catalog entries with parseable routed-command definitions. */ const routedCommands = cliCommandCatalog.filter((entry) => Boolean(entry.route)).flatMap((entry) => { const definition = routedCommandDefinitions[entry.route.id]; return definition ? [createParsedRoute({ entry, definition })] : []; }); //#endregion //#region src/cli/program/routes.ts /** Find the first route matching a command path and parseable argv. */ function findRoutedCommand(path, argv) { for (const route of routedCommands) if (route.matches(path)) { if (argv && route.canRun && !route.canRun(argv)) continue; return route; } return null; } //#endregion //#region src/cli/route.ts async function prepareRoutedCommand(params) { const { startupPolicy } = resolveCliExecutionStartupContext({ argv: params.argv, jsonOutputMode: hasFlag(params.argv, "--json"), env: process.env, routeMode: true }); const { VERSION } = await import("./version-Dpd_K_tD.js"); await applyCliExecutionStartupPresentation({ argv: params.argv, startupPolicy, showBanner: process.stdout.isTTY && !startupPolicy.suppressDoctorStdout, version: VERSION }); const shouldLoadPlugins = typeof params.loadPlugins === "function" ? params.loadPlugins(params.argv) : params.loadPlugins; await ensureCliExecutionBootstrap({ runtime: defaultRuntime, commandPath: params.commandPath, startupPolicy, loadPlugins: shouldLoadPlugins ?? startupPolicy.loadPlugins }); } /** Try a lightweight route-first command before falling back to the full CLI program. */ async function tryRouteCli(argv) { if (isTruthyEnvValue(process.env.OPENCLAW_DISABLE_ROUTE_FIRST)) return false; const invocation = resolveCliArgvInvocation(argv); if (invocation.hasHelpOrVersion) return false; if (!invocation.commandPath[0]) return false; const route = findRoutedCommand(invocation.commandPath, argv); if (!route) return false; if (route.canRun && !route.canRun(argv)) return false; await prepareRoutedCommand({ argv, commandPath: invocation.commandPath, loadPlugins: route.loadPlugins }); return route.run(argv); } //#endregion export { tryRouteCli };