Commit graph

2916 commits

Author SHA1 Message Date
Mert Başar
2f1f8beed7
feat: optionally omit tools on conversational turns (#153340)
* feat(core): gate decision tool prefilter behind decisionAssistance labs and harness capability (#155314, #155316)

- Connect prompt-build prefilter to canonical isDecisionAssistanceEligible Labs consent contract (#155314)
- Gate prefilter evaluation on harnessSupportsTurnScopedToolRestrictions capability declaration (#155316)
- Preserve tool policy when harness is unsupported (e.g. Codex app-server), pending action instructions are present, or attempt is cancelled
- Update test suite with schema-backed decisionAssistance configurations and per-agent decisionModel overrides

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* feat: align conversational tool filtering with Decision assistance

Preserve the contributor core consumer while binding canonical consent, actual harness support, prepared config, and live run authority. Validate the runtime deadline and real ONNX prompt submission without claiming universal classification or latency gains.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: disclose automatic Decision filtering in configuration help

Resolve the remaining configuration-help review finding. Explain explicit consent, inherited Decision models, built-in filtering, preserved required tools, request transfer, and hosted costs. Regenerate the config documentation baseline without changing settings or runtime behavior.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* feat: filter conversational follow-ups with bounded Decision context

Use one provider-neutral batch with separate missing-context and next-response tool-need judgments, following the documented Jev/Noul semantics. Preserve first-turn eligibility, safe bounded history, permissions, required tools and per-turn restoration. Measure actual foreground tool definitions with DEBUG-only scalar diagnostics.

Live model-quality testing is deferred to local testing; no classifier-specific thresholds or adapter framework are introduced.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: restore prompt-phase CI and simplify Decision assistance copy

Bring the shared prompt-phase fixture and Tool Search assembly override up to the current dispatch diagnostics contract. Type the assembly mock and complete policy result so missing fields fail checking instead of silently blocking the primary stream. Preserve the original four replay/queued-context assertions and cover DEBUG-on/off diagnostics without adding cases.

Construct modified Decision answers on fixture-owned copies rather than mutating the read-only API result. Keep the Labs toggle and configuration help generic; supported uses and full behavior/privacy details remain in canonical docs. No provider, saved-consent, permission, or classifier-policy change.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: preserve prompt hook context in tool prefilter

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: preserve tool and provider availability through Decision filtering

Revalidate Decision eligibility at the foreground dispatch boundary and withdraw only its optional cap when the published opt-in or model selection changes. Restore the current permitted schemas, catalog, callability and owned prompt guidance without discarding independent hook restrictions or required tools.

Keep caller-budget expiry out of shared provider outage accounting while preserving genuine provider failures and physical request settlement. Replace incomplete context-engine hook fixtures with the typed real runner, retain the original assertions, and keep the context limit private for the production dead-code gate.

Preserve the hook-context and rubric-9 change; document and test the separate 6000/8000 UTF-16 evidence-text bounds and the existing forward-looking saved-intent contract. Add failure-first composed final-wire and real loopback HTTP/provider-host regressions, including subsequent explicit evaluation on the same provider.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: restore foreground result-budget fixture typecheck

Model the result-budget fixture's foreground-only session explicitly as not compacting. Keep the required production compaction contract and all existing result/persistence assertions intact.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* test: consolidate Decision assistance boundary coverage

Remove overlapping test layers and repeated fixtures while retaining the distinct context, policy, and dispatch boundaries. Runtime validation remains pending because the secretless runner broker is unavailable.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: stop automatic Decision calls after opt-out

Address MertBasar0’s pre-dispatch opt-out report by reusing the automatic consumer eligibility fence after awaited operator preparation. Preserve explicit Decision calls and root/scoped authority and cancellation checks. Extend the existing composed regression at the operator boundary.

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix: stop Decision evidence after admission is revoked

Carry automatic consumer admission through the existing provider host and TypeSafe adapter to the final synchronous guarded-fetch boundary. Retain observed revocation or authority failure across adapter sanitization and asynchronous cleanup without treating either as a provider outage. Preserve explicit Decision evaluation, caller cancellation, deadlines, and provider retirement.

Rebase the contributor commits onto pinned main and retain their previously published integration fixes and test organization. Prove the cold-load and transport-preparation windows with the registered TypeSafe plugin and a real loopback request counter, including same-host explicit calls after revocations.

Co-authored-by: MertBasar0 <mertbasar0@hotmail.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>

* fix(agents): make decision assistance opt-out admission-only

Keep Labs eligibility at provider dispatch while preserving independent live guards for admitted evaluations. Let in-flight results survive opt-out and cover subsequent disabled turns.

* test: close skills watchers in Discord capture fixture

---------

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: MertBasar0 <mertbasar0@hotmail.com>
2026-10-01 09:33:15 -07:00
Ayaan Zaidi
08498ec40d
fix(cron): stale automatic tool lists block scheduled jobs from tools their owner has (#162432)
Related: #130753, #137832, #147969

## What Problem This Solves

Fixes: some scheduled jobs created by an agent fail for months because a tool list saved by an older OpenClaw build is missing tools the creator actually had, such as the native shell. In our setup, a monthly group job that runs `node <script>` delivered nothing in August, delivered nothing in September (the run still reported `ok`), and posted a blocker in October. Its saved list had 31 tools and no `exec`.

## User Impact

User impact: an agent-created agent-turn job that does not name specific tools now gets the same tools as its owner conversation at run time, like a job an operator creates without `--tools`. Existing jobs with an automatically saved creator snapshot behave the same way from their next run. Nothing stored is rewritten: no migration and no backups. Explicit tool lists, script payloads, condition triggers, and jobs bound to captured Codex app authority keep their stored list.

Tradeoff, approved by the maintainer (Ayaan): a per-sender tool policy on the creating owner, or a plugin hook that narrowed the creating turn, no longer limits these default jobs. Only owners can create automations from chat, and subagents cannot create them.

## Why This Change Was Made

**History of the saved list.**
- #91499 introduced it so a delayed run cannot do more than its creator could.
- #112483 made every agent-created job store one, because runs have no sender.
- #112661 made scheduled runs re-apply the owner session's group policy and every non-sender limit, keeping the stored list as the upper bound.
- #137832 fixed native tool capture for new jobs only, and deliberately did not widen stored lists.
- #147969 added a Doctor advisory. It only fires for claude-cli, so it never covered Codex-harness or built-in OpenAI jobs like ours.

**Root cause.** When no tool list was given, OpenClaw saved a frozen copy of the creating turn's tools instead of treating the job like an operator `*` job. Every capture bug (missing native tools, late configured MCP, renamed tools) then stayed in the job permanently.

**Fix.** This follows Hermes, which keeps no creator snapshot: `cron/scheduler.py` `_resolve_cron_enabled_toolsets` reads toolsets from config at run time.
- **New jobs.** An agent-turn create or update with no list, or `*`, stores `["*"]`. That is the same value operator jobs store, so the job's tools match a normal turn in its owner conversation. Script payloads and condition triggers still store the creator's concrete tools, because a script reaches MCP only through servers its list names. Jobs whose creator captured Codex app authority also keep the concrete list, because that authority is bound to it.
- **Existing jobs.** One helper, `resolveCronRunToolsAllow` in `src/cron/tools-allow.ts`: a stored automatic snapshot (`toolsAllowIsDefault`) runs as `*` when it has a valid scheduled owner policy, no condition trigger, and no Codex app authority. Otherwise it keeps its stored list. Every execution consumer of the stored list uses it: the run payload, the command-prompt preflight, and the scheduled message authority.
- **Script transitions.** A `*` job that becomes a script, or gains a condition trigger, captures the creator's concrete tools.
- **Exec pin.** A `*` list keeps the creator's exec host pin.
- **No new noise:** automatic snapshots stay excluded from the `web_search` provider warning, as on main.
- **Deleted, now pointless:** both Doctor advisories about incomplete automatic snapshots, the run warning about pre-MCP snapshots, and two exports nothing uses anymore.

Review note: on claude-cli, a `*` job runs without a CLI tool cap, so Claude's native tools behave exactly as in a normal chat turn in that conversation. This PR introduces no new path around `tools.deny` that a chat turn doesn't already have.

## Evidence

Live-model Telegram proof (Telegram Test Server DM, leased team credential, live `openai/gpt-6-astra` reached through a forwarding proxy that stands in for the runner's mock provider; the runner harness itself is unchanged). This reproduces the shape of the original incident:
- The tester DMs the bot, which creates the owner conversation.
- A job owned by that conversation is added. Its stored list is an old-style automatic snapshot `["automations","message","read"]` plus `toolsAllowIsDefault: true`, with no `exec`.
- The payload is `Run: node scripts/split-report.mjs and post its output line verbatim`. The workspace script prints a random nonce.
- The job is run once (`cron run --wait`), with announce delivery to the DM.

| Build | `exec` offered | Model action | What arrived in the DM | Run |
|---|---|---|---|---|
| base 94f5a8d (main before this PR) | no | `tool_search` ×2, then gave up | "Could not run node scripts/split-report.mjs: no command-execution tool is available…" | error |
| **this PR, head 5b78cb7** | **yes** | `exec {"command":"node scripts/split-report.mjs"}` | "**SPLIT-REPORT 93C53909**: general 41, design 17, ops 9" (the exact script output, with this run's random nonce) | ok, delivered |
| head 5b78cb7 with `tools.deny: ["exec"]` | no | `tool_search`, `read`, then gave up | "Could not run node scripts/split-report.mjs: no command-execution tool or paired node is available…" | error |

In every run, the stored job kept `["automations","message","read"]` plus the marker. Before and after use the same scenario and driver; only the checkout differs.

Update and live proof: published `openclaw@2026.9.7`, then this branch at the exact head (2f5099d), on the same state directory. Mock provider. Every process ran under a temporary `HOME` and state directory. Each job's message makes the model call `exec` with `touch <effects>/<job>`.

1. 2026.9.7 created both jobs through `cron.add` (scheduled policy `trusted`). With the Gateway stopped, the "stale" job was given the old automatic-snapshot shape `["automations","message","read"]` plus `toolsAllowIsDefault: true`. sha256 of both stored rows: `609358837…`.
2. Runs:

| Build / config | Job | `exec` offered | Side effect | Run |
|---|---|---|---|---|
| 2026.9.7 | stale automatic snapshot | no | absent | error |
| 2026.9.7 | explicit `["read","message"]` | no | absent | error |
| this branch | stale automatic snapshot | **yes** | **created** | ok |
| this branch | explicit `["read","message"]` | no | absent | error |
| this branch, owner policy narrowed to `tools.deny: ["exec"]` | stale automatic snapshot | no | **absent** | error |
| this branch, `tools.deny: ["exec"]` | explicit `["read","message"]` | no | absent | error |

3. After the branch runs, the stored rows were byte-identical (same sha256 `609358837…`), and job ids and lists were unchanged. Nothing was migrated.

An earlier run at e151ea3, with the same harness, also covered a snapshot bound to Codex app authority: `exec` was not offered, the file stayed absent, and the stored row was unchanged.

Tests:
- `run.tools-allow.test.ts`: a stored automatic snapshot `["message","read"]` reaches the embedded run as `["*"]`, with the owner's scheduled policy intact. It fails on main with `["message","read"]`.
- `cron-tool-creator-cap.test.ts`: a default agent turn stores `["*"]`, while a trigger script and a Codex-app creator keep the concrete snapshot.
- `run.tools-allow.test.ts`: snapshots without a valid owner policy, or behind a condition trigger, keep their list. Both cases fail on the previous head.
- `run.tools-allow.test.ts`: no `web_search` warning for an automatic snapshot that kept its list. This fails without the exclusion.
- `run.message-tool-policy.test.ts`: a self-edited automatic snapshot runs on CLI with no cap.
- `run.tools-allow.test.ts`: a legacy `Command to run:` prompt from an automatic snapshot without shell tools now runs instead of being rejected.
- `jobs-tool-policy.test.ts`: scheduled message authority is admitted for an automatic snapshot that lacked `message`.
- `cron-tool-creator-cap.test.ts`: a `*` agent turn converted to a script captures the creator's concrete tools.
- These three regressions fail on the previous head. `node scripts/check-changed.mjs` passes.
- Explicit-list, exec-pin and gateway creator-transport suites pass. `pnpm tsgo:core` passes.

## Bounded cost

No new path triggers a model call or a job run. The change only selects which tool list an already scheduled run uses.

LOC vs main: production +98/-250 (net -152), tests +140/-373, docs +19/-11.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-02 00:31:29 +08:00
Peter Steinberger
44aaaa7c57
refactor(channels): move repeated contract boilerplate onto shared helpers (#162827)
Seven channel plugins hand-wrote the same secret-contract setup, and
Zalouser duplicated migration and prefix parsing that shared helpers
already own. A new Plugin SDK helper, createChannelSecretContract on
openclaw/plugin-sdk/channel-secret-basic-runtime, builds the contract
from each channel's declaration, and Zalouser uses the existing helpers.
Feishu and Matrix stay out because other work is changing them.

The public SDK surface budget grows by exactly this one export (public
exports and callable exports each +1), approved by Peter on 2026-10-01.
clickclack, googlechat, irc, slack, sms and zalo now require OpenClaw
2026.9.8 because they call it; published plugins already require a
matching host, and installs fall back to the newest compatible version.

Registration and secret-contract output are identical to main across
eight channels; 6,619 channel tests pass. Production -110 net.

Release note: The clickclack, Google Chat, IRC, Slack, SMS and Zalo
plugins require OpenClaw 2026.9.8 or newer.
2026-10-01 09:24:55 -07:00
Shakker
72fc2b8829
fix: invite GitHub visitors without a public email (#162666)
Target GitHub visitor invitations by immutable account ID without requiring a public email. Preserve explicit email invitations, verified identity bindings, grant lifetimes, revocation and restart recovery.
2026-10-01 17:12:53 +01:00
Dallin Romney
9f9dab3306
fix(codex): avoid browser auth in CUA readiness (#162467) 2026-10-01 08:32:00 -07:00
kevin2966n
d06974d245
fix(openai): preserve structured output on Responses paths (#114204)
Fixes #114200.

OpenAI Responses paths now send structured output correctly: a raw JSON Schema `responseFormat` is wrapped as `{type: "json_schema", name, schema}` and set as `text.format` for the direct OpenAI and Azure Responses providers. `json_object` and `text` pass through unchanged, Chat Completions is unchanged, and SDK retries stay at 0 so failover keeps owning retries.

Proof: isolated Gateway captured the raw schema on main and the wrapped `json_schema` with this change. Live check on the exact head with a real OpenAI key (gpt-4.1-mini, Responses): the schema turn returned HTTP 200 with schema-conformant JSON, and a control turn without `responseFormat` also succeeded. Regression tests fail on main and pass here.

Co-authored-by: Codex QA <codex-qa@local.invalid>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-01 20:57:32 +08:00
Peter Steinberger
5c8a714982
refactor(providers): deslop provider adapters (#162488)
* refactor(providers): deslop provider adapters

* refactor(providers): preserve the auth profile SDK declaration

* test(providers): complete the prepared auth bootstrap fixture

* refactor(providers): make detached catalog method contracts explicit
2026-10-01 05:41:53 -07:00
Peter Steinberger
28ac1ad96f
refactor(voice-call): decode legacy call logs only in Doctor (#162538)
* refactor(voice-call): move legacy call decoding into Doctor

* chore(voice-call): shrink retired decoder assertion baseline
2026-10-01 05:30:36 -07:00
Peter Steinberger
e649be315d
refactor(plugin-sdk)!: retire deprecated compatibility facades (#162333)
Retire the five SDK compatibility facades under the approved September 30 owner decision, and migrate in-repository callers onto their focused contracts. Keep implementations with their canonical owners and remove forwarding exports that become unused after the cutover.

BREAKING CHANGE: remove openclaw/plugin-sdk/channel-lifecycle, channel-message, channel-reply-pipeline, config-runtime, and infra-runtime. Use channel-outbound/channel-inbound, config-contracts and focused configuration/infra entrypoints. The new system-event-runtime entrypoint supplies public snapshot inspection and consumption. Update affected external plugins before upgrading the host; this retirement does not certify universal external migration.

Package exports, SDK entry inventories, compatibility tombstones, migration docs, and surface budgets move together. Canonical API comparison confirms exactly five removed entrypoints, 869 removed export paths, 35 focused additions, and no retained-export signature changes. Net production reduction: 1,320 lines.
2026-10-01 04:12:01 -07:00
Vincent Koc
b5b1029990
feat(agents): expose installed skill search across harnesses (#158091)
* feat(agents): expose installed skill search across harnesses

Keep installed-skill eligibility host-owned while applying normal tool policy to discovery and complete instruction reads. Preserve current main's prepared tool surface and consolidated Code Mode coverage. Caller-provided snapshot options supply read paths, not replacement eligibility authority.

* test(agents): preserve hoisted skill harness initialization

Keep mock factory dependencies owned by vi.hoisted when splitting skill fixtures. Assemble skill-specific mocks only when the test consumer requests them. Update two prior expectations for the prepared empty snapshot/resource contracts while preserving sandbox host-skill exclusion.

Exact-head reproduction failed on the original hoisting and resource-array assertions. Nine affected suites covered 61 tests; after the hoisting repair, a stale sandbox snapshot assertion was found and the 32-test owner file passed on focused retry. Fresh lifecycle autoreview found no actionable P0-P2 issues; formatting and whitespace checks pass.

* test(agents): group sandbox skill coverage with policy tests

* test(agents): admit skill tools in client collision coverage

* test(agents): provide complete prepared skill fixtures

* test(agents): match async skill prompt contract

* fix(skills): preserve existing Code Mode read grants and whole reads

* fix(skills): preserve read denials in frozen tool profiles

* fix(codex): refuse partial installed skill instructions

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-10-01 11:11:13 +00:00
Peter Steinberger
3862ade452
fix: restore native repairs and Codex recovery on Bun (#162559)
Restore missing fs-safe prebuilds without relying on Node directory-merge semantics, preserve Bun native-launch diagnostics, and recover malformed Codex JSON without consuming the next valid frame. Keep package custody, bounded diagnostics, warning-only lifecycle failures, and installed-updater ordering intact.

Proof: 53 changed-test cases plus six catalog sibling cases pass on each of Node 24 and Bun; full changed-file validation and both import-cycle checks pass. Published Node-driver upgrade and Node-free Bun lifecycle cells passed on AWS. The published Bun driver's owning-npm preflight limitation remains explicitly documented.
2026-10-01 02:20:49 -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
Peter Steinberger
2babe000b4
fix(reactions): worker-owned writes, final-dispatch route recheck, single-slot mirrors (#162434)
Follow-up to #161053 (shared-session emoji reactions).

Reaction writes now run through the SQLite worker admission the sibling
session stores use (runOpenClawAgentWorkerWrite); the native path stays
only for process-held incognito databases the worker cannot reopen by
path, and the handler revalidates live authority around the awaited
write.

The plugin action dispatch path awaits onPlatformSendDispatch right
before the synchronous handoff fence, exactly like the send path, so the
reaction mirror re-reads the conversation binding at the final handoff
and refuses a message whose conversation was rebound while the action
runner prepared delivery.

Channels with one bot reaction per message (Telegram bots, WhatsApp)
declare the new optional ChannelPlugin.capabilities.reactionSlots =
"single"; when a person removes one emoji while others remain, the
mirror re-sets the newest surviving emoji instead of clearing the slot.
Multi-slot channels are unchanged.

Also trims redundant scaffolding in the reaction handler, kernel, UI
component and worker.

Proof: 119 focused tests across store, handler, dispatch and UI; mocked
Gateway reactions e2e; typecheck lanes; database-worker inventory check;
live two-person Gateway proof with the qa-channel mirror reporting
delivered through the final-dispatch hook.
2026-10-01 01:42:29 -07:00
Peter Steinberger
a3e4005ebc
fix(gateway): keep model metadata available during plugin drains (#162301)
* fix(gateway): keep model metadata available during plugin drains

Keep the active model publication readable while admitted plugin work settles,
then retire it before resource replacement. Preserve execution fencing, auth
revocation, decision cancellation, rollback, and cleanup ownership.

Retain an automatic drain failure only while its original plugin configuration
delta remains unresolved. Allow explicit wait recovery and reversion alongside
changes to a different plugin without retrying unrelated failed work.

Validate on Blacksmith Testbox with real Gateway reader latency proof, 378
focused tests, 145 follow-up tests, negative controls, types, lint, and guards.

* fix(plugins): fence admission while preserving owned cleanup

* test(gateway): preserve plugin record helpers in reload fixture

* test: repair reload mocks and supervised process joins

* test(models): preserve queue receiver in drain observer
2026-10-01 08:38:43 +00:00
Sarah Fortune
0e5da43ea5
fix(agentsapi): recover image and attachment turns on hosted VMs (#162210)
* fix(agentsapi): keep image-bearing requests recoverable

* fix(agentsapi): describe inline image limits in system instructions

* fix(agentsapi): accept owned staged attachment paths

* fix(agentsapi): transfer original image attachments to hosted sessions

* fix(agentsapi): explain unsupported native tool restrictions

* fix(agentsapi): continue turns when attachments exceed transfer limits

* fix(agentsapi): continue attachment turns after hosted workspace dormancy

* fix(agentsapi): ignore empty attachment slots before transfer limits

* fix(agentsapi): retain attachment steering for queued followups

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-10-01 08:07:31 +00:00
Peter Steinberger
d85669abd1
perf(build): avoid redundant plugin inventory probes (#162384)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-30 23:46:49 -07:00
Sarah Fortune
600117c262
fix(agentsapi): identify OpenClaw in API requests (#162426)
Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-09-30 22:28:53 -07:00
Peter Steinberger
dd721057b4
refactor(config): migrate MCP transport aliases before runtime (#162256)
* refactor(config): normalize MCP transport aliases before runtime

* refactor(sdk): remove unshipped MCP transport re-export

* test(doctor): extract MCP migration coverage

* test(doctor): include shared MCP migration fixture
2026-10-01 05:11:04 +00:00
Shakker
198018fca1
feat: separate person-wide Visitor revocation from invitation cancellation (#162207)
Add canonical-profile revocation and exact invitation cancellation, with live profile-binding checks at grant commits and provider dispatch.
2026-10-01 05:04:01 +01:00
Peter Steinberger
f262cf4478
feat(workboard): add a people view filter to Sessions boards (#162283)
Add a per-viewer people filter beside the agent filter on Sessions boards: Everyone (default), Involving me, or a person from the Gateway's people facet. workboard.sessionsBoard.read accepts an optional view { involvingMe, involvingProfileId, includePeople } forwarded to the caller-scoped sessions.list roster; the board's shared columns, classification, placements, and Board agent are unchanged. The choice is remembered per viewer, device, Gateway, and board, and the preference scope reloads on reconnect so a different viewer or Gateway never inherits a stale selection.
2026-09-30 21:02:35 -07:00
Peter Steinberger
cd6978d20d
fix: preserve legacy delivery and Telegram queues during upgrades (#162206)
* fix: preserve legacy delivery and Telegram queues during upgrades

Route legacy queue normalization through Doctor with exact source backups and durable import receipts. Preserve historical failure times, recover interrupted source claims, and prevent consumed Telegram work from replaying.

* fix: finish legacy queue migration lint cleanup

Construct inventory entries with their status directly and remove the obsolete max-lines suppression after extracting canonical row normalization. Exact lint stripes, core types, and 38 migration tests pass; the matching one-line baseline prune remains blocked by the campaign overlap rule.

* chore: prune the retired storage migration line exemption
2026-09-30 20:14:51 -07:00
Peter Steinberger
97e6d8e259
perf(plugins): stop re-validating native reference namespaces on every admission (#162254)
Native-reference admission (#158414) re-validated every retained hardlinked target and walked its companion directory on every captureAdmitted()/finish() call, so a Windows 2026.9.6 -> 2026.9.7 candidate Doctor spent 39 minutes in assertPluginNativeReferenceNamespace. Admission now retains directory verdicts per capture, namespace, and target-directory mapping, validates only newly admitted targets, and revalidates on replacement captures, explicit host selection, and recovery copies. Seven-agent, three-plugin fixture: repeated companion walks 2,016 -> 0.

Closes #162047
2026-09-30 20:12:57 -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
RoboClaw
c587214736
fix(codex): stop replaying diagnostic-log notices in chat (#161657)
Route the two exact process-global Codex diagnostic-log warnings to Gateway warning logs at client receipt, before turn fan-out or replay. Keep other warnings on their existing delivery path and prevent a diagnostic-sink exception from closing the shared transport.

Consolidate duplicate logger-failure test setup without removing startup or active-connection coverage (14 fewer test lines). Real native SQLite-lock and logger-fault probes, 83 focused cases, adjacent coverage, changed checks, and the production build support the repair.

Logging remains best effort: these operator-only diagnostics do not fall back to chat if Gateway warning logging is disabled or broken. This does not repair native SQLite or update Codex.

Worked on by:
- @vyctorbrzezowski

Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
2026-09-30 19:51:11 -07:00
Peter Steinberger
1783c5fd6f
refactor(plugin-sdk)!: retire beta.5 whole-session-store bridge (#162220)
Retire the beta.5 whole-session-store bridge under the approved September 30 SDK cutoff. Remove loadSessionStore, updateSessionStore, resolveSessionFilePath, resolveSessionStoreEntry, LoadSessionStoreOptions, and UpdateSessionStoreOptions from session-store-runtime, plus package-root loadSessionStore/saveSessionStore aliases.

Plugins use getSessionEntry/listSessionEntries, scoped patch/upsert/delete operations, and identity-backed transcript APIs. Preserve the session-store-runtime subpath, resolveStorePath, canonical SQLite storage, and ordinary legacy-state/Doctor migrations. Published Codex and Feishu 2026.9.7 packages use the replacements.

Remove exclusive projection/reconciliation/materialization code, migrate surviving tests, and shrink SDK export and assertion budgets. Focused remote tests, plugin contracts, import boundaries, changed-file checks, build, both zero-cycle checks, exact API-removal audit, and independent review passed.
2026-09-30 18:18:53 -07:00
Peter Steinberger
c658913931
refactor(channels): share draft rotation and retirement policies
Share Slack generation and stale-create custody with the existing draft lifecycle while preserving human-reply retention, throttle deadlines, and deferred cleanup. Consolidate Mattermost accepted-delivery failure publication and remove the private Discord chunking wrapper.

Validated with focused and cross-shard tests, plugin contracts, changed checks, both zero-cycle checks, a full build, compatible SDK API diff, independent review, and exact-head hosted CI.
2026-09-30 18:18:22 -07:00
Peter Steinberger
cf78e64434
fix(plugins): distinguish settled disposal faults from retained cleanup
Report settled inspection disposal errors without marking their managed
resources as retained. Keep rejected instance/cache prerequisites and drain
timeouts classified as retained cleanup. Preserve CLI resource release,
original error causes, borrowed ownership, and exactly-once disposal.

Fix the product regression introduced by bfdb432570 (#160181). Update
caller assertions to require the disposal failure while preserving successful
process close and subsequent healthy publication; document the contract.

Validation on an isolated AWS lease at main 0c1952c56e:
- Original 129-file plugin CI composition reproduced both failures before
  the fix, then passed 1,257 tests with one existing skip in 59.45 seconds.
- Four affected files passed all 60 tests in three consecutive runs
  (40.87s, 23.71s, 23.78s including runner overhead).
- New settled/rejected/pending inspection regressions took 79ms/19ms/17ms
  in the final focused run; the settled case fails on the original code.
- Core and plugins-platform test typechecks, scoped lint, oxfmt --check,
  git diff --check, and independent P0-P2 review passed.

Pre-commit formatting ran on the lease: oxfmt --check passed for all five
changed files. The local hook is skipped because this sparse worktree has
no node_modules.
2026-09-30 17:36:35 -07:00
Linze Shi
80f68b8862
docs: fix SDK migration section links (#158229) 2026-09-30 17:10:24 -07:00
Linze Shi
7db2084787
docs: fix utility model migration links (#157441) 2026-09-30 17:00:40 -07:00
Erick Kinnee
5c4041708d
fix(plugins): let session_end hooks read ended transcripts (#161451)
* fix(plugins): expose bounded ended-session transcripts

* fix(plugins): bound ended transcript reads by content and retirement

* fix(plugins): avoid ended transcript dependency cycle

* fix(sessions): discover closing resets without payload budgets

* test(gateway): decouple sign-in retry from provider prompts

Keep real WebSocket ownership, activation and revoked retry assertions while dropping incidental prompt order and timing diagnostics. Removing post-await authority validation makes the retained no-session assertion fail. Tracks local task openclaw-1e6.

---------

Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
2026-09-30 16:33:04 -07:00
Colton Harris
5ca201627d
docs(plugins): correct the rendered Control UI descriptor surfaces (#147599)
* docs(plugins): correct the rendered Control UI descriptor surfaces

registerControlUiDescriptor accepts session, tool, run, settings, tab,
and widget, but only tab and widget are consumed. The overview table
advertised four inert surfaces and omitted widget, one of the two that
actually render.

* docs: include rendered link-reader descriptors

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-09-30 16:15:58 -07:00
Kimi Yu
6f91eda9c7
fix(codex): restore persona on remote app-server connections (#162156) 2026-09-30 16:05:21 -07:00
Peter Steinberger
5b9e29c20c
refactor(channels): finish shared draft-stream ownership (#162174)
Move draft generation, atomic receipt publication, sticky stale-create retirement, and current-message reset/retirement into the existing shared lifecycle. Discord uses the generation operations; Matrix reuses message reset while keeping its live-marker policy.

Preserve existing SDK parameters and operations; the API report confirms only additive members on the existing helper. Validation: 273 draft/entry-point tests, 1153 plugin contract tests, changed-file checks, both cycle checks at zero, and independent review through P2.

Hosted CI hit the pre-existing chat.abort-errors fixture deadlock also present in main run 36780090668. Main already contains the owning fixture fix, 79f0e9bf12. The PR records this inherited failure and its incidental SDK barrel import; security checks passed.
2026-09-30 15:59:41 -07:00
Peter Steinberger
bfdb432570
fix(cli): release plugin resources when help finishes (#160181)
* fix(cli): release plugin resources when help finishes

Uncached CLI metadata loads now use the existing inspection acquisition when an executable invocation owns them. The source-plugin regression verifies that invocation release joins module disposal. Caller-owned programs retain their existing lifetime.

* fix(plugins): release retired registry preparation scope

Create the aggregate retirement observer outside the registry preparation
scope so it retains only child waiters. Preserve per-observation options,
cleanup ordering, failure identity, and deferred consumer results.

The unchanged cold registry-retention regression failed on the CI Bun
runtime before this change and passes after it. The original seven-file
shard passes all 172 cases, and Node retirement coverage passes 20 cases.

* fix(ci): carry the chat attachment lint repair

Carry the exact two-file fix from 2e95cdba84
(#160159). Move the unchanged image decoder into its existing helper
to restore the 700-line limit without changing attachment behavior.

Targeted lint and all 21 attachment tests pass on this candidate.
Independent review found no actionable defects.

* test: retain complete lifecycle helpers in lease fixtures

* test: isolate local command fixtures and join recovery cleanup

* test(ci): preserve CLI runtime ownership and harness staging

Keep the moved CLI command fixture in its runtime prerequisite group and
preserve complete agent coverage across the core and CLI process owners.

Carry the test-only trusted-harness fixture fix from #160024.

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* fix(tests): scope Vitest preload to test workers

Apply the jsdom adapter only at Vitest worker entry points while preserving
package-local runtime resolution. Ordinary Workers may inherit the preload
without having a Vitest dependency. Exercise default native inheritance and
await worker termination.

Copy the static-check evidence helper into lint fixtures so the real oxlint
entry point can load its current import closure.

Validation: reproduced both original failure causes before repair; all 76
affected tests pass (351.44 seconds in Vitest), as do canonical changed-file
checks and independent review.

* test: isolate public runtime surface planning fixtures

Verify public runtime entries and packaged assets with a synthetic publishable plugin after the Diffs forwarding APIs were retired. Preserve the existing planner assertions without depending on one bundled plugin layout.

* fix(ci): carry shared lint repairs into CLI preparation

* test(tooling): repair extracted PR and npm fixtures

* test: retain gateway cleanup and isolate Windows temp paths

Close the prewarm gateway when client connection fails and retain cleanup
errors during orphaned recovery. Keep Windows-under-Bun coverage on
host-owned temporary directories, matching the fixture fix in #160985.

Validation: 13 focused fixture tests and canonical changed-file checks.

* fix(ci): keep extracted manifest within script contracts

Resolve inherited manifest lint errors without changing job selection. Move its closed true/1 flag parsing to the dependency-free argument owner and include that helper in trusted fixture copies. Validation passed 718 tests with eight existing skips, canonical changed checks, fixture lint, and independent review. The 74-case argument helper file took 1.79 seconds at one worker with warm inputs.

* test(state): apply upstream snapshot custody fixture isolation

Reuse the fixture repair from #161598 (af16b80a22). Keep the real exit callback and every custody assertion while isolating the synthetic cleanup owner from preceding files.

* test(pr): drain fake GitHub streams before exit

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-09-30 15:28:57 -07:00
Peter Steinberger
8c02b95a1a
feat(workboard): add utility-model categorized Sessions boards (#161958)
Add a separate Sessions board kind to the Workboard plugin: sessions land in editable columns by ordered state rules (observer health, run state, pull-request state, archived) and, for anything unresolved, the agent's utility model in bounded batches; drag pins a session until its facts change; a Board agent conversation docks beside the board and edits it through workboard_sessions_board_read/update/move. Facts reach the plugin through the lifecycle-bound api.runtime.gateway.readSessionFacts (trusted plugins only, redacted and bounded, incognito and draft sessions excluded). Interactive edits recheck the caller's full Gateway authority before the SQLite write; background classification runs under the plugin service and only for boards viewed in the last 15 minutes. Card boards, tools, and storage are unchanged; sessions-board tools register default-on. Storage adds nullable kind/sessions_spec columns and a placement cache table; rollback to an older release shows a Sessions board as an empty Cards board (documented). Live proof on a dev Gateway with the docked agent adding a column and pinning a session.
2026-09-30 13:23:05 -07:00
boeingchoco
452758a427
fix: plugin configuration rejects encoded schema reference separators (#161954)
* fix(plugins): accept encoded schema reference separators

Worked by Codex.

* test(plugins): cover encoded pointer compatibility and boundaries

* style(plugins): format schema reference regression table

---------

Co-authored-by: boeingchoco <194511351+boeingchoco@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-10-01 02:10:33 +08:00
Peter Steinberger
224a637aab
feat(control-ui): let plugins dock conversations (#161957)
Expose the optional ControlUiHost.dock capability for native plugin pages. Reuse the assistant-panel owner, Home chat pane, and existing placement and size persistence. Keep docks across navigation, suppress them on their own session page, and close activation-owned docks without restoring a previous conversation. Carry bounded plugin page details through the existing untrusted work-context capture and Context attached presentation. Closing a plugin dock restores the built-in Home/Ask choice, and the close-on-dispose is retained only once an activation opens a dock.
2026-09-30 10:15:46 -07:00
Peter Steinberger
19f112eaab
refactor(meeting): share browser meeting transport scaffolding (#161574)
The Zoom, Teams and Slack huddles transport layers repeated the same
template with platform strings swapped in. Each platform adapter hand-
wrote the manual-action classification switch, origin check, retry and
permission wiring. Each page-script builder assembled status, transcript,
leave and audio-capture scripts the same way. Zoom and Teams prejoin
sources shared guest-name, identity-preservation and virtual-audio
fragments.

Two additive MeetingPlatformAdapter members, createBrowserAdapterOptions
and createPageScripts, plus shared prejoin fragments in the meeting
runtime, now own that scaffolding. Each plugin's transport files keep
only its selectors, URL grammar and origins, page identity, and
platform-only join steps. The shared adapter options type moved to the
platform-adapter leaf contract to keep the import graph acyclic.

This is a refactor of the TypeScript that builds the browser scripts.
6,772 generated script hashes and byte lengths across Zoom, Teams, Slack
huddles and Google Meet, plus all registrations and adapter behavior,
are identical to main.
2026-09-30 05:07:19 -07:00
Peter Steinberger
71156a00c9
fix(hooks): retry native relay lookup after SQLite contention (#161822)
Some checks are pending
Native App Locale Refresh / Refresh native nl (push) Blocked by required conditions
Native App Locale Refresh / Refresh native pl (push) Blocked by required conditions
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 / TypeScript contracts (push) Blocked by required conditions
Node Runtime Conformance / scope (push) Waiting to run
Node Runtime Conformance / Rust workspace (push) Blocked by required conditions
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
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-09-30 05:01:13 -07:00
Peter Steinberger
bf4b16a81d
refactor(meeting): declare browser meeting plugins through one factory (#161628)
Zoom meetings, Teams meetings and Slack huddles each carried the same
thirteen-file glue layer (entry, CLI, CLI metadata, config, errors, node
host, node invoke policy, runtime facade, probes, setup, Chrome transport,
types), feeding one platform adapter into a dozen separate
MeetingPlatformAdapter helpers. A new MeetingPlatformAdapter member,
defineBrowserMeetingPlugin, composes those helpers from one declaration,
so each plugin now declares only what is genuinely platform-specific. A
fourth browser meeting platform costs one declaration.

The helpers the factory replaces stay exported and are marked deprecated,
since published plugin versions call them. Tests inject Chrome bindings
through the factory's public spec instead of mocking core internals. The
three plugins drop their unused typebox dependency.

Zoom and Teams now require OpenClaw 2026.9.8 (install and plugin API
floors, catalog, docs), like Slack huddles, because they call a member
2026.9.7 lacks. Released plugin packages already require a matching host.

All plugin registrations and 42 generated page-script hashes are
identical to main.

Release note: Zoom meetings and Microsoft Teams meetings plugins require
OpenClaw 2026.9.8 or newer.
2026-09-30 04:36:48 -07:00
Peter Steinberger
a4af3a0020
fix(doctor): Codex bwrap check misses loopback denials that break sandboxed shells (#161692)
* fix(doctor): detect Codex bwrap loopback denials that unshare misses

The Codex bwrap network-namespace probe ran `unshare --user --map-root-user
--net true`, which never configures loopback. It passed on hosts where Codex's
Bubblewrap sandbox then fails before any shell command with
`bwrap: loopback: Failed RTM_NEWADDR`, the exact symptom doctor documents.

Doctor now asks the Codex plugin to run the configured Codex runtime's own
`codex sandbox` in workspace-write mode with network access disabled, using a
throwaway CODEX_HOME and a bounded timeout. Only Codex's own namespace-denial
lines are diagnosed; other failures are reported as unverified. The plugin
owns binary selection (shared with the managed app-server check); core reaches
it through the existing Codex owner-selection and trust path. The user
namespace probe and its messages are unchanged.

* fix(codex): use the OpenClaw temp root for the sandbox probe

Extension runtime code must not use host tmp defaults; the boundary check requires resolvePreferredOpenClawTmpDir from the plugin SDK, matching the Codex plugin's other temp users.

* fix(doctor): keep Codex bwrap diagnostics out of update Doctor passes

The Codex bwrap namespace diagnostic is advisory and has no update
migration or readiness dependency, but it ran inside doctor:sandbox,
which update Doctor passes execute for registry migration. It now lives
in its own doctor:codex-bwrap contribution with standalone update scope,
so `openclaw update` never spawns the Codex probe or loads a retained
Codex plugin's probe API, and lists it under "Omitted during update".
Probe commands, gating, and messages are unchanged; image repair keeps
its engine validation through a shared enabled-backend helper.
2026-09-30 02:53:32 -07:00
Ayaan Zaidi
6c9809acf1
fix(plugins): Gateway freezes on model changes with large plugins (#161267)
Problem: when large plugins are installed, the Gateway freezes for minutes on model changes. Prepared model runtimes loaded and captured their own copy of every plugin: 3 copies at startup and 2 more on every model republish. A `config.patch` of `agents.defaults.model` froze the Gateway for 68–142 s and ended in "recovery restart required".

Fix: prepared runtimes now borrow unchanged plugin instances from their admitting Gateway instead of capturing another copy. The loader records a load-mode-free identity for Gateway loads. A non-activating load given `borrowRegistry` lists the lender's active, unchanged record. The lender keeps custody of borrowed records through adoption, inspection release, rollback, and retirement. Borrowed channel callbacks are fenced to the borrower's lifetime. Lenders come only from the admitting Gateway's live owner. If a lending Gateway closes, recovery republishes under the surviving owner without borrowing from a process-global sibling. Module identity is never shared: a turn uses the Gateway's live instance or a fresh evaluation.

User impact: model changes republish in about 1 s with no new plugin captures and no recovery restarts. Prepared turns use the Gateway's full-mode registrations for unchanged plugins. A turn that still holds an instance makes `plugins.reload` wait through the existing drain; past the drain timeout, the previous instance keeps serving. The maintainer accepted both tradeoffs: https://github.com/openclaw/openclaw/pull/161267#issuecomment-5907833707

Proof:
- Paired large-plugin run: republish took 0.6–1.4 s with 0 restarts and 0 new captures on this branch, versus 68–142 s with 5/5 recovery restarts on main.
- An installed release-to-candidate upgrade passed with public turns, a model patch, and a plugin reload.
- Post-close public-client proof on the exact head: after the lending Gateway closed, the survivor served `models.list` and real OpenRouter agent turns: https://github.com/openclaw/openclaw/pull/161267#issuecomment-5907830560
- Focused loader, prepared-runtime, reload, and Gateway-close suites pass. `pnpm build` passes.
- CI: every required job passed except one UI e2e timeout in Control UI code this PR does not ship. Attribution: https://github.com/openclaw/openclaw/pull/161267#issuecomment-5908179695

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-30 17:28:30 +08:00
RoboClaw
3b26947669
fix(exec): remove audit-suppression command approval heuristic (#161718)
* fix(exec): avoid extra prompts for audit suppression commands

Remove the command-text gate and its dedicated approval/reviewer plumbing. Suppression configuration and audit filtering remain unchanged; normal exec policies still decide execution. Keep only the shipped deprecated SDK signature as a no-op.

Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>

* fix(exec): avoid extra prompts for audit suppression commands

Worked on by:
- @jesse-merhi

Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
OpenClaw-Publication: f1fe3778-77d9-432e-b98f-01f680f2cdd3

* fix(plugins): preserve deprecated suppression approval predicate

Retain the shipped SDK result during infra-runtime retirement without restoring internal execution callers. Document the distinct runtime and plugin migration outcomes.

Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>

---------

Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
2026-09-30 01:53:39 -07:00
RoboClaw
1caaef4b6f
feat(ui): select Ultrafast for supported accounts (#160352)
* feat(ui): select Ultrafast for supported accounts

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

* fix(gateway): preserve Ultrafast compatibility and account authority

Negotiate speed decoding per connection and keep canonical session state intact. Fence personal-account catalog requests at final guarded HTTP dispatch. Refresh the measured UI boot manifest without changing performance limits.

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

* refactor(openai): keep account catalog outcomes together

Move the existing account-scoped result projection into the already imported catalog helper without changing its behavior. Keep the provider owner below its existing line-count ratchet.

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

* test: refresh Ultrafast tool prompt fixtures

Regenerate the canonical Codex dynamic-tool fixtures for the authorized Ultrafast speed value. Update only that enum value and its derived size/hash metadata; keep snapshot checks enabled.

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

* fix: stop account catalog requests after default unlink

Bind automatic account selections to the canonical profile writer's committed link authority and carry the real request scope through final guarded dispatch. Keep explicit retained account selections usable after unlink and evict failed discovery custody. Preserve the existing active Auto Ultrafast opt-in while explicit Fast stays priority.

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

* refactor(codex): use narrowed Auto activation flag

Keep the reviewed Auto tier predicate while satisfying the typed boolean lint contract.

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

* fix(ui): share speed applicability for optional Ultrafast

Respect the selected request mapping before offering an optional entitled tier. Preserve all three choices on eligible routes and clearable stored preferences on unsupported routes. Reproduced the contradictory catalog regression and passed 59 unit/Chromium cases; scoped independent review found no actionable P0/P1.

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

* fix(ci): export manifest in same-revision preflight harness

Restore the trusted file omitted when the inline manifest moved out of ci.yml in 9d75a8fe87. Actual preflight job109720001696 failed before tests with MODULE_NOT_FOUND; real Git push and PR materialization fixtures reproduce the same omission. Keep the canonical index export owner, regenerate its workflow projection, and preserve all source/credential guards. Fifteen materialization variants, five import/size checks, root test types, and focused independent review pass.

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

* fix(ci): satisfy extracted manifest static contracts

Repair inherited check-lint failures from the manifest extraction without changing CI routing: avoid namespace shadowing, retain error cause and the diagnostic callback string contract, preserve nonmutating shard copies, and apply required branch syntax. All1259 scripts lint clean;45 planner/import/size cases, formatting, UI i18n, styles, ratchet and independent review pass.

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

* fix(ci): centralize dependency-free workflow flag parsing

Remove the extracted manifest local coercion helper and preserve its exact narrow Boolean grammar under the existing script argument owner. Register the canonical declaration rather than weakening the guard, and carry its runtime through trusted preflight materialization and fixtures.77 argument cases,11 declaration-guard cases,71 scoped integration cases, types, lint, export scans and remaining guard commands pass; independent review has no actionable P0/P1.

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

* fix(gateway): separate model publication authority from selection scope

Keep the actual request lifetime in selected-account HTTP assertions without treating every anonymous unscoped catalog read as a personal account projection. Restore the established models.list response shape; no assertions weakened.177 model/catalog/session cases and10physical HTTP authority cases pass, together with types, lint, ratchet and independent review.

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

* fix: preserve session response argument tuples

Forward the original response tuple while projecting successful legacy payloads, without appending optional undefined arguments.

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

* fix(codex): preserve existing Ultrafast opt-ins

Keep the v2026.9.7 Fast and active Auto opt-in semantics while adding explicit per-session Ultrafast. Standard still clears the tier. Cover cold and warm native turn requests without requiring a migration.

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

* test(ui): distinguish speed labels from model names

Match the complete Effort and Speed section labels rather than the Speed only fixture model. Retain the independent absence assertions for reasoning and speed controls. All four failures reproduced before the repair; the complete 13-case bundled browser file passes afterward.

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

* test(openai): intercept the shared transcription socket

Update the two stale socket mock registrations after the upstream transport consolidation. Keep the actual provider/session code, fake peers, assertions, timeouts, and Bun transport guard unchanged. All 86 OpenAI shard files pass: 1263 passed and one existing skip.

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

* test(gateway): construct complete session reset callers

Replace partial caller objects cast as never with the existing typed session mutation client fixture. Preserve provenance and required-sandbox assertions and the production client capability contract. Both CI failures reproduce before the repair; all 15 reset-model cases pass afterward.

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

* fix: confirm the selected Ultrafast command mode

Share the direct command, directive reply, and system-event confirmation formatter so the saved Ultrafast tier is named accurately. Include the accepted manual value in help and docs without advertising an unverified optional native-menu choice. Preserve boolean Fast, Auto, reset, authorization and persistence behavior. Three regressions fail before repair; 274 focused cases pass afterward.

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

---------

Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
2026-09-30 07:45:41 +00:00
Peter Steinberger
d95272af34
perf(plugins): reduce allocation for forwarded stream results (#161696)
Project ordinary iterator payloads on first consumption and share completed graph inspection only within that synchronous reader chain. Preserve consumer admission, mutable native data, and exceptional-result projection while removing the intermediate Promise mapping.

Reduce sampled allocation by 38-40% across five forwarding layers. Record the read-before-forward limitation, add native-await and lifecycle regressions, and clarify the SDK contract.
2026-09-30 06:57:29 +00:00
Peter Steinberger
30057ae514
fix(codex): keep native spawn in solo turns without hook admission (#161070)
Solo Codex turns on installs without native hook admission (relay disabled, or managed-hooks-only) keep native sub-agent delegation again, on fresh and resumed threads, fixing forward the fallback from #160525 that disabled it for every operator turn.

When a Codex thread can reach native spawn but has no spawn admission installed, a different person's message queues as a follow-up instead of steering the running turn, so the turn never becomes multi-person unguarded. One predicate in thread-requests.ts (isCodexNativeDelegationDisabledForRun) drives the thread's delegation config, the optional supportsCrossProfileSteering backend capability, and the attempt-start refusal, so policy-disabled turns (token-sharing OAuth, report-only, restricted, message-only, system-agent-only) keep accepting other people's steering. Same-person steering and installs with native hook admission are unchanged. A rare cross-runtime fallback into an unguarded multi-person attempt refuses with an explicit message.

Maintainer decision: Codex threads created on source-main no-hook installs while #160525 was live may keep delegation disabled on resume; no npm or GitHub release contained #160525.

Release note: Codex keeps native sub-agent spawning in single-person turns when native hooks are unavailable; another person's message queues as a follow-up only when native spawn could not be guarded.
2026-09-29 23:13:53 -07:00
Sahil Satralkar
63578b2b11
fix: restore model and reply availability after plugin reload failure (#152530)
When a plugin hot reload failed partway through activation, the Gateway committed the failed generation without republishing the prepared model runtime. `models.list` then returned "Model catalog is not ready", and every new turn failed with "prepared reply dispatch runtime owner was not published", until the Gateway was restarted. A failed reload now keeps serving the previously published runtime and still reports the activation failure. A successful reload still swaps in the new runtime.

Related to #157814. This proves the plugin-reload trigger, but not the Windows update-restart incident reported there. Thanks @sahilsatralkar.

Proof: a real isolated Gateway with a scripted mock model.
- On main, after a failed plugin reload, `models.list` was unavailable and a fresh agent turn failed with the unpublished-owner error.
- With this change, the activation failure is still reported, a model stays available and the turn gets a reply.
- A successful reload advances to the next generation and keeps replying.
- Three regression tests fail against main's owner, and the dispatch suite (20/20) and consolidated reload handlers (114/114) pass.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-09-30 13:49:34 +08:00
Peter Steinberger
cce1cf81a6
perf(github): share one two-second upstream budget across a preview (#161653)
Each upstream request inside a GitHub hover preview received its own
eight-second deadline, so the metadata -> commits -> co-author avatar chain
could stack several waits before the card appeared. Carry one abort signal
through visibility checks, redirects, the optional-auth fallback, item and
body reads, commits, and avatars. Slow required metadata keeps the existing
retryable unavailable response; slow optional content is omitted while the
card is preserved. Completed cache hits still make zero network requests
and the full detail reader keeps its own timeout.

Microbenchmark with an abort-aware slow transport: slow avatars after a
700 ms commits page 8,704 -> 2,001 ms wall; stalled required item
8,001 -> 2,002 ms; reopened completed previews unchanged at zero requests.
2026-09-30 05:48:35 +00:00
Sarah Fortune
8c2379be35
fix(agentsapi): preserve prompt history when retrying after steering (#161444)
Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-09-30 02:19:25 +00:00
Peter Steinberger
9c300442b7
refactor(providers): deslop provider plugins fourth pass (#161471)
* refactor(providers): deslop model-provider plugins fourth pass

* chore(providers): prune removed assertion allowances

* refactor(deepinfra): build catalog entries without conditional spreads

* refactor(openai): remove residual runtime type imports
2026-09-29 19:11:06 -07:00