UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

287 lines (259 loc) • 17.3 kB
--- summary: "Operator helper methods, exec approvals, and agent delivery fallback" read_when: - Building an operator surface on top of the Gateway - Resolving exec approvals from a client - Requesting outbound delivery from an agent run title: "Gateway protocol operator methods" sidebarTitle: "Operator methods" doc-schema-version: 1 --- Methods an operator client calls on behalf of a person: helper reads, exec approval resolution, and delivery behavior for agent runs. ## Operator helper methods - `commands.list` (`operator.read`) fetches the runtime command inventory for an agent. - `agentId` is optional; omit it to read the default agent workspace. - `scope` controls which surface the primary `name` targets: `text` returns the primary text command token without the leading `/`; `native` and the default `both` path return provider-aware native names when available. - `textAliases` carries exact slash aliases such as `/model` and `/m`. - `nativeName` carries the provider-aware native command name when one exists. - `provider` is optional and only affects native naming plus native plugin command availability. - `includeArgs=false` omits serialized argument metadata from the response. - `tools.catalog` (`operator.read`) fetches the runtime tool catalog for an agent. The response includes grouped tools and provenance metadata: - `source`: `core` or `plugin` - `pluginId`: plugin owner when `source="plugin"` - `optional`: whether a plugin tool is optional - `tools.effective` (`operator.read`) fetches a prospective tool preview for a session. - `sessionKey` is required. - The gateway derives trusted runtime context from the session server-side instead of accepting caller-supplied auth or delivery context. - The response is a session-scoped server-derived projection from saved settings, including core, plugin, channel, and already-discovered MCP server tools. It is not the exact tool inventory of an active run: run authority, credentials, discovery, and final run policy can change which tools are offered. Absence from this preview does not establish that a tool is disabled, and inclusion does not guarantee execution access. - The projection can use cached inventory while refreshing it. Unsaved UI edits are not inputs, and saved or runtime changes may not appear immediately. - `tools.effective` is read-only for MCP: it may project a warm session MCP catalog through the final tool policy, but does not create MCP runtimes, connect transports, or issue `tools/list`. If no matching warm catalog exists, the response may include a notice such as `mcp-not-yet-connected`, `mcp-not-yet-listed`, or `mcp-stale-catalog`. - Effective tool entries use `source="core"`, `source="plugin"`, `source="channel"`, or `source="mcp"`. - `tools.invoke` (`operator.write`) invokes one available tool through the same gateway policy path as `/tools/invoke`. - `name` is required. `args`, `sessionKey`, `agentId`, `confirm`, and `idempotencyKey` are optional. - If both `sessionKey` and `agentId` are present, the resolved session agent must match `agentId`. - Owner-only core wrappers such as `cron`, `gateway`, and `nodes` require owner/admin identity (`operator.admin`) even though `tools.invoke` itself is `operator.write`. - The response is an SDK-facing envelope with `ok`, `toolName`, optional `output`, and typed `error` fields. Approval or policy refusals return `ok:false` in the payload rather than bypassing the gateway tool policy pipeline. - `skills.status` (`operator.read`) fetches the visible skill inventory for an agent. - `agentId` is optional; omit it to read the default agent workspace. - The response includes eligibility, missing requirements, config checks, and sanitized install options without exposing raw secret values. - `skills.search` and `skills.detail` (`operator.read`) return ClawHub discovery metadata. `skills.detail({ slug, version? })` accepts the publisher-qualified `installRef` from search and reads that release's card and scan summary. See [Skill registry details](/gateway/protocol/operator-methods#skill-registry-details). - `skills.upload.begin`, `skills.upload.chunk`, and `skills.upload.commit` (`operator.admin`) stage a private skill archive before installing it. This is a separate admin upload path for trusted clients, not the normal ClawHub skill install flow, and is disabled by default unless `skills.install.allowUploadedArchives` is enabled. - `skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })` creates an upload bound to that slug and force value. - `skills.upload.chunk({ uploadId, offset, dataBase64 })` appends bytes at the exact decoded offset. - `skills.upload.commit({ uploadId, sha256? })` verifies the final size and SHA-256. Commit only finalizes the upload; it does not install the skill. - Uploaded skill archives are zip archives containing a `SKILL.md` root. The archive's internal directory name never selects the install target. - `skills.install` (`operator.admin`) has three modes: - ClawHub mode: `{ source: "clawhub", slug, version?, force? }` installs a skill folder into the default agent workspace `skills/` directory. - Upload mode: `{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }` installs a committed upload into the default agent workspace `skills/<slug>` directory. The slug and force value must match the original `skills.upload.begin` request. Rejected unless `skills.install.allowUploadedArchives` is enabled; the setting does not affect ClawHub installs. - Gateway installer mode: `{ name, installId, timeoutMs? }` runs a declared `metadata.openclaw.install` action on the gateway host. Older clients may still send `dangerouslyForceUnsafeInstall`; this field is deprecated, accepted only for protocol compatibility, and ignored. Use `security.installPolicy` for operator-owned install decisions. - `skills.update` (`operator.admin`) has two modes: - ClawHub mode updates one tracked slug or all tracked ClawHub installs in the default agent workspace. Updates that would replace a skill directory whose installed files no longer match the recorded install digests are refused; the per-skill failure in `details.results` carries `code: "force_required"`. Retry with the optional `force: true` parameter to replace such a skill anyway. - Config mode patches `skills.entries.<skillKey>` values such as `enabled`, `apiKey`, and `env`. ### `models.list` views `models.list` accepts an optional `view` parameter (`src/agents/model-catalog-visibility.ts`): - Omitted or `"default"`: if `agents.defaults.modelPolicy.allow` is configured, the response is the allowed catalog, including dynamically discovered models for `provider/*` entries. Otherwise the response is the full gateway catalog. - `"configured"`: a compact catalog that also retains configured defaults and fallbacks for current-model controls. These metadata rows are not necessarily permitted manual choices. Published rows matched by `provider/*` remain included. Without an allowlist, configured and authenticated rows remain visible. - `"provider-config"`: source-authored `models.providers.*.models` inventory, independent of picker allowlists. Rows include public model capabilities and route-aware availability, but omit provider endpoints, auth material, and runtime request configuration. - `"all"`: full gateway catalog, bypassing `agents.defaults.modelPolicy.allow`. Use for diagnostics/discovery UIs, not normal model pickers. Clients that advertise `model-selection-policy` in connect `caps` receive `manualSelectionAllowed` on every `models.list` row. The same fact appears in their initial `models.snapshot`. Filter rows with `false` only when deriving manual choices; keep the complete catalog for current-model capabilities and readiness. Scoped configured reads also retain known metadata for the current session model, without changing its selection or granting permission. The fact is independent of `available` and does not authorize a session write. The server checks the current policy again when a model is selected. Capless connections retain the previous row shape. Generic client libraries do not opt in: a proxy forwarding a capable connection must support its negotiated row shape, or use a capless context for an older closed-schema consumer. Ordinary requests read the published catalog without starting provider discovery. Views select rows; they do not decide whether discovery runs. If the owner is not published yet, the request reports that the model catalog is not ready. A result whose owner becomes stale during projection is rejected with `UNAVAILABLE`, `retryable: true`, and `retryAfterMs: 0`. The Control UI shares one retry across catalog consumers, retaining cancellation and any explicit request deadline. - `preparedOnly: true` remains supported for automatic clients. Ordinary reads are passive with or without this flag. - `refresh: true` requests provider acquisition before reading the new published generation. Concurrent refreshes share the owner build. A failed acquisition retains compatible rows and reports its `providerOutcomes`; successful empty acquisition remains empty. - `provider: "<id>"` filters the published result through the captured provider aliases. Unknown provider IDs return `INVALID_REQUEST` with the rejected ID. Omit the filter or run `openclaw models list --all` to list models and their provider IDs. - `includeDetails: true` includes available input modalities, effective `contextTokens`, and a `local` endpoint classification. It does not expose endpoint URLs, headers, credentials, costs or runtime request parameters. For a conversation picker, pass `sessionKey` to read the session's canonical agent and saved account selection. A conflicting `agentId` is rejected. The viewer's current account default does not replace a saved session's selection. For a new draft, `authProfileId` previews a retained account owned by the identified caller with `operator.read` access. It does not save an account default. `sessionKey` and `authProfileId` are mutually exclusive. Saved-session metadata and draft previews stay current across unrelated session creations and writes. Before publishing, the Gateway rechecks the selected session's identity and canonical metadata, runtime configuration, and current access authority. Recreating a row with identical session facts does not invalidate the read. `chat.metadata` also tolerates title, activity, and ordinary preference updates to the selected row when its metadata inputs and access facts remain unchanged. Account, model, runtime, lifecycle, and access changes still invalidate an in-flight metadata read. Session and identified-account results include `accountSelection` display facts with the models. Collaborators do not receive another person's private account locator. The `provider-config` view remains shared authored inventory and omits account selection. `refreshFailed: true` reports a failed acquisition while compatible rows remain usable; recovery clears it. A successful empty catalog remains empty. The Gateway advertises `session-scoped-model-catalog` for this contract. `chat.metadata` remains available to legacy clients; the Control UI reads models directly and keeps commands in its metadata cache. Opening a conversation picker performs a passive read, without a model-cache timer or implicit provider refresh. Metadata refresh publishes model-owner facts without preparing every agent's commands and model projections. Requests prepare their agent's metadata on demand; a slow agent does not delay other agents. Retained commands and projections are bounded and do not retain completed requests' session documents. Account selection is projected for the current session even when its model catalog is shared. Provider renewal with unchanged inventory and auth metadata preserves cached metadata without broadcasting `chat.metadata.changed`. Discovery progress alone does not invalidate metadata; catalog changes and `refreshFailed` transitions still do. Shared model or account replacement still gates these reads, and history uses only already-prepared catalogs without starting or waiting for preparation. The Models settings page uses `preparedOnly: true` for its initial load, then requests `refresh: true` the first time a primary, utility, or fallback model picker opens for the current core-data snapshot. Pending opens share that page's request; completed reopens read the current published catalog without acquiring providers again. Explicit **Retry** requests a new acquisition. Replacing core settings data, the page, agent, or Gateway resets this request state. Core data reloads after configuration changes, so the next picker open can discover models from newly configured providers. Usable choices remain available when refresh fails. This replaces the former five-minute automatic refresh policy; elapsed time alone does not make a reopened Settings picker refresh. The Gateway shares concurrent provider acquisition. `preparedOnly: true` and `refresh: true` remain mutually exclusive. The Gateway advertises these published-read and details controls as `published-model-catalog`. Clients that require this contract must check the capability before sending the new fields; an older Gateway requires an update or restart, not a silent local fallback. The model CLI uses this contract for `models list` and `models list --refresh`. ## Skill registry details Use the exact `installRef` from `skills.search` when requesting details. For example: ```json { "slug": "@example-publisher/example-skill", "version": "1.2.0" } ``` Omitting `version` selects the latest published release. The response retains `skill`, `latestVersion`, `metadata`, and `owner`, and adds `registry`, `source`, `installRef`, and `selectedRelease`. `latestVersion` and `metadata` always describe the listing's latest release; `selectedRelease`, `card`, and `security` describe the requested release. Publisher and release mismatches never substitute another skill or version. `card` contains full card text when its `status` is `available`. Otherwise it has `status: "unavailable"` and a `reason`. `security` reports `scanStatus`, `hasWarnings`, `hasScanResult`, and any scan time, summary, or VirusTotal URL. Missing scans are explicitly unavailable. Optional release or card failures leave basic listing metadata readable and appear in the affected section or `warnings`. `requirements` reports the latest release's registry setup keys, operating systems, and systems when available. Its `scope: "registry-setup"` and `note` explain that setup keys combine environment and configuration requirements and do not include binary requirements. Structured requirements for older releases are unavailable because ClawHub only publishes these facts for latest. These are registry declarations, not checks of a local agent's eligibility; use `skills.status` for local requirements and configuration checks. `downloadability` is independent of card availability, listing visibility, and scan results. Missing or removed releases are `unavailable`; other skill releases are `unknown` because ClawHub does not publish an exact-release artifact availability assertion. Both states include a reason. Installation still performs its own resolution, integrity, and policy checks. External `skills-sh:` references remain install-only. `skills.detail` rejects them rather than returning a native registry skill with the same slug. ## Exec approvals - When an exec request needs approval, the gateway broadcasts `exec.approval.requested`. - Operator clients resolve by calling `exec.approval.resolve` (requires `operator.approvals`). - For `host=node`, `exec.approval.request` must include `systemRunPlan` (canonical `argv`/`cwd`/`rawCommand`/session metadata). Requests missing `systemRunPlan` are rejected. - After approval, forwarded `node.invoke system.run` calls reuse that canonical `systemRunPlan` as the authoritative command/cwd/session context. - If a caller mutates `command`, `rawCommand`, `cwd`, `agentId`, or `sessionKey` between prepare and the final approved `system.run` forward, the gateway rejects the run instead of trusting the mutated payload. ## Agent delivery fallback - `agent` requests can include `deliver=true` to request outbound delivery. - `bestEffortDeliver=false` (the default) keeps strict behavior: unresolved or internal-only delivery targets return `INVALID_REQUEST`. - `bestEffortDeliver=true` allows fallback to session-only execution when no external deliverable route can be resolved (for example internal/webchat sessions or ambiguous multi-channel configs). - Final `agent` results may include `result.deliveryStatus` when delivery was requested, using the same `sent`, `suppressed`, `partial_failed`, and `failed` statuses documented for [`openclaw agent --json --deliver`](/cli/agent#json-delivery-status).