Commit graph

254 commits

Author SHA1 Message Date
RoboClaw
a2f5e58e09
docs(tokenjuice): clarify native Codex shell output (#189009)
Clarify Tokenjuice compaction for OpenClaw embedded and dynamic tools, and explain why native Codex shell results returned to the model stay unchanged. Preserve runtime behavior and configuration.

Supersedes #128543, thanks @santhiprakash.

Co-authored-by: Santhi Prakash <b.santhiprakash@gmail.com>
2026-10-31 12:22:15 +08:00
RoboClaw
8c832244f0
docs: add a dedicated Google Vertex AI setup guide (#188797)
Consolidate ADC setup, environment requirements, model selection, and verification in one guide.

Co-authored-by: Kristopher Overholt <koverholt@google.com>
2026-10-31 07:03:47 +08:00
RoboClaw
851a5ea4af
feat: add Particle model provider (#187135)
Closes #187112

## What Problem This Solves

Particle users had to hand-configure a custom endpoint to use Particle-1.

## What Changed

- New `particle` provider plugin (`@openclaw/particle-provider`): `PARTICLE_API_KEY` auth with interactive and non-interactive onboarding, docs, and the Particle logo in provider pickers.
- The account's models are listed live from `GET /v1/models` (`catalog.liveModelDiscovery` plus manifest `modelCatalog.discovery: refreshable`), so new Particle-hosted models need no OpenClaw release.
- The catalog row uses the ID Particle lists and returns, `particle-ai/particle-1`; the short alias `particle-1` folds to it on input.
- Thinking is row data, with no provider hook: `compat.defaultThinkingLevel: high`, efforts none/low/high/max, `thinkingLevelMap` for xhigh/max. The row is in the thinking-profile contract test.

## User Impact

`particle/particle-ai/particle-1` (default `high` thinking, text and image input, tools, streaming) plus the other models the account lists. Packaged installs need the normal release of `@openclaw/particle-provider`.

## Proof

- Isolated Gateway (sandboxed HOME/OPENCLAW_HOME/OPENCLAW_STATE_DIR, key from env): `models list --refresh --provider particle` shows `particle-ai/particle-1`, `deepseek-ai/deepseek-v41-flash-1017` and `z-ai/glm-5.3-flash`, one row each (the API lists each twice). Real agent turns all reply `OK`: Particle-1 at default `high`, via the `particle-1` alias, at `max` and at `off`; GLM 5.3 Flash and DeepSeek V4.1 Flash at `off`.
- `pnpm catalog:compare-released` (2026.10.9, 2026.9.36, 2026.10.10-beta.5): no behavior change.
- Unit tests: onboarding, streaming tool call and usage, live listing with the duplicated prefixed IDs, the thinking-profile contract.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-30 12:29:13 +05:30
Vincent Koc
863839d032
feat(liquid-ai): add native Decision model provider (#177369)
* feat(liquid): add native Decision model provider

Add credential-only setup, Decision catalog, native d1 and d1-ultra adapters, bounded image and response handling, and provider docs. Share the existing SystemOne codec without changing OpenRouter behavior.

Validation: independent scoped P0-P2 review, qualified formatting, generated catalogs, public-diff scrub and diff checks. Focused Testbox allocation queued and was stopped; dependency-backed tests, build and authenticated live proof remain required before landing. The unchanged API-key helper was excluded from review context by its filename guard.

* fix(liquid): repair provider CI contracts

Construct readonly Decision contexts with typed fixture overrides, cover the new docs navigation labels, and account for the two shared SystemOne codec exports. Targeted formatting, exact Swedish navigation assertion, Chinese glossary coverage, diff checks, and independent P0-P2 review passed. Dependency-backed checks remain on PR CI; config baseline regeneration is pending qualified tooling.

* fix(liquid): align provider validation baselines

* test(liquid): prove registered Decision transport authority

* test(liquid): satisfy guarded transport lint rules

* fix(liquid): regenerate current config baselines

* docs(liquid): refresh generated plugin reference count

* fix(liquid-ai): isolate native provider credentials from Liquid Inference

* chore(config): regenerate Liquid AI baseline after integration
2026-10-27 16:54:09 +08:00
Josh Lehman
65ad180052
feat(knowledge): bundle the Knowledge memory plugin (#180139)
* feat(knowledge): import Knowledge plugin sources

Imported from openclaw/knowledge at 7847e55. Uses the public SDK root()
and the host's typed projectKey.

* style(knowledge): apply repository formatting and lint autofixes

* test(knowledge): port the Knowledge suite to vitest

* docs(knowledge): document the bundled Knowledge plugin

* refactor(knowledge): conform to bundled-plugin lint, types and file-size rules

* fix(knowledge): locate workers and packaged data from the runtime entry

Built output moves shared modules into host chunks, so module-relative
URLs no longer reach the storage and registry workers, the default
ontology or the sample vault. Resolve them from api.runtimeSource, ship
the data as static assets, and read files through @openclaw/fs-safe.

* chore(knowledge): register plugin inventory, config baseline and labels

* refactor(knowledge): drop standalone-host leftovers

Metadata-only registration has no runtime entry; locate packaged files
only when the host supplies one. Remove the older-host panel guard and
references to docs that did not move with the plugin.

* refactor(knowledge): remove unused exports and dead search helpers

* openclaw-ef3.7.3: open Knowledge databases through SDK helpers and stamp schema versions

Replace raw DatabaseSync construction and PRAGMA-based header versioning in the
operational (state.sqlite) and registry databases with openNodeSqliteDatabase,
runSqliteImmediateTransactionSync and a knowledge_schema version table. Stores
written before stamping are dated by their tables and migrated additively;
their native header is left untouched. Identity and registry upserts use Kysely.

* openclaw-ef3.7.2: port Knowledge transactions and conflict inserts to SDK patterns

BEGIN IMMEDIATE blocks become runSqliteImmediateTransactionSync, INSERT OR
IGNORE/REPLACE become Kysely onConflict inserts, and sqlite_master probes use
tableExists. Register Knowledge's worker-only SQL modules in workerModules.

* openclaw-ef3.7.4: move Knowledge JSON projections out of raw SQL

Publication source and receipt lookups use jsonPathValue with Kysely. The recent
projection parses each published plan once in TypeScript instead of json_each/
json_extract, and applies record eligibility and source grouping while streaming
newest-first events. Storage base transactions and upserts use SDK helpers.

* openclaw-ef3.7.6: document type assertion invariants in Knowledge storage modules

Every type assertion in the storage, registry, recent, retrieval, lifecycle,
session-activity and attachment modules now states its invariant, satisfying
the assertion SAFETY ratchet against main.

* openclaw-ef3.7.6: keep the Knowledge schema step type module-private

* openclaw-ef3.7.2: resolve Knowledge worker SQLite SDK modules through the host resolver

* openclaw-ef3.7.4: keep Knowledge SQL out of the control UI bundle

Recent activity SQL moves to recent-activity.ts so recent.ts only carries the
schemas the control UI imports, and session activity records retried calls with
a portable ON CONFLICT DO NOTHING prepared statement instead of the SQLite SDK.

* refactor(knowledge): move scan primitives to a leaf module

Breaks the evidence-files -> publication-files -> vault import cycle.

* openclaw-ef3.7: import digest from scan-primitives to break the lifecycle -> vault -> retrieval cycle

* openclaw-ef3.7.5: classify Knowledge keyword-index FTS5 as engine-private

Knowledge's keyword index is a rebuildable cache in each store's own
state.sqlite, opened by SqliteIdentityStore and never through the selected
Gateway engine. Classify its fts5, temp-schema and rowid constructs in
retrieval.ts as owned engine maintenance; other constructs there stay counted.

* chore(knowledge): justify or remove type assertions

Adds SAFETY invariants for the assertion ratchet and removes casts that
real types or narrowing make unnecessary.

* refactor(knowledge): drop the Publisher alias and unused MAX_ENTRIES re-exports

* fix(knowledge): bound Markdown block runs before link lexing

JavaScriptCore reports regexp matches that exceed its backtracking memory
cap as no match. marked's paragraph rule hits that cap after ~49K lines in
one block, then lexes the rest line by line, so scanning a near-limit
record took hours under Bun. Split runs over 10K non-blank lines before
lexing; links are unchanged.

* fix(knowledge): transfer workspace attachments without model byte copying

knowledge-live-728: reuse durable chunk uploads behind a scoped workspace-file tool and document programmatic source retention.
(cherry picked from commit d196fdc0b1c30c4850a1f97d94a512ae2b27aa74)

* fix(knowledge): declare knowledge_attach_file in the plugin manifest

* feat(knowledge): add knowledge-unlinked-claims skill for post-relink review

* fix(knowledge): resume interrupted store setup and admit state once

- Resume a store whose setup was interrupted: an empty state.sqlite is a new
  database, and writeOnce completes an empty vault.json or registry sentinel.
- Admit each physical state database once per thread: the schema check,
  history indexes and additive operational tables move out of every
  connection and every operation.
- Keep maintenance schedule bookkeeping in registry meta instead of
  maintenance.json.

* feat(knowledge): steer the memory prompt toward entity pages and recall before planning

Describe Knowledge as world knowledge about ontology entities, search named
entities once before planning, keep pages for sustained work through
knowledge-entities and knowledge-capture, record agent findings on pages
instead of skipping them, word remembered claims no more broadly than their
excerpt, and record supersession with knowledge-correct.

* fix(knowledge): keep knowledge_remember a search-free fast path for one-off claims

* fix(knowledge): complete an empty registry sentinel before checking it

A crash after the registry sentinel is created but before its ID is written
left an empty registry.id. The constructor compared it with the registry ID
before writeOnce could complete it, so every registry operation failed until
manual recovery. writeOnce now runs first and reports whether it wrote; the
comparison still refuses a sentinel that names another registry.

* feat(knowledge): append a generated Knowledge index to owner-private sessions

* fix(knowledge): honor operator roles and name the real memory audience denial

Operator browsing of an agent's private knowledge now stays within the caller's role agents and requires operator.admin on a shared Gateway. A missing memory audience no longer blames a parent reset; the error points to the memory_audience_denied Gateway log entry without naming other sessions.

(cherry picked from commit 2745ceeed4)

* test(knowledge): keep the flush-plan test to tool policy and read-only behavior

Prompt phrasing is not a contract; the persistence tool set, NO_REPLY, determinism, and read-only null plan stay asserted.

* chore(knowledge): regenerate config baseline and worker inventory on current main

* test(knowledge): match the missing-audience denial by its new diagnostic

* fix(knowledge): re-admit a state database whose inode was recycled

Admission was cached per device:inode, so a deleted and recreated or restored database on a recycled inode skipped schema creation and failed with missing tables. An admitted inode must now also carry the current schema stamp; otherwise it is admitted again.

* fix(knowledge): check operator role and shared-Gateway policy live before each read

Operator browsing now calls the host's allowsAgent() and isSharedGateway() each time the principal is re-resolved, so a role or roster change during an awaited read refuses it before disclosure instead of trusting dispatch-time values.

* fix(knowledge): pin the rendered memory index for a session until its cutoff moves

Each turn re-rendered current records, and edits keep recorded_at, so a rename between turns changed the system prompt. The rendered text is now pinned per agent, session incarnation, store binding and cutoff, and authority is still checked live before reuse.

* feat(knowledge): subject hint on remember and agent review after maintenance relink

knowledge_remember accepts an optional per-item about hint, stored as
subject_hint; remember and relink resolve it before the claim text. A
configured maintenance.reviewJobId automation is queued after a pass that
leaves private remembered claims unlinked; its agent turn follows the
knowledge-unlinked-claims skill.

* feat(knowledge): count every pageless claim for the maintenance review

Maintenance queued the review only for unlinked knowledge_remember claims,
so claims saved unlinked through knowledge_create_claim were never reviewed.
The pending count and the skill's enumeration now cover every current claim
with no linked page and no source page, via knowledge_relink include: all
(dry run only; relink still links only remembered claims).

* feat(knowledge): list the busiest pages' newest decisions and commitments in the index

* fix(knowledge): recheck operator authority when saving store assignments

A store-assignment change checks operator.admin at admission, then waits for
the registry, store lanes and the config lock before writing. An operator who
disconnected or lost access meanwhile could still persist new membership.

plugins.sessionAction now gives handlers a live client.assertCurrent backed by
the Gateway's request authority. Knowledge passes it to the config writer as
writeOptions.assertCurrent, so publication is refused once the caller's
authority has ended, and accepts assignment changes only from hosts that
provide it.

* fix(knowledge): satisfy the type-assertion and forced-exit boundary guards

- History reads use a typed Kysely query against a declared history table
  instead of casting raw rows.
- The download picker uses an optional Window.showSaveFilePicker declaration
  and the DOM FileSystemWritableFileStream type instead of a window cast.
- The source-ingest scripts run from an async entry function and return from
  the help branch instead of calling process.exit.

* test(knowledge): narrow possibly-missing records in maintenance and index tests

* openclaw-87bf: split shared Knowledge skill guidance into topic references

* openclaw-395: rewrite meeting ingestion skill as a short routed procedure

* openclaw-395: speaker mapping, page-creation rules, writing style and new-store setup for meeting ingestion

* openclaw-14d: slim knowledge-entities onto shared topic references with gbrain parity

* openclaw-14d: carry gbrain meeting-ingestion rules into knowledge-meeting-ingest

* openclaw-c0f openclaw-b6d openclaw-5f3: no reference rereads on handoff, ingestion-scoped web lookups, ontology-led typing

* openclaw-b6d openclaw-5f3 openclaw-395: participant identity lookups, project typing, single-pass transcript digest

* openclaw-395: verify from drafts; no full published-page readback

* openclaw-951: lookup-first identity resolution with a reusable identity map

* openclaw-b22: compact knowledge_grep/lookup hits and a 10-hit default for agent calls

* feat(knowledge): search every named entity, page significant ones now, and state the remember call shape

* fix(knowledge): apply live operator policy to store record counts

stores_snapshot counted every running store's private records with an access
that checked only static operator scopes, so an operator whose role excludes
an agent, or a non-admin on a shared Gateway, could read that agent's private
record count. Counts now resolve through featurePrincipal, pinned for each
storage check, through a member the operator may browse; forbidden counts stay
null.

* fix(knowledge): type withSearchDetail through Type.Object instead of a chained assertion

* test(knowledge): remove unchecked any casts from the Knowledge suite

The repository keeps unchecked `as any` casts at zero; the imported Knowledge
tests had 602. Most were redundant (casting values already typed any). The
rest now use real types: typed fixture returns, contract and record types,
literal tuples, non-null assertions where tests already rely on presence,
small subclasses for storage and Git fakes, and single-step assertions to real
types for deliberately partial inputs. No assertion changed.

The five ingestion-contract @ts-expect-error checks are deliberate negative
type tests and join the inventory's explicit allow-list.

* feat(knowledge): route /learn into knowledge-ingest with source-faithful supersession

* chore(knowledge): align fs-safe with main at 0.26.11

* chore(knowledge): regenerate config baseline and worker inventory on current main

* fix(knowledge): state the invariant behind the search-detail input cast

* docs(learn): describe /learn as saving to skills or memory

* fix(knowledge): break storage and retrieval import cycles and clear lint errors

* chore(knowledge): regenerate config baseline on current main

* chore(knowledge): regenerate plugin inventory on current main

* fix(knowledge): key the pinned memory index by physical store

A binding can move to a different physical store (share the store, then use
own), so a pin keyed by binding, session and cutoff could serve the previous
store's index. The pin key now includes the store's vault ID.

* test(knowledge): walk test trees with listDirectoryTreeStrict

* test(knowledge): consolidate duplicated and low-value tests

* test(knowledge): drop low-stakes single-purpose tests

* ci: raise test-lines ceiling to 6,363,000 for bundled Knowledge

* ci: keep main's test-lines ceiling; regenerate worker inventory after main merge
2026-10-25 10:30:07 -07:00
Peter Steinberger
b888760002
fix(bedrock-mantle): route discovered GPT models through Responses (#182437)
Assign numbered OpenAI GPT discovery rows their existing Responses API and regional endpoint at the Mantle catalog owner. Preserve GPT-OSS and Claude routing.

Fixes #108216
2026-10-24 23:25:01 -07:00
Peter Steinberger
c68f41ad7c
feat(providers): add Abliteration model provider (#182248)
* feat(providers): add Abliteration provider

Adds abliteration.ai as an official external provider plugin
(@openclaw/abliteration-provider) over its OpenAI-compatible Chat
Completions API.

- API-key onboarding (abliteration-api-key / --abliteration-api-key);
  ABLITERATION_API_KEY, plus the vendor's documented ABLIT_KEY.
- Static catalog: Abliterated Large Flash (default; text+image, 1M ctx),
  Large v2, Abliterated Model, and the deprecated Large model.
- Per-model reasoning_effort maps that expose only each model's real
  modes; Large v2 cannot disable reasoning, so Off sends low.
- prompt_cache_key routing hint; no store or prompt_cache_retention.
- Provider guide, plugin inventory/reference, external catalog entry,
  first-party icon from abliteration.ai/icon.svg, gated live test.

* chore(abliteration): regenerate generated docs after rebase
2026-10-23 22:33:24 -07:00
RoboClaw
bff1d869fc
feat(baseten): support elephant-1 and mammoth-1 decisions
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
2026-10-24 05:05:27 +00:00
lavicosa
ed083ae19c
feat(providers): add Requesty provider (#180788)
Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
2026-10-23 17:35:01 -06:00
TUARAN
9c283a48ca
fix(crabbox): reject non-decimal run timeouts (#179000)
fix(crabbox): reject non-decimal --timeout values in crabbox run

`crabbox run --timeout` accepted hexadecimal, binary, octal and exponent spellings (for example `0x10`) as a number of seconds instead of rejecting them, so a typo silently became a different timeout. The value now goes through the existing decimal duration parser and anything else is rejected with a timeout error.

Evidence: built CLI on Linux. On main all four spellings were accepted and the command went on to fail later at the model step (twice); with this change each fails right away with the timeout error (twice). Decimal values such as 1 and 86400, the default and the range checks behave as before. Proof: https://github.com/openclaw/openclaw/pull/179000#issuecomment-6361418959. Production +1.

Thanks @TUARAN.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-23 05:17:30 -04:00
Jason (Json)
b387f936b7
feat(clawrouter): support batch audio transcription (#178920)
* feat(clawrouter): add native tts-1 speech provider

* feat(clawrouter): add native tts-1 speech provider

OpenClaw-Publication: 55eb4025-830e-4a1e-96c5-6928a4078734

* docs(clawrouter): regenerate speech provider inventory

* Publish openclaw/claw-parity-speech-20261020

OpenClaw-Publication: 0c7ad4a0-9345-42ff-a821-4b1fdcd01ed7

* feat(clawrouter): add native batch audio transcription

* test(clawrouter): move Talk transcription proof to core

* docs(clawrouter): regenerate transcription provider reference

* fix(clawrouter): preserve parenthesized transcription filenames
2026-10-21 15:45:48 -07:00
Jason (Json)
76707b46ae
feat(clawrouter): add entitled native image generation (#178876)
* feat(clawrouter): add scoped native image generation

* fix(clawrouter): honor image transport policy and deadlines

* feat(clawrouter): add entitled native image generation

OpenClaw-Publication: f6b9a737-68b0-4826-a5e7-60660b9f6762

* docs(clawrouter): refresh native image contract reference

* Publish openclaw/claw-parity-images-20261020

OpenClaw-Publication: e7938dd4-f1e7-43f5-9902-2c15e714a904

* test(clawrouter): track proxy tunnels as duplex streams

* Publish openclaw/claw-parity-images-20261020

OpenClaw-Publication: bea530bb-325b-4031-88be-76e6d61f70b8

* Publish openclaw/claw-parity-images-20261020

OpenClaw-Publication: df1897dc-d875-4580-9de7-36df71128b7d

* Publish openclaw/claw-parity-images-20261020

OpenClaw-Publication: ad8751e4-eb09-463b-ac84-62acef2b451e
2026-10-20 20:58:21 -07:00
Jason (Json)
755a562fc4
feat(clawrouter): add native tts-1 speech provider (#178860)
Some checks are pending
Plugin Init Scaffold Validation / scope (push) Waiting to run
Plugin Init Scaffold Validation / Validate provider scaffold (push) Blocked by required conditions
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / Preflight plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / Seal prepared plugin npm release (push) Blocked by required conditions
Plugin NPM Release / Trusted publisher OIDC exchange (push) Blocked by required conditions
Plugin NPM Release / approve_plugins_npm_release (push) Blocked by required conditions
Plugin NPM Release / Publish plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Vitest Cache Warm / dependencies (push) Waiting to run
Vitest Cache Warm / warm (push) Waiting to run
Website Installer Sync / Select installer platforms (push) Waiting to run
Website Installer Sync / static (push) Blocked by required conditions
Website Installer Sync / Docker installers (bookworm) (push) Blocked by required conditions
Website Installer Sync / Docker installers (trixie) (push) Blocked by required conditions
Website Installer Sync / Debian installer (bookworm) (push) Blocked by required conditions
Website Installer Sync / Debian installer (trixie) (push) Blocked by required conditions
Website Installer Sync / Build tools failure (bookworm) (push) Blocked by required conditions
Website Installer Sync / Build tools failure (trixie) (push) Blocked by required conditions
Website Installer Sync / Non-root installer (bookworm) (push) Blocked by required conditions
Website Installer Sync / Non-root installer (trixie) (push) Blocked by required conditions
Website Installer Sync / Fedora installer (non-root) (push) Blocked by required conditions
Website Installer Sync / Fedora installer (root) (push) Blocked by required conditions
Website Installer Sync / macos-installer (push) Blocked by required conditions
Website Installer Sync / windows-installer (push) Blocked by required conditions
Website Installer Sync / sync-website (push) Blocked by required conditions
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run
* feat(clawrouter): add native tts-1 speech provider

* feat(clawrouter): add native tts-1 speech provider

OpenClaw-Publication: 55eb4025-830e-4a1e-96c5-6928a4078734

* docs(clawrouter): regenerate speech provider inventory

* Publish openclaw/claw-parity-speech-20261020

OpenClaw-Publication: 0c7ad4a0-9345-42ff-a821-4b1fdcd01ed7

* Publish openclaw/claw-parity-speech-20261020

OpenClaw-Publication: a29b5bf3-2771-49a9-a7c1-1849b9e54ce4

* Publish openclaw/claw-parity-speech-20261020

OpenClaw-Publication: d306b894-90fe-4b46-8ae2-a7921a88e1d5
2026-10-21 03:05:13 +00:00
Jason (Json)
121758697b
feat(clawrouter): support native typed Decisions
* feat(clawrouter): support native typed Decisions

* feat(clawrouter): support native typed Decisions

OpenClaw-Publication: b488d69e-d5ba-4636-b135-54454e0eb858

* fix(clawrouter): complete Decisions CI contracts

* Publish openclaw/claw-parity-decisions-20261020

OpenClaw-Publication: fd7e8520-79cc-4bbd-8c6f-a878a61f86fa
2026-10-20 19:23:31 -06:00
Midhun V Nadh
de8de9c569
feat: add Bifrost gateway setup and model discovery (#175509)
* feat(providers): add Bifrost provider and allow anonymous self-hosted gateways

Bifrost is an OpenAI-compatible LLM gateway that unifies 20+ providers, but
OpenClaw had no bundled provider for it, so operators configured it by hand.

Add extensions/bifrost following the LiteLLM provider shape: interactive setup
asks for the gateway base URL, optionally for a virtual key, then lists the
models served by the gateway's /openai/v1/models endpoint and defaults to the
first. Discovery failures name the reason before falling back to manual entry,
and a config change during discovery aborts before credentials are sent.

Point providers at Bifrost's OpenAI-compatible surface
(http://localhost:8080/openai) rather than the core /v1 API, so discovery and
chat completions share one base URL. Bifrost advertises provider-qualified model
IDs such as openai/gpt-4o-mini, which resolve as bifrost/openai/gpt-4o-mini.

A gateway started without authentication needs no credential, so setup records
auth: "none" instead of storing a key that resolves to nothing. That reuses the
existing explicit-no-auth owner rather than adding a second mechanism, and
re-running setup for a URL change keeps an already configured key.

The shared self-hosted setup helper forced a non-empty API key, which pushed
SGLang and vLLM users toward a placeholder value for servers that accept
anonymous requests. Accept an empty key there and record the provider as
auth: "none", matching what the config already models.

* feat(providers): add Bifrost provider icons

Bifrost shipped without artwork, so it was the only user-facing provider
with no assets/icon.png or assets/activity.svg and the only bundled
provider still falling back to a letter avatar in the model picker.

- assets/icon.png: 512x512 inversion of the official Apache-2.0 mark,
  dark-on-white to match the other bundled provider icons.
- assets/activity.svg and ProviderIcon-bifrost.svg: OpenClaw-authored
  gateway glyph (many upstreams converging on one endpoint), registered
  in PROVIDER_ICON_NAMES so the model picker stops falling back.
- ATTRIBUTION.md: documents both, pinning the upstream commit.

* fix(providers): narrow anonymous-provider assertion and raise config budget

- provider-self-hosted-setup.interactive.test.ts reached through
  result.configPatch.models.providers.fixture, but configPatch, models and
  providers are all optional, so strict null checking rejected it. Bind the
  provider entry to a local and assert on that instead of a non-null cast.
- The Bifrost plugin schema grows the plugin config surface 4693 -> 4714.
  Regenerate the baseline hash and raise the budget deliberately.

* fix(providers): stop Bifrost onboarding from discarding a supplied key

ClawSweeper flagged two authentication defects, both confirmed against source.
resolveExplicitProviderNoAuth treats auth:"none" as terminal and strips the
Authorization header, so a stale anonymous marker silently defeats a credential.

applyBifrostConnection merged ...existing and only ever added the marker, so
re-running interactive setup against a gateway that now has a virtual key
inherited auth:"none" through the merge and through applyBifrostModelConfig.
An authenticated gateway then rejected inference although setup accepted the key.
The keyed branch now clears the marker, matching how omlx and llama-cpp drop
anonymous state once a credential exists.

runNonInteractive inferred anonymity from --bifrost-api-key and the inline
provider apiKey only, while the delegated method resolves BIFROST_VIRTUAL_KEY and
existing profiles too. A key in either of those made the wrapper write auth:"none",
which the delegate then preserved while saving the key it had resolved. The
ad-hoc check is gone: the delegated method owns the decision and returns null when
no credential resolves, so this path always applies one and must clear the marker.

Replaces the catalog shape test with coverage of the Bifrost-owned decision it
guarded, the single join of the version segment for /openai and /openai/v1.
Docs no longer describe merge and replace mode as though interactive onboarding
left the model list empty; only the non-interactive preset does.

Base-fail/head-pass: both new transition tests fail against 4d2478c4a6 and pass
here. tsgo:extensions, tsgo:extensions:test, oxlint, oxfmt and docs:check-links
are clean.

* fix(providers): clear anonymous mode when no URL flag is supplied

Third instance of the same defect, in the one branch the previous fix left
alone: runNonInteractive returned the delegate the original config whenever
--custom-base-url was absent, so applyBifrostConnection never ran and an
earlier auth:"none" survived. The delegate then saved the key while
applyProviderConfigWithDefaultModelsPreset spread existingProviderRest through,
leaving resolveExplicitProviderNoAuth terminal and stripping Authorization.

This path always applies a credential, so a gateway already on file counts as
configured. The base URL now resolves from the flag or the existing row, and
either way the credentialed connection update runs and clears the marker.

Base-fail/head-pass against 838b5e17cc: 1 failed / 18 passed -> 19 passed.

Live proof on an enforcing Bifrost gateway: config carrying auth:"none" plus an
active bifrost:default profile, re-authenticated with the key and no URL flag.
auth clears, then

  winnerProvider: "bifrost"   authMode: "auth-profile"   fallbackUsed: false
  finalAssistantMessageRawText: "REAUTH_OK"

106 tests across the 9 Bifrost/SGLang/vLLM/shared-setup files; tsgo:extensions,
tsgo:extensions:test, oxlint and oxfmt clean.

* docs(providers): state which Bifrost authentication modes are supported

The guide said supplying a virtual key handles deployments that enforce
authentication, which is true for modern keys with Bifrost HTTP auth off and
false otherwise. Two configurations complete setup and then fail at inference,
so operators hit it as a 401 during a session rather than at configuration:

- a legacy key without the sk-bf- prefix, honored only via x-bf-vk
- auth_config.is_enabled, which consumes Authorization for HTTP auth

Adds a support matrix and the x-bf-vk provider-row configuration, verified
against a local listener to send both x-bf-vk and Authorization. Warns that the
env reference must be set: unset, OpenClaw sends the literal text
${BIFROST_VIRTUAL_KEY} and Bifrost rejects the request with 401 while ignoring
the valid Authorization on the same request.

docs:check-links 15647 links, 0 broken. docs:check-links:anchors unchanged at 5
pre-existing failures, none in this file. oxfmt clean.

* docs(providers): separate dashboard auth from inference auth

ClawSweeper's Revision 4 review found the new support matrix conflated the two layers:
Bifrost keeps dashboard HTTP authentication (Authorization = user creds) and inference
virtual-key governance (x-bf-vk) as independent boundaries. Enabling
auth_config.is_enabled does not consume Authorization for the virtual key; it requires
separate HTTP credentials. Rewrote the matrix to qualify each setup by its actual behavior,
and the x-bf-vk fallback configuration now clearly applies only to legacy keys or inference-auth
deployments.

docs:check-links 15647 links, 0 broken; docs:check-links:anchors unchanged at 5 pre-existing
failures (none bifrost or secret-placeholder); oxfmt clean; markdown not in oxlint scope.

* fix(bifrost): preserve explicit credential and catalog scope

* fix(bifrost): preserve catalog routing and report setup failures

* style(bifrost): use a type-only setup import

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-10-20 13:28:34 -07:00
Peter Steinberger
0061cdde5f
fix(qianfan): prevent oversized memory embedding batches (#178130)
* fix(qianfan): respect embedding batch limits

Declare the documented 16-input cap through the Qianfan embedding adapter while reusing the compatible transport and existing memory splitter. Keep unknown models uncapped and generic validation errors terminal.

Related: #125640. Thanks @gaodaabao for the report and @saladinyao-cyber and @vildevev for the earlier splitting and provider-cap work.

* fix(qianfan): align embedding identity with provider selection

* fix(qianfan): resolve embedding credentials and cold model identity
2026-10-20 12:26:07 -07:00
Vito Cappello
f1689ee0c6
revert: compact at useful task boundaries and before cache expiry (#178021) (#178425)
This reverts commit 68efa3d998.

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-10-20 09:02:00 -04:00
RoboClaw
68efa3d998
feat: compact at useful task boundaries and before cache expiry (#178021)
* feat: compact at useful task boundaries and before cache expiry

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* feat: compact at useful task boundaries and before cache expiry

Worked on by:
- @VACInc

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: cabd1eb8-7cdd-4522-a0a5-042ad4e95f2b

* test: prove compaction capability retirement during an active run

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* Publish openclaw/self-compaction-cache-expiry

Worked on by:
- @VACInc

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: b80c0191-135e-4d2f-9dcd-6a228badcc82

* Publish openclaw/self-compaction-cache-expiry

Worked on by:
- @VACInc

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 0926a3ae-bc63-4a08-9407-abacc4b45137

* test: align compaction fixtures with prepared runtime state

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* Publish openclaw/self-compaction-cache-expiry

Worked on by:
- @VACInc

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: f2b38c57-608a-405f-8fc5-20188ba12b52

* test: preserve config exports in compaction fixtures

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* Publish openclaw/self-compaction-cache-expiry

Worked on by:
- @VACInc

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
OpenClaw-Publication: 2e785763-9c85-42f6-8a0f-59b5f3c118b8

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-10-20 08:57:54 -04:00
RoboClaw
8f278569da
feat(typesafe): support prepared Decision V2 batches (#158565)
* feat: describe decision capabilities in model catalogs

Keep task, protocol, modalities, reasoning, grounding, probability semantics,
abstention and route billing distinct without changing chat Model types.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix: apply shared plugin model policy to decisions

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat: support plugin-owned model credentials

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): preserve richer answers with versioned data codecs

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): run typed tasks with prepared model credentials

Preserve V1 while moving typed decision execution, both bundled engines, catalog projection and physical credential ownership onto the shared runtime.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix(decisions): preserve native headers and route-aware accounting

Keep existing request/auth owners, first-class V1/V2 SDK contracts and actual provider USD precedence. Capture only legitimate effective-route prices; preserve missing usage and the established diagnostic scope.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat(catalog): publish typed decisions on a versioned feed

Preserve v1/v2 chat projections and standalone pricing while adding explicit v3 publication and consumption. Carry the reviewed upstream v2 publisher/wire/pricing prerequisites without rebasing the published stack or changing state-store lifecycle. Preserve source-qualified zeros and qualified tariffs.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* chore(sdk): record approved Decision V2 data allowance

Apply only the +14 exports / +6 callables for the existing decisions data contract. Peter Steinberger explicitly approved the complete +18/+6 stack allowance on 2026-09-26; the remaining four execution types belong to the dependent PR. No additional API or guard exception.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix(typesafe): estimate pinned hosted Jev token costs

Declare the documented versioned hosted route, native token tariff and request limits in the existing manifest. Keep moving aliases and local checkpoints monetarily unknown, reject foreign price fallbacks, and report the actual loopback route through existing normalization before shared accounting.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix(models): include inference metadata in extracted tooling

* fix(decisions): preserve explicit owner-agent selection

* fix(decisions): resolve V2 credentials for the operation agent

* test(decisions): align accounting fixtures with captured rates

Declare free output in estimable native fixtures, keep decimal precision assertions numeric, and mark the injected catalog fetch for the existing hermetic transport guard. Keep the publisher validator bound to its validated bundle type.

* fix(decisions): preserve prepared route and auth facts

* test(model-catalog): verify retained caches with released readers

* test(decisions): handle optional normalized catalog providers

* chore(decisions): satisfy scoped runtime lint

* fix(model-catalog): keep manifest auth ownership out of published feeds

* fix(typesafe): keep decision facts within native contracts

* fix(decisions): authorize model identity independently of auth profile

* fix(typesafe): declare automatic reasoning capability

* fix(auth): retain plugin credential authority through dispatch

* fix(decisions): retain credential authority through prepared dispatch

* refactor(decisions): assert resolved credential authority directly

* test(auth): preserve health probe exports in lifecycle fixture

* fix(decisions): distinguish plain record validation

* fix(decisions): repair v2 CI integration

* fix(decisions): align accounting ratchet evidence

* docs(typesafe): clarify prepared V2 release compatibility

* test(typesafe): add opt-in native decision validation

* test(typesafe): retain prepared runtime in admission fixture

* test(typesafe): retain prepared runtime across SDK assertions

* fix(typesafe): migrate transport benchmark to Decision V2

* test(typesafe): preserve V2 fixtures through shared transport helpers

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: roboclaw-bot <roboclaw-bot@users.noreply.github.com>
2026-10-20 12:58:55 +08:00
RoboClaw
e055783d9f
fix(crabbox): show readable tool outcomes and request progress (#177368)
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
2026-10-19 14:17:34 +00:00
RoboClaw
c33a7f6324
feat: add native Levanto Sage decision provider (#157433)
* feat: describe decision capabilities in model catalogs

Keep task, protocol, modalities, reasoning, grounding, probability semantics,
abstention and route billing distinct without changing chat Model types.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix: apply shared plugin model policy to decisions

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat: support plugin-owned model credentials

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): preserve richer answers with versioned data codecs

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): run typed tasks with prepared model credentials

Preserve V1 while moving typed decision execution, both bundled engines, catalog projection and physical credential ownership onto the shared runtime.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat: add native Levanto Sage decision provider

Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>

* chore(sdk): record approved Decision V2 data allowance

Apply only the +14 exports / +6 callables for the existing decisions data contract. Peter Steinberger explicitly approved the complete +18/+6 stack allowance on 2026-09-26; the remaining four execution types belong to the dependent PR. No additional API or guard exception.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix(models): include inference metadata in extracted tooling

* fix(decisions): preserve explicit owner-agent selection

* fix(decisions): resolve V2 credentials for the operation agent

* fix(decisions): preserve prepared route and auth facts

* test(decisions): handle optional normalized catalog providers

* chore(decisions): satisfy scoped runtime lint

* test(levanto): type the guarded DNS fixture

* test(levanto): resolve the guarded transport fixture

* fix(decisions): authorize model identity independently of auth profile

* fix(auth): retain plugin credential authority through dispatch

* fix(decisions): retain credential authority through prepared dispatch

* refactor(decisions): assert resolved credential authority directly

* test(auth): preserve health probe exports in lifecycle fixture

* fix(decisions): distinguish plain record validation

* fix(decisions): repair v2 CI integration

* fix(levanto): align package metadata and document V2 compatibility

* test(levanto): add opt-in native decision validation

* fix(levanto): align validator and config baseline checks

* test(levanto): prove host credential retirement before dispatch

* test(levanto): use canonical agent roster in authority proof

* test(levanto): cover unsupported boxes and native image contracts

Keep the question translator exhaustive for the V2 Box variant while preserving unsupported behavior. Prove registered-host rejection before credential resolution and transport, retain a supported-image control, and extend opt-in native qualification across Tags, Sort, PNG, JPEG and WebP without requiring optional vendor usage.

* docs(levanto): describe five paid live qualification requests

* docs(plugins): refresh composed Sage inventory counts

* docs(levanto): correct prepared decision SDK anchor

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-10-19 16:46:42 +08:00
RoboClaw
d5125f703c
feat: use SubQ Snap for typed decisions (#171965)
* feat: add SubQ Snap decision provider

* fix(subq): satisfy provider validation guards

* fix(subq): preserve answer keys and external packaging

* test(subq): make JSON serialization assertion explicit

* test(subq): prove operator and consumer authority before dispatch

* test(subq): verify credential changes fence final dispatch

Exercise direct core calls without a caller predicate through the real prepared-secret owner and registered SubQ transport. Prove replacement and removal during DNS preparation send no request; preserve allowed and consumer-policy controls. Shared production enforcement comes from the integrated canonical host fix.

---------

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-10-19 01:25:58 +00:00
RoboClaw
51aa1b76d5
feat(deepseek): search the web with the standalone Search API (#175729)
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
2026-10-17 20:37:46 +00:00
RoboClaw
38f411fbe7
feat(openshell): run brokered inference on sandboxed nodes (#168458)
Provision dedicated broker-attached native workers through OpenShell and bind
optional canonical agent files through the existing File Transfer owner.
Preserve explicit policy restrictions, private pairing, and required-worker
failure behavior with focused CLI/bootstrap and runtime authority coverage.


OpenClaw-Publication: 5588eb80-4e62-4b2c-9142-7a6d4aff5d77

Co-authored-by: sallyom <11166065+sallyom@users.noreply.github.com>
2026-10-17 22:41:15 +08:00
Ayaan Zaidi
22dd373b2e
improve(advisor): steer agents back on course with a much simpler plugin (#174568)
## What Problem This Solves

Advisor almost never interjects when an agent goes off course. Corrections waited until every tool call settled, then passed through a second verifier fork, and the verifier rejected most real corrections, so in practice the agent kept looping, polling or drifting without hearing anything.

## User Impact

With Advisor enabled, an agent that repeats a failing step, polls finished work, works around a blocker it could fix, or drifts beyond the request gets one short correction in its active run, before its next step. Advisor stays off by default and its config keys are unchanged.

## Why This Change Was Made

Advisor is now one review and one steer, using primitives core already has:

- Count tool calls in user-triggered runs. When `everyToolCalls` or `everyMinutes` is due, fork the session (`forkSession`) and ask whether the agent is on track.
- On `CORRECTION`, steer the active run (`steerActiveRun`). The advice joins the requester's own run, so its permissions and sender restrictions still apply. If the run already ended, or steering is refused (for example `hooks.allowPromptInjection=false`), nothing is delivered. The run ending also cancels a review still in flight.
- The plugin reference now documents the single-pass review.
- A due review forks only once every running tool call has its real result (Codex native tools: their item completion; outer Code Mode calls: their recorded output; a raw call and a native child that share an ID settle separately). The original dispatch-time recheck is kept: a review queued before another call starts stands down and stays due until that call's result, because a live unfinished-call fork once produced synthetic aborted results and false retry advice., because Codex fills a missing output with a synthetic `aborted` result in forks.
- Removed: the verifier stage, the old settlement bookkeeping, Codex item bookkeeping, the next-turn injection fallback and the reply parser's word and token rules. The model decides; code only reads the `NO_CHANGE`/`CORRECTION` shape.
- The default instructions say plainly what "off course" means.

The plugin drops from about 1,600 to about 420 lines including tests (+339/−1617 overall).

## Evidence

- Focused tests: `pnpm vitest run extensions/advisor` (12 passed; the outer-call, shared-ID receipt and dispatch-recheck cases each fail without their fix) and `src/plugins/contracts/boundary-invariants.test.ts` (12 passed). `ui:i18n:verify` and the config-doc baseline check pass.
- Live, isolated Gateway, `openai/gpt-6.1-sol` on the Codex harness, Advisor at `everyToolCalls: 3`. Task: poll a check script whose config has a typo. Rows 18–20: the third identical failure. Row 21: the Advisor steer, stored after the tool result with `sourceTool: plugin:advisor`. Row 22: the agent switches from re-running to inspecting the config, fixes the key, and reports READY. Gateway log: `advisor: steered active run`.
- Built-in OpenClaw runtime (`agentRuntime.id: "openclaw"`), same setup with the Control UI: reviews fork with a warm cache (17–25k cached input tokens, 75 uncached), and corrections are stored between tool calls while the run keeps going.
- Steer-only head, built-in runtime, test-only `reviewInstructions` that force a correction: the steer is stored at row 26 directly after a tool result (`sourceTool: plugin:advisor`), the run continues at row 28, and the log shows `advisor: steered active run`. No other turn is started.
- Codex harness, three 15-second commands in a row with `everyToolCalls: 1`: each review forked within 1 ms of the command's `commandExecution` item completing (10:00:51.3, 10:01:08.1) and never while a command was running.
- Codex Code Mode, one outer call that runs a command, waits 15 seconds, then runs another (`everyToolCalls: 1`): the child command finished at 10:21:48.3 while the outer call stayed open; the review forked only after the outer call recorded its output at 10:22:06.5.
- Permission boundary, isolated Gateway: with `hooks.allowPromptInjection=false` and test-only `reviewInstructions` that force a correction, every correction logged `correction not delivered (blocked by plugins.entries.advisor.hooks.allowPromptInjection=false)`.
- Replay of a real 4-hour coding session (62 review points at the default 10-tool-call trigger, real transcript history): Advisor proposed the same course change the user later asked for about 20 minutes earlier in two of four user interventions ("stop debugging unrelated Gateway startup and implement the fix"; "stop expanding the evidence bundle").

Labs description on this branch:

![Labs Advisor row](https://github.com/user-attachments/assets/ad593f1c-7ff6-43cb-88c9-1ba4600dc0e2)

**Merge danger:** two-way door. A revert restores the previous plugin entirely; nothing migrates and no state is written. Blast radius is limited to users who turned on the Advisor lab: their agents can receive one short steered correction per review while a run is active.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-16 22:57:43 -07:00
Vincent Koc
317eb48737
feat(onnx): use prepared decision model execution (#174162)
* feat: describe decision capabilities in model catalogs

Keep task, protocol, modalities, reasoning, grounding, probability semantics,
abstention and route billing distinct without changing chat Model types.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix: apply shared plugin model policy to decisions

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat: support plugin-owned model credentials

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): preserve richer answers with versioned data codecs

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): run typed tasks with prepared model credentials

Preserve V1 while moving typed decision execution, both bundled engines, catalog projection and physical credential ownership onto the shared runtime.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* chore(sdk): record approved Decision V2 data allowance

Apply only the +14 exports / +6 callables for the existing decisions data contract. Peter Steinberger explicitly approved the complete +18/+6 stack allowance on 2026-09-26; the remaining four execution types belong to the dependent PR. No additional API or guard exception.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix(models): include inference metadata in extracted tooling

* fix(decisions): preserve explicit owner-agent selection

* fix(decisions): resolve V2 credentials for the operation agent

* feat(onnx): use prepared decision model execution

* test(onnx): cover registered prepared decision execution

* fix(decisions): preserve prepared route and auth facts

* test(decisions): handle optional normalized catalog providers

* chore(decisions): satisfy scoped runtime lint

* fix(onnx): satisfy prepared catalog contracts

* fix(decisions): authorize model identity independently of auth profile

* fix(auth): retain plugin credential authority through dispatch

* fix(decisions): retain credential authority through prepared dispatch

* refactor(decisions): assert resolved credential authority directly

* test(auth): preserve health probe exports in lifecycle fixture

* fix(decisions): distinguish plain record validation

* fix(decisions): repair v2 CI integration

* docs(onnx): clarify prepared V2 release compatibility

* test(onnx): keep prepared host coverage at the host boundary

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
2026-10-17 08:00:10 +08:00
Patrick Erichsen
d6d7435f59
feat(plugins): default package installs to ClawHub (#173669)
* feat(plugins): default unprefixed packages to ClawHub

Use the shared source planner for CLI, chat, and assistant installs. Keep explicit npm and local sources, preserve canonical built-in shortcuts, and retain the selected registry in update and repair records.

Autoreview findings addressed:
- [P2] Preserve ClawHub provenance in search hints that match aliases
  Route scoped packages through ClawHub and add @latest to ambiguous unscoped search hints.
- [P2] Preserve usable search hints for scoped names with file suffixes
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Update the remaining source-selection test expectations
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Keep npm prerelease retry hints on npm
  Treat file-suffixed package names as registry specs, migrate source-selection tests, and retain npm in retry guidance.
- [P2] Restrict catalog shortcuts to canonical plugin IDs
  Restrict bare shortcuts to canonical IDs and retain npm in shared hook-pack prerelease guidance.
- [P2] Preserve npm in hook-pack prerelease guidance
  Restrict bare shortcuts to canonical IDs and retain npm in shared hook-pack prerelease guidance.

* docs(plugins): show ClawHub as the default install source

Update setup examples and generated inventory instructions to omit the ClawHub prefix. Document explicit npm selection and canonical plugin-ID shortcuts.

* fix(plugins): keep recovery tied to the selected source

* test(plugins): cover search commands and saved registry choices

* test(plugins): align pre-action recovery with selected sources

* test(plugins): prove source-bound recovery through the CLI

* fix(plugins): retain official identity during config recovery
2026-10-16 22:07:52 +00:00
RoboClaw
eaaf553321
feat(openrouter): support native Jev decisions (#158510)
* feat: describe decision capabilities in model catalogs

Keep task, protocol, modalities, reasoning, grounding, probability semantics,
abstention and route billing distinct without changing chat Model types.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix: apply shared plugin model policy to decisions

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat: support plugin-owned model credentials

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): preserve richer answers with versioned data codecs

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* feat(decisions): run typed tasks with prepared model credentials

Preserve V1 while moving typed decision execution, both bundled engines, catalog projection and physical credential ownership onto the shared runtime.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

* fix(decisions): preserve native headers and route-aware accounting

Keep existing request/auth owners, first-class V1/V2 SDK contracts and actual provider USD precedence. Capture only legitimate effective-route prices; preserve missing usage and the established diagnostic scope.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat(catalog): publish typed decisions on a versioned feed

Preserve v1/v2 chat projections and standalone pricing while adding explicit v3 publication and consumption. Carry the reviewed upstream v2 publisher/wire/pricing prerequisites without rebasing the published stack or changing state-store lifecycle. Preserve source-qualified zeros and qualified tariffs.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* chore(sdk): record approved Decision V2 data allowance

Apply only the +14 exports / +6 callables for the existing decisions data contract. Peter Steinberger explicitly approved the complete +18/+6 stack allowance on 2026-09-26; the remaining four execution types belong to the dependent PR. No additional API or guard exception.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat(openrouter): support native Jev decisions

Register Jev through the first-class Decision V2 SDK using prepared OpenRouter auth, guarded System One transport, canonical typed-only catalog rows and truthful usage. Preserve routing privacy across configuration layers and retain V1 lossless refusal for richer billing metadata.

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix(models): include inference metadata in extracted tooling

* fix(decisions): preserve explicit owner-agent selection

* fix(decisions): resolve V2 credentials for the operation agent

* test(decisions): align accounting fixtures with captured rates

Declare free output in estimable native fixtures, keep decimal precision assertions numeric, and mark the injected catalog fetch for the existing hermetic transport guard. Keep the publisher validator bound to its validated bundle type.

* fix(decisions): preserve prepared route and auth facts

* test(model-catalog): verify retained caches with released readers

* test(decisions): handle optional normalized catalog providers

* chore(decisions): satisfy scoped runtime lint

* fix(model-catalog): keep manifest auth ownership out of published feeds

* test(openrouter): use the current conversational catalog boundary

* test(openrouter): align registered fixtures with public type contracts

* fix(decisions): authorize model identity independently of auth profile

* test(openrouter): verify admission after transport preparation

* fix(auth): retain plugin credential authority through dispatch

* fix(decisions): retain credential authority through prepared dispatch

* refactor(decisions): assert resolved credential authority directly

* test(auth): preserve health probe exports in lifecycle fixture

* fix(decisions): distinguish plain record validation

* docs(openrouter): refresh plugin reference

* test(openrouter): initialize cold runtime before deadline

* fix(decisions): repair v2 CI integration

* fix(decisions): align accounting ratchet evidence

* test(openrouter): explain isolated decision transport mock

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: roboclaw-bot <roboclaw-bot@users.noreply.github.com>
2026-10-17 01:48:19 +08:00
Peter Steinberger
28f5f250e1
feat: use oMLX for local chat and memory embeddings (#173327)
* feat(omlx): support local chat and memory embeddings

* docs(omlx): clarify inference catalog model selection

* docs(omlx): register provider configuration baseline

* fix(omlx): preserve credentials when rerunning setup

* fix(omlx): share request authentication with embeddings

* test(omlx): use a literal request header fixture

* fix(omlx): normalize noninteractive setup options

* refactor(omlx): clarify type imports and request fixtures

* fix(omlx): preserve credential boundaries across setup and embeddings

* chore: align environment variable budget with main

* fix(omlx): honor effective inference authentication

* fix(omlx): preserve explicit local authorization headers

* fix(agents): apply prepared auth to local request headers

* test(omlx): align auth fixtures with prepared credentials

* fix(omlx): honor header-only chat authentication

* fix(auth): preserve non-secret provider auth in direct chat

* fix(omlx): honor memory header overrides before resolving secrets

* fix(embeddings): exclude declared auth headers from cache identity

* fix(memory): preserve legacy compatible embedding index identities

* docs(plugins): refresh generated inventory totals

* fix(setup): replace saved provider snapshots on activation

* docs(plugins): refresh generated reference total

* test(setup): compare normalized provider snapshots

* fix(setup): retain selected credentials for provider requests

* fix(omlx): resolve profile bindings during setup discovery

* test(omlx): use isolated default profile state

* fix(auth): honor explicit catalog credentials before ambient keys

* fix(omlx): keep discovery bound to configured credentials

* fix(agents): accept prepared keys in no-auth header helper

* fix(setup): preserve no-auth markers when binding saved profiles

* fix(omlx): honor custom auth with saved profiles

* fix(omlx): respect model-level auth overrides

* test(omlx): type resolved request override fixtures

* fix(omlx): replace saved auth when credentials change

* fix(omlx): preserve saved auth when setup key is omitted

* fix(omlx): keep configured catalog credentials authoritative

* fix(plugins): preserve the narrow CLI migration patch type

* fix(plugins): apply authoring auth patches through their owner

* fix(plugins): carry auth patch types through remaining callers

* chore(plugin-sdk): account for shared auth patch operation

* chore: shrink auth result assertion allowance

* fix(omlx): bind generated setup to its saved credential

* fix(omlx): retain agent scope when reusing setup auth

* fix(omlx): preserve selected setup secret references

* fix(omlx): retain explicit setup and memory credentials
2026-10-16 06:07:25 -07:00
Shakker
24ed521600
feat: run sandbox Auto Review with a restricted host reviewer (#173455)
Add an optional sandboxed code-review tool that preserves caller permissions and returns canonical validated reports through a restricted host reviewer.

Refs #173636 and #173761.
2026-10-16 06:46:46 +01:00
Gio Della-Libera
e4433bd4d5
feat(plugins): add optional agent-guidance plugin (#173602)
* feat(plugins): add optional agent-guidance plugin

* fix(agent-guidance): reject empty instruction configuration

* improve(agent-guidance): clarify setup and use shared plugin artwork

* fix(agent-guidance): validate config with the existing SDK record guard

Replace the unchecked Record cast flagged by checks-fast-baseline-ratchets with the existing isRecord type guard. Preserve accepted values and error behavior without expanding the SDK.

---------

Co-authored-by: Gio Della-Libera <giodl73-repo@users.noreply.github.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-10-15 19:47:21 -07:00
Shakker
494d418aa1
feat: let agents read public GitHub items (#172692)
Expose the existing public GitHub reader through github_read, with Gateway-held identity selection, current caller authority, cancellation and bounded results.
2026-10-15 04:42:12 +01:00
RoboClaw
e210870acf
feat: trigger automations from MCP events (#165399)
* feat: trigger automations from MCP events

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat: trigger automations from MCP events

Worked on by:
- @steipete

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
OpenClaw-Publication: 18b8c78b-d141-44b4-9c38-3b05bb10abc0

* docs: clarify MCP event downgrade compatibility

Removing event jobs does not reverse inherited database schema upgrades. Require target-release preflight and a compatible pre-upgrade backup when the older release refuses upgraded state.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* feat: trigger automations from MCP events

Worked on by:
- @steipete

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
OpenClaw-Publication: b55549d5-44b2-4066-a96e-12f8af1dba48

* chore(workboard): refresh generated event schedule assets

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

* fix: keep MCP authorization available on first use

Publish newly enrolled file identity through its existing owner. Preserve append-only method contracts, close wrapper runtime inputs, regenerate authorized config/tool metadata, and keep receipt publication and request encoding with coherent owners.

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
2026-10-14 20:27:04 +00:00
Ayaan Zaidi
a77bf04780
feat(labs): add experimental Advisor that steers agents off avoidable work (#169564)
Some checks are pending
Native App Locale Refresh / Refresh native pt-BR (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ru (push) Blocked by required conditions
Native App Locale Refresh / Refresh native sv (push) Blocked by required conditions
Native App Locale Refresh / Refresh native th (push) Blocked by required conditions
Native App Locale Refresh / Refresh native tr (push) Blocked by required conditions
Native App Locale Refresh / Refresh native uk (push) Blocked by required conditions
Native App Locale Refresh / Refresh native vi (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-CN (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-TW (push) Blocked by required conditions
Native App Locale Refresh / Commit native locale refresh (push) Blocked by required conditions
Node Runtime Conformance / scope (push) Waiting to run
Node Runtime Conformance / TypeScript contracts (push) Blocked by required conditions
Node Runtime Conformance / Rust workspace (push) Blocked by required conditions
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Waiting to run
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Blocked by required conditions
Plugin Init Scaffold Validation / Validate provider scaffold (push) Blocked by required conditions
Plugin Init Scaffold Validation / scope (push) Waiting to run
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / Preflight plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / Seal prepared plugin npm release (push) Blocked by required conditions
Plugin NPM Release / Trusted publisher OIDC exchange (push) Blocked by required conditions
Plugin NPM Release / approve_plugins_npm_release (push) Blocked by required conditions
Plugin NPM Release / Publish plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Vitest Cache Warm / dependencies (push) Waiting to run
Vitest Cache Warm / warm (push) Waiting to run
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run
Built on #170146 (`forkSession`), #170152 (`steerActiveRun`), #171307 (shared `api.runContext`), #171534 (event `phases`), #171580 (forks show in-flight calls as pending) and #171610 (`payload: "metadata"`), #171651 (internal skill-workshop reviews are not user turns) and #171661 (Codex outer tool-call lifecycle), all on `main`. Related: #169558.

## What Problem This Solves

Agents sometimes spend turns on work nobody asked for, repeat failing or stalled tool calls, or report results the tools do not support. Nothing notices until the user does.

## User Impact

Operators can turn on **Settings → Agents & Tools → Labs → Advisor** (default off). While the agent works, Advisor reviews the conversation every few tool calls or minutes, on the session's own model. If it finds avoidable work, it steers the running turn with one short correction, or queues the correction for the next turn when steering is unavailable. Otherwise nothing happens. It never runs tools, delays, stops or approves anything. **Configure** beside the switch opens the plugin settings page:
- `everyToolCalls` (default 10) and `everyMinutes` (default 20); `0` turns a trigger off.
- **Review instructions** (`reviewInstructions`, optional, at most 4,000 characters): edits what Advisor looks for and when it stays quiet. A blank field uses the evaluated built-in guidance, which is shown as placeholder text. Changes apply on the next review without a restart. The output format, the safety rules and the verify step stay fixed, so custom guidance cannot bypass fail-closed parsing or verification. Custom guidance is not covered by the evaluation below.

## Why This Change Was Made

A default-off bundled plugin (`advisor`) built only on public SDK seams:
- **Admission:** the history-free `before_agent_reply` hook (`eligibleTriggers: ["user"]`) records each user-triggered run in `api.runContext` and never claims the turn. Advisor does not subscribe to `llm_input`, `agent_end` or `after_tool_call`, because subscribing makes the host copy the conversation history or tool results on every turn.
- **Trigger:** the service's single subscription to the agent-event stream counts `tool` starts, so stalled and backgrounded commands count too. Every N tool starts or M minutes, a review becomes due. It uses `phases` and `payload: "metadata"`, so the host never clones tool results, updates or arguments for Advisor.
- **Safe boundary:** a due review (and its verify step) dispatches only when no tool call is in flight. Built-in calls settle on their `result` event; Codex calls settle on native item completion (`codex_app_server.item` `completed`, which fires after codex-rs records the output), including outer code-mode calls. Run end is always a safe boundary. Forking mid-call would show the open call as `aborted` (codex-rs normalization). Live, before this rule, that led to a false "retry it" correction that made an agent repeat successful commands. Run timing starts at lifecycle start, and end or error closes the run.
- **Review, stage 1:** `api.runtime.subagent.forkSession` runs on the plugin service scheduler. The review sees the full live context at cached-input prices and runs no tools. The reply's first line must be `NO_CHANGE` or `CORRECTION`.
- **Verify, stage 2:** runs only after a `CORRECTION`. A second fork of the same cached context checks the draft against the conversation. The problem must be shown by tool results or user messages, not by pending work. The advice must keep every user requirement (prohibitions, scope, ordering, timing, environment), and its next step must be cheaper and still complete the request. The fork replies `APPROVE` (with the final text) or `REJECT`.
- **Fail closed:** both replies are parsed structurally. A malformed reply, a reserved decision word inside the body, a timeout or an error means no steering. The warning is bounded and content-free; it never contains model or provider text.
- **Delivery:** `api.session.workflow.steerActiveRun`, falling back to `enqueueNextTurnInjection` (24 h TTL).
- One review in flight per session, covering both stages under one deadline. Reviews are cancelled on reset, disable and service stop. The interval counter restarts when a review finishes. Tool events from channel runs, which carry no `sessionKey`, are routed through the admitted run's key.

An earlier version reviewed a bounded text excerpt with a separately configured model. In a real-API evaluation it made 2 false corrections in 5 runs: it misread polled background commands as extra launches. The full-context fork made none, so the excerpt reviewer and the model setting were removed.

Settings UI: a new generic, optional `multiline` hint in plugin manifest `uiHints` (manifest types, normalizer, and an additive optional field in the Gateway protocol config schema) renders a string field as a textarea in the existing config form. Fields without the hint render exactly as before. Advisor is its first user.

Labs: **Configure** follows the settings-row control slot (a ghost action beside the switch), through a new optional `actions` slot on `SettingsToggleRow`. The shared toggle-row click handler now ignores clicks on links, buttons and fields. Before, clicking a Labs "Documentation" link also toggled the lab; a regression test fails on the old handler.

## Evidence

Labs before (current `main`, no Advisor row):

![Labs before](https://github.com/user-attachments/assets/3d5234db-8b6f-43b9-aec4-d32db7e6ca0a)

Labs after, with Advisor enabled:

![Labs after](https://github.com/user-attachments/assets/bc894ba5-30e6-407b-8296-51c57e8a07e5)

Plugin settings page opened by **Configure**, with the multiline **Review instructions** field:

![Advisor plugin settings](https://github.com/user-attachments/assets/549bc02c-54c7-419e-98c4-3bccb7911843)

Ordinary-turn overhead, with Advisor enabled and no review due. Clones were counted per call site with an instrumented `structuredClone` across 10 real Gateway turns per workload, in a pinned Linux container (mock provider). The table shows serialized bytes the host clones for Advisor per turn:

| Workload | Before this change (`llm_input` + unfiltered events) | This PR | Advisor disabled |
|---|---:|---:|---:|
| Short turn | 2,988 | 1,375 | 0 |
| 200 KiB history | 209,377 | 1,380 | 0 |
| 1 MiB history | 1,053,153 | 1,380 | 0 |
| 5 tools × 256 KiB results | 1,326,523 | 2,899 | 0 |

Hot-path CPU, measured as interleaved microbenchmarks (median per turn): the history copy at 1 MiB costs 0.28 ms before and 0 ms now; the event dispatch on a tool-heavy turn costs 0.90 ms before and 0.14 ms now. Latency on whole turns was not resolvable on the shared host: block drift reached 35%. That pilot is recorded as exploratory and makes no p95 claim. A review itself (two forks at most) runs only when a trigger fires.

Review-decision evaluation, real APIs. Each scenario's conversation is replayed in the provider's native format (tool calls, tool results, tool schemas with `tool_choice: none`), with the review message appended, as the fork sends it. Corrections were graded by a model judge with a written rubric: evidence, a cheaper step that still completes the request, user instructions kept, at most 120 words. Final numbers come from a **blind holdout**: 40 new scenarios written by a separate agent that never saw the prompt, frozen before the run, 3 runs per model.

| Model | Variant | False corrections | Recall | Correction quality |
|---|---|---|---|---|
| `gpt-5.6-luna` | single pass | 3/60 | 60/60 | 87.3% |
| `gpt-5.6-luna` | **with verify step** | **0/60** | 60/60 | **95.0%** |
| `gpt-6.1-sol` (Codex default) | with verify step | 0/60 | 60/60 | 95.0% |
| `claude-sonnet-5-5` | with verify step | 3/60 (one scenario) | 60/60 | 84.1% |

The original prompt corrected 9–16 of 24 legitimate runs per model on the first scenario set. Its live failure: told an agent to run a requested wait loop in parallel. The verify step costs about 1.4–2.1 s and well under a cent, and it runs only when stage 1 proposes a correction.

Live on this branch (isolated Gateway, Codex and built-in luna, review every 3 tool calls):
- **Requested polling** (8 checks, 2 s apart): Codex reviewed 4 times, `NO_CHANGE` each time (4.2–5.3 s, about 15–16k cached tokens, input 75). Luna drafted 2 corrections; stage 2 rejected both. No steering, and every requested check ran.
- **Search task:** both agents broadened the search after one miss, so there was no waste to correct. Codex said `NO_CHANGE`; luna drafted a correction and stage 2 rejected it.
- **Steering delivery:** shown live on an earlier head of this branch (luna, `steered: true`, guidance in the next provider request, the agent changed course). On this head, the approve-then-steer path is covered by the tests below.

Known limits:
- `claude-sonnet-5-5` falsely corrects one hard negative scenario in all 3 runs, and its correction quality is below 95%.
- On Codex with a restricted tool profile (for example `tools.profile: coding`), the existing `/btw` native-tool rule refuses forks, so Advisor cannot review those sessions. It logs the refusal once per review interval.

Tests:
- Plugin: 46 tests. The default guidance composes to the byte-identical evaluated prompt; custom guidance replaces only the guidance part; whitespace-only means default; the verify message is unaffected; config edits apply on the next review. Earlier coverage: through the real plugin API surface. They cover: hook and service as separate registrations; channel tool events without `sessionKey`; approve then steer and the next-turn fallback; reject, malformed, conflicting-token, empty and timed-out stage 1 or 2 replies, each with zero deliveries and one bounded, content-free warning; the interval restarting after a slow or failed review; cancellation on reset, disable and stop.
- Config form: the textarea renders and edits save for `multiline` fields; manifest hint normalization is tested.
- Labs page: 65 tests, covering on/off writes, the Configure link and in-app navigation under a base path, and no toggle on link click.

**Merge danger:** two-way door; default off. A revert removes the plugin, its Labs row and the Configure link. A saved `plugins.entries.advisor` entry would remain in config.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-14 02:05:07 -07:00
Jacqueline Henriksen
dd1776f133
feat(openai): support typed Decisions API evaluations (#166320)
Add OpenAI Platform Decisions support through the existing Decision provider contract for Boolean, choice, and score evaluations. Require API-key authentication; ChatGPT/Codex subscription OAuth does not authorize this endpoint.

Verified with focused tests and real built-CLI calls through an isolated Gateway to OpenAI.

Original implementation by @jjjhenriksen. Additional verification requested by @obviyus.

## Work sessions

- [Original discussion with @obviyus](https://team.openclaw.ai/chat/roboclaw)
- [Implementation and verification](https://team.openclaw.ai/chat/roboclaw/dashboard/a2e03f26-7143-42d1-b0c0-0e8814d63cd2)

Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Co-authored-by: Kimiyu-186 <202845257+Kimiyu-186@users.noreply.github.com>
2026-10-13 21:29:21 -07:00
Ayaan Zaidi
1c147d4bca
feat: run Meta models through the Muse Code CLI agent runtime (#170487)
## What Problem This Solves

OpenClaw cannot run agents through Meta's Muse Code CLI. Muse has no ACP support, so the acpx route does not work, and `meta/*` models only run on the built-in runtime.

## User Impact

Users can install the external `@openclaw/muse` plugin and set `agentRuntime: { id: "muse" }` on a `meta/*` model or on the `meta` provider. Turns then run through `muse serve`, using Muse's own sign-in (subscription browser login, stored key, or `META_API_KEY`). Muse owns its native tools, sandbox, MCP servers and session state. OpenClaw keeps channels, approvals, the transcript and session mapping. The runtime is opt-in and never auto-selected.

## Why This Change Was Made

- New external plugin `extensions/muse`. It registers an `AgentHarnessV2` with id `muse` and talks to Muse through the official `@muse-code/sdk` over the Muse Session Protocol. The SDK is pinned to 1.4.2, the newest version the repo's `minimumReleaseAge` policy admits.
- **Exec policy.** The effective policy is resolved through the SDK `execPolicy` contract across the global, agent and override layers, including `tools.exec.mode`, then tightened by the host-local exec-approval floors (`loadExecApprovalsReadOnlyAsync`, `minSecurity`/`maxAsk`). An explicit full-session elevation is the only bypass. Deny becomes `muse serve --disable-shell --disable-write` with `denyUnmatched`. Full with `ask: off` becomes `allowAll`. Everything else becomes `promptUnmatched`, and each Muse request goes to OpenClaw's approval flow (allow-once or deny, server-offered choices only, 120-second wait). Exec allowlist, `ask: always`, OpenClaw sandbox, workspace-only file access, restricted tool policy and `adaptive` thinking are refused before Muse starts, with a user-visible message.
- **Settlement.** On abort, timeout, approval failure or transcript failure, the harness interrupts and then waits for the native turn's terminal outcome before releasing the attempt. If no terminal arrives, it closes the host after 5 seconds.
- **Sessions.**
  - Bindings live in plugin keyed state (SQLite) and are published only after Muse accepts the turn. A Muse session is resumed only when workspace, model, credential, read-only posture and approval mode are unchanged.
  - A server-authored resume refusal starts a new session and logs why. Muse ran nothing in that case.
  - `reset` and `withSessionContextReset` (after a committed history cut) drop the binding.
- **Context.** A fresh Muse session (first turn, model change, refused resume, or committed context reset) is seeded once with OpenClaw workspace bootstrap context (`resolveBootstrapContextForRun`) and the retained conversation (`openModelContextAsync`, bounded by `resolveAgentHarnessHistoryLimits`). If the retained context cannot be read, the turn fails visibly before anything is dispatched.
- **Input and results.** Prepared images are forwarded as MSP image parts. Native tool failures carry `lastToolError` back to core.
- **Failure reporting.** Failures are logged to the Gateway log with Muse's stderr tail. Muse's `authRequired` failure becomes "not signed in on the Gateway host; run `muse login`".
- **Config baseline (maintainer-approved).** The plugin config budget goes from 4553 to 4575. 21 entries are the generic `plugins.entries.muse.*` entries every plugin gets; 1 is `binaryPath`, which is needed when the Gateway service's PATH lacks `~/.local/bin`.
- **Data-model compatibility.** The plugin is new. It adds no tables or columns and uses only its own plugin keyed-state namespace, so there is no existing stored data to migrate.

Known gaps (documented in `docs/plugins/muse.md`):
- OpenClaw agent tools are not bridged: MSP has no client-tool contract.
- No live steering, compaction, isolated completion or `/btw` through Muse.
- Model Setup cannot activate a new `meta` API key while `meta/*` routes to `muse`.
- Chat shows a generic failure notice; the actionable cause is in the Gateway log.

## Evidence

Redacted real-Muse output for these runs is in https://github.com/openclaw/openclaw/pull/170487#issuecomment-6153089573.

All runs use real Muse, signed in through Meta's device OAuth flow. The flow was approved in the browser for the host and for each Docker container.

| Check | Result |
|---|---|
| `OPENCLAW_MUSE_LIVE_AUTH=device pnpm test:docker:live-muse` on the current tree: package-installed OpenClaw, real Muse from Meta's installer, `muse login` inside the container | Pass. Real reply. Recall after a Gateway restart (wire `session/resume`). Recall in a replacement native session after a model change (history seeding). An approved `bash` command ran. A denied command did not run (no file). A run aborted with `chat.abort` 3 s after approving `sleep 20 && printf late > file` left no late file after 25 s. After `muse logout`, the Gateway log shows "Muse Code is not signed in on the Gateway host … `muse login`". |
| `pnpm test:docker:muse-runtime` on the current tree: offline fake MSP host behind a real Gateway | Pass. Fresh session, cached reuse, resume after restart, allow and deny with server-minted choice ids, `/reset` starts a new session, allowlist refused before any Muse process starts. |
| Host `pnpm openclaw agent --local`, two separate processes, real Muse login | Pass. Turn 2 recalled a per-run fact from turn 1. |
| `runtime.live.test.ts` against real Muse 1.3.0 (no credentials) | Pass. Handshake, start/resume, invalid key, interrupt, process exit. |
| `extensions/muse/harness.test.ts` | 47 pass. Regressions fail on the old code for each fixed defect. |
| Extension test typecheck, `oxfmt`, `oxlint`, scoped `tsgo`, docs checks, plugin-inventory, plugin npm-release test, config baseline check | Pass |

Defects found by the e2e runs and review, all fixed here:
- An unlimited Gateway budget fired the turn timer immediately.
- Approval failures showed up as aborts, and an approval that failed before the turn started was missed.
- The run handle did not match tool authority.
- `supports()` refused the official endpoint.
- A refused resume blocked later turns.
- Final text was assembled from racing deltas.
- Exec `mode` and agent layers were ignored.
- Interrupts did not wait for settlement.
- Images were dropped.
- `lastToolError` was lost.
- The session binding survived context resets.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-13 15:25:28 -07:00
Peter Steinberger
febccf6716
feat: save suggested cloud profiles on first use (#170875)
Cloud is available in New Session without hand-writing a profile. When no cloud worker profiles exist and the Crabbox CLI on the Gateway host reports a usable provider, environments.list carries one non-dispatchable suggested profile discovered through a cached, manifest-declared Crabbox discovery path. Picking Cloud calls the new admin-only environments.adoptSuggestedProfile, which writes cloudWorkers.profiles.cloud through the normal config.patch owner (snapshot CAS and live-authority checks) and then selects it like any configured profile. Existing cloud profiles are returned untouched; dispatch, repository defaults and Doctor read only real config.

The saved profile uses Linux, the smallest advertised standard class, an 8 h lifetime, 45 min idle and suspend defaults, and warm images on.

Refs: https://github.com/openclaw/openclaw/pull/170875
2026-10-13 04:49:16 -07:00
Peter Steinberger
d46497e0f6
feat: connect MCP apps through a principal-bound relay plugin (#168233)
* feat(mcp-relay): connect remote MCP clients to Gateway sessions

Add a disabled-by-default bundled plugin with an outbound authenticated
WebSocket, persistent Ed25519 identity, single-use pairing codes, and
Gateway-owned grants with durable revocation tombstones.

Expose status, conversation reads, owner-authored message submission, and
bounded reply polling through existing documented SDK contracts. Keep
approval handling in OpenClaw, omit custom source attribution, and provide
running-Gateway CLI commands plus setup and security documentation.

Validate with 121 focused tests, protocol vectors, and docs checks. Extension
type lanes report no mcp-relay errors; unrelated QA-lab declarations and
SDK declaration-preparation timeout leave environment-limited gates for CI.

* fix(mcp-relay): repair session creation and use terminal replies

Omit sessions.create idempotency keys for the principal-less in-process
client while retaining the required key for chat.send. Enforce the real
Gateway contract in the request fake so new-conversation sends regress
when the unsupported key returns.

Use agent.wait terminalReply as the sole reply source and direct expired
snapshots to read_conversation. Remove transcript reconstruction, receipt
lookups, and the run/session admission cache. Preserve conversation
existence and current grant/connection authority around publication.

Log redacted operation and Gateway diagnostics through the plugin logger
and document the revised reply behavior. The plugin suite passes 122 tests
in 108.68 seconds on Node 24.21.0. Regressions reproduced the original send
failure, conversation-deletion race, and overlapping parameter redaction
before their fixes.

* feat(gateway): allow opt-in Control UI framing

Validate explicit frame ancestors and apply them only to Control UI app documents. Preserve default CSP and X-Frame-Options denial, keep protected public and media surfaces unchanged, and hot-apply the policy to subsequent responses.

* feat(mcp-relay): advertise the direct Control UI URL

Accept an optional HTTPS controlUiUrl with matching manifest and runtime validation. Advertise controlUi.url only in configured remote status results, preserving the existing default response and relay authority.

* docs: explain direct Control UI embedding in ChatGPT

Document HTTPS setup, explicit trusted ancestors, separate Gateway origin policy, partitioned browser pairing, and existing cookie-backed plugin and SSO limitations. Refresh generated config baselines and relay inventory references.

* chore(mcp-relay): fix lint findings

* docs(mcp-relay): require a public, ungated Control UI URL for ChatGPT embedding

* fix(mcp-relay): use the SDK record guard and cover openKeyedStoreV2 in the state fake

* feat(gateway): add service-bound remote Control UI ingress

Expose optional controlUiIngress on trusted plugin service contexts, with
versioned HTTP/WS transport, presentation, and settlement contracts. Reuse
the canonical HTTP, upgrade, device admission, and dispatch owners through
bounded in-memory Node transports carrying immutable remote provenance.

Require device-authenticated operators within a read/write ceiling. Deny
local recovery/trust, identity proxies, browser shared credentials, no-auth
hosts, role-configured hosts, undeclared routes, and privileged scopes.
Keep exact origins and frame policy handle-local, isolate sandbox routing,
and compose plugin grant authority with host lifecycle and effect guards.
Close fences admission and joins pending streams, sockets, and accepted work.

Realizes B2 and core B5. Implements the runtime lifetime portion of B4,
signed plugin-read cookie descriptors from B7, bounded core transport from
B8, and shared-secret/recovery/service-worker denial from B9. Enrollment,
durable audience credential binding, relay protocol/hosting/session delivery,
and embedded presentation remain OC-2 and later phases. No schema, protocol,
or existing device-token representation changes; no enrollment stubs.

Add owner contract tests and an isolated paired-device HTTP/WS composition
proof, public SDK export registration, and capability/security documentation.
Remove one inherited unused local in channel-presence-policy to unblock
core typechecking.

Validation: affected owner/sibling tests, core/extension/UI/script typechecks,
full build and affected runtime build, targeted lint, SDK export checks,
docs checks, and fresh isolated review pass. Final integration proof passes
in 173.69s; transport proof in 25.67s; security/factory proof in 125.52s.
No CI dispatched. Existing full-lint/deadcode findings and SDK surface-budget
overages remain recorded; this capability adds exactly one public subpath,
ten exports, and no callable exports to the surface budget.

* fix(mcp-relay): merge duplicate SDK import

* feat(gateway): prepare remote Control UI enrollment contract

Add service-bound issue/cancel contracts and validate exact read/write scopes and device identity in the bootstrap owner. Keep enrollment unavailable before any credential issuance or pairing write until durable audience storage and downgrade behavior are approved.

Document the storage gate and prove isolated ingress rejects shared credentials and the existing auto-approval bootstrap fallback. No schema or credential representation changes.

* refactor(gateway): use regular device tokens for remote Control UI ingress

Replace the rejected remote enrollment stub with the existing trusted-proxy
operator pairing path. A live plugin grant authenticates signed browsers and
auto-approves ordinary devices at the ingress read/read-write ceiling. Reject
shared credentials, bootstrap tokens, role changes, excess scopes, and key
mismatches. Bound credential-free token recovery without changing valid-token
reconnect behavior or the existing HTTP device-token path.

Remove issuePairingBootstrap/cancelPairingBootstrap, their forwarding, the
manual enrollment policy and unavailable storage seam, and obsolete tests.
Document plugin grant-holder authentication, normal device visibility and
revocation, and the accepted direct-listener validity of ordinary tokens.
No schema, migration, credential format, or new lifecycle machinery changes.

Prove fresh pairing, token handoff/reconnect, read/write RPCs, admin denial,
normal device list/revoke, same-key recovery, and direct-listener scope limits
through one isolated Gateway fixture. Owner tests and all core type graphs,
changed-file lint, docs, and focused guards pass. SDK surface budgets and the
changed check's unused exports retain the exact inherited OC-2 failures.

* feat(gateway): support credential-free embedded Control UI ingress

Allow restricted HTTPS wildcard frame ancestors and preserve shared-origin
handles with independent grant lifetimes. Advertise ingress origins in hello
and board, Canvas, and MCP App sandbox responses while retaining existing
mount paths and relative plugin-tab grants.

Mark ingress documents so the browser stays on its serving Gateway, requests
the grant ceiling, stores normal device tokens, and retries a rejected token
once without credentials. Hide shared-credential login and connection inputs,
and skip service-worker registration in embedded ingress.

Validate through the isolated HTTP/WebSocket/Canvas composition, owner and UI
regressions, affected type graphs, lint, docs, UI build, and SDK API comparison.

* refactor(mcp-relay): remove unshipped direct Control UI embedding

* fix(gateway): give remote Control UI upgrade sockets net.Socket timeouts

The Gateway WebSocket keepalive arms an inactivity timeout on the upgrade
request's socket. Remote Control UI ingress hands the upgrade an in-memory
duplex without setTimeout, so the first keepalive tick after an embedded
browser authenticated threw `transport.setTimeout is not a function` from a
timer and crashed the Gateway.

Give the server side of the in-memory transport net.Socket inactivity-timeout
semantics (setTimeout/timeout, refreshed by traffic in either direction,
cleared with the operation) plus no-op setNoDelay/setKeepAlive. A regression
test runs the real keepalive against an ingress-upgraded socket; it reproduced
the crash before the fix.

* fix(gateway): grant the ingress ceiling to returning embedded browsers

The embedded Control UI requests no explicit scopes and lets core grant the
remote ingress ceiling. Core applied that default only to credential-free
connects, so a returning browser presenting its stored device token got an
empty scope set and every RPC failed with `missing scope: operator.read`.

Apply the ceiling default to every remote ingress connect with an empty scope
request, after signature verification as before. The integration test now
covers the real reconnect shape (device token, empty scopes); it failed
before this change.

* perf(mcp-relay): pass compressed and cacheable Control UI responses through

The tunnel dropped Accept-Encoding and Content-Encoding and forced
Cache-Control: no-store, so every Control UI asset crossed the Gateway uplink
uncompressed and was refetched on every launch. The Gateway already serves
Brotli (the main bundle shrinks 268 KB -> 72 KB) with immutable caching.

Forward Accept-Encoding, keep Content-Encoding and the Gateway's Cache-Control,
and leave shared-cache prevention to the relay, which marks every tunneled
response private on its per-grant origin.

* fix(gateway): complete embedded Control UI owner reads

Use the existing shared-owner actor for locally approved ingress connections and their device-token reconnects. Authenticate credential-free Control UI reads with the live grant, retain owner resource authorization and token revocation, and admit private backgrounds plus the exact bootstrap config alias.

Gate embedded question requests under the read/write ceiling without changing personal session-question or admin, approval, and pairing rules. Extend the suite-level ingress and UI reconnect regressions; document the resource and identity contracts.

* feat(ui): add embedder Gateway switcher transport

Expose linked Gateways, primary selection, and host settings through the existing identity menu for framed remote ingress. Validate parent snapshots and omit unsupported native actions while preserving the WebKit transport.

* feat(gateway): bind remote ingress and RPC to live principals

Add capability-negotiated owner and verified-person grants with a chosen
operator ceiling intersected with current role and access authority. Share
that principal across Control UI transport and origin-free Gateway RPC.

Keep signed ingress connects tokenless, preserve paired-device visibility,
and retain grant authority through HTTP resources, nested plugin calls,
personal actions, computer operations, and pending effects. Closing a UI
handle also drains its actual RPC execution.

* fix(ui): keep remote ingress connections tokenless

Sign ingress connects without cached or supplied credentials and leave
scope selection to the live grant. Remove ingress token recovery and
prevent credential-backed warm boot across relay grants.

Use the admitted personal profile for question eligibility while preserving
the ordinary direct Gateway authentication and credential paths.

* test(gateway): require tokenless ingress HTTP reads

Keep a valid paired token as a negative control alongside the shared
Gateway token, and prove credential-free reads use the live grant ceiling.

* refactor(gateway): simplify remote ingress ownership and adapters

* refactor(gateway): remove ingress accounting and settlement

* refactor(mcp-relay): simplify plugin authority and tunnel ownership

Remove the unshipped grant-state migration and old-host fallback. Centralize
result limits and publication checks in the service, keep live authority at
host effects, and let scheduler scopes own tunnel cancellation.

Simplify state candidates, Connected apps refreshes, and duplicate test layers
while preserving tokenless ingress and revocation regressions.

* refactor(mcp-relay): simplify state and tunnel ownership

* refactor(plugins): complete principal-bound ingress factory cutover

* fix(mcp-relay): reopen retired bindings and bound UI buffers

Evict stale principal and UI handles so live grants can reopen under current authority. Bound assembled WebSocket messages and the relay output queue without adding drain machinery.

Use the runtime V2 store owner in integration fixtures, retain sanitized logging, and align the plugin version with the repository sync tool.

* fix(mcp-relay): evict bindings retired by unsupported auth

Include unsupported-auth in binding retirement so corrected Gateway authentication can admit a fresh binding. Cover recovery when the old binding keeps returning its stored error.

* build(mcp-relay): refresh generated Control UI assets

* test(mcp-relay): bind the retired ingress mock explicitly

* fix(mcp-relay): serialize grant writes and bound pending uploads

Use the existing grant mutation queue for creation and approval so revocation cannot be overtaken. Bound accepted HTTP uploads before enqueueing and terminate saturated control-frame sends through the connection lifecycle.

* fix(mcp-relay): preserve active grant authority
2026-10-12 23:41:14 -07:00
RoboClaw
a50da5612c
fix(tts): accept Fish Audio Drama 3 preview (#170473)
Enable Fish Audio drama-3-preview through the existing speech provider while keeping s2.1-pro as the default. Preserve inline directions, existing output formats, and model validation; document preview usage and limitations.

Validation: 12 provider tests, extension typechecks, targeted lint and docs checks passed; independent review found no actionable P0-P2 issues. Live synthesis was not exercised without a Fish API key.

Requested by @steipete.

## Work sessions

- [Discussion, implementation and verification](https://team.openclaw.ai/chat/roboclaw/dashboard/a9179b84-11d1-47a7-a001-708375f93968)

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
2026-10-12 18:15:59 -07:00
usimic
0a3231562b
feat(ollama): show cloud balance in status usage (#167474)
* feat(ollama): show cloud balance in provider usage

* fix(ollama): preserve media hooks and clarify balance errors

* fix(ollama): isolate local balance auth from cloud key

* fix(ollama): require local opt-in for balance usage

* fix(ollama): keep endpoint credentials ahead of cloud env key

* test(ollama): narrow usage auth token result

* fix(ollama): quietly omit unavailable cloud balances

Preserve the contributor balance hooks and endpoint credential routing. Reuse the shared timestamp parser and consolidate local URL proof at the usage-loader boundary.

* fix(ollama): keep cloud credentials off local balance requests

Treat the legacy OLLAMA_API_KEY marker as synthetic auth for local endpoints, matching discovery. Preserve explicit endpoint keys and SecretRef resolution.

* fix(ollama): honor stored endpoint credentials in usage

Use the existing asynchronous usage credential candidates. For local endpoints, exclude ambient Cloud credentials and synthetic markers before selecting a stored key.

* fix(ollama): give balance errors recovery guidance

Keep unsigned-in and unsupported balance endpoints quiet. For visible network, response, and HTTP failures, name the next server or access check without exposing response contents.

* refactor(ollama): keep plugin registration within its line budget

* fix(ollama): resolve stored keys for both local auth markers

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-10-12 16:34:06 -07:00
Miles
0ff0202128
feat(llama-cpp): add managed local OCR and vision setup (#148193)
* feat(llama-cpp): add managed local OCR and vision setup

* test(llama-cpp): clarify synthetic endpoint credential fixtures

* fix(llama-cpp): preserve media across managed setup

* docs: refresh config baseline

* test: isolate native output fidelity fixture

* test(ui): await avatar loader completion

* style(ui): format avatar loader test

* chore: restore focused local media scope

* refactor(llama-cpp): separate runtime inspection from preparation

Keep managed server preparation within its size budget and preserve upstream diagnostic behavior. Retain real media SDK exports in tests and satisfy catalog lint checks.

* fix(llama-cpp): enforce media budgets over inherited router limits

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-10-11 22:30:36 -07:00
Peter Steinberger
37f1d88eeb
fix(llama-cpp): setup replaces selected uncached GGUF with a recommendation (#168064)
* fix(llama-cpp): offer the selected uncached model during setup

* fix(llama-cpp): preserve cache ownership and optional size lookup
2026-10-09 19:27:13 -07:00
Peter Steinberger
aa3505d87f
fix(visitor-access): GitHub visitor invites fail when the Gateway host hits GitHub's anonymous rate limit (#165368)
* fix(visitor-access): resolve GitHub logins through the Gateway credential

Resolve visitor invitation and revocation logins through the trusted Gateway
runtime, reusing its credential selection and canonical identity validation.
Keep immutable account IDs authoritative and disable anonymous retries for
Visitor Access while preserving the existing sign-in recovery behavior.

Report missing accounts, primary and secondary rate limits with retry times,
and sanitized upstream failures. Preserve cancellation and caller, plugin,
and Gateway lifetime checks. Document the shared credential and cover both
runtime wiring paths plus the registered visitor flow.

* fix(visitor-access): report invalid GitHub logins without a retry hint

* test(visitor-access): update OIDC fixture for Gateway lookup
2026-10-05 00:58:35 -07:00
Peter Steinberger
9666c02c53
feat(x): add the X (Twitter) mentions channel plugin (#165138)
* feat(x): add bundled mentions and public reply channel

Connect allowlisted X mentions to bound group sessions with thread context,
durable ingress, account-scoped cursors, and public threaded replies. Preserve
visible work-session links and append a configurable automation signature.

Verify both the bot recipient and sender before dispatch. Support Activity
streaming with polling fallback, SecretRef inputs and OAuth refresh rotation,
and administrator-only allowlist controls in the X replies plugin page.

Keep channel routing, queue custody and ambiguous-delivery recovery with their
existing core owners. Use only SDK subpaths available in OpenClaw 2026.9.8.

* test(x): verify mention delivery and operator controls

Cover cursor ordering and replay handoff, stream recipient filtering and
fallback, thread assembly, weighted reply chains, refresh ownership, and
administrator authorization. Distinguish safe pre-dispatch failures from
uncertain POST outcomes and preserve receipts for partial reply chains.

Validation: X suite 50 tests in 15.93s wall time; Zalo sibling suite 164 tests
in 145.31s. The shared host ambiguity integration suite also passed 8 tests.
The X queue fixture proves the plugin contract, not SQLite crash durability.

* docs(x): document setup, access controls and API costs

Document bot credentials, event modes, account settings, the allowlist page,
thread context and public reply behavior. Explain API costs, retry uncertainty,
and the 2026.9.8 SDK compatibility boundary. Add the channel to navigation,
glossary and generated plugin/channel inventories.

Record exactly 58 new channel config entries and 21 standard plugin entries
in the canonical config baseline; core field count remains unchanged.

* fix(x): use a product-neutral default reply signature

* fix(x): log the reason when an allowlist method fails

* fix(x): treat 4xx reply rejections as undelivered and keep 5xx ambiguous

A 429 or other client rejection of the reply POST proves X created no post, so the reply now
carries the not-dispatched marker (retryable only for 429). Server errors after dispatch stay
ambiguous so a retry cannot duplicate a public reply.

* improve(xai): name and describe the xAI plugin in its manifest

* docs(xai): regenerate config baseline for plugin display name

* fix(x): satisfy bundled channel and build contracts

* test(x): preserve real exports in partial mocks
2026-10-04 16:35:20 -07:00
Peter Steinberger
37ffe3ce94
feat: back up to external disks and Cloudflare R2 with storage locations (#161913)
Adds named storage locations as a generic, pluggable capability, with backup as its first consumer.

- Core storage owner (src/storage): storage.locations config, a location marker that binds identity (runtime never creates it, so unplugged disks and different disks at the same path are refused), client-side streaming encryption (scrypt key from a SecretRef passphrase, per-object HKDF keys, AES-256-GCM segments), and a built-in filesystem provider for external disks and mounts.
- Plugin SDK: api.registerStorageProvider plus manifest contracts.storageProviders; providers move opaque bytes only.
- Bundled cloudflare plugin: an r2 provider over the S3 API with conditional writes and bounded multipart uploads; auto-enabled when a location uses provider "r2".
- Backups: backup create --to <location> with verified archives, UTC retention, list/verify/restore --from, Gateway-owned offsite schedules (installed Git schedules unchanged), per-installation namespace claims fenced at publication and deletion, backup record for external jobs, backup.status RPC, Doctor/status hints, and a Systems page Backups section.

No config or state migration; the storage section is new and optional. Proof: live R2 and mounted-disk round trips, namespace takeover trace, and a published 2026.9.7 upgrade cell with an existing Git backup schedule.
2026-10-01 02:05:44 -07:00
Sarah Fortune
7dc4a94490
docs: give Agents API its own onboarding guide (#162255)
Summary:
- Moves Agents API onboarding into a dedicated plugin guide and updates navigation, provider references, the plugin README, and release links.

Automerge notes:
- PR branch already contained follow-up commit before automerge: docs: address Agents API onboarding review

Validation:
- ClawSweeper review passed for head af284a9707b38cc6b72094559a4b14ffdac83019.
- Required merge gates passed before the squash merge.

Prepared head SHA: af284a9707b38cc6b72094559a4b14ffdac83019
Review: https://github.com/openclaw/openclaw/pull/162255#issuecomment-5922939944

Co-authored-by: Sarah Fortune <sjf@openai.com>
Approved-by: sjf-oa
2026-10-01 02:54:25 +00:00
Peter Steinberger
c432db8665
feat(slack-huddles): join Slack huddles as a signed-in Slack user (#159879)
Add an opt-in slack-huddles plugin that joins active Slack huddles as a
dedicated signed-in Slack user. Slack has no bot or app huddle API, so the
plugin drives the Slack web client in the OpenClaw Chrome profile on the
shared meeting runtime, with in-page audio capture and a virtual microphone
for agent, bidi, and transcribe modes, mirroring zoom-meetings and
teams-meetings.

Membership is proven only by Slack's in-huddle channel header on the
requested channel. Sessions are workspace-scoped, joins are always muted,
talk-back unmutes only after Slack reports the virtual input, and every
click rechecks live authority. The shared meeting status source gains
optional liveOwnershipSource and afterAudioRoutingSource hooks. They
recheck ownership after awaited device and sink work, and roll back only
this pass's effects. Absent hooks emit no code, so the generated Zoom and
Teams scripts are byte-identical.

The plugin is disabled by default and requires OpenClaw 2026.9.8 or newer,
the first release that can carry the ownership hook.

Release note: Add an opt-in Slack huddles plugin that joins active huddles
as a dedicated signed-in Slack user through the shared meeting runtime.
Requires OpenClaw 2026.9.8 or newer.
2026-09-28 17:34:03 -07:00
Peter Steinberger
6d6ea35f76
feat(video): add Kie AI, Z.AI, and Novita video generation (#160080)
* feat(kie): add Kie AI video generation provider

Add 13 documented Market video models with automatic text/image routing, local image uploads, body-level API errors, and bounded polling/downloads. Register API-key onboarding and discovery, wire live QA and CI filters, and document provider capabilities.

Validation: 34 mocked Kie cases pass; core/extension types, bundled registration, inventory, docs, workflow, formatting, and assertion-safety checks pass. Independent review found no actionable issues. The new test command took 186.18s including cold compilation. Live provider proof remains with the lead; Veo awaits API contract reconciliation.

* fix(config): allow Runway and Kie provider credentials in models.providers

Treat runway and kie as bundled provider overlays so apiKey credentials, including SecretRefs, validate without custom baseUrl or models fields. Keep credential resolution in the existing provider auth owner.

Validation: both SecretRef-only schema cases failed before the fix and pass afterward (28 schema cases). All 12 Runway cases pass, including a generated request using the real SDK resolver with a resolved file SecretRef snapshot. Core/extension type checks and the fresh independent review of both requested commits pass.

* feat(zai): add CogVideoX video generation

Extend the Z.AI plugin with regional async CogVideoX text-to-video and image-to-video generation. Reuse provider auth and HTTP helpers, support local image data URIs, and declare duration, geometry, audio, quality, and frame-rate controls.

Wire registration, live provider selection, release shards, generated inventory, and provider documentation. Mocked provider flows, focused contracts, typechecks, inventory, docs, formatting, workflow checks, lint, and assertion safety passed. Live proof remains with the lead.

* feat(novita): add Wan and Hailuo video generation

Extend the Novita plugin with native Wan 2.6 and Hailuo 2.3 async video routes, automatic family image routing, data URI image inputs, and model-specific capabilities. Default Wan output to silent and validate Hailuo duration/resolution combinations before submission.

Wire registration, live provider selection, release shards, generated inventory, and concise provider documentation. Mocked registered-provider flows, focused contracts, typechecks, inventory, docs, formatting, workflow checks, lint, and assertion safety passed. Live proof remains with the lead.

* fix(ci): repair video provider integration checks

Guard the native-live provider list before splitting and add Kie extension and documentation labeler coverage.

Regenerate the config baseline at exactly 4371 plugin entries. The 21 new paths all belong to the shared Kie plugin entry: root/config/enabled (3), hooks (6), llm (8), and subagent (4). Z.AI and Novita add no config entries; existing core, channel, and plugin entries are unchanged.

Focused labeler and native-live shard tests, config baseline, lint, formatting, and diff checks pass. The targeted TS2532 is removed; 19 inherited type diagnostics remain in untouched files. Workflow-planning has the same 17 unique failures and 432 passes on this branch and merge-base 7c346c1c65 because its fixture omits ci-static-step.sh.
2026-09-28 12:48:22 +00:00
Sarah Fortune
c0196aec9e
feat(agentsapi): configure hosted or self-hosted environments (#158307)
* feat(agentsapi): configure hosted or self-hosted environments

* style(agentsapi): format environment configuration

* test(agentsapi): verify SDK continuation request paths

* test(agentsapi): complete typed attempt fixtures

* test(agentsapi): complete host capability fixture

* refactor(agentsapi): update environment instructions

* test(agentsapi): preserve hosted transfers after rebase

* chore(agentsapi): refresh baseline and formatting after rebase

* test(agentsapi): adapt environment fixtures to workspace context

* docs(agentsapi): explain the external executor controller

* docs(agentsapi): refresh generated plugin inventory

* docs(agentsapi): refresh generated plugin reference

* test(agentsapi): use SDK function type after rebase

* docs(agentsapi): refresh standalone environment config baseline

* refactor(agentsapi): remove unused config type export

* docs(agentsapi): state the executor connection deadline

* test(agentsapi): adapt environment fixture to projection class

* test(agentsapi): cover persisted environment bindings and reset

* style(agentsapi): format persisted binding test

* test(agentsapi): adapt environment fixture to shared prompt helpers

* test(agentsapi): run persistence proof in database worker lane

* test(agentsapi): assert registered harness results safely

* docs(agentsapi): refresh hashes after conflict resolution

* test(agentsapi): bind persisted harness fixture methods

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-09-27 21:59:00 -07:00
Peter Steinberger
4994ec4501
fix(openai): retire the Sora video provider after the API shutdown (#159543)
OpenAI shut down its Sora video API: sora-2 and sora-2-pro report
shutdown_date 2026-09-24 and POST/GET /v1/videos now return HTTP 404 for
every project. Every video_generate call routed to openai/* failed with an
opaque "OpenAI video generation failed (HTTP 404)", and because the bundled
openai plugin still advertised a configured video provider, agents on
OpenAI-only installs kept selecting it.

Remove the OpenAI video-generation provider, its manifest contract and
metadata, live-test defaults and workflow filters, and the docs that
advertised Sora. Stale openai/sora-* refs need no migration: the media
runtime already skips them with "No video-generation provider registered
for openai" and continues to configured fallbacks or auto-detected
providers.
2026-09-27 22:52:14 +00:00