Commit Graph

36310 Commits

Author SHA1 Message Date
Yuval Dinodia
150ca2fedd fix(agents): keep merged delivery routes account-bound (#98240)
* fix(agents): keep merged delivery routes account-bound

mergeDeliveryContext gated route-field crossing on channel only, so a
completion origin that knew its account but not a concrete target
inherited a different account's to/threadId on the same channel. A
subagent, cron, or media completion for bot-a could be addressed to
bot-b's chat but sent through bot-a (cross-account misroute) or dropped.

This restores the account-bound guard added in 1ed8592467 and removed as
collateral by 025db6cf9e (PR #89949); same-account and missing-account
merges still backfill so the media route-pin path is preserved. Restores
the deleted regression test.

* fix(agents): centralize account-bound completion routes

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 18:32:35 -07:00
Vincent Koc
35af831fd0 Merge branch 'main' of https://github.com/openclaw/openclaw
* 'main' of https://github.com/openclaw/openclaw: (29 commits)
  refactor(gateway): trim attach grant implementation
  feat(gateway): scoped attach grants for external MCP loopback clients
  fix(gateway): iOS Talk treats SecretRef-backed API keys as missing (#98210)
  test(infra): add unit tests for SQLite number normalization (#98009)
  test(config): add unit tests for resolveExecCommandHighlighting (#98087)
  test(utils): add unit tests for chunkItems (#98219)
  fix(core): propagate caller env PATHEXT through isExecutableFile on Windows (#98093)
  fix(matrix): guard JSON.parse against malformed homeserver response bodies (#97973)
  fix(sms): guard Twilio JSON.parse against malformed API response bodies (#97999)
  Add Swedish mobile app localization (#98043)
  fix(anthropic): surface Discord pre-tool commentary
  fix(tui): correct disconnect copy for device scope upgrades (#98144)
  chore(ui): refresh fa control ui locale
  chore(ui): refresh nl control ui locale
  chore(ui): refresh vi control ui locale
  chore(ui): refresh th control ui locale
  chore(ui): refresh pl control ui locale
  chore(ui): refresh uk control ui locale
  chore(ui): refresh id control ui locale
  chore(ui): refresh tr control ui locale
  ...
2026-06-30 18:27:32 -07:00
Ayaan Zaidi
1241885db6 refactor(gateway): trim attach grant implementation 2026-06-30 18:22:05 -07:00
Cameron Beeley
2deb696ef4 feat(gateway): scoped attach grants for external MCP loopback clients
Per-session, TTL-bounded, revocable bearer grants (mcp-grant-store) let an external/interactive
harness reach the gateway's scoped MCP loopback tools without the cli-backend's process-global
token. A grant is a lower-trust boundary: it binds the session server-side AND fail-closes on every
caller-supplied context header (x-session-key plus message-channel/account/current-channel/thread/
source-reply/event-kind), so a grant holder can neither scope-shop the session nor spoof
delivery/action context into scoped tools or the message tool. New attach.grant/attach.revoke
operator methods mint/revoke grants and return the loopback MCP config. Owner/non-owner cli-backend
path unchanged.
2026-06-30 18:22:05 -07:00
ooiuuii
201eb9cd29 fix(gateway): iOS Talk treats SecretRef-backed API keys as missing (#98210)
* fix(gateway): resolve Talk SecretRefs for scoped native clients

* fix(gateway): constrain Talk secret materialization

* fix(gateway): redact Talk source provider secrets

* fix(gateway): satisfy Talk config lint

* docs(gateway): clarify Talk secret config payload

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-06-30 20:17:33 -05:00
dwc1997
3669280b9a test(infra): add unit tests for SQLite number normalization (#98009)
* test(infra): add unit tests for SQLite number normalization

* fix: remove undefined param test, not in function signature
2026-06-30 18:15:38 -07:00
solodmd
4a200e6ecf test(config): add unit tests for resolveExecCommandHighlighting (#98087) 2026-06-30 18:15:31 -07:00
zengLingbiao
09ebc1d566 test(utils): add unit tests for chunkItems (#98219)
Add 8 test cases covering fixed-size array splitting, empty input,
size <= 0, size=1, size > length, exact division, readonly input
preservation, and fractional size behavior.
2026-06-30 18:15:24 -07:00
wendy
8028269d32 fix(core): propagate caller env PATHEXT through isExecutableFile on Windows (#98093)
* fix(core): propagate caller env PATHEXT through isExecutableFile on Windows

isExecutableFile hardcoded undefined when calling resolveWindowsExecutableExtSet,
ignoring any caller-provided custom env.PATHEXT. This meant resolveExecutablePath
and resolveExecutableFromPathEnv would fall back to process.env.PATHEXT even when
the caller supplied a different env with an extended PATHEXT (e.g. .PS1).

- Add optional options.env parameter to isExecutableFile
- resolveWindowsExecutableExtSet now reads from options?.env
- All 3 callers pass their available env through

Affects Windows deployments using sandbox/container environments where
PATHEXT differs from process.env (Docker Windows containers, CI runners, tests).
Fully backward compatible: undefined env falls back to process.env.PATHEXT.

* fix(core): also propagate caller env PATHEXT in node-host invoke resolver

- Fix sibling system.which resolver in src/node-host/invoke.ts:378
  to use caller env PATHEXT instead of process.env only
- Add comprehensive Windows-mocked tests for caller env PATHEXT
  propagation through isExecutableFile, resolveExecutableFromPathEnv,
  and resolveExecutablePath
- Tests cover: custom env accepted, fallback to process.env,
  path-separator and PATH-based resolution paths

* fix(core): also propagate caller env PATHEXT through node-host invoke resolver

- Add env?.PathExt and process.env.PathExt casing to both
  resolveWindowsExecutableExtSet and resolveWindowsExecutableExtensions
  for compatibility with callers using PascalCase env keys
- Isolate positive PATHEXT tests from process.env.PATHEXT by
  explicitly setting it to .TXT before each test, ensuring they
  prove caller env propagation rather than host env leak

* fix(core): add env?.PathExt casing to node-host system.which resolver

---------

Co-authored-by: wendy-chsy <wan.wenyan@xydigit.com>
2026-06-30 18:15:19 -07:00
Marvinthebored
b3b51b0c91 fix(anthropic): surface Discord pre-tool commentary
Route Anthropic pre-tool narration through the commentary progress lane, preserve shared channel progress defaults, and keep Discord/Telegram reasoning gates explicit.

Thanks @Marvinthebored!
2026-06-30 18:12:07 -07:00
Dallin Romney
3eaaa2ca3c fix(tui): correct disconnect copy for device scope upgrades (#98144)
* fix(tui): correct disconnect copy for device scope upgrades

On disconnect, the TUI told users "Pairing required. Run `openclaw devices
list`, approve your request ID, then reconnect." This is misleading: the
gateway is asking for a device *scope upgrade* (the device is already
paired), and "pairing" points users at `openclaw pairing`, which only
handles chat DM pairing — a different subsystem.

- Reword the hint to name the scope upgrade and the actual recovery command
  (`openclaw devices approve --latest`), including the `--token`/`--password`
  escape hatch for when the device can't approve its own upgrade.
- Also match the gateway's "scope upgrade" disconnect reason, not just
  "pairing required".

AI-assisted (Claude Code).

* fix(tui): clarify device approval preview hint
2026-06-30 18:10:04 -07:00
Vincent Koc
f524b38f20 chore(deadcode): remove stale CLI testing aliases 2026-06-30 18:06:15 -07:00
Vincent Koc
630dbbb1a1 chore(deadcode): remove stale outbound testing aliases 2026-06-30 18:06:15 -07:00
Vincent Koc
ebbe606e4b chore(deadcode): remove stale ACP testing aliases 2026-06-30 18:06:15 -07:00
sunlit-deng
70cc909eea fix(openrouter): send explicit auth headers (#98187)
* fix(openrouter): send explicit auth headers

* test(openrouter): type stream mock calls
2026-06-30 18:03:14 -07:00
headbouyJB
518937be4e fix(system-prompt): move exec-approval + Authorized Senders below cache boundary (#98267)
* fix(system-prompt): move exec-approval + Authorized Senders below cache boundary

buildExecApprovalPromptGuidance (channel-varying: CLI /approve vs native
approval UI) and buildUserIdentitySection / "## Authorized Senders"
(owner/identity-varying, dropped when minimal) were emitted into the static,
cacheable prefix *above* SYSTEM_PROMPT_CACHE_BOUNDARY. They fork the cacheable
prefix at ~token 1,460, invalidating client-side prefix caching for the rest of
the ~17.8K-token system prompt — causing minutes-long cold prefills on local
models (llama.cpp / MLX / Ollama) after any channel-varying cron/heartbeat turn.

Follow-on to #40256, which moved Messaging/Voice/Reactions below the boundary
but missed these two. Relocates both into the existing below-boundary
channel-guidance block. Pure cache-stability change with no behavioural change
(the guidance is position-independent for correctness). Extends the boundary
test to assert both sections sit below SYSTEM_PROMPT_CACHE_BOUNDARY.

Measured on a local deployment: shared cross-channel prefix grew ~1,460 ->
~15,486 tokens; post-cron interactive turns went from minutes to ~10s.

Fixes #98261

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H6Hz9UEpxQ4W3d8XecvupH

* fix(system-prompt): suppress relocated exec-approval line under tool_call_style override

Addresses review (clawsweeper): the exec-approval guidance lived inside the
`tool_call_style` fallback, so a provider override of that section previously
replaced it. Relocating it below the boundary emitted it unconditionally, which
changed behaviour for providers/plugins that override `tool_call_style`. Gate the
relocated line on the absence of a `tool_call_style` override, restoring the
original "override replaces the whole section" contract. Extends the
provider-override test to assert the default approval line is suppressed when
the section is overridden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H6Hz9UEpxQ4W3d8XecvupH

* fix(system-prompt): tighten cache boundary proof

* fix(system-prompt): tighten cache boundary proof

* fix(system-prompt): tighten cache boundary proof

---------

Co-authored-by: headbouyJB <23249268+headbouyJB@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-30 18:00:21 -07:00
Dallin Romney
f749de4f0a fix(device-pairing): don't churn requestId on subset re-requests (#98145)
* fix(device-pairing): don't churn requestId on subset re-requests

A reconnect that re-requested a subset of an already-pending device
pairing request still superseded it with a fresh requestId. This is the
root cause of the "unknown requestId" failures during device approval:

1. A TUI connect files a broad scope-upgrade request; the owner copies its
   id from `openclaw devices list`.
2. `openclaw devices approve <id>` reconnects as a CLI probe that only needs
   `operator.pairing` — a subset of the pending scopes.
3. That subset re-request superseded the pending request with a new id, so
   the originally-listed id no longer existed and approve failed.

Refresh the existing request in place when the incoming request only asks
for roles/scopes a single pending request (same device key + role) already
covers. Escalations that request *more* than the pending request still
supersede with a fresh id, so the requestId stays bound to at least the
scope snapshot the owner saw (the existing security-motivated behavior and
its test are preserved).

AI-assisted (Claude Code).

* fix(device-pairing): align subset pairing with scope coverage
2026-06-30 18:00:12 -07:00
welfo-beo
fc97e92ddd fix: surface node approval guidance from devices CLI (#98115)
* fix: surface node approval guidance from devices CLI

* fix: preserve node approval connection guidance

* fix: handle admin retry unknown device approvals

* fix: require stable node approval matches

---------

Co-authored-by: welfo-beo <187608477+welfo-beo@users.noreply.github.com>
Co-authored-by: welfo-beo <welfo-beo@users.noreply.github.com>
2026-06-30 17:55:30 -07:00
zengLingbiao
490a4c5d9b test(gateway): add unit tests for node wake state tracking and testing seam (#98205)
Add 17 unit tests for nodes-wake-state.ts covering:
- Exported wait/poll constants
- nodeWakeById Map operations (insert, overwrite, multi-entry, inFlight)
- nodeWakeNudgeById Map operations (independent tracking)
- clearNodeWakeState function (removal, no-op, scoped deletion)
- testing seam (getNodeWakeByIdSize, hasNodeWakeEntry, resetWakeState)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:53:56 -07:00
ly-wang19
6285f5c776 fix(utils): keep reply directive ids unicode-safe (#96938)
* fix(utils): keep reply directive ids unicode-safe

* test(utils): catch trailing lone surrogate in hasUnpairedSurrogate helper

Per PR #96938 review: the test helper missed a high surrogate at end of
string because charCodeAt(out-of-bounds) returns NaN, and NaN comparisons
are always false. Guard bounds explicitly so the truncation test actually
proves what it claims, plus two cases pinning helper behavior.

* chore(utils): rerun QA smoke to confirm memory-index timeout flake on #96938

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-06-30 17:47:39 -07:00
xingzhou
aadd57c31c fix(pdf): reject empty parsed page ranges (#97698) 2026-06-30 17:46:45 -07:00
qingminlong
e2dd5a0309 fix(sessions): avoid cross-cwd recent resumes (#97785) 2026-06-30 17:46:40 -07:00
Peter Lee
856cd1824c test: migrate leaky raw mkdtemp calls to createSuiteTempRootTracker() (#96058)
Gap finding: tempdir-8h9i0j1k, tempdir-9i0j1k2l

Replace bare fs.mkdtemp/mkdtempSync calls in 4 test files with the
shared createSuiteTempRootTracker() helper, adding proper cleanup
where none existed.

Background: the project has standardized on shared temp dir helpers
since 88b87d893d (withTempDir) -> 13df67ebc8 (createSuiteTempRootTracker)
-> 06431fd99b / #87298 (CI guard + docs guidance). This PR continues
that migration for the highest-risk files.

Files changed:
- src/skills/lifecycle/install-fallback.test.ts: variable overwrite risk
- src/auto-reply/reply/session-hooks-context.test.ts: helper leaks temp dirs
- src/auto-reply/reply/abort.test.ts: createAbortConfig leaks root dir
- src/auto-reply/inbound.test.ts: test cases without cleanup

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:43:28 -07:00
Wynne668
ba3f68030b fix(cron): clear agentTurn thinking override by blanking the field (#96293)
* fix(cron): clear agentTurn thinking override when patched with null

Cron agentTurn patches could clear model/fallbacks/toolsAllow overrides by
sending an explicit null, but thinking had no clear path: the patch schema and
normalizer dropped thinking:null before it reached the merge logic, and the
payload merge only handled string values. Blanking the Thinking/Effort field in
the Cron Control UI therefore silently preserved the old value.

Add thinking:null support across the patch schema, exported type, normalizer,
and payload merge (mirroring model). The Control UI now sends an explicit clear
for model/thinking when an edited job blanks a previously stored override, and
the CLI gains --clear-thinking for parity with --clear-model.

* docs(cron): document --clear-thinking beside sibling clear flags
2026-06-30 17:43:22 -07:00
Peter Lee
91d0e77e2e test: migrate src/commands tests to shared temp dir helpers (#96359)
* test: migrate src/commands tests to shared temp dir helpers

* fix(test): remove unused path import in migrate apply test
2026-06-30 17:43:16 -07:00
Yzx
16b275a0fb fix: warn when configured channel plugins cannot load (#96397)
* fix(gateway): warn for blocked configured channel plugins

* fix(gateway): preserve configured channel warning source
2026-06-30 17:43:10 -07:00
solodmd
b1fae752f8 fix(anthropic-oauth): bound OAuth token endpoint response reads (#96644)
postJson reads the Anthropic OAuth token endpoint response body with
an unbounded await response.text(). A compromised or hijacked OAuth
endpoint can stream an arbitrarily large body and force the runtime
to buffer the entire payload before parsing — an OOM/DoS vector.

Replace with readResponseWithLimit at 16 MiB cap + TextDecoder decode
to match the sibling bounded-read pattern (provider-http-errors.ts:308).

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 17:43:06 -07:00
xingzhou
29371cfe1f fix #96840: [Bug]: Targetless message.send fails with 'Action send requires a target' in WebChat despite docs stating source-reply sink should handle it (#97167)
* fix(message): route WebChat sends to source sink

* fix(webchat): preserve message tool source replies

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-30 17:34:26 -07:00
Yuval Dinodia
82871fe21b fix(doctor): merge colliding model-ref map keys instead of dropping (#96544)
* fix(doctor): merge colliding model-ref map keys instead of dropping

When two retired model-ref keys in a models map upgrade to the same
current ref, rewriteModelRefMapKeys dropped the second entry silently
and still logged a success line, so doctor --fix lost one entry's
params/streaming/alias/agentRuntime tuning while falsely reporting it
as upgraded.

Mirror the sibling provider-models-array merge path (#90047): deep-merge
the colliding entries preserving disjoint fields, keep the existing
value deterministically on a true field conflict, and push a merge or
collision change-log line instead of dropping.

* fix(doctor): block prototype keys when merging colliding model-ref map entries

mergeModelRefMapEntries copied arbitrary incoming config fields into a
plain object, so a colliding model entry carrying a __proto__ field could
mutate the merged entry prototype during legacy config migration. Skip
isBlockedObjectKey fields before assigning or recursing, matching the
shared config merge guard. Disjoint-field merging is unchanged.

* fix(doctor): preserve canonical model migration values

* fix(doctor): filter blocked keys on both merge sides and report retired source key

* fix(doctor): preserve colliding retired model settings

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:20:49 -07:00
ZOOWH
5a73361ed2 fix(plugins): apply output text transforms to toolcall_delta and toolcall_end events (#97769)
* fix(plugins): apply output text transforms to toolcall_delta and toolcall_end events

toolcall_delta and toolcall_end events bypassed the output replacement
pipeline, leaking masked tokens (e.g. PII placeholders) into tool call
arguments and external systems.

Closes #97761

* fix(plugins): transform nested tool call arguments in output replacements

Add recursive transformToolCallArgumentText to handle strings, arrays,
and nested objects in tool call arguments, not just the name field.

* fix(plugins): keep tool names unchanged and cover result path

- Remove toolCall.name transformation to prevent breaking tool routing
- Add arguments transform to stream.result()/done.message via
  transformContentText for tool-call content blocks

* fix(plugins): narrow argument transform to toolCall content blocks only

Only transform arguments on content blocks with type=toolCall to avoid
touching non-tool-call blocks that happen to have an arguments field.

* test(plugins): assert stream.result() tool-call content block is transformed

* test(plugins): fix result-path fixture to actually contain toolCall block

The previous fixture used makeAssistantMessage('final') which produces
a plain text content block, not a toolCall block. The stream.result()
assertion was vacuously passing.

* style(plugins): fix type cast in result-path test assertion

* fix(agents): preserve tool argument transforms after repair

* refactor(agents): keep tool transform boundary narrow

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:15:01 -07:00
Agustin Rivera
3811001d27 fix(exec): bind Windows allowlist execution path (#98260)
* fix(exec): bind windows allowlist execution path

* fix(exec): add windows shadow execution proof

* fix(exec): preserve wildcard allowlist behavior

* fix(exec): correct blocked plan test fixture
2026-06-30 14:33:08 -07:00
Dallin Romney
44ec7580e2 fix(cli): stop pairing list crashing with empty channel enum (#98142)
When no chat DM pairing channels are configured, `openclaw pairing list`
(no channel argument) threw `Channel required ... (expected one of: )`
with an empty enum that reads like a bug. Users who hit this are usually
trying to approve a TUI/device or scope-upgrade request, which lives under
`openclaw devices`, not `openclaw pairing` (which only handles chat DM
pairing).

- Guard the channel hint in help text and errors so an empty channel list
  no longer renders a bare `()` / `(expected one of: )`.
- When no pairing channels exist, redirect to `openclaw devices list` /
  `openclaw devices approve` instead of failing opaquely.

AI-assisted (Claude Code).
2026-06-30 14:15:19 -07:00
Agustin Rivera
b885c81479 fix(mcp): require owner for Claude permission replies (#98256)
* fix(mcp): require owner for Claude permission replies

* fix(mcp): prove owner-gated permission replies
2026-06-30 13:58:02 -07:00
Gio Della-Libera
9f07b21e62 Doctor: expose auth profile findings (#97125)
Expose `core/doctor/auth-profiles` as a default-disabled structured Doctor lint check.

This maps the existing auth-profile health diagnostics into structured findings while preserving legacy Doctor repair behavior. The check remains opt-in through `--only core/doctor/auth-profiles` or `--all`; default `doctor --lint` behavior is unchanged.

Validation:
- focused auth-profile/hints/contribution Vitest passed
- changed-file oxfmt and oxlint passed
- core tsgo passed
- git diff --check passed
- exact-head hosted CI/Testbox gates passed

Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
2026-06-30 13:28:26 -07:00
Alix-007
640258d7b3 fix(usage): reject inverted startDate-endDate range in usage.cost and sessions.usage (#94096)
* fix(usage): reject inverted startDate-endDate range

* chore: retrigger CI for real behavior proof check

* refactor(usage): resolve validated date ranges once

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 12:55:43 -07:00
Jason (Json)
786abe78df Streamline OpenClaw onboarding (#98218)
* feat: streamline onboarding setup flow

* fix: harden onboarding preflight installs

* test: isolate gateway preflight safety env

* fix: keep local gateway probes on loopback

* fix: honor onboarding node manager installs

* docs: align setup onboarding reference

* fix: harden bare gateway probe fallback

* fix: honor env gateway auth in bare TUI probe

* test: isolate wizard TUI hatch mocks
2026-06-30 11:22:26 -07:00
Ayaan Zaidi
3f147ae5ca test(provider-transport-fetch): cover split large SSE event 2026-06-30 11:08:38 -07:00
Peter Lindsey
81d60ca30d fix(provider-transport-fetch): raise SSE sanitize buffer cap to 16 MiB
The 64 KiB inter-event SSE sanitize buffer added in #96989 rejects a single
legitimate event larger than 64 KiB — e.g. a large gpt-5.5 reasoning summary on
the openai-chatgpt-responses API — throwing "SSE response exceeded max buffer
size (65536 bytes) without event boundary" and failing the whole request. The
default ChatGPT-subscription gpt-5.5 path is unusable (present in v2026.6.11-beta.1).

Decouple the two bounds: keep the non-OK error-body cap tight at 64 KiB
(SSE_NONOK_BODY_MAX_BYTES), and raise the inter-event sanitize buffer to the same
16 MiB ceiling as the JSON-synthesis path. The guard still trips on a genuinely
boundary-less (hostile/broken) stream, just not on a real large event.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 11:08:38 -07:00
Ayaan Zaidi
68c533cfb3 fix(config): preserve unreadable write rejection for exported writes 2026-06-30 10:52:44 -07:00
Ayaan Zaidi
c1605064d0 test(config): distill unreadable config write guard cases 2026-06-30 10:52:44 -07:00
yetval
14198836b2 fix(config): fail closed when config is unreadable before a full-file write
A present-but-unreadable openclaw.json (for example EACCES after a sudo
command leaves it root-owned) returns an empty best-effort fallback
snapshot. A later full-file write (openclaw doctor, including the update
doctor pass) then serialized a skeletal config over the still-rich file,
dropping gateway.mode and bricking gateway startup.

The fallback base has no raw bytes and an empty resolved config, so the
existing size-drop and gateway-mode-removed guards never fired, and the
update path passes allowConfigSizeDrop=true.

Record the read failure on the snapshot (readError) and treat an
unreadable base as an always-blocking write reason
(unreadable-config-before-write) that allowConfigSizeDrop does not bypass.
The allowDestructiveWrite escape hatch and the rejected-artifact path are
preserved, so explicit recovery still works and the blocked payload is
saved to openclaw.json.rejected.<timestamp>.

Refs #78493.
2026-06-30 10:52:44 -07:00
Ayaan Zaidi
8829dc4aae fix(gateway): reject deleted-agent exec followups before dedupe 2026-06-30 10:49:23 -07:00
Ayaan Zaidi
35d06e6356 refactor(gateway): distill deleted-agent RPC guard 2026-06-30 10:49:23 -07:00
Pick-cat
afe137d839 fix(gateway): reject deleted-agent sessions before dedupe and attachment offload 2026-06-30 10:49:23 -07:00
Pick-cat
379756fc92 fix(gateway): guard deleted-agent sessions before agent reset commands 2026-06-30 10:49:23 -07:00
Pick-cat
8cf599cb93 test(gateway): model ops as configured in voice-wake agent fixture 2026-06-30 10:49:23 -07:00
Pick-cat
60f30be526 test(gateway): add live agent RPC deleted-agent integration proof 2026-06-30 10:49:23 -07:00
Pick-cat
71e6505fb1 fix(gateway): reject agent RPC runs for deleted-agent sessions
Related #65524
2026-06-30 10:49:23 -07:00
0668000787
b2787a1c7a fix(text): strip antml:namespaced tool call XML from visible content
When a proxied Anthropic-Messages endpoint degrades a native tool_use block
into plain text, the assistant emits antml:namespaced XML tags
(<antml:invoke>, <antml:parameter>). These were not recognized by the
visible-text sanitizer, leaking tool-call XML into user-visible replies.

Added antml: (and mm:) namespace handling to:
- TOOL_CALL_QUICK_RE regex for fast pre-check
- TOOL_CALL_TAG_NAMES set for tag name recognition
- Tag name scanner to accept ':' in tag names
- TOOL_CALL_XML_PAYLOAD_START_RE for XML payload detection
- shouldDetectXmlPayload to include antml:invoke tags

Fixes #97750.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:24:28 -07:00
cxbAsDev
f284ce3b4d fix(cli): bound docs search API response reads with committed test (#98188) 2026-06-30 10:00:17 -07:00