Commit Graph

4382 Commits

Author SHA1 Message Date
wangmiao0668000666
bd7b0ad85f fix(plugins): remove abort listener when channel runtime context is disposed (#109708) 2026-07-17 10:11:21 +01:00
Peter Steinberger
6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
Peter Steinberger
0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00
Peter Steinberger
765bb37364 feat(setup): stream provider prepare progress to every surface (#109764)
* feat: stream provider preparation progress

* fix(android): refresh gateway method constants
2026-07-17 00:55:04 -07:00
Abner Shang
a33ddc9dc5 fix(openai): close OAuth callback prompts cleanly (#89491)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:58:41 -07:00
Peter Steinberger
c13925b387 fix(webhooks): keep routes cold when SecretRefs are unavailable (#109715)
* fix(webhooks): isolate unresolved route secrets

* chore(plugin-sdk): refresh API baseline

* docs(secrets): refresh credential surface
2026-07-16 23:56:59 -07:00
Yuval Dinodia
73cf9a8bed fix(plugins): plugins.deny is bypassed by a mixed-case manifest id (#109237)
* fix(plugins): canonicalize manifest plugin ids to lowercase

Plugin config policy lists (plugins.deny, plugins.allow, plugins.entries)
are lowercase-normalized through normalizePluginId, but a plugin's
self-declared manifest id was only trimmed, never lowercased. A plugin
publishing "id": "Malicious-Scraper" therefore never matched an operator
denylist entry of "malicious-scraper" and fell through to default
activation, loading its hooks, channels, secret integrations, and tools.
The same gap let a mixed-case spelling evade the core reserved-id check.

Canonicalize the id at the manifest parse boundary where
PluginManifestRecord.id is minted, so every downstream policy consumer
compares against the same canonical form.

* test(plugins): prove mixed-case deny at gateway startup

* test(plugins): assert denied gateway record is absent

* test(plugins): materialize allowed secret fixture

* fix(plugins): compare a derived policy key instead of rewriting manifest identity

Manifest ids stay exactly as declared. Deny, allow, and per-entry checks now
compare a lowercase policy key derived at each enforcement boundary, matching
the lowercase-normalized config lists.

The previous approach lowercased PluginManifestRecord.id at the parse boundary.
That id is also matched against the plugin runtime export id, and a mismatch is
a hard load failure, so an existing plugin declaring the same mixed-case id in
both its manifest and its runtime export would stop loading after upgrade.

The Gateway fixture now declares a mixed-case manifest id with a matching
mixed-case runtime export, covering that upgrade case, and drops the allowlist
that previously scoped discovery by a lowercase id and masked the denylist
behavior under test.

* fix(plugins): close mixed-case policy gaps

* test(plugins): use tracked policy fixture temp dir

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:13:13 -07:00
Peter Steinberger
e873a7f955 refactor(memory): move QMD coordination to SQLite (#109636)
* refactor(memory): move QMD coordination to SQLite

* chore: keep release notes in PR body

* chore: annotate lease SQLite primitive
2026-07-16 22:01:34 -07:00
Peter Steinberger
a77c0770ff refactor(speech-core): share TTS request pre-resolution across discord and voice-call (#109640) 2026-07-16 21:47:06 -07:00
Ayaan Zaidi
16c14e5bbf feat(channels): expose the turn-adoption lifecycle seam
Replace the bare onTurnAdopted callback and queuedFollowupLifecycle with one
turnAdoptionLifecycle surface (onSettled guaranteed via finally; adoption-loss
aborts queued steering turns without transcript replay), threaded through the
turn kernel and agent runner, exposed to plugins via
runtime.state.openChannelIngressDrain and the channel-outbound SDK barrel,
with surface budgets re-measured against the narrowed baselines (#108656).
2026-07-17 10:12:54 +05:30
ooiuuii
7641aa80c2 fix: plugins update rewrites config for install-record-only updates (#98422)
* Avoid config rewrites for plugin index updates

* Preserve config freshness for records-only plugin updates

* Validate records-only plugin update config

* fix(plugins): reload index-only updates

Co-authored-by: luyifan <al3060388206@gmail.com>

* chore(protocol): refresh generated clients

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(gateway): wire plugin refresh handler

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:38:45 -07:00
Patrick Erichsen
6083268612 feat(plugins): consume hosted listing metadata (#109629) 2026-07-16 21:22:25 -07:00
Patrick Erichsen
55bb6cfa2e feat(control-ui): proxy plugin catalog icons (#109510) 2026-07-16 20:31:27 -07:00
Patrick Erichsen
bd2bf34b41 feat: carry Featured state into Control (#109418)
* feat: consume live featured catalog state

* fix(plugins): honor hosted curation for published bundled plugins

* fix(plugins): accept package-less trusted ClawHub provenance
2026-07-16 20:27:07 -07:00
Peter Steinberger
349f78776d fix(models): refresh bundled provider catalogs (#109410)
* fix(models): refresh bundled provider catalogs

* docs(models): refresh generated docs map

* fix(xiaomi): keep provider helper private

* chore(release): defer catalog release note
2026-07-16 16:47:25 -07:00
Peter Steinberger
334c182c27 refactor(diffs): move ephemeral artifacts to SQLite (#109328)
* refactor(diffs): move ephemeral artifacts to SQLite

* fix(plugin-state): satisfy SDK validation gates

* test(diffs): satisfy lint contracts

* fix(plugin-state): count expired blobs toward quotas

* fix(plugin-state): harden blob storage boundaries

* fix(plugins): replace stale install provenance
2026-07-16 16:47:19 -07:00
Peter Steinberger
8680faf83c refactor(discord): retire internal abort signal helper (#109369) 2026-07-16 15:12:50 -07:00
Peter Steinberger
40b10eb3d1 perf: avoid plugin cold loads in request hot paths (#109348)
* perf: avoid cold plugin discovery in hot paths

* chore: remove stale harness policy re-export

* fix: preserve active thinking clamps in status
2026-07-16 14:54:32 -07:00
Peter Steinberger
0631252f4b refactor: reduce plugin SDK test import overhead (#109333)
* refactor(test): split plugin SDK test helpers

* fix(test): align plugin SDK test subpaths
2026-07-16 13:55:23 -07:00
Peter Steinberger
2409df768c fix(kimi): honor K3 thinking off (#109335)
* fix(kimi): honor K3 thinking off

* chore: defer Kimi release note

* test(kimi): narrow live reasoning blocks
2026-07-16 13:50:15 -07:00
David Gorelik
63b0cac9f0 fix: reply hooks can claim ordinary agent turns (#108353)
* fix: honor reply hooks for user agent turns

* fix: preserve reply hook turn context

* fix: gate CLI reply hooks by trigger

* fix(plugins): run reply hooks once per admitted turn

Co-authored-by: Clive (OpenClaw) <clive@openclaw.local>

* fix(plugins): reconcile reply hooks after rebase

* fix(auto-reply): dispatch hooks for active steers

* test: use valid channel context shape in steer hook test

---------

Co-authored-by: Clive (OpenClaw) <clive@openclaw.local>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 11:50:43 -07:00
NianJiu
42ff5ec754 feat(kimi): add Kimi K3 support (#109202)
* feat(moonshot): add Kimi K3 support

* feat(kimi): add K3 subscription models

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 11:41:12 -07:00
Peter Steinberger
6175e6a98c refactor: remove stale internal deprecated compatibility (#109266)
* refactor(agents): remove stale deprecated internals

* refactor(channels): remove dead target compat aliases

* refactor(plugins): collapse private deprecated types

* refactor(onboarding): remove stale provider skip alias

* style(agents): format deprecated cleanup

* refactor(agents): internalize sanitizer options
2026-07-16 11:35:34 -07:00
Bill
3590f7df7e fix(agents): route opted-in embedded runs through the CLI backend on subscription-only claude-cli auth (#106840)
Embedded runs targeting a CLI runtime provider fall through to the openclaw
harness and call the provider API directly with the runtime's credentials
(cli_runtime_passthrough_openclaw). Anthropic routes direct anthropic-messages
calls on subscription OAuth tokens to metered extra-usage billing — this is
long-standing behavior, not a recent change. Without extra-usage balance,
every such run (e.g. active-memory recall) fails with a billing error; with
extra-usage enabled, the run silently draws paid metered usage instead of the
plan limits the CLI runtime was configured for. Only CLI-backed execution
runs on plan limits for those credentials.

Add an opt-in RunEmbeddedAgentParams.cliBackendDispatch: "subscription-auth"
that dispatches the run through runCliAgent as a one-shot turn when the
provider is claude-cli, a CLI backend is registered, and the ordered auth
profile selection for the passthrough resolves to a subscription (oauth/token)
credential or nothing rather than an API key; resolution stays on stored
credential metadata, with no credential materialization or refresh on the
per-turn path. The dispatch translates toolsAllow into the selectable-backend
surface (native: [], allowlisted loopback MCP tools; wildcard allowlists stay
MCP-only), runs with a fresh CLI process (no live-session reuse; session-
scoped bundle-MCP retirement on run end rather than the process-wide loopback
close), bridges CLI tool result events to onAgentToolResult with native-path
semantics (normalizeToolName + isToolResultError), and drops CLI session
bindings from the result.

The selectable-backend MCP list now also bounds the loopback MCP grant
server-side: the grant carries a per-run gateway tool allowlist enforced in
scoped tool resolution, so tools outside the run's allowlist can be neither
listed nor called even under CLI bypass permission modes where
--allowedTools is advisory.

active-memory recall opts in so recall works on claude-cli subscription-only
instances and stops drawing metered extra usage where it previously could.
Scoped to claude-cli; other CLI runtimes keep the passthrough until their
direct-API contract is verified.

The dispatch also mirrors the run into the run's session transcript through the session
accessor (user turn, tool call/result records as they stream, final assistant
snapshot at run end) so transcript consumers keep parity with embedded runs:
active-memory's persistTranscripts, timeout partial-text salvage, and the
live terminal-search watcher that polls the session file mid-run.

Post-review hardening: canonical anthropic/<model> refs whose configured
agentRuntime is claude-cli resolve through the runtime policy before the
dispatch gate (they previously stayed on the failing passthrough); restricted
dispatches serve an exclusive loopback-only MCP bundle so user/plugin MCP
servers stay outside the run's tool universe; and the transcript recorder
flushes the latest assistant snapshot the moment the run aborts, so timeout
salvage sees partial text even while the killed CLI child is still settling.

Recalls routed to the claude-cli runtime default to a 45s budget (measured
CLI-dispatched runs take 14-20s, over the plain 15s default); explicit
timeoutMs config always wins.

Transcript mirror keeps bare-array tool_result content (claude stream-json
echoes MCP results without a {content} wrapper); dropping it classified every
successful recall as no_relevant_memory.

CLI dispatch resolves inside session/global lane admission so dispatched
runs obey the same lifecycle, placement, and concurrency gates as native
embedded runs.

LOC-ratchet offsets move the loopback grant-context builders to
cli-runner/mcp-grant-context.ts and dedupe the run/prep stage-summary
emitters into attempt-stage-timing.ts; unused type exports dropped and the
now-used stream-message baseline entry removed.

The recall timeout default now consumes the runner's own dispatch
eligibility through a new plugin-runtime seam
(agent.resolveCliBackendDispatchEligibility): API-key and missing-backend
routes keep the passthrough and its plain 15s default.

Eligibility honors an explicitly pinned authProfileId (the credential the
run executes on) before ordered profile selection, in both directions.

Transcript mirror composes buildAssistantMessage + buildUsageWithNoCost
directly; main trimmed the zero-usage wrapper export (ab0ccc244b) before
this branch's usage landed.

Dispatch eligibility is provider-owned: the anthropic plugin's claude-cli
backend declares CliBackendPlugin.subscriptionAuthDispatch and core reads
the registered descriptor instead of a core provider allowlist.

Dispatch fails closed on tool policy (only non-empty named allowlists are
expressible on the CLI surface; deny-all, wildcards, absent allowlists, and
disableTools/modelRun keep the passthrough), threads the pinned
authProfileId into CLI runtime resolution, and emits onExecutionStarted at
the admitted dispatch boundary.
2026-07-16 10:37:54 -07:00
Peter Steinberger
4432016f7f refactor: prune redundant OpenClaw env controls (#109211)
* refactor: prune redundant OpenClaw env controls

* docs: refresh environment reference map
2026-07-16 10:06:39 -07:00
Peter Steinberger
ae547607b0 test: consolidate setup migration tests (#109110) 2026-07-16 08:25:55 -07:00
Peter Steinberger
a2eb27c03a refactor(plugins): split update lifecycle (#108877)
* refactor(plugins): split update lifecycle

* fix(plugins): break update type cycle

* fix(plugins): keep update modules below line budget

* fix(plugins): preserve update export surface
2026-07-16 07:54:21 -07:00
Peter Steinberger
16d1f487fe feat(widgets): unify show_widget across surfaces (#108983)
* feat(widgets): unify show_widget across surfaces

* docs(canvas): keep lazy show_widget descriptor in sync with the loaded tool
2026-07-16 05:24:11 -07:00
LZY3538
a50bdf600e fix(plugin-sdk): let runtime completions request reasoning (#108759)
* fix(plugin-sdk): forward completion reasoning

* test(plugin-sdk): cover ultra reasoning normalization

* test(plugin-sdk): preserve omitted reasoning option

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 05:23:54 -07:00
Peter Steinberger
d5eebf02e2 fix(workboard): record resolved runtime metadata instead of hardcoded codex engine (#108887)
* fix(workboard): record resolved runtime metadata instead of hardcoded codex engine

Workboard executions labeled every dispatched run engine=codex, model=default,
and id suffix :codex even for Claude/other harness agents. The gateway agent
admission phase now returns the resolved {harness, provider, model} for plugin
subagent runs; the dispatcher records it verbatim and omits engine/model when
unresolved. Engine becomes an open runtime identifier in the workboard
contract (built-in launch choices stay a closed list), store/UI normalizers
preserve historical labels as written instead of inventing codex, and new
execution ids use an :agent-session suffix. Fixes #108362

* fix(workboard): accept undefined engine in ui engineModel helper
2026-07-16 04:10:27 -07:00
Peter Steinberger
66604df9b6 refactor(channels): share retry helpers and remove dead state probes (#108903)
* refactor(channels): generalize channel retry runner and retry-after parsing; drop dead configured-state probes

* fix(channels): align retry and metadata contracts
2026-07-16 04:03:15 -07:00
Jason (Json)
73980e7e42 fix(codex): remove duplicate provider setup choice (#107979)
* fix(codex): stop advertising harness as model provider

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(wizard): keep migration plugins out of optional setup

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:31:11 -07:00
loong954
804de49dda fix: prevent stale plugin installs from blocking lifecycle commands (#107691)
* fix(plugins): handle ENOTDIR gracefully in npm-project-roots

The listManagedPluginNpmProjectRootsSync and listManagedPluginNpmProjectRoots
functions only caught ENOENT errors when reading the projects directory,
but an ENOTDIR error (when a file path is mistakenly used as a directory)
would propagate unhandled and crash the CLI.

Replace the local isMissing helper with the shared isNotFoundPathError from
infra/path-guards.ts, which already covers both ENOENT and ENOTDIR.

Fixes #107467

* test(plugins): use managed temp directory fixture

* chore: keep release notes out of contributor PR

* fix(plugins): restore not-found path guard export

* fix(plugins): normalize Windows managed install paths

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-16 01:59:48 -07:00
Peter Steinberger
cb9f1a6df8 perf(test): clear completed deadline timers (#108780) 2026-07-16 01:45:55 -07:00
Peter Steinberger
011d0279ca refactor(plugins): centralize slot reset policy (#108763) 2026-07-16 01:45:22 -07:00
Peter Steinberger
30ae21fca7 fix: prevent SQLite lock stalls and schema drift (#108663)
* fix: harden SQLite state storage

* build: allow strict SQLite migration SQL

* test: align SQLite and model-default assertions
2026-07-16 01:45:06 -07:00
Peter Steinberger
2c977bebce fix(plugins): preserve trust policy after update failures (#108649) 2026-07-16 00:56:06 -07:00
Peter Steinberger
dde90a345a refactor(plugin-sdk): narrow wildcard barrels to explicit used exports (#108440)
* refactor(plugin-sdk): narrow wildcard barrels to explicit used exports

* refactor(tools): delete dead tool-planning module exposed by barrel narrowing

* fix(plugin-sdk): restore deprecation tag on OpenClawSchemaType alias

* test(agents): drop test for deleted runtime proxy module

* refactor(tools): trim descriptor types to cache consumers

* refactor(deadcode): harvest exports orphaned by barrel narrowing

* refactor(deadcode): harvest exports orphaned by barrel narrowing (rest)

* fix(agents): restore sdk imports and test markers via public predicate

* fix(plugin-sdk): named type re-exports in plugin-entry; trim types barrel precisely

* chore(plugin-sdk): account unmasked deprecated provider types in budgets

* fix(plugins): name star-only type rows for dts bundling

* fix(plugins): restore host-hook surface; unexport internal api compositions

* fix(plugins): named type imports for api composition; restore needed source exports

* fix(plugins): knip-visible type imports for registry surfaces

* test: adapt tests to privatized media and command internals

* fix(qa-lab): re-export snapshot conversation type

* style: format sessions sdk imports

* fix(plugins): restore smoke entry export; pin budgets to exact actuals

* fix(plugins): canonical smoke-entry import; drop orphaned root shims

* fix(plugins): allowlist manifest probe, repoint qa web import, drop dead browser barrels

* fix(plugin-sdk): pin codex auth marker and scaffold provider type

* fix(qa-lab): keep web-facing model-selection shim within boundary rules

* fix(plugin-sdk): preserve merged contracts through narrowed barrels

* chore(plugin-sdk): pin post-rebase surface budgets
2026-07-16 00:45:23 -07:00
Peter Steinberger
7a398fe6f8 fix(update): preserve plugin policy on failures (#108661) 2026-07-16 00:38:44 -07:00
Peter Steinberger
7e1d93d36d refactor(deadcode): enforce full-repository hard zero (#108717)
* refactor(deadcode): enforce full-repository hard zero

* refactor(deadcode): drop rebased test-support leftovers

* refactor(openai): remove stale TTS test bridge

* test(config): cover bundled tuple baseline merging

* fix(deadcode): reject external Windows paths

* test(config): preserve heterogeneous tuple coverage
2026-07-16 00:16:20 -07:00
Peter Steinberger
d8b723fb00 fix: channel turns recover safely after gateway restart (#108283)
* fix(gateway): recover channel turns safely after restart

* refactor(gateway): keep recovery identity internal

* refactor(gateway): keep recovery metadata private

* fix(gateway): preserve recovery action authority

* fix(gateway): close recovery lifecycle gaps

* fix(gateway): fail closed on missing delivery receipts

* fix(gateway): fail closed on unmirrorable replies

* fix(gateway): persist terminal delivery intent

* fix(gateway): align recovery lifecycle types

* fix(gateway): require exact terminal thread receipt

* fix(gateway): close recovered terminal tool calls

* test(gateway): type terminal tool correlation

* fix(gateway): satisfy restart recovery CI contracts

* fix(gateway): require terminal tool correlation

* fix(agents): scope recovery receipts to source turns

* fix(gateway): fail closed without restart correlation

* fix(gateway): dedupe terminal source redelivery

* fix(agents): keep recovery tool results causal

* test(auto-reply): clean recovery fixture directories

* fix(gateway): allow live terminal sends without recovery claims

* fix(agents): reconcile delivered sends through restart aborts

* fix(agents): keep recovery continuations in source turns

* fix(agents): keep source-less sends non-terminal

* fix(auto-reply): dedupe active source redelivery

* fix(agents): harden recovery receipt contracts

* fix(agents): admit terminal recovery successors

* docs(recovery): document canonical receipt ownership

* fix(agents): fail closed on stale turn authority

* test(auto-reply): assert rebound session state

* fix(plugins): keep restart recovery hook list internal
2026-07-15 23:01:26 -07:00
Peter Steinberger
da59d6ade9 feat(onboarding): detect local inference providers (#108605)
* feat(onboarding): detect local inference providers

* fix(onboarding): satisfy inference choice lint

* chore(i18n): refresh onboarding locales

* chore: leave changelog to release automation

* chore(plugin-sdk): refresh API baseline

* fix(onboarding): preserve source config during local activation
2026-07-15 22:46:16 -07:00
Peter Steinberger
bae9752c5a refactor(deadcode): enforce repository hard zero (#108641) 2026-07-15 22:40:00 -07:00
Peter Steinberger
9ff855db05 fix(plugins): canonicalize plugin entry path per process to prevent duplicate register() (#108508)
On git-channel installs where both extensions/<id>/index.ts and
dist/extensions/<id>/index.js exist, two registry assemblies resolved the same
plugin id to different physical files (preferBuiltPluginArtifacts drives both the
artifact choice and the load-cache key), so the path-keyed module cache
evaluated the entry twice — two live plugin instances with separate state,
binding hooks to one and registerTool to the other. Memoize the first resolved
runtime entry path per plugin-id + real root + entry-kind so both assemblies
converge on one module instance; clear the memo on activated-runtime-state and
registry-load-cache resets so reload/install/doctor re-resolve. No-op on
dist-only installs.

Closes #107933
2026-07-15 21:58:13 -07:00
Peter Steinberger
de3f7925c4 test(release): harden QA and live validation (#108589) 2026-07-15 20:45:36 -07:00
Peter Steinberger
7eeb1096db fix(codex): re-home app-server usage reporting on the harness seam
The deleted text provider's usage hook was the only source for the /status
Codex subscription usage line. Harnesses can now contribute an optional
usage snapshot (provider hooks keep priority; only distinct synthetic hook
owners fall through), and the codex harness reports app-server rate limits
via account/rateLimits/read with the same conversion and account identity
as before. No text provider resurrected; deadcode and SDK surface gates
clean.
2026-07-16 03:06:47 +01:00
Peter Steinberger
3c8269ca52 refactor(codex)!: fold the codex text provider into openai with a doctor migration
The live codex text provider was a redundant projection of the openai
catalog (exclusive provider ownership; the openai plugin's ChatGPT OAuth
discovery already serves gpt-5.6-* route-aware). Folding it:

- extensions/codex no longer registers a text provider, catalog entry, or
  synthetic text auth; provider.ts/provider-catalog.ts/provider-discovery.ts
  and the route-blind model-name heuristics are deleted; the narrow
  post-harness reasoning fallback moves to an app-server-owned module
- openai thinking policy keys on explicit selected-route provenance
  (api === openai-chatgpt-responses) instead of value-shape inference
- models.list gains an optional additive agentRuntime field (configured
  intent); session agentHarnessId remains the execution proof
- doctor --fix migrates the shipped codex/* config shape end to end:
  every model slot, provider-config merge with blocker-aware conflict
  handling, sessions, cron payloads (two-phase: runtime policy persists
  before cron refs rewrite), transcripts; migrated refs carry model-scoped
  agentRuntime.id=codex preserving the shipped wizard semantics; auto
  runtime policies normalize to codex with sibling fields preserved;
  blocked provider conflicts retain the whole legacy namespace fail-closed
  with an actionable warning
- the stale openai:default profile cleanup (#91352) was deliberately
  deferred to a follow-up after review showed it needs per-agent identity
  proofs; doctor keeps warning about unusable profiles

Fixes #105561
Fixes #84637
Fixes #90420
2026-07-16 03:06:43 +01:00
Peter Steinberger
ab3f057cfd refactor: split plugin loader by responsibility (#108513)
* refactor(plugins): split plugin loader

* refactor(plugins): keep loader helpers internal

* refactor(plugins): remove unused loader type import

* test(plugins): cover split runtime registry boundary
2026-07-15 17:51:13 -07:00
Dallin Romney
2d9b78fff7 refactor(qa): canonicalize live scenario coverage (#108464) 2026-07-15 16:50:41 -07:00
clawsweeper[bot]
15a304d6e1 fix(agents): wake owning session after generated-media direct delivery (#108024)
* fix(agents): wake owning session after generated-media direct delivery

When a background media generation (image/music/video) completes but the
requester's agent turn cannot be woken, delivery falls back to sending the
media straight to the channel. The owning session never learned about it,
leaving the attachment orphaned with no agent follow-up.

Queue a system event plus a scoped heartbeat wake after both direct
fallback paths (announce delivery and the shared background lifecycle) so
the agent continues the conversation in its own voice. Subagent requester
sessions skip the heartbeat since their completions route via announce.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(agents): persist generated media session handoffs

Co-authored-by: Molty <steipete@gmail.com>

* chore: prune max-lines baseline

* fix(agents): harden durable media handoffs

* fix(agents): charge media retries once

* chore: refresh max-lines baseline

* fix(agents): persist delivery settlement cleanup

* fix(agents): fence interrupted media delivery

* fix(agents): fence durable handoff admission

* fix(agents): reconcile terminal handoffs at retry limit

* fix(agents): align durable handoff types

* test(agents): type durable handoff fixtures

* fix: satisfy session delivery lint

* fix: avoid payload map spreads

* fix: satisfy durable handoff gates

* test: align generated media handoff expectations

* fix: avoid serializing session recovery state during load

---------

Co-authored-by: Molty <steipete@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:54:12 -07:00