1816 Commits

Author SHA1 Message Date
Antonio Mello
65122d2227
Merge d8f4873df414218e1cf0cdd9a48dfa7407ea43f1 into 6b4c24c2e55b5b4013277bd799525086f6a0c40f 2026-03-20 21:43:30 -07:00
Jaaneek
916f496b51
Add Grok 4.20 reasoning and non-reasoning to xAI model catalog (#50772)
Merged via squash.

Prepared head SHA: 095e645ea58b2259b25c923aeaf11bbcb2990c8f
Co-authored-by: Jaaneek <25470423+Jaaneek@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
2026-03-20 15:28:30 -04:00
Peter Steinberger
62ddc9d9e0 refactor: consolidate plugin sdk surface 2026-03-20 19:24:10 +00:00
Peter Steinberger
7b00a0620a test: stabilize gateway alias coverage 2026-03-20 19:17:44 +00:00
Antonio
d8f4873df4 fix(test): use double cast for GatewayClient in cron caller options test
ConnectParams schema type changed upstream; use 'as unknown as GatewayClient'
to safely construct the test fixture.
2026-03-20 11:23:34 -03:00
Antonio
b9c59976d3 fix(test): use async jiti import and fix control-ui client id for Node 24.13+
Node 24.13+ sealed the require property on ESM module objects, breaking
Jiti's sync CJS path when tryNative is false. Switch to async .import().
Also update GatewayClient id from "control-ui" to "openclaw-control-ui"
to match the upstream rename.
2026-03-20 10:06:46 -03:00
Antonio
62daaba64a fix(cron): do not bypass ownership check when callerSessionKey is present
When a gateway caller supplies a callerSessionKey it is explicitly
requesting session-scoped access (multi-agent / multi-user deployments).
Previously, resolveCronCallerOptions unconditionally set ownerOverride
to true whenever the client held ADMIN_SCOPE, which meant the
service-layer ownership check was a no-op for every mutation
(cron.update, cron.remove, cron.run) since those methods all require
ADMIN_SCOPE.

Now ownerOverride is only true when the client is an admin that did NOT
supply a session key — the typical local-CLI / control-UI case.  When a
session key is present the ownership check fires as intended.

Also exports resolveCronCallerOptions and adds direct unit tests
covering admin + sessionKey, admin without sessionKey, non-admin, and
null client scenarios.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:20:37 -03:00
Antonio
7f2778b2bc fix(cron): expose callerSessionKey in AJV schemas so session isolation reaches handlers
The per-caller ownership enforcement introduced for issue #35447 was
silently bypassed: all four mutation/list schemas used
additionalProperties:false but did not declare callerSessionKey, causing
AJV to strip the field before the handler could read it.  As a result
resolveCronCallerOptions always received an empty caller and fell back to
allow-all behaviour.

Fix:
- Add optional callerSessionKey (NonEmptyString) to CronListParamsSchema,
  CronUpdateParamsSchema, CronRemoveParamsSchema and CronRunParamsSchema.
- Update the four handlers in server-methods/cron.ts to read
  p.callerSessionKey instead of the previous p.sessionKey (which was
  never populated through these schemas).
- Add validator tests covering acceptance of the new field and rejection
  of empty strings across all four operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 08:20:37 -03:00
Antonio
467c2078ea fix(cron): add per-agent/session isolation for job visibility and mutations
Closes #35447

In multi-user deployments (Telegram, Slack, DingTalk) the cron service
exposed all jobs to all callers. Any session could list, remove, update,
or trigger jobs created by a different agent/session.

Changes:
- service/ops.ts: Add `CronMutationCallerOptions` type (callerAgentId,
  callerSessionKey, ownerOverride). Add `callerOwnsJob()` helper that
  matches by agentId or sessionKey and falls back to allow when no
  owner metadata is present (backward compat). Thread the caller opts
  through `listPage`, `remove`, `update`, `enqueueRun`, `run`, and the
  internal `inspectManualRunPreflight`/`prepareManualRun` helpers.
  Mutations on a job owned by a different session throw a structured
  error with code CRON_PERMISSION_DENIED.
- service.ts: Expose the new optional caller parameter on the public
  CronService methods (update, remove, run, enqueueRun).
- gateway/server-methods/cron.ts: Add `resolveCronCallerOptions()` that
  extracts the caller sessionKey from request params and sets
  ownerOverride=true when the client holds the operator.admin scope.
  Pass the resolved caller opts into cron.list, cron.update, cron.remove,
  and cron.run. Respond with PERMISSION_DENIED on CRON_PERMISSION_DENIED.
- gateway/protocol/schema/error-codes.ts: Add PERMISSION_DENIED error code.
- service.session-isolation.test.ts: 19 new tests covering listPage
  filtering, and remove/update/enqueueRun ownership enforcement including
  admin bypass (ownerOverride) and legacy job backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 08:20:37 -03:00
caesargattuso
57f1cf66ad
fix(gateway): skip seq-gap broadcast for stale post-lifecycle events (#43751)
* fix: stop stale gateway seq-gap errors (#43751) (thanks @caesargattuso)

* fix: keep agent.request run ids session-scoped

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-20 14:56:54 +05:30
Ayaan Zaidi
2afd65741c
fix: preserve talk provider and speaking state 2026-03-20 11:08:21 +05:30
Ayaan Zaidi
47e412bd0b fix(review): preserve talk directive overrides 2026-03-20 11:01:24 +05:30
Ayaan Zaidi
4a0341ed03 fix(review): address talk cleanup feedback 2026-03-20 11:01:24 +05:30
Ayaan Zaidi
4ac355babb feat(gateway): add talk speak rpc 2026-03-20 11:01:24 +05:30
Josh Avant
de9f2dc227
Gateway: harden OpenResponses file-context escaping (#50782) 2026-03-19 22:02:13 -05:00
Josh Avant
8e132aed6e
Hardening: refresh stale device pairing requests and pending metadata (#50695)
* Docs: clarify device pairing supersede behavior

* Device pairing: supersede pending requests on auth changes
2026-03-19 18:26:06 -05:00
Vincent Koc
22528af34d test(ci): trim gateway plugin harness churn 2026-03-19 12:22:41 -07:00
fuller-stack-dev
36f394c299
fix(gateway): increase WS handshake timeout from 3s to 10s (#49262)
* fix(gateway): increase WS handshake timeout from 3s to 10s

The 3-second default is too aggressive when the event loop is under load
(concurrent sessions, compaction, agent turns), causing spurious
'gateway closed (1000)' errors on CLI commands like `openclaw cron list`.

Changes:
- Increase DEFAULT_HANDSHAKE_TIMEOUT_MS from 3_000 to 10_000
- Add OPENCLAW_HANDSHAKE_TIMEOUT_MS env var for user override (no VITEST gate)
- Keep OPENCLAW_TEST_HANDSHAKE_TIMEOUT_MS as fallback for existing tests

Fixes #46892

* fix: restore VITEST guard on test env var, use || for empty-string fallback, fix formatting

* fix: cover gateway handshake timeout env override (#49262) (thanks @fuller-stack-dev)

---------

Co-authored-by: Wilfred <wilfred@Wilfreds-Mac-mini.local>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-19 22:46:40 +05:30
Gustavo Madeira Santana
34ee75b174
Matrix: restore doctor migration previews 2026-03-19 08:09:52 -04:00
Gustavo Madeira Santana
4443cc771a
Matrix: wire startup migration into doctor and gateway 2026-03-19 08:03:57 -04:00
Gustavo Madeira Santana
94693f7ff0
Matrix: rebuild plugin migration branch 2026-03-19 01:58:29 -04:00
Gustavo Madeira Santana
afa95fade0
Tests: align fixtures with current gateway and model types 2026-03-19 00:25:24 -04:00
Tak Hoffman
126839380c
Tests: fix current check failures 2026-03-18 22:58:40 -05:00
lixuankai
c86de678f3
feat(android): support android node sms.search (#48299)
* feat(android): support android node sms.search

* feat(android): support android node sms.search

* fix(android): split sms search permissions

* fix: document android sms.search landing (#48299) (thanks @lixuankai)

---------

Co-authored-by: lixuankai <lixuankai@oppo.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-19 08:52:15 +05:30
Peter Steinberger
510f4276b5 refactor: tighten sdk reply pipeline contract 2026-03-19 03:13:15 +00:00
clay-datacurve
7b61ca1b06
Session management improvements and dashboard API (#50101)
* fix: make cleanup "keep" persist subagent sessions indefinitely

* feat: expose subagent session metadata in sessions list

* fix: include status and timing in sessions_list tool

* fix: hide injected timestamp prefixes in chat ui

* feat: push session list updates over websocket

* feat: expose child subagent sessions in subagents list

* feat: add admin http endpoint to kill sessions

* Emit session.message websocket events for transcript updates

* Estimate session costs in sessions list

* Add direct session history HTTP and SSE endpoints

* Harden dashboard session events and history APIs

* Add session lifecycle gateway methods

* Add dashboard session API improvements

* Add dashboard session model and parent linkage support

* fix: tighten dashboard session API metadata

* Fix dashboard session cost metadata

* Persist accumulated session cost

* fix: stop followup queue drain cfg crash

* Fix dashboard session create and model metadata

* fix: stop guessing session model costs

* Gateway: cache OpenRouter pricing for configured models

* Gateway: add timeout session status

* Fix subagent spawn test config loading

* Gateway: preserve operator scopes without device identity

* Emit user message transcript events and deduplicate plugin warnings

* feat: emit sessions.changed lifecycle event on subagent spawn

Adds a session-lifecycle-events module (similar to transcript-events)
that emits create events when subagents are spawned. The gateway
server.impl.ts listens for these events and broadcasts sessions.changed
with reason=create to SSE subscribers, so dashboards can pick up new
subagent sessions without polling.

* Gateway: allow persistent dashboard orchestrator sessions

* fix: preserve operator scopes for token-authenticated backend clients

Backend clients (like agent-dashboard) that authenticate with a valid gateway
token but don't present a device identity were getting their scopes stripped.
The scope-clearing logic ran before checking the device identity decision,
so even when evaluateMissingDeviceIdentity returned 'allow' (because
roleCanSkipDeviceIdentity passed for token-authed operators), scopes were
already cleared.

Fix: also check decision.kind before clearing scopes, so token-authenticated
operators keep their requested scopes.

* Gateway: allow operator-token session kills

* Fix stale active subagent status after follow-up runs

* Fix dashboard image attachments in sessions send

* Fix completed session follow-up status updates

* feat: stream session tool events to operator UIs

* Add sessions.steer gateway coverage

* Persist subagent timing in session store

* Fix subagent session transcript event keys

* Fix active subagent session status in gateway

* bump session label max to 512

* Fix gateway send session reactivation

* fix: publish terminal session lifecycle state

* feat: change default session reset to effectively never

- Change DEFAULT_RESET_MODE from "daily" to "idle"
- Change DEFAULT_IDLE_MINUTES from 60 to 0 (0 = disabled/never)
- Allow idleMinutes=0 through normalization (don't clamp to 1)
- Treat idleMinutes=0 as "no idle expiry" in evaluateSessionFreshness
- Default behavior: mode "idle" + idleMinutes 0 = sessions never auto-reset
- Update test assertion for new default mode

* fix: prep session management followups (#50101) (thanks @clay-datacurve)

---------

Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
2026-03-19 12:12:30 +09:00
Vincent Koc
ef1346e503 Plugin SDK: route reply payload through public subpath 2026-03-18 12:01:15 -07:00
Peter Steinberger
62edfdffbd refactor: deduplicate reply payload handling 2026-03-18 18:14:57 +00:00
Peter Steinberger
8d73bc77fa refactor: deduplicate reply payload helpers 2026-03-18 17:30:25 +00:00
Vincent Koc
f187e8bac4 Plugin SDK: use public slack subpath 2026-03-18 09:40:57 -07:00
liyuan97
b64f4e313d
MiniMax: add M2.7 models and update default to M2.7 (#49691)
* MiniMax: add M2.7 models and update default to M2.7

- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to provider catalog and model definitions
- Update default model from MiniMax-M2.5 to MiniMax-M2.7 across onboard, portal, and provider configs
- Update isModernMiniMaxModel to recognize M2.7 prefix
- Update all test fixtures to reflect M2.7 as default

Made-with: Cursor

* MiniMax: add extension test for model definitions

* update 2.7

* feat: add MiniMax M2.7 models and update default (#49691) (thanks @liyuan97)

---------

Co-authored-by: George Zhang <georgezhangtj97@gmail.com>
2026-03-18 09:24:37 -07:00
Vignesh Natarajan
1890089f49 fix: serialize duplicate channel starts (#49583) (thanks @sudie-codes) 2026-03-18 01:57:12 -07:00
Josh Lehman
937f118d8e
Gateway: add docs hint for plugin override trust error (#49513) 2026-03-17 22:53:34 -07:00
Vincent Koc
04eb17bfab Tests: clean up trusted proxy pairing seed 2026-03-17 21:33:25 -07:00
Vincent Koc
870f260772
Gateway: cover trusted-proxy scope regression (#49372)
* Gateway: cover trusted-proxy scope regression

* Changelog: note trusted-proxy regression coverage

* Gateway: format trusted-proxy regression test
2026-03-17 19:59:01 -07:00
Peter Steinberger
ccf16cd889
fix(gateway): clear trusted-proxy control ui scopes 2026-03-17 10:07:53 -07:00
Peter Steinberger
6d9bf6de93
refactor: narrow extension public seams 2026-03-17 09:58:33 -07:00
Peter Steinberger
4b125762f6
refactor: clean extension api boundaries 2026-03-17 09:38:21 -07:00
Bob
ea15819ecf
ACP: harden startup and move configured routing behind plugin seams (#48197)
* ACPX: keep plugin-local runtime installs out of dist

* Gateway: harden ACP startup and service PATH

* ACP: reinitialize error-state configured bindings

* ACP: classify pre-turn runtime failures as session init failures

* Plugins: move configured ACP routing behind channel seams

* Telegram tests: align startup probe assertions after rebase

* Discord: harden ACP configured binding recovery

* ACP: recover Discord bindings after stale runtime exits

* ACPX: replace dead sessions during ensure

* Discord: harden ACP binding recovery

* Discord: fix review follow-ups

* ACP bindings: load channel snapshots across workspaces

* ACP bindings: cache snapshot channel plugin resolution

* Experiments: add ACP pluginification holy grail plan

* Experiments: rename ACP pluginification plan doc

* Experiments: drop old ACP pluginification doc path

* ACP: move configured bindings behind plugin services

* Experiments: update bindings capability architecture plan

* Bindings: isolate configured binding routing and targets

* Discord tests: fix runtime env helper path

* Tests: fix channel binding CI regressions

* Tests: normalize ACP workspace assertion on Windows

* Bindings: isolate configured binding registry

* Bindings: finish configured binding cleanup

* Bindings: finish generic cleanup

* Bindings: align runtime approval callbacks

* ACP: delete residual bindings barrel

* Bindings: restore legacy compatibility

* Revert "Bindings: restore legacy compatibility"

This reverts commit ac2ed68fa2426ecc874d68278c71c71ad363fcfe.

* Tests: drop ACP route legacy helper names

* Discord/ACP: fix binding regressions

---------

Co-authored-by: Onur <2453968+osolmaz@users.noreply.github.com>
2026-03-17 17:27:52 +01:00
Josh Lehman
1399ca5fcb
fix(plugins): forward plugin subagent overrides (#48277)
Merged via squash.

Prepared head SHA: ffa45893e0ea72bc21b48d0ea227253ba207eec0
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-17 07:20:27 -07:00
Peter Steinberger
e5919bc524
docs(gateway): clarify URL allowlist semantics 2026-03-17 00:03:27 -07:00
Peter Steinberger
57204b4fa9
fix(gateway): surface env override keys in exec approvals 2026-03-16 23:24:32 -07:00
Peter Steinberger
43838b1b14 refactor(device): share missing-scope helper 2026-03-17 06:24:01 +00:00
Peter Steinberger
aa2d5aaa0c
feat(plugins): add image generation capability 2026-03-16 22:58:55 -07:00
Peter Steinberger
00b57145ff
refactor: move agent runtime into agents layer 2026-03-16 22:53:16 -07:00
Peter Steinberger
9ebe38b6e3
refactor: untangle remaining plugin sdk boundaries 2026-03-16 21:16:32 -07:00
Peter Steinberger
3e010e280a
feat(plugins): add media understanding provider registration 2026-03-16 20:42:00 -07:00
Peter Steinberger
fe4368cbca fix: align thinking defaults and plugin sdk exports 2026-03-17 03:16:39 +00:00
Peter Steinberger
1ffe8fde84 fix: stabilize docker test suite 2026-03-17 03:02:03 +00:00
Peter Steinberger
662031a88e
feat(plugins): add speech provider registration 2026-03-16 18:50:09 -07:00