Commit Graph

22140 Commits

Author SHA1 Message Date
Josh Lehman eea7800df3
Tests: remove provider auth conflict marker 2026-03-25 10:34:32 -07:00
Josh Lehman c733d5040d
Tests: reset provider auth module cache 2026-03-25 10:34:32 -07:00
Josh Lehman fc025f20b4
CLI: stabilize preaction title test 2026-03-25 10:34:32 -07:00
Josh Lehman a9da221071
Agents: preserve media-only rate-limit replies 2026-03-25 10:34:31 -07:00
chenxingzhen e40e9500df
fix: address cross-target messaging and reasoning-only payload issues
1. run.ts: remove didSendViaMessagingTool guard from incomplete turn
   detection — this boolean is too coarse and blocks cross-target sends
   (e.g. agent posts to slack but should still reply in originating
   channel). Same-origin dedup is handled downstream by
   buildReplyPayloads()/shouldSuppressMessagingToolReplies.

2. agent-runner-execution.ts: exclude isReasoning payloads from
   hasNonErrorContent check — reasoning-only payloads are dropped
   during delivery, so they should not prevent 429/overload error
   surfacing. Also remove didSendViaMessagingTool guard for same
   cross-target reason as run.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:34:09 -07:00
chenxingzhen 5ff4522e74
fix: preserve payload filtering and session bookkeeping on rate-limit fallback
agent-runner-execution.ts: instead of returning kind:"final" which
bypasses buildReplyPayloads() filtering (streaming dedup, message_send
suppression) and post-run session bookkeeping (usage/model/provider
metadata updates), inject the error payload into runResult.payloads
and let it flow through the normal kind:"success" path.

Also adds !runResult.didSendViaMessagingTool guard to prevent
duplicate error messages when the reply was already delivered via
messaging tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:34:09 -07:00
chenxingzhen 9e67e1125b
fix: add profile cooldown bookkeeping and mutating-tool side-effect warning
1. run.ts: call maybeMarkAuthProfileFailure before early return in
   incomplete turn detection, so the exhausted credential enters cooldown
   and multi-profile setups rotate to a healthy profile on the next turn
2. run.ts: check attempt.toolMetas for mutating tools and warn users
   about potential side-effects when tools already executed before the
   turn was interrupted, preventing blind retries of mutating actions

Addresses third round of review feedback on PR #50930.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:34:09 -07:00
chenxingzhen 9e46042e70
fix: address second round of PR review feedback
1. run.ts: exclude suppressed/recoverable tool error turns from
   incomplete turn detection via !attempt.lastToolError guard — prevents
   false-positive rate-limit message when buildEmbeddedRunPayloads
   intentionally suppresses tool warnings
