UNPKG

@gguf/claw

Version:

Multi-channel AI gateway with extensible messaging integrations

357 lines (354 loc) 15.2 kB
import "./paths-B4BZAPZh.js"; import { B as theme, P as setVerbose, k as info, z as isRich } from "./utils-CP9YLh6M.js"; import "./thinking-EAliFiVK.js"; import { D as resolveSessionModelRef, ar as lookupContextTokens, b as classifySessionKey } from "./reply-BylFHBd4.js"; import { x as parseAgentSessionKey } from "./session-key-CZ6OwgSB.js"; import "./registry-B-j4DRfe.js"; import { f as defaultRuntime } from "./subsystem-BCQGGxdd.js"; import "./exec-DYqRzFbo.js"; import "./agent-scope-BnZW9Gh2.js"; import { Gt as DEFAULT_PROVIDER, Ut as DEFAULT_CONTEXT_TOKENS, Wt as DEFAULT_MODEL, p as resolveConfiguredModelRef } from "./model-selection-CqaTAlhy.js"; import "./github-copilot-token-D2zp6kMZ.js"; import "./boolean-BsqeuxE6.js"; import "./env-VriqyjXT.js"; import "./message-channel-Bena1Tzd.js"; import "./send-CsyONLnQ.js"; import { i as loadConfig } from "./config-PQiujvsf.js"; import "./manifest-registry-4k4vkhPS.js"; import "./runner-U04aiHHC.js"; import "./image-DxEpBZim.js"; import "./models-config-B459BnCS.js"; import "./pi-model-discovery-4uUnLc3n.js"; import "./pi-embedded-helpers-BdscQhyS.js"; import "./sandbox-UAzvS0V6.js"; import "./image-ops-CI1VknD1.js"; import "./common-a25M2Kvi.js"; import "./chrome-Dd5zBIFu.js"; import "./tailscale-C3JsBEiY.js"; import "./auth-DZSWPd8D.js"; import "./server-context-DAWsUNUs.js"; import "./frontmatter-6HZ0_y2V.js"; import "./skills-CLmzWt48.js"; import "./routes-DIQa_0pt.js"; import "./redact-B7Mjvk0c.js"; import "./errors-kfGqPQ4b.js"; import "./fs-safe-_OpKPuZA.js"; import "./paths-D1WZUYry.js"; import "./ssrf-6f5m2MMA.js"; import "./store-DSGYY-H9.js"; import "./ports-DwDxX6cS.js"; import "./trash-DLzIf__E.js"; import { L as resolveFreshSessionTotalTokens, a as loadSessionStore } from "./sessions-Z1BZU3xh.js"; import "./dock-7F-MiPtF.js"; import "./normalize-Ci8UyR3Z.js"; import "./accounts-Bj1dJ-fd.js"; import "./accounts-DOl1Wkxo.js"; import "./accounts-t6R5_PzC.js"; import "./bindings-Dja1z-h8.js"; import "./logging-xYH6GmRT.js"; import "./send-uu2Jc-Js.js"; import "./plugins-CKbXkuXd.js"; import { c as resolveStorePath } from "./paths-C2NfoGZE.js"; import "./tool-display-Bx4M6uNT.js"; import "./fetch-guard-C1sYsWgl.js"; import "./api-key-rotation-CpGefdGL.js"; import "./local-roots-DiDvXIIo.js"; import "./sqlite-JcMMx8Z5.js"; import "./model-catalog-CIixTnGt.js"; import "./tokens-D4lZk7-h.js"; import "./with-timeout-DijiQjw6.js"; import "./deliver-DgvS3uCz.js"; import "./diagnostic-UUwku4RV.js"; import "./diagnostic-session-state-ByqoIyGn.js"; import "./send-DbwyyQAv.js"; import "./model-VbWjwqaW.js"; import "./reply-prefix-DAK7-zK4.js"; import "./memory-cli-DxmtLhh_.js"; import "./manager-C0teWocQ.js"; import "./retry-rUEdE6zT.js"; import "./chunk-CMylpCPi.js"; import "./markdown-tables-B9VGUdDc.js"; import "./ir-24qCLTKH.js"; import "./render-CXDO_kgw.js"; import "./commands-registry-bb_U-3FM.js"; import "./client-BdSkEtCd.js"; import "./call-BCz_8mqq.js"; import "./pairing-token-B-_eiWlR.js"; import { n as formatTimeAgo } from "./format-relative-DdvuDKIv.js"; import "./channel-activity-DynIQUB_.js"; import "./fetch-Bu5zBCce.js"; import "./tables-C70h_80U.js"; import "./send-CAfFUUkm.js"; import "./pairing-store-T5DpOfoL.js"; import "./proxy-BiOWrea2.js"; import { t as formatDocsLink } from "./links-BVCMOGeE.js"; import { n as runCommandWithRuntime } from "./cli-utils-CX1oQ81G.js"; import { t as formatHelpExamples } from "./help-format-dbk2xW0E.js"; import "./progress-CaVMHLaE.js"; import "./resolve-route-2TU_aaLs.js"; import "./replies-NhrZJ3yf.js"; import "./skill-commands-N8Sho46-.js"; import "./workspace-dirs-CE3CxabZ.js"; import "./pi-tools.policy-DTy1DnPK.js"; import "./outbound-attachment-CntoLTI_.js"; import "./delivery-queue-CxDDEWQg.js"; import "./session-cost-usage-BlUDaylg.js"; import "./send-4LoRaltQ.js"; import "./onboard-helpers-DbjfBSMX.js"; import "./prompt-style-VqCNjBi8.js"; import "./pairing-labels-DaESq9ML.js"; import "./exec-approvals-q0C8VDMT.js"; import "./nodes-screen-5fMfTT2n.js"; import "./control-service-BoO2TGOx.js"; import "./stagger-B6VQyn1F.js"; import "./channel-selection-DuDSoVSC.js"; import "./runtime-guard-DlT3NecY.js"; import { n as parsePositiveIntOrUndefined } from "./helpers-B5MBaaJr.js"; import "./skills-status-kQ1GipOi.js"; import "./dangerous-tools-DyngmY3-.js"; import "./skill-scanner-D56xvwQF.js"; import "./channels-status-issues-ClkP4ZUC.js"; import "./systemd-B6S4ND7H.js"; import "./service-Bw9h81em.js"; import "./diagnostics-CArN76wS.js"; import "./table-D-EOwMue.js"; import "./audit-BjSHYL1a.js"; import { t as statusCommand } from "./status-DuhTF2p3.js"; import { r as healthCommand } from "./health-Bt3xmMjK.js"; import "./update-check-CHLDbXI4.js"; import "./dm-policy-shared-XAIBK3tz.js"; import "./node-service-x4yUQJuC.js"; import "./status.update-BdrAB0yT.js"; //#region src/commands/sessions.ts const KIND_PAD = 6; const KEY_PAD = 26; const AGE_PAD = 9; const MODEL_PAD = 14; const TOKENS_PAD = 20; const formatKTokens = (value) => `${(value / 1e3).toFixed(value >= 1e4 ? 0 : 1)}k`; const truncateKey = (key) => { if (key.length <= KEY_PAD) return key; const head = Math.max(4, KEY_PAD - 10); return `${key.slice(0, head)}...${key.slice(-6)}`; }; const colorByPct = (label, pct, rich) => { if (!rich || pct === null) return label; if (pct >= 95) return theme.error(label); if (pct >= 80) return theme.warn(label); if (pct >= 60) return theme.success(label); return theme.muted(label); }; const formatTokensCell = (total, contextTokens, rich) => { if (total === void 0) { const label = `unknown/${contextTokens ? formatKTokens(contextTokens) : "?"} (?%)`; return rich ? theme.muted(label.padEnd(TOKENS_PAD)) : label.padEnd(TOKENS_PAD); } const totalLabel = formatKTokens(total); const ctxLabel = contextTokens ? formatKTokens(contextTokens) : "?"; const pct = contextTokens ? Math.min(999, Math.round(total / contextTokens * 100)) : null; return colorByPct(`${totalLabel}/${ctxLabel} (${pct ?? "?"}%)`.padEnd(TOKENS_PAD), pct, rich); }; const formatKindCell = (kind, rich) => { const label = kind.padEnd(KIND_PAD); if (!rich) return label; if (kind === "group") return theme.accentBright(label); if (kind === "global") return theme.warn(label); if (kind === "direct") return theme.accent(label); return theme.muted(label); }; const formatAgeCell = (updatedAt, rich) => { const padded = (updatedAt ? formatTimeAgo(Date.now() - updatedAt) : "unknown").padEnd(AGE_PAD); return rich ? theme.muted(padded) : padded; }; const formatModelCell = (model, rich) => { const label = (model ?? "unknown").padEnd(MODEL_PAD); return rich ? theme.info(label) : label; }; const formatFlagsCell = (row, rich) => { const label = [ row.thinkingLevel ? `think:${row.thinkingLevel}` : null, row.verboseLevel ? `verbose:${row.verboseLevel}` : null, row.reasoningLevel ? `reasoning:${row.reasoningLevel}` : null, row.elevatedLevel ? `elev:${row.elevatedLevel}` : null, row.responseUsage ? `usage:${row.responseUsage}` : null, row.groupActivation ? `activation:${row.groupActivation}` : null, row.systemSent ? "system" : null, row.abortedLastRun ? "aborted" : null, row.sessionId ? `id:${row.sessionId}` : null ].filter(Boolean).join(" "); return label.length === 0 ? "" : rich ? theme.muted(label) : label; }; function toRows(store) { return Object.entries(store).map(([key, entry]) => { const updatedAt = entry?.updatedAt ?? null; return { key, kind: classifySessionKey(key, entry), updatedAt, ageMs: updatedAt ? Date.now() - updatedAt : null, sessionId: entry?.sessionId, systemSent: entry?.systemSent, abortedLastRun: entry?.abortedLastRun, thinkingLevel: entry?.thinkingLevel, verboseLevel: entry?.verboseLevel, reasoningLevel: entry?.reasoningLevel, elevatedLevel: entry?.elevatedLevel, responseUsage: entry?.responseUsage, groupActivation: entry?.groupActivation, inputTokens: entry?.inputTokens, outputTokens: entry?.outputTokens, totalTokens: entry?.totalTokens, totalTokensFresh: entry?.totalTokensFresh, model: entry?.model, modelProvider: entry?.modelProvider, providerOverride: entry?.providerOverride, modelOverride: entry?.modelOverride, contextTokens: entry?.contextTokens }; }).toSorted((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0)); } async function sessionsCommand(opts, runtime) { const cfg = loadConfig(); const resolved = resolveConfiguredModelRef({ cfg, defaultProvider: DEFAULT_PROVIDER, defaultModel: DEFAULT_MODEL }); const configContextTokens = cfg.agents?.defaults?.contextTokens ?? lookupContextTokens(resolved.model) ?? DEFAULT_CONTEXT_TOKENS; const configModel = resolved.model ?? DEFAULT_MODEL; const storePath = resolveStorePath(opts.store ?? cfg.session?.store); const store = loadSessionStore(storePath); let activeMinutes; if (opts.active !== void 0) { const parsed = Number.parseInt(String(opts.active), 10); if (Number.isNaN(parsed) || parsed <= 0) { runtime.error("--active must be a positive integer (minutes)"); runtime.exit(1); return; } activeMinutes = parsed; } const rows = toRows(store).filter((row) => { if (activeMinutes === void 0) return true; if (!row.updatedAt) return false; return Date.now() - row.updatedAt <= activeMinutes * 6e4; }); if (opts.json) { runtime.log(JSON.stringify({ path: storePath, count: rows.length, activeMinutes: activeMinutes ?? null, sessions: rows.map((r) => { const model = resolveSessionModelRef(cfg, r, parseAgentSessionKey(r.key)?.agentId).model ?? configModel; return { ...r, totalTokens: resolveFreshSessionTotalTokens(r) ?? null, totalTokensFresh: typeof r.totalTokens === "number" ? r.totalTokensFresh !== false : false, contextTokens: r.contextTokens ?? lookupContextTokens(model) ?? configContextTokens ?? null, model }; }) }, null, 2)); return; } runtime.log(info(`Session store: ${storePath}`)); runtime.log(info(`Sessions listed: ${rows.length}`)); if (activeMinutes) runtime.log(info(`Filtered to last ${activeMinutes} minute(s)`)); if (rows.length === 0) { runtime.log("No sessions found."); return; } const rich = isRich(); const header = [ "Kind".padEnd(KIND_PAD), "Key".padEnd(KEY_PAD), "Age".padEnd(AGE_PAD), "Model".padEnd(MODEL_PAD), "Tokens (ctx %)".padEnd(TOKENS_PAD), "Flags" ].join(" "); runtime.log(rich ? theme.heading(header) : header); for (const row of rows) { const model = resolveSessionModelRef(cfg, row, parseAgentSessionKey(row.key)?.agentId).model ?? configModel; const contextTokens = row.contextTokens ?? lookupContextTokens(model) ?? configContextTokens; const total = resolveFreshSessionTotalTokens(row); const keyLabel = truncateKey(row.key).padEnd(KEY_PAD); const keyCell = rich ? theme.accent(keyLabel) : keyLabel; const line = [ formatKindCell(row.kind, rich), keyCell, formatAgeCell(row.updatedAt, rich), formatModelCell(model, rich), formatTokensCell(total, contextTokens ?? null, rich), formatFlagsCell(row, rich) ].join(" "); runtime.log(line.trimEnd()); } } //#endregion //#region src/cli/program/register.status-health-sessions.ts function resolveVerbose(opts) { return Boolean(opts.verbose || opts.debug); } function parseTimeoutMs(timeout) { const parsed = parsePositiveIntOrUndefined(timeout); if (timeout !== void 0 && parsed === void 0) { defaultRuntime.error("--timeout must be a positive integer (milliseconds)"); defaultRuntime.exit(1); return null; } return parsed; } function registerStatusHealthSessionsCommands(program) { program.command("status").description("Show channel health and recent session recipients").option("--json", "Output JSON instead of text", false).option("--all", "Full diagnosis (read-only, pasteable)", false).option("--usage", "Show model provider usage/quota snapshots", false).option("--deep", "Probe channels (WhatsApp Web + Telegram + Discord + Slack + Signal)", false).option("--timeout <ms>", "Probe timeout in milliseconds", "10000").option("--verbose", "Verbose logging", false).option("--debug", "Alias for --verbose", false).addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw status", "Show channel health + session summary."], ["openclaw status --all", "Full diagnosis (read-only)."], ["openclaw status --json", "Machine-readable output."], ["openclaw status --usage", "Show model provider usage/quota snapshots."], ["openclaw status --deep", "Run channel probes (WA + Telegram + Discord + Slack + Signal)."], ["openclaw status --deep --timeout 5000", "Tighten probe timeout."] ])}`).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.openclaw.ai/cli/status")}\n`).action(async (opts) => { const verbose = resolveVerbose(opts); setVerbose(verbose); const timeout = parseTimeoutMs(opts.timeout); if (timeout === null) return; await runCommandWithRuntime(defaultRuntime, async () => { await statusCommand({ json: Boolean(opts.json), all: Boolean(opts.all), deep: Boolean(opts.deep), usage: Boolean(opts.usage), timeoutMs: timeout, verbose }, defaultRuntime); }); }); program.command("health").description("Fetch health from the running gateway").option("--json", "Output JSON instead of text", false).option("--timeout <ms>", "Connection timeout in milliseconds", "10000").option("--verbose", "Verbose logging", false).option("--debug", "Alias for --verbose", false).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.openclaw.ai/cli/health")}\n`).action(async (opts) => { const verbose = resolveVerbose(opts); setVerbose(verbose); const timeout = parseTimeoutMs(opts.timeout); if (timeout === null) return; await runCommandWithRuntime(defaultRuntime, async () => { await healthCommand({ json: Boolean(opts.json), timeoutMs: timeout, verbose }, defaultRuntime); }); }); program.command("sessions").description("List stored conversation sessions").option("--json", "Output as JSON", false).option("--verbose", "Verbose logging", false).option("--store <path>", "Path to session store (default: resolved from config)").option("--active <minutes>", "Only show sessions updated within the past N minutes").addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([ ["openclaw sessions", "List all sessions."], ["openclaw sessions --active 120", "Only last 2 hours."], ["openclaw sessions --json", "Machine-readable output."], ["openclaw sessions --store ./tmp/sessions.json", "Use a specific session store."] ])}\n\n${theme.muted("Shows token usage per session when the agent reports it; set agents.defaults.contextTokens to cap the window and show %.")}`).addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.openclaw.ai/cli/sessions")}\n`).action(async (opts) => { setVerbose(Boolean(opts.verbose)); await sessionsCommand({ json: Boolean(opts.json), store: opts.store, active: opts.active }, defaultRuntime); }); } //#endregion export { registerStatusHealthSessionsCommands };