Commit Graph

31156 Commits

Author SHA1 Message Date
George Pickett
0e9a6da7b8 Reply media: persist preferred tmp-root media 2026-04-13 16:46:03 -07:00
jet
62284b58bc fix: cache tmp dir resolution, add test for TTS temp path
Address review feedback:
- Cache resolvePreferredOpenClawTmpDir() result to avoid sync I/O
  on every media path check and prevent mkdir side effects
- Add test for TTS voice output from /tmp/openclaw/ path
2026-04-13 16:46:02 -07:00
jet
f6424aa484 fix(tts): allow OpenClaw temp directory paths in reply media normalizer
TTS output files are written to /tmp/openclaw/tts-*/voice-*.opus by
resolvePreferredOpenClawTmpDir(), but the reply-media-path normalizer
only allows managed global paths and workspace volatile paths.
Absolute paths under /tmp/openclaw/ are blocked with 'Absolute host-local
MEDIA paths are blocked in normal replies', causing TTS audio attachments
to be silently dropped before delivery.

Add isOpenClawTmpPath() check to isAllowedAbsoluteReplyMediaPath() so
that files in the OpenClaw temp directory are treated as trusted.

Closes #63110
2026-04-13 16:46:02 -07:00
Omar Shahine
0362f21784 fix: sendPolicy deny should suppress delivery, not inbound processing (#53328) (#65461)
* fix: sendPolicy deny suppresses delivery, not inbound processing (#53328)

Previously, sendPolicy "deny" returned early before the agent dispatch,
preventing the agent from ever seeing the message. This broke the use
case of an agent listening on WhatsApp groups with sendPolicy: deny to
read messages without replying — the agent couldn't read them at all.

Move the deny gate from before the agent dispatch to after it. The agent
now processes inbound messages normally (context, memory, tool calls),
but all outbound delivery paths are suppressed: final replies, tool
results, block replies, working status, plan updates, typing indicators,
and TTS payloads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: propagate sendPolicy to ACP tail dispatch instead of hardcoded allow

The ACP tail dispatch path (ctx.AcpDispatchTailAfterReset) was passing
sendPolicy: "allow" unconditionally, which would bypass delivery
suppression in a /reset <tail> turn when the session has sendPolicy deny.

Pass through the resolved sendPolicy so the tail dispatch respects it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: guard before_dispatch hook and ACP tail dispatch under sendPolicy deny

before_dispatch handled replies were leaking through sendFinalPayload
before the suppressDelivery guard was checked. ACP tail dispatch (from
/new <tail>) was being rejected by acp-runtime.ts deny checks instead
of proceeding with delivery suppression handled downstream.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* auto-reply: propagate deny suppression to reply_dispatch

* fix(acp): suppress onReplyStart when user delivery is denied

When sendPolicy resolves to "deny", ACP tail dispatch still invoked
onReplyStart via startReplyLifecycle before the suppressUserDelivery
check. Channels wire onReplyStart to typing indicators, so deny-scoped
sessions could still emit outbound typing events on /reset <tail>
flows and command bypass paths.

Gate startReplyLifecycleOnce on suppressUserDelivery so the lifecycle
is marked started but the callback is skipped. Payload delivery was
already suppressed; this closes the typing-indicator leak flagged by
Codex review (PR #65461 P1/P2).

* fix(acp): route non-tail deny turns through ACP when suppression is wired

tryDispatchAcpReplyHook was returning early for non-tail, non-command ACP
turns under sendPolicy: "deny", causing ACP-bound sessions to fall back
to the embedded reply path instead of flowing through acpManager.runTurn.
That diverged ACP session state, tool calls, and memory whenever
delivery suppression was active.

Now the early-return only fires when sendPolicy is "deny" AND the event
lacks suppressUserDelivery — i.e., when downstream delivery suppression
is not wired up. When suppressUserDelivery is set, dispatch-acp-delivery
already drops outbound sends (see onReplyStart / deliver guards), so ACP
can safely run the turn with state consistency preserved.

Existing behavior preserved:
- Command bypass still overrides deny
- Tail dispatch still overrides deny
- Plain-text deny turns without suppression still short-circuit

Addresses Codex bot P1 feedback on #65461.

* fix: gate empty-body typing indicator behind suppressTyping (#53328)

* fix: guard plugin-binding + fast-abort outbound paths under sendPolicy deny

The original PR computed suppressDelivery inside the try block, which was
after two outbound paths:

1. The plugin-owned binding block (sendBindingNotice calls for
   unavailable/declined/error outcomes, plus the plugin's own "handled"
   outcome) ran before the suppressDelivery flag existed, so plugin
   notices still leaked under deny.
2. The fast-abort path dispatched "Agent was aborted." via
   routeReplyToOriginating / sendFinalReply before the flag existed.

Move resolveSendPolicy() above the plugin-binding block so suppressDelivery
covers every outbound path downstream, matching the PR description's claim
that "all outbound paths are guarded by the flag."

Plugin-bound inbound handling under deny: plugin handlers can emit
outbound replies we cannot rewind, so skip the claim hook entirely under
deny and fall through to normal (suppressed) agent processing.
touchConversationBindingRecord still runs so binding activity stays
tracked.

Fast-abort under deny: still run the abort and record the completed
state, just don't emit the abort reply.

Tests:
- suppresses the fast-abort reply under sendPolicy deny
- delivers the fast-abort reply normally when sendPolicy is allow
  (regression guard)
- skips plugin-bound claim hook under deny and falls through to
  suppressed agent dispatch

Addresses Codex review findings on PR #65461.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Lobster <lobster@shahine.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 16:42:25 -07:00
Peter Steinberger
07b839f9b1 test: align failover source model expectation 2026-04-14 00:16:03 +01:00
Vincent Koc
12246711d8 docs(changelog): note perf fixes 2026-04-14 00:10:46 +01:00
Vincent Koc
9376f52419 fix(ci): mirror whatsapp runtime dependency 2026-04-14 00:01:44 +01:00
Agustin Rivera
a1c44d28fc Feishu: tighten allowlist target canonicalization (#66021)
* fix(feishu): tighten allowlist id matching

* fix(feishu): address review follow-ups

* changelog: note Feishu allowlist canonicalization tightening (#66021)

* fix(feishu): collapse typed wildcard allowlist aliases to bare wildcard

Previously normalizeFeishuTarget folded chat:* / user:* / open_id:* /
dm:* / group:* / channel:* down to '*', so those entries acted as
allow-all. The new typed canonicalization was producing literal keys
(chat:*, user:*, ...) that never matched any sender, silently
flipping those configs from allow-all to deny-all. Restore the prior
behavior by collapsing a wildcard value to '*' inside
canonicalizeFeishuAllowlistKey.

---------

Co-authored-by: Devin Robison <drobison@nvidia.com>
2026-04-13 16:59:07 -06:00
Agustin Rivera
692438cbb2 fix(stream): tighten voice stream ingress guards (#66027)
* fix(stream): tighten voice stream ingress guards

* fix(stream): address review follow-ups

* fix(stream): normalize trusted proxy ip matching

* changelog: note voice-call media-stream ingress guard tightening (#66027)

* fix(stream): require non-empty trusted proxy list before honoring forwarding headers

Without an explicit trusted proxy list, the prior gate treated every
remote as 'from a trusted proxy', so enabling trustForwardingHeaders
let any direct caller spoof X-Forwarded-For / X-Real-IP and rotate the
resolved IP per request to evade maxPendingConnectionsPerIp. Require
trustedProxyIPs to be non-empty AND match the remote before trusting
forwarding headers.

---------

Co-authored-by: Devin Robison <drobison@nvidia.com>
2026-04-13 16:51:16 -06:00
Vincent Koc
955270fb73 fix(ci): repair telegram ui and watch regressions 2026-04-13 23:49:59 +01:00
Vincent Koc
94779b4fb1 fix(ci): repair telegram topic cache typing 2026-04-13 23:33:41 +01:00
Vincent Koc
a165f7b063 fix(ci): repair agent test mocks 2026-04-13 23:30:17 +01:00
Vincent Koc
9dc4a270e4 fix(ci): align cron tests with default model 2026-04-13 23:28:28 +01:00
Vincent Koc
8ab89989c2 fix(ci): restore plugin-local whatsapp deps 2026-04-13 23:26:25 +01:00
Gustavo Madeira Santana
b5dcc11273 plugins: trim staged runtime cargo 2026-04-13 18:10:40 -04:00
Peter Steinberger
e04a63d08a chore: fix pulled lint assertion 2026-04-13 23:09:32 +01:00
Peter Steinberger
3fdc70a434 fix: normalize OpenAI minimal reasoning 2026-04-13 23:09:21 +01:00
Mariano
3d06d90e83 fix(memory): unify default root memory handling (#66141)
* fix(memory): unify default root memory handling

* test(memory): align legacy migration expectation

* docs(changelog): tag qmd root-memory fix

* docs(changelog): append qmd root-memory entry

* docs(changelog): dedupe qmd root-memory entry

* docs(changelog): attribute qmd root-memory fix

---------

Co-authored-by: mbelinky <mbelinky@users.noreply.github.com>
2026-04-13 23:59:57 +02:00
Vincent Koc
cc2a377009 fix(ci): repair baileys lockfile snapshot 2026-04-13 22:49:26 +01:00
Vincent Koc
792653df15 fix(ci): clear residual tsgo blockers 2026-04-13 22:37:25 +01:00
Vincent Koc
a16331c36e fix(ci): align cron and session tests with runtime 2026-04-13 22:37:25 +01:00
Vincent Koc
36a58e714c fix(ci): mirror whatsapp runtime dependency 2026-04-13 22:37:25 +01:00
Vincent Koc
f3283a330b fix(ci): repair extension boundary contracts 2026-04-13 22:37:25 +01:00
Vincent Koc
ea25cf2595 fix(ci): unblock discord boundary typing 2026-04-13 22:37:24 +01:00
Val Alexander
9315302516 fix(ui): replace marked.js with markdown-it to fix ReDoS UI freeze (#46707) thanks @zhangfnf
Replace marked.js with markdown-it for the control UI chat markdown renderer
to eliminate a ReDoS vulnerability that could freeze the browser tab.

- Configure markdown-it with custom renderers matching marked.js output
- Add GFM www-autolink with trailing punctuation stripping per spec
- Escape raw HTML via html_block/html_inline overrides
- Flatten remote images to alt text, preserve base64 data URI images
- Add task list support via markdown-it-task-lists plugin
- Trim trailing CJK characters from auto-linked URLs (RFC 3986)
- Keep marked dependency for agents-panels-status-files.ts usage

Co-authored-by: zhangfan49 <zhangfan49@baidu.com>
Co-authored-by: Nova <nova@openknot.ai>
2026-04-13 16:08:35 -05:00
Tak Hoffman
f94d6778b1 fix(active-memory): Move active memory recall into the hidden prompt prefix (#66144)
* move active memory into prompt prefix

* document active memory prompt prefix

* strip active memory prefixes from recall history

* harden active memory prompt prefix handling

* hide active memory prefix in leading history views

* strip hidden memory blocks after prompt merges

* preserve user turns in memory recall cleanup
2026-04-13 16:05:43 -05:00
Bob
8c7f17b953 fix: count unknown-tool retries only when streamed (#66145)
Merged via squash.

Prepared head SHA: b79209cdb5
Co-authored-by: Bob <dutifulbob@gmail.com>
Reviewed-by: @osolmaz
2026-04-13 22:49:05 +02:00
Byron
891e42beec fix(ui): preserve user-selected session on reconnect and tab switch (#59611) thanks @loong0306
Fixes #57072 — chat UI state desync after route navigation.

- applySessionDefaults() now detects user-selected sessions and preserves them on reconnect
- Chat tab session switching consolidated to use switchChatSession() helper
- Overview session-key handler uses shared resetChatStateForSessionSwitch to prevent stale state leaks
- Session select dropdowns now set ?selected to reflect actual state

Co-authored-by: loong0306 <loong0306@gmail.com>
Co-authored-by: Nova <nova@openknot.ai>
2026-04-13 15:24:56 -05:00
Vincent Koc
10a92e2ff4 perf(config): keep runtime compat migrations lightweight 2026-04-13 21:14:22 +01:00
rafaelreis-r
68e0e456f3 fix: allow plugin commands on Slack when channel supports native commands (#64578)
Merged via squash.

Prepared head SHA: 2ec97bf0b3
Co-authored-by: rafaelreis-r <57492577+rafaelreis-r@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-04-13 13:14:02 -07:00
Vincent Koc
ce1fffa97e perf(agents): narrow session helper imports 2026-04-13 21:09:44 +01:00
Vincent Koc
99755fcb2f perf(agents): lazy-load session store updates 2026-04-13 21:07:50 +01:00
Vincent Koc
dd27aa945e perf(agents): lazy-load delivery runtime 2026-04-13 21:05:30 +01:00
Vincent Koc
f126088761 perf(agents): keep attempt execution runtime cold 2026-04-13 21:03:52 +01:00
Mariano
305a80ce32 [codex] fix(ui): guard dreaming wiki plugin calls (#66140)
Merged via squash.

Prepared head SHA: 030562b044
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
2026-04-13 22:01:11 +02:00
Vincent Koc
ac00ba1943 perf(commands): lazy-load agent secret resolution 2026-04-13 20:56:03 +01:00
Vincent Koc
f2e08295e6 perf(commands): narrow agent config imports 2026-04-13 20:51:35 +01:00
Mariano
3d42e33dd0 fix(memory-core): run Dreaming once per cron schedule (#66139)
Merged via squash.

Prepared head SHA: 48229a24cb
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
2026-04-13 21:50:32 +02:00
Vincent Koc
99237c2dde perf(commands): narrow session test imports 2026-04-13 20:45:04 +01:00
Vincent Koc
9a2675e9fd perf(agents): lazy-load cli runner seams 2026-04-13 20:43:58 +01:00
Vincent Koc
25a2ea4480 perf(config): scope dry-run legacy validation 2026-04-13 20:40:52 +01:00
Vincent Koc
e02c6ca82a perf(config): narrow channel legacy rule loading 2026-04-13 20:37:21 +01:00
Agustin Rivera
43d4be9027 fix(queue): split collect batches by auth context (#66024)
* fix(queue): split collect batches by auth context

Co-authored-by: zsx <git@zsxsoft.com>

* fix(queue): keep overflow summary on splits

* fix(queue): preserve grouped collect retry semantics

* fix(queue): drop USER.md from pr

* fix(queue): keep overflow summary in first auth group

* fix(queue): clear overflow summary state after first auth group

* fix(queue): narrow auth split key

* fix(queue): flush collect summary-only drains

* changelog: note collect-mode auth-context batch split (#66024)

---------

Co-authored-by: zsx <git@zsxsoft.com>
Co-authored-by: Devin Robison <drobison@nvidia.com>
2026-04-13 13:35:39 -06:00
Agustin Rivera
48aae82bbc fix(outbound): replay queued session context (#66025)
* fix(outbound): preserve replay session context

* fix(outbound): remove user work log

* changelog: note outbound session-context replay fix (#66025)

---------

Co-authored-by: Devin Robison <drobison@nvidia.com>
2026-04-13 13:30:42 -06:00
Tak Hoffman
7c09ba70ef fix(trace command): Improve trace raw diagnostics and trace command UX (#66089)
* improve trace raw diagnostics and command acks

* address trace review feedback

* avoid sync transcript reads in raw trace

* preserve raw cli output for trace

* gate trace emission at reply time

* reflect raw trace mode in status surfaces
2026-04-13 14:26:57 -05:00
Vincent Koc
6157933e39 perf(config): skip cold runtime refresh on one-shot writes 2026-04-13 20:25:21 +01:00
Vincent Koc
bd20a920a2 perf(config): use generated SecretRef policy metadata 2026-04-13 20:19:04 +01:00
Mariano
a0a4a768dc test(cron): fix #66019 maintenance regression coverage (#66122)
Merged via squash.

Prepared head SHA: 7f2a604e91
2026-04-13 21:03:45 +02:00
屈定
95ee120a91 fix: classify openrouter json 404 model errors
Rewrites the stale branch on top of current `main` and preserves the original issue as regression coverage for the exact OpenRouter JSON 404 payload from #51571.

No production behavior changes are introduced here; current `main` already classifies this payload as `model_not_found`, and this merge locks that in across the shared matcher, failover classifier, and fallback loop.

Co-authored-by: 屈定 <mrdear@users.noreply.github.com>
Co-authored-by: Altay <altay@uinaf.dev>
2026-04-13 19:53:55 +01:00
Vincent Koc
961eb95e9a perf(secrets): lazy-load provider env var exports 2026-04-13 19:52:02 +01:00