2. run.ts: use generic error message ("Agent couldn't generate a
   response") instead of attributing to rate limit, since the detection
   cannot distinguish mid-turn 429 from other empty-payload causes
3. agent-runner-execution.ts: remove "after tool calls completed" from
   error message — this secondary check can also trigger on first-call
   429 (before any tool execution), so the message should be accurate
   for both pre-tool and mid-turn failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:34:09 -07:00
chenxingzhen 71caada7d0
fix: address PR review feedback on mid-turn rate limit detection
1. run.ts: differentiate error message by stopReason — use rate-limit
   message only for "toolUse", generic message for "error" stop reason
2. run.ts: exclude deterministic approval-prompt turns from incomplete
   turn detection via !attempt.didSendDeterministicApprovalPrompt guard
3. agent-runner-execution.ts: prioritize metaErrorMsg (raw upstream error)
   over errorPayloadText to avoid self-matching on pre-formatted "⚠️"
   messages from run.ts
4. agent-runner-execution.ts: skip already-formatted payloads (startsWith
   "⚠️") so tool-specific 429 errors are preserved rather than overwritten

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:34:08 -07:00
chenxingzhen ccbc0dc07b
fix: mid-turn 429 rate limit silent no-reply and context engine registration failure
- Fix legacy.ts: use registerContextEngineForOwner with core owner to
  bypass public-sdk protection on default slot
- Add incomplete turn detection in run.ts: surface error when prompt()
  resolves prematurely during mid-turn 429 retry producing empty payloads
- Fix TS2367: use correct StopReason union members (toolUse|error)
  instead of non-existent end_turn|max_tokens

Fixes issues introduced by PR #47046 (5e293da)
2026-03-25 10:34:08 -07:00
Matt Van Horn e0972db7a2
fix: stop leaking reply tags in iMessage outbound text (#39512) (thanks @mvanhorn)
* fix: stop leaking reply tags in iMessage outbound text (#39512) (thanks @mvanhorn)

* fix: preserve iMessage outbound whitespace without directive tags (#39512) (thanks @mvanhorn)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-25 23:00:16 +05:30
Tak Hoffman f63c4b0856
test: keep vitest on forks only 2026-03-25 12:22:22 -05:00
Harold Hunt 055ad65896
Telegram: ignore self-authored DM message updates (#54530)
Merged via squash.

Prepared head SHA: c1c8a85168
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
2026-03-25 13:16:35 -04:00
Peter Steinberger 685f17460d
build: update appcast for 2026.3.24 2026-03-25 10:10:34 -07:00
Jackal Xin 2de32fbf14
fix: reconcile session compaction count after late compaction success (#45493)
Merged via squash.

Prepared head SHA: d0715a5555
Co-authored-by: jackal092927 <3854860+jackal092927@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-25 10:00:41 -07:00
Peter Steinberger cff6dc94e3
docs: format changelog for release 2026-03-25 09:34:30 -07:00
Peter Steinberger 97a7e93db4
build: prepare 2026.3.24 release 2026-03-25 09:31:05 -07:00
liyuan97 e2e9f979ca
feat(minimax): add image generation provider and trim model catalog to M2.7 (#54487)
* feat(minimax): add image generation and TTS providers, trim TUI model list

Register MiniMax image-01 and speech-2.8 models as plugin providers for
the image_generate and TTS tools. Both resolve CN/global base URLs from
the configured model endpoint origin.

- Image generation: base64 response, aspect-ratio support, image-to-image
  via subject_reference, registered for minimax and minimax-portal
- TTS: speech-2.8-turbo (default) and speech-2.8-hd, hex-encoded audio,
  voice listing via get_voice API, telephony PCM support
- Add MiniMax to TTS auto-detection cascade (after ElevenLabs, before
  Microsoft) and TTS config section
- Remove MiniMax-VL-01, M2, M2.1, M2.5 and variants from TUI picker;
  keep M2.7 and M2.7-highspeed only (backend routing unchanged)

* feat(minimax): trim legacy model catalog to M2.7 only

Cherry-picked from temp/feat/minimax-trim-legacy-models (949ed28).
Removes MiniMax-VL-01, M2, M2.1, M2.5 and variants from the model
catalog, model order, modern model matchers, OAuth config, docs, and
tests. Keeps only M2.7 and M2.7-highspeed.

Conflicts resolved:
- provider-catalog.ts: removed MINIMAX_TUI_MODELS filter (no longer
  needed since source array is now M2.7-only)
- index.ts: kept image generation + speech provider registrations
  (added by this branch), moved media understanding registrations
  earlier (as intended by the cherry-picked commit)

* fix(minimax): update discovery contract test to reflect M2.7-only catalog

Cherry-picked from temp/feat/minimax-trim-legacy-models (2c750cb).

* feat(minimax): add web search provider and register in plugin entry

* fix(minimax): resolve OAuth credentials for TTS speech provider

* MiniMax: remove web search and TTS providers

* fix(minimax): throw on empty images array after generation failure

* feat(minimax): add image generation provider and trim catalog to M2.7 (#54487) (thanks @liyuan97)

---------

Co-authored-by: tars90percent <tars@minimaxi.com>
Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-25 09:29:35 -07:00
xieyongliang 7cc86e9685
fix(release): add plugin-sdk:check-exports to release:check (#54283)
* fix(plugins): resolve sdk alias from import.meta.url for external plugins

When a plugin is installed outside the openclaw package (e.g.
~/.openclaw/extensions/), resolveLoaderPluginSdkPackageRoot() fails to
locate the openclaw root via cwd or argv1 hints, resulting in an empty
alias map. Jiti then cannot resolve openclaw/plugin-sdk/* imports and
the plugin fails to load with "Cannot find module".

Since sdk-alias.ts is always compiled into the openclaw package itself,
import.meta.url reliably points inside the installation directory. Add it
as an unconditional fallback in resolveLoaderPluginSdkPackageRoot() so
external plugins can always resolve the plugin SDK.

Fixes: Error: Cannot find module 'openclaw/plugin-sdk/plugin-entry'

* fix(plugins): pass loader moduleUrl to resolve sdk alias for external plugins

The previous approach of adding import.meta.url as an unconditional
fallback inside resolveLoaderPluginSdkPackageRoot() broke test isolation:
tests that expected null from untrusted fixtures started finding the real
openclaw root. Revert that and instead thread an optional moduleUrl through
buildPluginLoaderAliasMap → resolvePluginSdkScopedAliasMap →
listPluginSdkExportedSubpaths → resolveLoaderPluginSdkPackageRoot.

loader.ts passes its own import.meta.url as the hint, which is always
inside the openclaw installation. This guarantees the sdk alias map is
built correctly even when argv1 does not resolve to the openclaw root
(e.g. single-binary distributions, custom launchers, or Docker images
where the binary wrapper is not a standard npm symlink).

Tests that call sdk-alias helpers directly without moduleUrl are
unaffected and continue to enforce the existing isolation semantics.
A new test covers the moduleUrl resolution path explicitly.

* fix(plugins): use existing fixture file for moduleUrl hint in test

The previous test pointed loaderModuleUrl to dist/plugins/loader.js
which is not created by createPluginSdkAliasFixture, causing resolution
to fall back to the real openclaw root instead of the fixture root.
Use fixture.root/openclaw.mjs (created by the bin+marker fixture) so
the moduleUrl hint reliably resolves to the fixture package root.

* fix(test): use fixture.root as cwd in external plugin alias test

When process.cwd() is mocked to the external plugin dir, the
findNearestPluginSdkPackageRoot(process.cwd()) fallback resolves to
the real openclaw repo root in the CI test runner, making the test
resolve the wrong aliases. Using fixture.root as cwd ensures all
resolution paths consistently point to the fixture.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(release): add plugin-sdk:check-exports to release:check

plugin-sdk subpath exports (e.g. openclaw/plugin-sdk/plugin-entry,
openclaw/plugin-sdk/provider-auth) were missing from the published
package.json, causing external plugins to fail at load time with
'Cannot find module openclaw/plugin-sdk/plugin-entry'.

Root cause: sync-plugin-sdk-exports.mjs syncs plugin-sdk-entrypoints.json
into package.json exports, but this sync was never validated in the
release:check pipeline. As a result, any drift between
plugin-sdk-entrypoints.json and the published package.json goes
undetected until users hit the runtime error.

Fix: add plugin-sdk:check-exports to release:check so the CI gate
fails loudly if the exports are out of sync before publishing.

* fix(test): isolate moduleUrl hint test from process.cwd() fallback

Use externalPluginRoot as cwd instead of fixture.root, so only the
moduleUrl hint can resolve the openclaw package root. Previously,
withCwd(fixture.root) allowed the process.cwd() fallback to also
resolve the fixture root, making the moduleUrl path untested.

Spotted by greptile-apps review on #54283.

* fix(test): use empty string to disable argv1 in moduleUrl hint test

Passing undefined for argv1 in buildPluginLoaderAliasMap triggers the
STARTUP_ARGV1 default (process.argv[1], the vitest runner binary inside
the openclaw repo). resolveTrustedOpenClawRootFromArgvHint then resolves
to the real openclaw root before the moduleUrl hint is checked, making
the test resolve wrong aliases.

Pass "" instead: falsy so the hint is skipped, but does not trigger the
default parameter value. Only the moduleUrl can bridge the gap.

Made-with: Cursor

* fix(plugins): thread moduleUrl through SDK alias resolution for external plugins (#54283) Thanks @xieyongliang

---------

Co-authored-by: bojsun <bojie.sun@bytedance.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jerry <jerry@JerrydeMacBook-Air-2.local>
Co-authored-by: yongliang.xie <yongliang.xie@bytedance.com>
Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-25 09:11:17 -07:00
Devin Robison c2a2edb329
Fix local copied package installs honoring staged project .npmrc (#54543) 2026-03-25 09:59:33 -06:00
Lin Z a0b9dc0078
fix(feishu): use message create_time for inbound timestamps (#52809)
* fix(feishu): use message create_time instead of Date.now() for Timestamp field

When a message is sent offline and later retried by the Feishu client
upon reconnection, Date.now() captures the *delivery* time rather than
the *authoring* time.  This causes downstream consumers to see a
timestamp that can be minutes or hours after the user actually composed
the message, leading to incorrect temporal semantics — for example, a
"delete this" command may target the wrong resource because the agent
believes the instruction was issued much later than it actually was.

Replace every Date.now() used for message timestamps with the original
create_time from the Feishu event payload (millisecond-epoch string),
falling back to Date.now() only when the field is absent.  The
definition is also hoisted to the top of handleFeishuMessage so that
both the pending-history path and the main inbound-payload path share
the same authoritative value.

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

* test(feishu): verify Timestamp uses message create_time

Add two test cases:
1. When create_time is present, Timestamp must equal the parsed value
2. When create_time is absent, Timestamp falls back to Date.now()

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

* chore: revert unrelated formatting change to lifecycle.test.ts

This file was inadvertently formatted in a prior commit. Reverting to
match main and keep the PR scoped to the Feishu timestamp fix only.

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

* fix(feishu): use message create_time for inbound timestamps (#52809) (thanks @schumilin)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-25 08:36:12 -07:00
Lin Z bd4237c16c
fix(feishu): close WebSocket connections on monitor stop (#52844)
* fix(feishu): close WebSocket connections on monitor stop/abort

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

* test(feishu): add WebSocket cleanup tests

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

* fix(feishu): close WebSocket connections on monitor stop (#52844) (thanks @schumilin)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-25 08:32:21 -07:00
Nimrod Gutman edb5123f26
fix(sandbox): honor sandbox alsoAllow and explicit re-allows (#54492)
* fix(sandbox): honor effective sandbox alsoAllow policy

* fix(sandbox): prefer resolved sandbox context policy

* fix: honor sandbox alsoAllow policy (#54492) (thanks @ngutman)
2026-03-25 16:51:13 +02:00
Peter Steinberger e9ac2860c1
docs: prepare 2026.3.24-beta.2 release 2026-03-25 06:58:39 -07:00
Harold Hunt da60aff17a
Tests: isolate security audit home skill resolution (#54473)
Merged via squash.

Prepared head SHA: 82181e15fb
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
2026-03-25 09:43:19 -04:00
Peter Steinberger ee714f5a42
test(media): make local roots fixture windows-safe 2026-03-25 06:24:39 -07:00
Peter Steinberger ea08f2eb8c
fix(runtime): support Node 22.14 installs 2026-03-25 06:22:18 -07:00
Harold Hunt 3c3fd8c386
Discord: log rejected native command deploy failures (#54118)
Merged via squash.

Prepared head SHA: be250f9620
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
2026-03-25 09:19:46 -04:00
Peter Steinberger 436aa838fe
test(release): sync llama peer fixture 2026-03-25 06:06:47 -07:00
Peter Steinberger 284084672a
fix(ci): restore e2e docker cache boundary 2026-03-25 06:06:47 -07:00
Peter Steinberger 66c88b4c77
fix(update): preflight npm target node engine 2026-03-25 06:01:20 -07:00
Peter Steinberger c92002e1de
fix(media): align outbound media access with fs policy 2026-03-25 05:50:21 -07:00
Peter Steinberger 39ad51426c
test: add Open WebUI docker smoke 2026-03-25 05:28:51 -07:00
Peter Steinberger 9e95125f06
fix(config): ignore same-base correction publish warnings 2026-03-25 04:58:44 -07:00
Peter Steinberger b19cc399b6
test: fix clobbered config snapshot expectation 2026-03-25 04:54:37 -07:00
Peter Steinberger 3b6d980c52
refactor: unify whatsapp identity handling 2026-03-25 04:46:24 -07:00
Peter Steinberger cdba1e6771
fix: copy openclaw bin before docker install 2026-03-25 04:45:31 -07:00
Peter Steinberger d874f3970a
build: prepare 2026.3.24-beta.1 2026-03-25 04:41:26 -07:00
Peter Steinberger 7c2790cec4 test: isolate voice-call temp stores 2026-03-25 11:39:47 +00:00
Peter Steinberger c3d1dbc696
refactor(openai): extract codex auth identity helper 2026-03-25 04:24:46 -07:00
Peter Steinberger d363af8c13
refactor(auth): separate profile ids from email metadata 2026-03-25 04:24:46 -07:00
khhjoe f3fe019e3d fix(whatsapp): use async fs.promises.readFile for selfLid creds read 2026-03-25 04:24:31 -07:00
khhjoe 770a5ee5b1 fix(whatsapp): read selfLid from creds.json for reply-to-bot detection 2026-03-25 04:24:31 -07:00
khhjoe 93594a1440 fix(whatsapp): compare selfLid for reply-to-bot implicit mention in groups 2026-03-25 04:24:31 -07:00
khhjoe ff25407861 fix(whatsapp): unwrap FutureProofMessage (botInvokeMessage) to restore reply-to-bot detection 2026-03-25 04:24:31 -07:00
Peter Steinberger 52bec1612c test: collapse telegram transport and status suites 2026-03-25 11:23:18 +00:00
Peter Steinberger 12082f47bd test: collapse telegram button and access suites 2026-03-25 11:23:18 +00:00
Peter Steinberger b7f2b0d7b9
refactor: align pairing replies, daemon hints, and feishu mention policy 2026-03-25 04:22:53 -07:00
Peter Steinberger 524004ff32
docs: add missing changelog items 2026-03-25 04:22:23 -07:00
Peter Steinberger 3de04bdd6d test: collapse telegram context and transport suites 2026-03-25 11:17:58 +00:00