Commit Graph

11281 Commits

Author SHA1 Message Date
Alix-007
240487179b fix(web-fetch): keep spill content truncation UTF-16 safe (#101312)
* Fix UTF-16-safe web fetch spill truncation

* fix(web-fetch): report actual spill character count
2026-07-07 10:56:14 +01:00
Pavan Kumar Gondhi
9133d552ac fix: block mixed-case cron shell jobs from agent tool [AI] (#101350)
* fix: normalize cron tool shell guard kinds

* fix(cron): narrow mixed-case shell guard

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 10:52:20 +01:00
Alix-007
b84ae42063 fix(agents): keep prompt data truncation UTF-16 safe (#101303) 2026-07-07 10:46:23 +01:00
Peter Steinberger
a2a68d154b fix(agent): preserve explicit recipient sessions (#101507)
* fix(agent): honor recipient session routing

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: pingfanfan <pingfan.work@gmail.com>

* fix(agent): preserve canonical recipient routes

* fix(agent): require exact recipient routes

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

Co-authored-by: pingfanfan <pingfan.work@gmail.com>

* fix(agent): harden recipient route resolution

* fix(imessage): require canonical recipient handles

* fix(agent): refine provider recipient exactness

* fix(agent): bound direct alias session routing

* fix(signal): preserve direct alias route type

* fix(agent): honor binding-scoped recipient sessions

* fix(routing): honor configured main session aliases

* fix(clickclack): align account-owned session routes

* fix(twitch): preserve canonical recipient sessions

* fix(routing): isolate stable outbound identities

* chore: defer recipient session changelog

* fix(sms): use dedicated channel SDK facade

---------

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: pingfanfan <pingfan.work@gmail.com>
2026-07-07 10:07:13 +01:00
Petros Dhespollari
6894bb7508 fix(gateway): persist media metadata in agent.request transcripts (#86936)
* fix(gateway): persist agent request transcript media

Route inline and offloaded agent.request images through the canonical user-turn transcript recorder across embedded, CLI, and ACP runtimes. Share ordered media persistence with chat.send and cover media-only empty-reply turns.

Co-authored-by: Petros Dhespollari <info@peterdsp.dev>

* fix(gateway): avoid transcript media shadowing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 09:16:15 +01:00
pick-cat
e72dadbb3b fix(anthropic): resolve thinking as disabled when legacy budget is below 1024 (#101415)
* fix(anthropic): resolve thinking as disabled when legacy budget is below 1024

When adjustMaxTokensForThinking collapses the thinking budget below the
Anthropic minimum (1024), option resolution now sets thinkingEnabled to
false instead of always forcing it to true. This keeps every downstream
consumer (payload, replay, temperature, tool-choice) consistent — they
all see the same disabled state instead of an enabled flag with a
missing or API-rejected thinking block.

|| → ?? in both builders is defensive: the resolution layer already
prevents invalid budgets from reaching the builder through the normal
path, but ?? preserves an explicit zero when the builder is called
directly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(anthropic): guard raw streamAnthropic builder path against sub-minimum budgets

Add budget guards in both Anthropic payload builders so direct
streamAnthropic and bundled-plugin callers (e.g. Mantle) that bypass
option resolution also get the disabled-state rule instead of producing
API-rejected { type: "enabled", budget_tokens: < 1024 } requests.

Add proof-anthropic-thinking-budget.mts driving real production
functions with terminal output and negative control.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(anthropic): normalize legacy thinking budgets

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 08:42:40 +01:00
Peter Steinberger
59bc7b0e16 perf(test): scope opencode context catalog warmup 2026-07-07 03:13:59 -04:00
Jason (Json)
c87225fb4a fix: keep owner tools available in WebChat (#101271)
* fix: keep owner tools available in WebChat

* fix: align WebChat owner policy checks
2026-07-07 01:00:24 -06:00
Truffle
5537bc9c4d fix(media): allow Bedrock SDK auth for image and PDF tools (#72092)
* fix(media): allow aws-sdk auth mode for image and audio/video paths

Media understanding tools failed for amazon-bedrock deployments using
auth.mode "aws-sdk" (BYOK via role/SSO/profile creds). Each path called
requireApiKey, which throws on the empty-key sentinel before the AWS SDK
credential chain can resolve creds at call time.

The image path (image.ts) resolves auth via getApiKeyForModel; the
audio/video paths route through resolveProviderExecutionAuth. Both now
mirror the chat path's allowMissingApiKeyModes allowance: when the
resolved key is empty and the mode is aws-sdk, execute keyless and let
the SDK resolve credentials. The image path skips setRuntimeApiKey so no
empty-string secret is persisted; audio/video return the kind:"none"
execution auth so the runner bypasses key rotation.

Closes #72031

* fix(media): cover Bedrock PDF SDK auth

* fix(pdf): register plugin completion streams

* fix(media): recognize Bedrock SDK tool auth

* chore: move release note to PR

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 07:37:32 +01:00
Alix-007
3929c52069 fix(agents): keep structured prompt summaries UTF-16 safe (#101311)
* fix(agents): keep structured prompt summaries UTF-16 safe

* chore: align prompt summary branch with current main

* fix(agents): keep structured summaries UTF-16 safe

* chore: keep release notes in PR context

* chore: keep release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-07 07:32:05 +01:00
mushuiyu886
92e25df271 fix(agents): avoid repeated item progress snapshots (#101042)
* fix(agents): avoid repeated item progress snapshots

* chore: align ACP branch with current main

* fix(agents): deduplicate ACP parent progress

* chore: keep release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-07 07:31:13 +01:00
snowzlmbot
53580e13a4 fix(usage): preserve provider-billed zero totals (#101177)
* fix(usage): preserve provider-billed zero totals

* fix(usage): harden provider-billed cost provenance

* fix(openrouter): retry delayed generation metadata

* fix(openrouter): satisfy retry lint

* refactor(openrouter): consume streamed billed cost

* chore: keep release notes out of contributor PR

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:22:28 +01:00
Josh Lehman
5d9a2b114f feat(context-engine): report compaction successors as typed session targets (#101182) 2026-07-06 22:14:46 -07:00
Vincent Koc
84e5327720 fix(text): keep bounded outputs UTF-16 safe (#101355)
Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-06 21:33:24 -07:00
Marcus Castro
31432bf101 fix(reply): preserve steered audio for inbound TTS (#95596)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:18:36 +01:00
Peter Steinberger
7a5e5e1852 fix(codex): register the ring-zero crestodian tool directly instead of relying on a dead per-run plugin config override (#101281) 2026-07-07 05:08:08 +01:00
Ayaan Zaidi
c718afe247 refactor(agents): thread runtime-context carrier indexes 2026-07-06 20:34:01 -07:00
Peter Lindsey
f5931f5516 fix(agents): carry current-turn inbound metadata in a tail runtime-context message for byte-stable prompt caching
The active user turn was decorated at request-build time with an inbound
metadata block (Conversation info / reply-target / sender / forwarded /
chat-history), but the session store persists the bare text and the LLM boundary
strips that block from historical replay. So a user message's serialized bytes
changed retroactively — decorated as the active turn, bare as history — on every
turn, invalidating any prefix/exact-match provider prompt cache from that point
onward, every turn. (#90811 fixed the timestamp half of this same asymmetry.)

Rework of the earlier "strip the active turn" approach (which lost model-visible
context — ClawSweeper's P1) into one that keeps the context AND recovers the
cache cost:

- Route current-turn inbound metadata out of the user prompt and into the hidden
  runtime-context custom message (the mechanism from openclaw#89428), and
  relocate that carrier to the ABSOLUTE TAIL of the wire request (after the
  active user turn and any tool-call scaffolding). The user turn stays bare and
  byte-identical in both the active and historical positions; the volatile
  carrier vanishes next turn exactly where the assistant reply begins anyway, so
  the request is an append-only prefix-extension through the active user turn.
- A durable marker (UserMessage.runtimeContextCarrier, set by convertToLlm from
  the carrier's details) lets the Anthropic SDK transport, the managed Anthropic
  transport (anthropic-transport-stream / anthropic-payload-policy), and
  OpenAI-completions skip the carrier when selecting the deepest cache_control
  breakpoint, keeping the anchor on the last stable user turn.

Storage stays BARE (invariant preserved); runtime-only turns (room events) keep
their existing inline behavior, which is byte-stable because room-event/system
context is not strip-eligible; legacy bare-stored sessions are unchanged.

Reviewed with adversarial gpt-5.5/codex sweeps (correctness, byte-identity,
compatibility, test adequacy): found + fixed the managed Anthropic transport
cache-anchor path and added the missing OpenAI-completions/managed-transport
breakpoint tests; a theoretical runtime-only mutation was verified unreachable
and pinned with a test. Final sweep clean.

Co-authored-by: openclaw#89428 (runtime-context handoff approach)
2026-07-06 20:34:01 -07:00
Ayaan Zaidi
f7df9536b0 docs(agents): note codex session-id header naming divergence 2026-07-06 20:33:51 -07:00
Peter Lindsey
06061c4fe3 fix(agents): treat caller session_id headers as case-insensitive
buildOpenAIClientHeaders only skipped generating a session_id header
when the exact lowercase key was already present, so a caller-supplied
Session_ID or SESSION_ID header would end up on the wire alongside our
generated one instead of winning per the caller-wins header contract.
Check all resolved header keys case-insensitively before injecting.
2026-07-06 20:33:51 -07:00
Peter Lindsey
3d87932541 fix(agents): send session_id affinity header to ChatGPT Responses backend
The ChatGPT backend routes requests by session_id (codex-cli sends it); without it each request lands on an arbitrary machine and the prompt cache misses. Measured on live traffic: 56.0% -> 81.8% TRUE cache hit rate (12-turn A/B, identical prompts).
2026-07-06 20:33:51 -07:00
Alex Knight
87a17920a0 fix(diagnostics-otel): surface error message on run/harness error spans (#101244)
* fix(diagnostics-otel): surface error message on run/harness error spans

Errored openclaw.run / openclaw.harness.run spans only carried a
low-cardinality errorCategory (or a hardcoded "error"), so trace UIs
showed "outcome error" with no message. Thread the redacted error
message through run.completed / harness.run.completed / harness.run.error
onto an openclaw.error span attribute + span status, mirroring
recordWebhookError. The raw message stays off metric attrs to preserve
cardinality; support-bundle redaction covers the new error field by name.

* fix(diagnostics-otel): harden run failure telemetry

Co-authored-by: Alex Knight <aknight@atlassian.com>

* test(diagnostics-otel): assert wire-level redaction

* chore(changelog): defer release note to release process

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:29:39 +01:00
Peter Steinberger
118e5bd762 fix(agents): harden tool search child streams (#101295)
Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>
2026-07-07 04:25:16 +01:00
cxbAsDev
d90c9a1ede fix(agents): handle stdout/stderr stream errors in ssh sandbox commands (#101031)
* fix(agents): handle stdout/stderr stream errors in ssh sandbox commands

* fix(agents): also handle stdin stream errors in ssh sandbox command

* fix(agents): handle tar/ssh pipeline stream errors in sandbox upload

* fix(agents): kill ssh child on stdout/stderr/stdin stream errors in sandbox

* fix(agents): move upload fail helper before use to avoid TDZ in ssh sandbox

* docs(proof): note ssh-sandbox upload TDZ fix in proof header

* fix(agents): harden SSH sandbox stream errors

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 04:20:23 +01:00
Ayaan Zaidi
b2baf799b4 fix(agents): bound finalize hook hangs after compaction retry
Behavior: a plugin before_agent_finalize hook that never resolves could previously freeze an agent run forever after a successful compaction retry, with no errors and no recovery from a gateway restart; this was the frozen-runner mechanism behind #84777. before_agent_finalize now has the same 15s default budget as sibling modifying hooks and fails open with the original final answer, converting the freeze into a bounded delay.

Surface: plugin hook runner defaults (src/plugins/hooks.ts), docs/plugins/hooks.md.

Refs #84777.
2026-07-07 03:16:57 +00:00
Peter Steinberger
6273e82ca5 fix(lint): drop unused TRANSCRIPT_NOT_CONTINUABLE_ERROR_CODE import in model-fallback test 2026-07-06 19:29:35 -07:00
Peter Steinberger
1a307be2e0 feat(skills): add lifecycle curator for workshop-created skills (#101214)
Tracks per-skill usage from the skill.used diagnostic event (trusted-only
delivery, file-scoped identity), sweeps workshop-created skills daily from
gateway maintenance (active -> stale 30d -> archived 90d, pinned bypass,
restore-only unarchive, files never touched), filters archived skills from
snapshots fail-open, reports workspace-scoped overlap candidates, and adds
openclaw skills curator CLI, additive gateway methods, and a warn-only
doctor finding. Zero new config keys; SQLite/Kysely state only.
2026-07-07 03:25:44 +01:00
Vincent Koc
143751282c fix(agents): honor long lane timeouts 2026-07-07 04:17:46 +02:00
Sanjay Santhanam
00a8dae28b fix(agent-model): omit synthesized maxTokens fallback when nothing was configured (#98312)
* fix(agent-model): omit synthesized maxTokens fallback (Fixes #98295)

The configured-fallback resolver used DEFAULT_CONTEXT_TOKENS (200_000) as
the last-resort value for model.maxTokens when no configured, provider,
or bundled-catalog value was known. For strict OpenAI-compatible providers,
model.maxTokens is forwarded as max_completion_tokens on every request,
so the synthesized 200k value became a wire-level output cap that exceeded
the provider ceiling and produced HTTP 400 (Param Incorrect) on providers
like Xiaomi MiMo (131_072 max) — reported for mimo-v2.5 / mimo-v2.5-pro
added via 'models add' on a custom provider entry.

The sibling applyConfiguredProviderOverrides path already omits maxTokens
when nothing resolves; align resolveConfiguredFallbackModel with that
behavior. When the transport sees an undefined model.maxTokens, it omits
max_completion_tokens entirely and the provider applies its own default,
which is the correct behavior when the user has configured no output limit.

contextWindow retains DEFAULT_CONTEXT_TOKENS as its local budgeting
fallback (it is not shipped on the wire).

* test(agents): prove unknown output cap omission

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 03:15:03 +01:00
Ayaan Zaidi
486033b183 fix(agents): normalize compaction recovery tails
Compaction failure and timeout recovery can no longer leave a session transcript assistant-last and wedged after restoring pre-compaction state.

Transcript-continuation failures now carry a typed agent-core error code and no longer demote the active model through model fallback scoring.

Surface: embedded agent runner compaction recovery, model fallback classification, packages/agent-core.

Refs #100312. Includes regression coverage for #99943.
2026-07-07 02:09:21 +00:00
Ayaan Zaidi
ec289357a4 fix(agents): keep embedded lane watchdog bounded
Wedged model calls could hold an agent session lane for the normalized max timer duration when the user disabled the run timeout. In production that path resolves to MAX_TIMER_TIMEOUT_MS, so a zero-progress model call could block sibling work for about 24.8 days instead of failing through the normal terminal outcome path.

Cap the lane watchdog at the default agent deadline plus the existing grace window while preserving explicit shorter run timeouts. The disabled/max-timeout case now releases the lane at the default 48h deadline instead of inheriting the timer sentinel.

Refs #97588.

Refs #94650.
2026-07-07 02:07:45 +00:00
qingminlong
d6f097b3de fix(agents): normalize surrogate cache fingerprints (#101009)
* fix(agents): normalize surrogate cache fingerprints

* fix(agents): reuse provider surrogate sanitizer

* chore(agents): keep transport imports grouped

* fix(agents): avoid runtime import for surrogate sanitizer

* fix(agents): scope surrogate cache normalization

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 03:06:56 +01:00
Peter Steinberger
0d981095d4 refactor(codex): store app-server thread bindings in SQLite plugin state (#101210)
* test(codex): shorten placeholder auth fixture strings

* feat(plugin-state): add reject-new overflow policy for keyed namespaces

* feat(agents): thread agent identity and session generation through reset and hooks

* refactor(codex): add SQLite-backed app-server thread binding store

* refactor(codex): move app-server runtime callers onto the binding store

* refactor(codex): move conversation, entry, and thread-tool flows onto the binding store

* refactor(codex): move command handlers onto the binding store

* feat(codex): import legacy binding sidecars via doctor state migration

* fix(codex): keep doctor sidecar scan inside stateDir

* fix(codex): make binding migration landable

* chore(changelog): defer release note

* test(plugin-state): stabilize durable-capacity ordering
2026-07-07 03:03:44 +01:00
Josh Lehman
cb0d8a1294 refactor(sessions): move inbound meta, goals, and delivery reads behind the session accessor (#101180) 2026-07-06 18:07:26 -07:00
Vincent Koc
775ef966c3 refactor(deadcode): localize internal type aliases (#101243) 2026-07-06 17:57:32 -07:00
Vincent Koc
f305e707a3 feat(models): add Claude Mythos 5 support (#101238) 2026-07-06 17:19:49 -07:00
zengLingbiao
db25e9ec52 fix(web-shared): bound response.text() fallback to honor maxBytes (#99884)
* fix(web-shared): bound response.text() fallback to honor maxBytes

readResponseText's .text() fallback path ignored the maxBytes option,
reading the full body unbounded. When a foreign Response lacks a body
stream (no getReader) and no arrayBuffer(), the .text() call was the
last resort — but maxBytes was never applied.

- Honor maxBytes in the .text() fallback: truncate + set truncated=true
- Under-cap responses pass through unchanged
- No maxBytes set → original behavior preserved (regression safe)

* fix(web-shared): use byte-level truncation in .text() fallback

Replace text.length/text.slice (character-level) with TextEncoder/
TextDecoder (byte-level) so the maxBytes cap is respected at byte
granularity, consistent with the bounded-stream path at lines 240-298.

- bytes.byteLength > maxBytes instead of text.length > maxBytes
- TextDecoder().decode(bytes.slice(0, maxBytes)) for byte-safe truncation
- bytesRead reports actual bytes, not character count

* fix(web-shared): refuse unbounded .text() when maxBytes is set

When maxBytes is set the caller expects bounded memory. The .text()
fallback path buffers the full body before any post-read check,
defeating the cap. Fail-closed by returning empty with truncated=true
instead of calling .text() unbounded.

Without maxBytes .text() is safe — the caller accepts full allocation.

* fix(web-shared): byte-level truncation in .text() fallback with maxBytes

The .text() fallback used text.length (characters) and text.slice
(char-level) against a byte-level maxBytes cap. Use TextEncoder/
TextDecoder for byte-accurate comparison and truncation.

- bytes.byteLength > maxBytes instead of text.length > maxBytes
- TextDecoder().decode(bytes.slice(0, maxBytes)) for byte-safe truncation
- bytesRead reports actual byte count, not character count

* fix(web): fail closed on unbounded response fallbacks

* test(web): use streaming response fixtures

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 00:24:36 +01:00
Vortex Openclaw
1f6ddb5df0 feat(models): add Claude Sonnet 5 support (#98254)
* feat(models): add Claude Sonnet 5 support

Co-authored-by: Ariel Bravy <ariel@vortexradar.com>

* fix(models): align Sonnet 5 validation baselines

* fix(models): satisfy Sonnet 5 CI contracts

* fix(models): enforce Sonnet 5 provider contracts

* docs(changelog): defer Sonnet 5 release note

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Ariel Bravy <ariel@vortexradar.com>
2026-07-07 00:05:35 +01:00
Josh Lehman
d5e9b4d1a3 fix: preserve preflight overflow token counts into recovery budgeting (#101181)
Budget context engine assembly against the reserve and rendered prompt
pressure, and carry the preflight estimated prompt tokens, prompt budget,
and overflow tokens into the outer overflow recovery loop so compaction
engines compact against the prompt OpenClaw actually rendered instead of
a minimally over-budget guess.
2026-07-06 15:58:11 -07:00
velanir-ai-manager
8d46971129 fix: sanitize streamed assistant payload text (#101036)
* fix: sanitize streamed assistant payload text

* test(agents): cover streamed reply sanitization

---------

Co-authored-by: Yash Inani <yashinani@Yashs-MacBook-Pro.local>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 23:38:04 +01:00
ZOOWH
4204a94845 fix(edit): show candidate lines with similarity scores on oldText match failure (#97038)
* fix(edit): show candidate lines on oldText match failure

When edit tool cannot find oldText, include up to 3 near-match candidate
lines with similarity scores and line numbers. Caps input size (MAX_LINES
3000, MAX_LINE_LEN 200) to avoid unbounded CPU on large files. Reuses
existing levenshteinDistance helper.

Closes #97032

* fix(edit): use toSorted instead of sort for candidate ranking

Fixes lint violation: unicorn(no-array-sort)

* fix(edit): keep candidate truncation branch-compatible

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 15:21:56 -07:00
cxbAsDev
0e0888a887 fix(agents): handle ripgrep stdout/stderr stream errors in grep tool (#101014)
* fix(agents): handle ripgrep stdout/stderr stream errors in grep tool

* fix(agents): terminate ripgrep child on stdout/stderr stream errors

* test(agents): make mock child reflect kill state in grep stream-error test

* refactor(agents): harden grep stream cleanup

* refactor(agents): centralize grep stream failure cleanup

* test(agents): model grep child kill state safely

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 23:12:23 +01:00
cxbAsDev
3f9ee4c5a1 fix(agents): handle stdin stream errors in docker sandbox execution (#101032)
* fix(agents): handle stdin stream errors in docker sandbox execution

* fix(agents): terminate Docker child on stdin stream error

* fix(agents): add real proof for docker stdin stream errors

* refactor(agents): fold Docker stdin failure coverage into existing tests

* test(agents): model Docker stdin as an event stream

* test(agents): narrow Docker stream mocks before emit

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 23:12:04 +01:00
Peter Steinberger
38746af071 feat(gateway): let write-scope operators manage chat session organization (#100964)
sessions.patch becomes a params-aware dynamic-scope method: operator.write
now authorizes patches that touch only user-level chat-organization fields
(label, category, pinned, archived, unread); every other field, mixed
patches, and unknown keys keep requiring operator.admin (fail closed).
This unblocks the session controls shipped in #100814 for the Android app,
whose bounded operator session intentionally never requests operator.admin.

Also: session list ordering gains a deterministic key tiebreaker for equal
pinnedAt/updatedAt (stable offset paging and prompt-cache friendliness), a
user-assigned label now beats stored channel-derived display names in the
row projection so renames survive refreshes, and subagent spawn pins its
gateway calls to admin via the params-aware least-privilege resolver
instead of the static admin-only method check (#59428 contract preserved).

Refs #100712
2026-07-06 21:08:26 +01:00
Peter Steinberger
3accc99b43 fix(agents): handle find subprocess stream failures (#101158)
Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>
2026-07-06 20:56:36 +01:00
NIO
9ef7fff570 fix(agents): bound tool_search_code stderr accumulation (#101007)
* fix(agents): bound tool_search_code stderr accumulation

* fix(agents): report latest bounded stderr

---------

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-06 11:38:25 -07:00
SunnyShu
5f2f06b21b fix(agents): preserve overload wording for rate-limited responses (#98165)
* [AI] fix(agents): classify HTTP 429 overloaded bodies as overloaded, not rate_limit

Reorder overloaded check before rate_limit across all three classification paths:
- classifyFailoverClassificationFromHttpStatus (HTTP status path)
- classifyFailoverClassificationFromMessage (message text path)
- formatRateLimitOrOverloadedErrorCopy (user-facing copy path)

Previously, isRateLimitErrorMessage matched the bare '429' token in
overloaded-worded 429 bodies (e.g. z.ai code 1305), misclassifying them
as rate_limit and showing the wrong user-facing error message. 503/499
already check overloaded before defaulting; 429 now follows the same pattern.

Related to #98101

* [AI] fix(agents): put MODEL_CAPACITY_ERROR_RE before overloaded in user-facing copy

MODEL_CAPACITY_ERROR_RE is the most specific overloaded variant
('selected model is at capacity') and must be checked before the
broader isOverloadedErrorMessage matcher (which also covers model at
capacity), otherwise it's shadowed with a less specific message.

Related to #98101

* fix(agents): preserve overload copy for rate-limited responses

* fix(agents): retain provider retry guidance

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 18:55:16 +01:00
machine3at
c432c8c014 fix(auth): preserve copied auth profile order (#100833)
* fix(auth): preserve auth profile order when copying store to spawned agent

* fix(auth): preserve copied profile order

Co-authored-by: Vivek Behani <vivekbehani@me.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 18:52:55 +01:00
Wynne668
3dd5339a53 fix(openai): stop double-prefixing SSE bodies mislabeled as JSON (#96503)
* fix(openai): stop double-prefixing SSE bodies mislabeled as JSON

OpenAI-compatible gateways that stream real SSE (data: {...}) but label the
response application/json hit the streaming JSON-wrap fallback, which re-prefixed
each frame as 'data: data: {...}' and broke JSON.parse in the OpenAI SDK. Sniff
JSON-labeled streaming bodies and relabel genuine SSE as text/event-stream so the
SSE sanitizer parses them verbatim.

* test(openai): prove mislabeled SSE stays streaming

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 18:49:45 +01:00
Peter Steinberger
553acdfc1a feat(gateway): add tts.speak method returning synthesized audio inline (#100770)
* feat(gateway): add tts.speak method returning synthesized audio inline

* test(gateway): type tts.speak synthesis mock for failure shapes

* fix(gateway): restore lowercase normalizer import used by talk catalog

* test(gateway): shift advertised-method window for tts.speak

* fix(gateway): ready tts speak for landing

* docs(changelog): record tts speak gateway API

* test(agents): stabilize fast auto startup synchronization

* test(crabbox): stabilize sparse checkout exit guard
2026-07-06 18:25:08 +01:00