Commit Graph

19830 Commits

Author SHA1 Message Date
Peter Steinberger b9fb56566b fix(browser): treat Linux zombies as exited (#125831) 2026-08-18 07:32:02 -07:00
Peter Steinberger 2c5a694ccb refactor(memory): simplify LanceDB embedding lifecycle (#125841) 2026-08-18 07:21:12 -07:00
Peter Steinberger efaa867d93 feat(nodes): publish exact runner slots (#125708)
* feat(nodes): publish exact runner slots

* docs(runners): link slot inventory PR

* fix(ui): keep session menus clickable under previews

* perf(protocol): keep runner slot schema off broad barrel

* test(codex): tolerate elapsed media startup budget

* test(codex): type media client factory mocks

* fix(protocol): reject impossible runner slot counts

* test(ci): stabilize loaded lifecycle checks

* test(ui): allow loaded bulk-delete scheduling

* test(ui): stabilize loaded interaction checks

* test(ui): isolate loaded update notice checks

* test(ui): colocate bulk-delete lifecycle coverage

* test(gateway): publish session config before async setup
2026-08-18 07:08:06 -07:00
Peter Steinberger 4589d8514c fix(gateway): stop agent terminal processes after session archive (#125784)
* fix(gateway): stop terminal PTYs on session archive

Bind agent terminals to the durable session incarnation, drain exact ownership during archive, and terminate every job-control process group in the PTY session.\n\nCloses #125769

* test(gateway): cover terminal cleanup on archive

* test(gateway): align terminal outcome assertions

* test(gateway): preserve session exports in invoke test

* fix(gateway): await terminal exit before archive

* test(codex): consolidate supervised instruction coverage

Move the duplicated two-attempt regression into the canonical thread lifecycle test so the exact two-worker extension shard stays bounded on low-core CI.\n\nRelated: #125783
2026-08-18 06:27:42 -07:00
Ayaan Zaidi d412c6b284 fix(codex): inherit agent workspace instructions in native subagents (#125783)
* fix(codex): inherit agent workspace instructions in native subagents via thread developer instructions

* fix(codex): satisfy lint on thread instruction changes

* fix(codex): persist frozen agent instructions across supervised materialization
2026-08-18 17:15:15 +05:30
Jason (Json) 7c65bbcee3 fix(sessions): track context window provenance (#124303)
* fix(sessions): track context window provenance

* fix(sessions): complete context provenance coverage

* fix(sessions): honor authored context window caps

* fix(agents): distinguish context source helpers

* fix(sessions): clear context provenance on model invalidation

* test(codex): preserve local operator authority provenance

* fix(context): clamp effective caps to native windows

* fix(cron): use the runtime model facade

* fix(status): honor session context provenance

* test(status): use public context token inputs

* test(status): split session row cases

* test(status): classify split cases as test support

* test(status): declare runtime context provenance

* fix(sessions): preserve context ownership through finalization

* fix(sessions): apply context provenance to listings

* fix(cron): preserve projected context ownership

* fix(sessions): scope locked context ownership

* fix(status): share session context projection
2026-08-18 05:03:01 -06:00
Peter Steinberger 2d5334fb42 fix(tts): normalize streamed speech and report fallbacks (#125686)
* fix(tts): normalize streamed speech and report fallbacks

Streamed Discord voice now strips Markdown and raw link destinations like buffered synthesis.

Record the first failed streaming provider and reason code before successful file fallback.

* test(ui): stabilize reconnect retry timing

Drive the retry deterministically by advancing the exact 100 ms fake timer while preserving the ordering and outbox proof. Repairs CI run 32110130614 job 95627654678.

* fix(discord): ignore expected TTS stream skips

Address the ClawSweeper finding by retaining warning metadata only for actual failed attempts. Expected unsupported-for-streaming skips stay silent while real streaming failures still warn after successful file fallback.

* test(ui): settle interaction state before assertions

Repairs CI run 32117859632 by invoking the markdown table handler directly with a targeted event and waiting for durable IndexedDB composer state before navigation or page close.

* test: remove incidental UI and process identities

CI run 32120793258 exposed two owner-specific test assumptions.

Preserve the child-session hover visibility and pointer assertions, then focus and activate its menu with Enter so an unrelated delayed hovercard cannot intercept the pointer.

Assert the exact owned descendant PID is dead when QA cleanup completes instead of checking a globally reusable PGID.

* test(ui): stabilize connected send retry timing

CI run 32125741781 exposed the wall-clock race in the connected retry test.
2026-08-18 03:46:22 -07:00
Peter Steinberger 5f958cf8e6 fix(tts): avoid mislabeled local and ElevenLabs audio (#125628)
* fix(tts): report actual audio output formats

Detect local CLI audio containers before conversion and derive ElevenLabs delivery metadata from the effective output format. This prevents MP3 or PCM bytes from being persisted or delivered under incompatible file and voice metadata.

* fix(tts-local-cli): distinguish Ogg Opus audio

Treat Ogg as a source container unless its first packet is OpusHead, so Vorbis and M4A inputs are transcoded to the requested target instead of being mislabeled as native voice audio.

* fix(tts-local-cli): validate MP3 frame headers

Require valid MPEG version, layer, bitrate, and sample-rate fields before treating sync bytes as MP3, preventing reserved headers from bypassing conversion under MP3 metadata.

* fix(tts-local-cli): validate tagged MP3 output

Require structurally valid ID3v2 metadata followed by a strict MPEG frame, and stop trusting recognizable file extensions when their bytes do not match. Unknown or malformed output now fails closed instead of bypassing conversion.

* fix(tts-local-cli): accept free-format MPEG audio

Treat bitrate index zero as valid free-format MPEG audio and lock the ID3v2.4 footer offset contract with focused regression coverage.

* fix(tts-local-cli): normalize all Ogg output

Treat Ogg only as a source container and always transcode it to the requested target, so malformed or ambiguous Ogg bytes can never bypass conversion as native voice audio.
2026-08-18 03:24:44 -07:00
Peter Steinberger d95d591d98 fix(slack): require message timestamps for delivery success (#125762) 2026-08-18 03:16:17 -07:00
Peter Steinberger f886ab181e fix(ui): align session owner filtering terminology (#125645)
* fix(ui): align session owner filtering terminology

Owner filters now use owner terminology consistently across the Gateway, Control UI, and generated native protocol clients. The old terms were prerelease-only, so no migration or compatibility aliases are needed.

* fix(gateway): preserve creator provenance filtering

Keep creatorId scoped to immutable createdActor provenance while ownerId queries the current projected assignable owner. This preserves independent creator and responsibility filtering after reassignment.

* test(ui): wait for remembered draft before reload

CI exposed an IndexedDB draft-persistence race: the test reloaded before the write completed and then re-filled the message while restoration arrived. Wait on the canonical durable-draft helper before reload so the reload cannot race the write.

* fix(ui): keep session menus clear of hovercards

Horizontal sidebar previews were positioned from the inner link rect instead of the complete session row, allowing the hovercard to overlap trailing actions.

Anchor preview placement to the full row while preserving the link trigger and ownership flow so the session menu remains clickable.

* perf(ui): keep hovercard fix within startup budget

Use the sidebar direct-row invariant to anchor the hovercard outside trailing actions without a selector lookup. This preserves the fix without increasing the startup budget.

* fix(qa): preserve Matrix CLI timeout precedence

Keep the primary timeout operator-visible when descendant settlement also reports secondary cleanup trouble. Preserve the complete AggregateError as the public wrapper cause so settlement evidence remains inspectable.

* test(ui): isolate Markdown table clipboard boundary

With isolate:false, the shared module registry can retain clipboard imports before this test installs its module mock, leaving the spy disconnected from the production call.

Stub navigator.clipboard.writeText instead so the test exercises the real copyToClipboard boundary regardless of module load order, then restore the original descriptor.
2026-08-18 03:07:21 -07:00
Peter Steinberger f72782d87b refactor(test): restore auth persistence integrity (#125699)
* test: restore auth persistence integrity

Restore the SQLite-backed auth wizard assertions traced to 43ea501f38 and consolidate duplicated message-action and temp-directory fixtures.

* test: support npm 12 pack results
2026-08-18 02:58:30 -07:00
Peter Steinberger 5e3e52431e fix(voice-call): preserve carrier-confirmed termination state (#125717)
* fix(voice-call): serialize realtime termination

* fix(ui): trim debug overlay startup path
2026-08-18 02:17:11 -07:00
Peter Steinberger 29d6fa6eb2 fix(browser): surface initial navigation failures (#125743) 2026-08-18 02:08:10 -07:00
Peter Steinberger 8a0d28d6ba refactor(qa): simplify scenario runner infrastructure (#125738) 2026-08-18 02:03:37 -07:00
Peter Steinberger 20b46bbb3b perf(memory): avoid duplicate embeddings during filtered recall (#125735)
* perf(memory): search filtered sessions in one pass

* refactor(memory): model transcript capture outcome
2026-08-18 02:00:38 -07:00
Peter Steinberger 460b6b1e96 refactor(realtime): deduplicate voice audio handling (#125728)
Reuse the canonical realtime audio duration and OpenAI-compatible wire-format helpers while removing redundant state transitions and truncate payload construction. The production diff is net-negative.

Provider interruption policy and lifecycle ownership stay local to each provider; this does not introduce shared mutable assistant tracking or change behavior.
2026-08-18 02:00:12 -07:00
ClawSweeper 1bf4c1d18c fix(sessions): inherit agent bootstrap outside workspace (#125675)
* fix(sessions): inherit agent bootstrap outside workspace

* fix(sessions): layer execution-dir project context over agent bootstrap

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-18 14:23:28 +05:30
Peter Steinberger 8fa06aeaaf fix(agents): preserve fallback context history (#125714) 2026-08-18 01:40:41 -07:00
Peter Steinberger 43e0150aa4 fix(imessage): preserve inbound SMS routing in auto mode [AI-assisted] (#125633)
* fix(imessage): preserve inbound SMS routing in auto mode

* fix(imessage): preserve direct read receipt routing
2026-08-18 01:08:43 -07:00
Peter Steinberger 9ad1c0c682 fix(auth): surface revoked OAuth state without masking provider failures (#125515)
* fix(auth): preserve WHAM classifications and failure recording

WHAM 401/403 state now drives accurate re-auth guidance, while inline hook failures are contained after persistence so recorded failures cannot escape or be masked.

* docs(plugin-sdk): define auth cooldown classifications

document the additive cooldown diagnostic contract and cover its canonical public-SDK projection.

* fix(auth): keep WHAM diagnostics source-compatible

keep cooldownReason canonical, persist exact WHAM diagnostics in optional cooldownClassification, and preserve operator guidance plus failure-hook containment.

* fix(auth): keep failover on canonical cooldown reasons

ensure optional WHAM diagnostics never drive scheduling and discard mismatched persisted reason/classification pairs.
2026-08-18 00:35:06 -07:00
Peter Steinberger 9564b9fc00 fix(codex): preserve approval timeout outcomes (#125671)
Preserve operator approval terminal reasons through the harness, map denials and timeouts to Codex decline, and retain visible timeout evidence so the turn can continue instead of being killed.
2026-08-18 00:29:15 -07:00
Peter Steinberger 6cc40431d1 fix(voice): prevent choppy audio in realtime calls (#125620)
* fix(voice-call): pace realtime audio from stream clock

* fix(voice): preserve resampler state across audio chunks

* fix(voice-call): honor telephony TTS audio formats

* fix(voice-call): await acknowledged stream playback

* fix(voice): bound realtime input audio backlog

* chore(voice-call): shrink assertion baseline and localize tts format error

* test(voice-call): split playback-mark coverage into its own suite

* test(voice-call): drop helper left unused by suite split

* test(openai): scope queued audio copy assertion

* fix(openai): flush realtime resampler at response end

* fix(voice-call): reject containerized mulaw TTS
2026-08-18 00:07:01 -07:00
Peter Steinberger da4ad4110b fix(process): treat zombie lock owners as dead (#125658)
Linux signal-zero probes succeed for zombie processes. Reclaim memory promotion and session usage locks only when their exact zombie owner is still current, and route shared test waits through the canonical zombie-aware PID helper.
2026-08-17 23:55:08 -07:00
Hannes Rudolph 34c3d15a6b fix(macos): complete Codex onboarding and model picker (#124829)
* fix(setup): refresh Codex registry with staged install

* fix(macos): verify inference before onboarding handoff

* fix(setup): use native Codex home for subscription auth

* fix(codex): honor attempt-scoped setup config

* fix(macos): align onboarding handoff with reopen

* fix(setup): await prepared model convergence

* fix(ui): avoid false auth state for empty catalog

* fix(setup): scope catalog convergence to Codex gateway

* fix(setup): publish the committed runtime catalog

* fix(models): project configured static runtime models

* fix(codex): expose app-server model catalog

* fix(models): preserve Codex auth across reloads

* fix(ci): align Codex onboarding checks

* test(ui): stabilize dock suppression environment

* fix(codex): honor discovery config in app-server model catalog

The manifest documents discovery.enabled (bundled fallback list) and
discovery.timeoutMs (default 2500ms) for model discovery; the new catalog
path used the generic 60s request timeout and ignored the enable gate.
Also drop the test-only listModels injection seam in favor of vi.mock.

* fix(setup): refuse prepared Codex auth over an explicit remote transport

configureCodexCliPreparedAuth silently rewrote an explicitly configured
websocket/unix app-server to local stdio (keeping a dangling url), moving
the credential boundary onto this host. Fail setup with actionable
guidance instead; also surface the root cause when the prepared model
catalog refresh fails after activation.

* refactor(agents): one canonical model-catalog identity key

Three near-identical key helpers existed (models-list-result,
models-list-configured-static, harness/model-catalog). Export
resolveModelCatalogIdentityKey from the route-policy owner, collapse the
duplicate dedupe loops into dedupeByKey, make donor enrichment Map-based,
and inline the one-off harness-augment wrapper.

* fix(macos): restore custodian handoff for fresh activations

Landing every finish on the plain dashboard stranded the custodian
first-run flow (memory import, channels, permissions, hatch). Fresh
activations now hand off to custodian onboarding; live-verified
pre-existing setups reopen the normal dashboard, matching the removed
already-configured shortcut. Tests pin the destination per path.

Also isolate the post-startup Codex login test from developer machines:
ambient OPENAI_API_KEY and a real Codex login made it assert-fail.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-17 23:31:12 -07:00
Jacqueline Henriksen 72c227c7cc fix(llama): support embedding-only managed servers (#125383)
* fix(llama): support embedding-only managed servers

* docs(llama): describe embedding-only setup

* fix(llama): remove unused model reference export

* fix(llama-cpp): keep guided setup chat-capable

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-17 23:29:43 -07:00
Alix-007 cc6b9470ac fix(browser): prepare direct relay shutdown (#125176) 2026-08-18 02:27:34 -04:00
Peter Steinberger b68d13a0f0 fix(memory): bound LanceDB prompts and reload embedding config (#125567)
* fix(memory): bound LanceDB recall and reload embeddings

* fix(memory): preserve LanceDB index identity
2026-08-17 22:55:20 -07:00
Peter Steinberger 7f4bc83ce7 refactor(gateway): use typed doctor close diagnostics (#125629) 2026-08-17 22:55:10 -07:00
Peter Steinberger 31afd52e99 refactor(realtime): share audio duration calculation (#125612)
Fix xAI barge-in truncation that reported 3760 ms after only 3700 ms of decoded audio.

Share exact audio-duration math across OpenAI, xAI, and Google while keeping provider-specific rounding at each caller.
2026-08-17 22:25:42 -07:00
Peter Steinberger bbf7454b17 fix(codex): retain structured tool result details (#125610) 2026-08-17 22:13:33 -07:00
Peter Steinberger 69a0f2d0ff fix(browser): keep screenshot sharing hints capability-neutral (#125597)
Browser screenshot results always named the message tool even when policy had
removed it from the model's effective tool surface. Report the staged sanitized
outbound copy and its path without naming another independently gated tool, so
the result remains actionable without becoming hallucination bait. Update the
vision, fallback, and raw-image result tests to protect that contract.
2026-08-17 22:07:17 -07:00
Peter Steinberger 7fc3371eac fix(codex): enforce hosted search domains for web fetch (#125574)
* fix(codex): apply hosted search domains to web fetch

* fix(net): preserve allowlist error wording

* fix(codex): enforce search domains in side questions
2026-08-17 21:49:35 -07:00
Josh Avant 916aca13f3 feat: record subagent execution lineage (#122015)
* feat(audit): record subagent execution lineage

* fix(audit): type-check spawn lineage validation

* docs: preserve spawned-run lineage invariants

* fix(audit): preserve lineage for worker spawns

* fix(audit): bind worker lineage to live authority

* fix(audit): keep lineage carrier private

* fix(sessions): preserve ACP participant recording

* fix(audit): keep lineage out of runtime bearer

* fix(audit): keep lineage type private

* test(audit): match current worker claim shape

* test(audit): preserve readonly lineage result

* fix(audit): redeem spawn lineage privately

* fix(audit): preserve lineage redemption on copy

* test(audit): prove nested worker spawn lineage

* fix(audit): restore execution identity CI gates
2026-08-17 21:41:30 -07:00
Peter Steinberger 7e7b860bca fix: preserve message delivery after result middleware (#125497)
* fix(agents): carry typed message delivery receipts

* fix(agents): preserve receipts across harness middleware

* fix(agents): preserve plugin broadcast delivery receipts

* fix(agents): preserve partial broadcast delivery receipts
2026-08-17 21:16:14 -07:00
Peter Steinberger b7ccf62fbd fix(voice-call): keep Funnel off occupied HTTPS ports (#125552)
* fix(voice-call): support alternate Tailscale HTTPS ports

* refactor(voice-call): keep Tailscale DNS lookup private

* fix(voice-call): preserve config normalization contract
2026-08-17 21:04:17 -07:00
Peter Steinberger 7242074ecc fix(memory): prevent silent context loss in resets and search (#125534)
* fix(memory): record transcript capture failures

* fix(memory): backfill filtered search results
2026-08-17 20:46:52 -07:00
Peter Steinberger ebac731352 fix(google-meet): classify gateway CLI fallback with typed guards instead of message matching (#125495)
* fix(google-meet): classify gateway CLI fallback with typed guards instead of message matching

Replaces the message-substring classifier in the Meet CLI's
gateway-unavailable local fallback with the structural
isGatewayTransportError/isGatewayClientRequestError guards (seam shared
verbatim with #125458). Decision surface chosen per Meet semantics:
uncoded transport closes (unreachable sockets, now incl. ETIMEDOUT/
ENETUNREACH) fall back; coded closes incl. 1006 deliberately do not,
since a live gateway may still own Meet browser sessions; unknown-method
fallback stays but requires a structural gateway request error. Adds
ECONNRESET to GATEWAY_UNREACHABLE_SOCKET_CODES so connect-time resets
wrap into the typed unreachable error instead of escaping raw.

* test(process): treat Linux zombies as terminated
2026-08-17 20:40:46 -07:00
Peter Steinberger 1acabe40a9 feat(voice-call): let realtime agents end calls (#125525) 2026-08-17 20:39:13 -07:00
Peter Steinberger 41c0818751 fix(openai): prevent realtime barge-in truncation errors (#125502)
* fix(openai): clamp realtime barge-in truncation

Clamp OpenAI Realtime barge-in truncation to the audio duration produced for each assistant item. This prevents interruption failures observed live when 3,700 ms of decoded audio was paired with a 3,760 ms transport-clock timestamp.

* fix(openai): propagate PCM sideband audio format

The browser sideband negotiated PCM16, but its bridge defaulted to G.711 for duration accounting. Propagate the negotiated format so truncation uses the actual PCM duration and closes ClawSweeper's in-scope finding.
2026-08-17 19:29:50 -07:00
Peter Steinberger 75fcaba919 fix(voice-call): survive gateway in-process restart and stop CLI dead-ends (#125458)
* fix(voice-call): survive gateway in-process restart and stop CLI dead-ends

The gateway's in-process restart (SIGUSR1 config reload) reuses the cached
plugin registry, so service stop/start run on the same retained voice-call
registration. Generation fencing from #120289 treated that restart as a stale
actor: stop retired the generation forever, the next start silently bailed,
and every voicecall.* RPC answered UNAVAILABLE "runtime generation is
retired" while the webhook never rebound.

- Registrations now hold a replaceable generation: service start after stop
  mints a fresh generation, takes over a running slot owned by a retired
  predecessor, and reports start failures to service health instead of
  silently returning.
- The voicecall CLI classifies gateway failures with typed guards instead of
  message substrings: standalone/store fallback only when the gateway is
  genuinely absent; reachable-but-failed (request errors, auth, timeout)
  exits with actionable text; a standalone webhook port collision explains
  that a running Gateway probably owns the port instead of raw EADDRINUSE.
- Plugin SDK gateway-runtime exports structural isGatewayTransportError /
  isGatewayClientRequestError guards (+2 documented surface budget).
- Regression coverage: same-registration stop/start restart, retired-owner
  takeover, typed CLI fallback classification, and a real token-auth gateway
  server routing voicecall.status through callGatewayFromCli.

* refactor(voice-call): split CLI modules and dedupe gateway fallbacks

Collapse the four duplicated gateway-or-runtime command blocks (speak, dtmf,
end, continue fallback) into one generic runGatewayManagerCommand helper —
the continue command owns its legacy-method fallback and operation polling
via a gatewayCall closure, so the helper carries no per-command policy.
Smoke reuses the shared initiateVoiceCall path instead of a bespoke
fallback.

Split the 988-line cli.ts into concept modules (cli-gateway-call,
cli-call-log, cli-command-io) and drop its grandfathered max-lines
suppression plus the now-stale max-lines and assertion-safety baseline
entries (shrink-only ratchet maintenance).

Behavior-frozen: stdout/exit semantics unchanged; net -2 production LOC.

* fix(voice-call): redact gateway URLs in CLI operational errors

ClawSweeper P1: the operational-error formatter interpolated the raw
connectionDetails.url, so a configured gateway URL with userinfo or query
tokens would print credentials into terminal output. Redact the composed
message once with the canonical net-policy redactor (also covers
remote-controlled close-reason text), exported through the plugin SDK
gateway-runtime subpath (+1 documented surface budget). Regression test
covers a credential-bearing URL in both the URL and message fields.
2026-08-17 18:59:19 -07:00
Peter Steinberger b82d07f466 feat(doctor): report unusable cloud worker profiles (#124995) 2026-08-17 18:58:52 -07:00
Peter Steinberger 26353983f3 fix(memory): record the omitted memory corpus in corpus=all searches (#125500)
memory_search corpus=all silently swallowed a returned memory-manager
error (missing sqlite, embedding misconfiguration, corrupted index):
the error branch was gated on !shouldQuerySupplements, so the tool
served wiki-only results in a payload with no error/warning field and
recorded no cooldown — a degraded search read as complete, contradicting
the tool description's own disabled-flag contract. The thrown-error path
already surfaced this; only the returned-error path was silent.

Record the cooldown in both cases and, when supplements still serve,
carry a warning naming the unavailable memory corpus in the payload.
2026-08-17 18:50:49 -07:00
Peter Steinberger b5b17c654b fix: keep Workboard visible in the sidebar (#125473)
* fix(ui): keep workboard in sidebar navigation

* test(ui): align workboard navigation ownership

* fix(ui): preserve saved workboard sidebar slots

* test(ui): shrink assertion safety baseline

* fix(plugins): bind native routes to bundled owners

* refactor(plugins): isolate native route policy
2026-08-17 18:44:39 -07:00
pash-openai 31a240c2b7 fix(slack): remove interrupted previews when turns finish silently (#125494) 2026-08-18 01:36:21 +00:00
Peter Steinberger 1ca4103fe9 fix(voice-call): expose realtime/streaming stream paths through tailscale serve/funnel (#125468)
* fix(voice-call): expose realtime/streaming stream paths through tailscale serve/funnel

Tailscale serve/funnel now auto-exposes the realtime and streaming WebSocket stream paths when those audio modes are enabled; previously Twilio <Connect><Stream> could not reach wss://<ts-host><streamPath> and realtime calls dropped after ~1s with no log.

Also: CLI voicecall expose mounts/clears stream paths symmetrically, partial tailscale mounts roll back on failure, and a warning now fires when a call's stream WebSocket never arrives within the token TTL. Reported/observed live by Peter Steinberger.

* fix(voice-call): make tailscale stream exposure atomic

Preserve configured public Tailscale prefixes when mapping realtime and streaming routes, and roll back the full route set when any mount fails. The CLI now uses the same transactional setup path and reports failure instead of accepting a partial exposure.

* fix(voice-call): expose Twilio's configured streaming path

Keep realtime routes under the public webhook prefix they advertise, while mounting streaming.streamPath exactly as Twilio emits it. This preserves the canonical public-to-local route list without expanding the provider API outside the scoped repair.
2026-08-17 18:10:45 -07:00
Josh Avant aea7ee7088 fix(matrix): keep user ID authorization case-sensitive (#125432)
* fix(matrix): preserve case-sensitive user IDs

* docs(matrix): clarify exact user ID casing

* fix(matrix): preserve exact IDs during resolution

* docs(matrix): clarify approval target casing
2026-08-17 18:08:25 -07:00
Peter Steinberger d32c09f843 fix(ai): accept retained messages from Responses compact (#124974)
* fix(ai): accept retained output from Responses compact

Amp-Thread-ID: https://ampcode.com/threads/T-01a00b7c-b9f0-73d5-8fb7-e619e8e458e1

* fix(ai): replay retained compact messages

* fix(ai): scope retained compaction to OpenAI

* refactor(ai): reuse response endpoint contract

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 18:05:52 -07:00
Peter Steinberger 857c8c0864 fix(workboard): avoid false lifecycle warning during gateway startup (#125470)
* fix(workboard): defer lifecycle sweep until gateway ready

* test(workboard): cover lifecycle sweep after plugin reload
2026-08-17 17:56:04 -07:00
Peter Steinberger 720da745d9 fix(voice-call): keep realtime calls alive through brief stream reconnects (#125469)
* fix(voice-call): grace realtime stream disconnects

Share reconnect grace by CallSid and stream ID across classic and realtime streams while cleaning realtime bridge resources immediately.

Log terminal call reasons and document Twilio inbound voice and status callback setup.

* test(voice-call): align reconnect grace after rebase

Preserve the newly landed realtime generation and inactivity coverage while updating its terminal expectations for shared delayed finalization.

Remove the redundant replacement cross-product case so the lifecycle suite remains below the max-lines limit.
2026-08-17 17:51:46 -07:00
Marvinthebored 3d016975c3 fix(codex): degraded-engine continuity no longer projects the whole context window per turn (#125324)
* fix(codex): bound no-engine continuity projections to half the context window

A degraded or absent context engine sends fresh-thread continuity through
projectContextEngineAssemblyForCodex with the whole-window projection cap
((window - 20k) x 4 chars), so a large uncompacted transcript renders into
a single turn/start input consuming up to 90% of the model context window.
That turn fills its own native thread, the next turn's token fuse rotates
it, and the following fresh thread re-projects the transcript again -
observed as 11 near-window turn inputs on cold threads in one day
(openclaw/openclaw#125254).

Continuity projections now use a dedicated cap that reserves half the
context token budget, so the fresh thread keeps headroom for later turns
and the existing delta-resume path can actually engage. The active-engine
projection path keeps its whole-window cap unchanged.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): size continuity projections from real token cost, not the optimistic estimate

The continuity cap reserved half the context window in tokens but converted
that budget to characters with APPROX_RENDERED_CHARS_PER_TOKEN = 4, so at a
258,400-token window it permitted 516,800 chars. A live projection measured
703,134 chars for 226,146 input tokens, meaning that cap really costs about
166k tokens (~64% of the window), not the intended 129.2k.

Codex reports input tokens only after a turn and bounds turn input by
characters, so the projection cannot be sized in verified tokens before it is
sent. Convert the continuity budget at a conservative 3 chars/token instead,
which holds the reserved half in real tokens at the densest ratio observed.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): scope the continuity sizing claim to the density it was measured at

The half-window claim was stated as a guarantee, but the 3 chars/token
conversion rests on one observed projection. Input that tokenizes more densely
(CJK, base64, minified code) still exceeds the reserved half, so the constant is
renamed to CONTINUITY_EMPIRICAL_CHARS_PER_TOKEN and its comment says plainly
that it is an empirical floor rather than a bound.

The invariant test is narrowed to the measured density, and a companion test
pins the break-even ratio at 3 chars/token so the limitation is visible in the
suite instead of implied. Choosing between a guaranteed worst-case bound and
this empirical cap is a maintainer-owned tradeoff, left open on the PR.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* feat(codex): size continuity projections from the session's observed token density

Each completed Codex turn now records a calibration sample on the thread
binding: prompt chars actually sent vs the provider-reported input token cost
(uncached + cache read + cache write). The no-engine continuity cap converts
its half-window token budget at that observed ratio instead of a fixed
chars-per-token guess, so capChars / ratio stays at the reserved budget for
any content density - CJK, base64, and minified code included. The sample is
captured before startup rotation so a rotated-away thread's density still
sizes the fresh thread's projection; without a sample the empirical 3
chars/token default applies, and degenerate samples clamp to [0.5, 4].

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): make continuity calibration monotone - samples only tighten the cap

Red-team finding: a loose sample (up to 4 chars/token) followed by denser
content could size the cap past the empirical default, and stale or
non-continuity samples persist on the binding. Clamping the calibrated ratio
at the empirical default makes every such failure mode degrade to the
uncalibrated behavior instead of past it, and the invariant test asserts
monotonicity across poisoned samples directly.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

* fix(codex): record continuity calibration only from continuity projections

ClawSweeper P2: calibration ran after every successful turn filtered only by
prompt size, so a dense direct or active-engine prompt could persist a sample
whose density later shrinks continuity history it never measured. The
no-engine continuity appliers now mark the prompt state, finalize gates the
sample on that marker, and a cross-mode regression proves a large direct
prompt records nothing.

Related: #125254

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKtoZgXWnaAH8rmLiSydpN

---------

Co-authored-by: Marvinthebored <262704729+Marvinthebored@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 17:41:45 -07:00