Commit Graph

9186 Commits

Author SHA1 Message Date
damaozi
c6bb7b0c04 fix(whatsapp): groupAllowFrom sender filter bypassed when groupPolicy is allowlist (#24670)
(cherry picked from commit af06ebd9a6)
2026-02-24 04:20:30 +00:00
Brian Mendonca
3f5e7f8156 fix(gateway): consume allow-once approvals to prevent replay
(cherry picked from commit 6adacd447c)
2026-02-24 04:20:30 +00:00
HeMuling
3c13f4c2b4 test(subagents): mock sessions store in steer-restart coverage 2026-02-24 04:17:56 +00:00
HeMuling
d0e008d460 chore(status): clarify bootstrap file semantics 2026-02-24 04:17:56 +00:00
HeMuling
c3b3065cc9 fix(subagents): reconcile orphaned restored runs 2026-02-24 04:17:56 +00:00
Peter Steinberger
cd3927ad67 fix(sessions): preserve allow-any subagent model overrides (#21088) (thanks @Slats24) 2026-02-24 04:16:32 +00:00
Slats
87dd896963 fix: sessions_sspawn model override ignored for sub-agents
Fix bug where sessions_spawn model parameter was ignored, causing sub-agents
   to always use the parent's default model.

   The allowAny flag from buildAllowedModelSet() was not being captured or used.

   🤖 AI-assisted (Claude) - fully tested locally

   Fixes #17479, #6295, #10963
2026-02-24 04:16:32 +00:00
Peter Steinberger
f6b4baa776 test(telegram): align stop-phrase sequential key expectation (#25034) 2026-02-24 04:16:17 +00:00
Keith
b2719d00ff fix(subagents): restore isInternalMessageChannel guard in resolveAnnounceOrigin
Restores the narrower internal-channel guard from PR #22223 (fe57bea08) that was
inadvertently reverted by f555835b0.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: #22223 regression introduced in f555835b0

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-02-24 04:13:40 +00:00
Sahil Satralkar
420d8c663c Tests/Typing: stabilize subagent completion routing changes 2026-02-24 04:12:25 +00:00
Sahil Satralkar
8796c78b3d Gateway: propagate message target and thread headers into tools invoke context 2026-02-24 04:12:25 +00:00
Sahil Satralkar
f9ffd41cfa Subagents: fallback completion announce to internal session when outbound route is incomplete 2026-02-24 04:12:25 +00:00
Sahil Satralkar
28d658e178 Tests: verify tools invoke propagates route headers for subagent spawn context 2026-02-24 04:12:25 +00:00
Sahil Satralkar
3eabd53898 Tests: add regressions for subagent completion fallback and explicit direct route 2026-02-24 04:12:25 +00:00
Peter Steinberger
721d8b2278 test(discord): stabilize parent-info + doctor migration assertions (#25028) 2026-02-24 04:10:52 +00:00
Ian Eaves
3129d1c489 fix(gateway): start browser HTTP control server module 2026-02-24 04:06:03 +00:00
root
8d2035633b fix(agents): include SOUL.md, IDENTITY.md, USER.md in subagent/cron bootstrap allowlist
Subagent and isolated cron sessions only loaded AGENTS.md and TOOLS.md,
causing subagents to lose their role personality, identity, and user
preferences. Expand MINIMAL_BOOTSTRAP_ALLOWLIST to include the three
missing identity files.

Closes #24852

(cherry picked from commit c33377150e)
2026-02-24 04:04:35 +00:00
Peter Steinberger
aea28e26fb fix(auto-reply): expand standalone stop phrases 2026-02-24 04:02:43 +00:00
Peter Steinberger
588a188d6f fix: replace stale plugin webhook routes on re-registration 2026-02-24 04:01:41 +00:00
Peter Steinberger
d76742ff88 fix: normalize manifest plugin ids during install 2026-02-24 03:56:34 +00:00
Peter Steinberger
a388fbb6c3 fix: harden custom-provider verification probes (#24743) (thanks @Glucksberg) 2026-02-24 03:56:30 +00:00
Peter Steinberger
ebde897bb8 fix: add dmScope route guard regression tests (#24949) (thanks @kevinWangSheng) 2026-02-24 03:55:29 +00:00
shenghui kevin
57783680ad fix(whatsapp): guard updateLastRoute when dmScope isolates DM sessions
When session.dmScope is set to 'per-channel-peer', WhatsApp DMs correctly
resolve isolated session keys, but updateLastRouteInBackground unconditionally
wrote lastTo to the main session key. This caused reply routing corruption
and privacy violations.

Only update main session's lastRoute when the DM session actually IS
the main session (sessionKey === mainSessionKey).

Fixes #24912
2026-02-24 03:55:29 +00:00
Peter Steinberger
de0e01259a fix: expand openrouter thinking-off regression coverage (#24863) (thanks @DevSecTim) 2026-02-24 03:54:29 +00:00
Tim Jones
b96d32c1c2 chore: fix oxfmt formatting in extraparams test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 03:54:29 +00:00
Tim Jones
3e974dc93f fix: don't inject reasoning: { effort: "none" } for OpenRouter when thinking is off
"off" is a truthy string, so the existing guard `if (thinkingLevel && ...)`
was always entering the injection block and sending `reasoning: { effort: "none" }`
to every OpenRouter request — even when thinking wasn't enabled. Models that
require reasoning (e.g. deepseek/deepseek-r1) reject this with:
  400 Reasoning is mandatory for this endpoint and cannot be disabled.

Fix: skip the reasoning injection entirely when thinkingLevel is "off".
The reasoning_effort flat-field cleanup still runs. Omitting the reasoning
field lets each model use its own default behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 03:54:29 +00:00
Peter Steinberger
69a541c3f0 fix: sanitize pairing recovery requestId hints (#24771) (thanks @markmusson) 2026-02-24 03:53:45 +00:00
Mark Musson
b902d5ade0 fix(status): show pairing approval recovery hints 2026-02-24 03:53:45 +00:00
Peter Steinberger
6c1ed9493c fix: harden queue retry debounce and add regression tests 2026-02-24 03:52:49 +00:00
Peter Steinberger
a216f2dabe fix: extend discord thread parent fallback coverage (#24897) (thanks @z-x-yang) 2026-02-24 03:52:43 +00:00
Zongxin Yang
d883ecade6 fix(discord): fallback thread parent lookup when parentId missing 2026-02-24 03:52:43 +00:00
Peter Steinberger
7a42558a3e fix: harden legacy plugin schema compatibility tests (#24933) (thanks @pandego) 2026-02-24 03:50:53 +00:00
pandego
9f4764cd41 fix(plugins): guard legacy zod schemas without toJSONSchema 2026-02-24 03:50:53 +00:00
Peter Steinberger
dd145f1346 fix: suppress sessions_send warning leakage coverage (#24740) (thanks @Glucksberg) 2026-02-24 03:49:52 +00:00
Glucksberg
947883d2e0 fix: suppress sessions_send error warnings from leaking to chat (#23989)
sessions_send timeout/error results were being surfaced as raw warning
messages in Telegram chats because the tool is classified as mutating,
which forces error warnings to always be shown. However, sessions_send
failures are transient inter-session communication issues where the
message may still have been delivered, so they should not leak to users.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:49:52 +00:00
Glucksberg
1565d7e7b3 fix: increase verification max_tokens to 1024 for Poe API compatibility
Poe API's Extended Thinking models (e.g. claude-sonnet-4.6) require
budget_tokens >= 1024. The previous values (5 for OpenAI, 16 for
Anthropic) caused HTTP 400 errors during provider verification.

Fixes #23433

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:47:49 +00:00
Peter Steinberger
b5881d9ef4 fix: avoid WhatsApp silent turns with final-only delivery (#24962) (thanks @SidQin-cyber) 2026-02-24 03:47:20 +00:00
SidQin-cyber
3d22af692c fix(whatsapp): suppress reasoning/thinking content from WhatsApp delivery
The deliver callback in process-message.ts was forwarding all payload
kinds (tool, block, final) to WhatsApp. Block payloads contain the
model's reasoning/thinking content, which should only be visible in
the internal web UI. This caused chain-of-thought to leak to end users
as separate WhatsApp messages.

Add an early return for non-final payloads so only the actual response
is delivered to the WhatsApp channel, matching how Telegram already
filters by info.kind === "final".

Fixes #24954
Fixes #24605

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 03:47:20 +00:00
Peter Steinberger
3a653082d8 fix(config): align whatsapp enabled schema with auto-enable 2026-02-24 03:39:41 +00:00
Coy Geek
aef45b2abb fix(logging): redact phone numbers and message content from WhatsApp logs
Apply redactIdentifier() (SHA-256 hashing) to all recipient JIDs and
phone numbers logged by sendMessageWhatsApp, sendReactionWhatsApp,
sendPollWhatsApp, and runWebHeartbeatOnce. Remove poll question text
and message preview content from log entries, replacing with character
counts where useful for debugging.

The existing redactIdentifier() utility in src/logging/redact-identifier.ts
was already implemented but not wired into any WhatsApp logging path.
This commit connects it to all affected call sites while leaving
functional parameters (actual send calls, event emitters) untouched.

Closes #24957
2026-02-24 03:36:29 +00:00
Peter Steinberger
0bdcca2f35 test(whatsapp): add log redaction coverage 2026-02-24 03:34:31 +00:00
Sid
d95ee859f8 fix(cron): use full prompt mode for isolated cron sessions to include skills (#24944)
Isolated cron sessions (agentTurn) were grouped with subagent sessions
under the "minimal" prompt mode, which causes buildSkillsSection to
return an empty array. This meant <available_skills> was never included
in the system prompt for isolated cron runs.

Subagent sessions legitimately need minimal prompts (reduced context),
but isolated cron sessions are full agent turns that should have access
to all configured skills, matching the behavior of normal chat sessions
and non-isolated cron runs.

Remove isCronSessionKey from the minimal prompt condition so only
subagent sessions use "minimal" mode.

Fixes openclaw#24888

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 03:33:54 +00:00
zerone0x
bf91b347c1 fix(plugins): use manifest id as config entry key instead of npm package name (#24796)
* fix(plugins): use manifest id as config key instead of npm package name

Plugin manifests (openclaw.plugin.json) define a canonical 'id' field that
is used as the authoritative plugin identifier by the manifest registry.
However, the install command was deriving the config entry key from the npm
package name (e.g. 'cognee-openclaw') rather than the manifest id (e.g.
'memory-cognee'), causing a latent mismatch.

On the next gateway reload the plugin could not be found under the config key
derived from the npm package name, causing 'plugin not found' errors and
potentially shutting the gateway down.

Fix: after extracting the package directory, read openclaw.plugin.json and
prefer its 'id' field over the npm package name when registering the config
entry. Falls back to the npm-derived id if the manifest file is absent or
has no valid id. A diagnostic info message is emitted when the two values
differ so the mismatch is visible in the install log.

The update path (src/plugins/update.ts) already correctly reads the manifest
id and is unaffected.

Fixes #24429

* fix: format plugin install manifest-id path (#24796)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-24 03:33:51 +00:00
Peter Machona
9ced64054f fix(auth): classify missing OAuth scopes as auth failures (#24761) 2026-02-24 03:33:44 +00:00
Sid
38da3f40cb fix(discord): suppress reasoning/thinking block payloads from delivery (#24969)
Block payloads (info.kind === "block") contain reasoning/thinking content
that should only be visible in the internal web UI. When streamMode is
"partial", these blocks were being delivered to Discord as visible
messages, leaking chain-of-thought to end users.

Add an early return for block payloads in the deliver callback,
consistent with the WhatsApp fix and Telegram's existing behavior.

Fixes #24532

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 03:33:40 +00:00
Sid
c1fe688d40 fix(gateway): safely extract text from content arrays in prompt builder (#24946)
* fix(gateway): safely extract text from message content arrays in prompt builder

When HistoryEntry.body is a content array (e.g. [{type:"text",
text:"hello"}]) rather than a plain string, template literal
interpolation produces "[object Object]" instead of the actual message
text. This affects users whose session messages were stored with array
content format.

Add a safeBody helper that detects non-string body values and uses
extractTextFromChatContent to extract the text, preventing the
[object Object] serialization in both the current-message return path
and the history formatting path.

Fixes openclaw#24688

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: format gateway agent prompt helper (#24946)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-24 03:33:37 +00:00
banna-commits
e3da57d956 fix: add exponential backoff to announce queue drain on failure (#24783)
When the gateway rejects connections (e.g. scope-upgrade 'pairing required'),
the announce queue drain loop would retry every ~1s indefinitely because
the only delay was the fixed debounceMs (default 1000ms).

This adds a consecutiveFailures counter with exponential backoff:
2s, 4s, 8s, 16s, 32s, 60s (capped). The counter resets on successful drain.

The backoff is applied by shifting lastEnqueuedAt forward so that
waitForQueueDebounce naturally delays the next attempt.

Fixes #24777

Co-authored-by: Knut <knut@Knut-sin-Mac-mini.local>
2026-02-24 03:33:34 +00:00
青雲
52ac7634db fix: persist reasoningLevel 'off' instead of deleting it (#24406) (#24559)
When a user runs /reasoning off, the session patch handler deleted
the reasoningLevel field from the session entry. This caused
get-reply-directives to treat reasoning as 'not explicitly set',
which triggered resolveDefaultReasoningLevel() to re-enable
reasoning for capable models (e.g. Claude Opus).

The fix persists 'off' explicitly, matching how directive-handling.persist.ts
already handles the inline /reasoning off command.

Fixes #24406
Fixes #24411

Co-authored-by: echoVic <AkiraVic@outlook.com>
2026-02-24 03:33:30 +00:00
junwon
04bcabcbae fix(infra): handle Windows dev=0 in sameFileIdentity TOCTOU check (#24939)
* fix(infra): handle Windows dev=0 in sameFileIdentity TOCTOU check

On Windows, `fs.lstatSync` (path-based) returns `dev: 0` while
`fs.fstatSync` (fd-based) returns the real NTFS volume serial number.
This mismatch caused `sameFileIdentity` to always fail, making
`openVerifiedFileSync` reject every file — silently breaking all
Control UI static file serving (HTTP 404).

Fall back to ino-only comparison when either dev is 0 on Windows.
ino remains unique within a single volume, so TOCTOU protection
is preserved.

Fixes #24692

* fix: format sameFileIdentity wrapping (#24939)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-24 03:33:27 +00:00
Glucksberg
a3b82a563d fix: resolve symlinks in pnpm/bun global install detection (#24744)
Use tryRealpath() instead of path.resolve() when comparing expected
package paths in detectGlobalInstallManagerForRoot(). path.resolve()
only normalizes path strings without following symlinks, causing pnpm
global installs to go undetected since pnpm symlinks node_modules
entries into its .pnpm content-addressable store.

Fixes #22768

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:33:24 +00:00