Commit Graph

34865 Commits

Author SHA1 Message Date
Jai Govindani
84571e45ce fix(discord): pass config to subagent thread binding 2026-04-24 23:55:48 +01:00
Peter Steinberger
0c46e8000e fix(plugins): cache discovery registration snapshots
Co-authored-by: junpei.o <14040213+livingghost@users.noreply.github.com>
Co-authored-by: Yoshiaki Okuyama <okuyam2y@gmail.com>
Co-authored-by: Shion Eria <shioneria@foxmail.com>
Co-authored-by: Billy Shih <1472300+bbshih@users.noreply.github.com>
2026-04-24 23:55:29 +01:00
Peter Steinberger
9eeceaca43 fix: send copilot headers during compaction 2026-04-24 23:54:58 +01:00
Devin Robison
a35c166348 fix(gateway): restart channels after secret reload (#70720)
* fix(gateway): restart channels after secret reload

* fix(gateway): serialize secrets.reload and isolate channel restart errors

Address review feedback from Greptile (P1), Codex (P2), and Aisle (Medium,
CWE-362) on #70720:

- Serialize the entire secrets.reload path through a promise tail lock so
  concurrent callers cannot overlap the stop/start loop or diff against a
  stale pre-activation snapshot.
- Wrap each channel's stop/start pair in a try/catch so one channel failing
  to restart does not leave other changed channels unrestarted.
- Register slack/zalo/discord channel plugins with reload.configPrefixes in
  the test setup so channels.<id>.* diff paths actually match a restart rule
  (without this, the diff falls through to restart-gateway and the handler
  never enters the per-channel restart branch).
- Add tests covering concurrent-reload serialization and per-channel
  restart-failure isolation.

* fix(gateway): surface channel restart failures from secrets.reload

Address review feedback on the previous commit:

- Codex P1: `secrets.reload` swallowed per-channel restart failures and
  still returned `{ ok: true }`, so a rotation that left a channel on the
  old secret looked successful to the caller. The handler now collects
  restart failures during the loop and throws an aggregate error after
  attempting every channel, so the client-side RPC response surfaces the
  partial failure while unaffected channels still restart (preserving the
  original Greptile P1 non-cascading semantic).
- Greptile P2: test mock-call assertions sorted the captured channel
  arguments so they no longer depend on `Set`/object-key iteration order,
  which is not a stable contract of the handler.

* fix(gateway): harden secrets reload followups

* docs(changelog): note secret-backed channel restart on secrets.reload

* test(gateway): align secrets reload snapshot activation

* test(gateway): reset plugin runtime state in aux handlers

* fix(gateway): refresh reload rules and roll back channels

* fix(gateway): harden secrets.reload rollback tests

* test(gateway): inject aux handler reload plan

* test(gateway): avoid resettable reload-plan mocks

* test(gateway): isolate aux handler tests from skip env-var leakage

test-helpers.mocks.ts and test-helpers.server.ts set
OPENCLAW_SKIP_CHANNELS=1 / OPENCLAW_SKIP_PROVIDERS=1 at module load. When
a shared vitest worker imports those helpers before this file's tests
run, the leaked env vars route the secrets.reload skip-mode branch and
the channel restart loop never fires. Add a beforeEach that clears both
env vars so the suite is independent of worker import order.

* fix(gateway): restore required generation on secrets.reload rollback

setCurrentSharedGatewaySessionGeneration can clear `required` as a side
effect of activating a new generation. The previous rollback path
restored only `current`, leaving `required` cleared and weakening
shared-gateway auth-generation enforcement after a failed reload (Aisle
CWE-287). Capture both fields before activation and restore both in the
catch block. Add a focused regression test that locks in the contract.

* fix(gateway): track restart channels for rollback before stopChannel awaits

Pushing to stoppedChannels only after `await stopChannel` succeeded meant
that if stopChannel rejected mid-call (for example, a plugin stopAccount
hook throws after the runtime already closed the socket), the rollback
loop skipped that channel entirely. A failed secrets.reload could then
leave the channel down. Track the channel before awaiting so rollback
always attempts to bring it back, and add a regression test.
2026-04-24 16:54:16 -06:00
Vincent Koc
2d53ad5cb6 fix(channels): harden manifest read-only metadata 2026-04-24 15:50:46 -07:00
Peter Steinberger
0c54254231 fix(discord): record gateway transport activity 2026-04-24 23:48:41 +01:00
Peter Steinberger
719d6df156 fix: align github copilot request headers 2026-04-24 23:47:43 +01:00
Peter Steinberger
304126ad79 refactor(realtime-voice): centralize consult policy helpers 2026-04-24 23:45:49 +01:00
Peter Steinberger
a7696b496a test: improve Docker aggregate scheduling 2026-04-24 23:44:02 +01:00
Peter Steinberger
99cfa50451 test(slack): cover first native stream thread target 2026-04-24 23:42:50 +01:00
Patrick Erichsen
137f5c3a8b fix(agents): repair stale bootstrap completion (#71230)
* fix(agents): repair stale bootstrap completion

* fix: reconcile stale workspace bootstrap explicitly

* fix: keep bootstrap reconciliation in workspace lifecycle
2026-04-24 15:41:11 -07:00
Vincent Koc
5d1568963b docs(changelog): backfill 2026.4.23 authors (media-image routing, codex oauth, approvals) 2026-04-24 15:39:56 -07:00
Vincent Koc
adccd0d75e docs(changelog): backfill Thanks @ on confirmed 2026.4.23 authors 2026-04-24 15:38:07 -07:00
Altay
9d3c56d236 fix: don't classify 400/422 with no body as format error (#67024)
* fix: keep no-body 400/422 failover errors out of format

* fix: keep failover changelog entry in unreleased fixes
2026-04-25 01:37:28 +03:00
Peter Steinberger
9613a0759c refactor(google-meet): tidy browser create control 2026-04-24 23:34:33 +01:00
Peter Steinberger
5c445f7842 fix(slack): suppress block streaming during previews 2026-04-24 23:34:04 +01:00
Vincent Koc
5009c588d9 docs(changelog): backfill missing authors on 2026.4.24 security, setup, browser, Meet, fallback, Telnyx, Codex, sidecar entries 2026-04-24 15:32:27 -07:00
Vincent Koc
ee3bb1f36b docs(changelog): backfill missing Thanks @ and PR links (Control UI, Google Meet, DeepSeek, Pi, Models) 2026-04-24 15:29:29 -07:00
Vincent Koc
5394efe71f feat(channels): use manifest configs for read-only discovery 2026-04-24 15:18:45 -07:00
Peter Steinberger
d4a8fdb6ce fix(discord): supervise gateway registration failures 2026-04-24 23:15:28 +01:00
Vincent Koc
4de80807b9 fix(plugins): bound tool result middleware details 2026-04-24 15:11:51 -07:00
Peter Steinberger
e2f13959d4 feat(voice-call): share realtime agent consult tool
Centralize the shared realtime agent consult tool for browser Talk, Google Meet, and Voice Call.
2026-04-24 23:11:18 +01:00
Peter Steinberger
900ba7cf33 fix(google-meet): handle browser mic prompt 2026-04-24 23:06:58 +01:00
Peter Steinberger
8a7d67f305 docs: require PR review evidence checklist 2026-04-24 23:06:31 +01:00
Peter Steinberger
535a1d699e fix(plugins): preserve interactive dedupe on cache restore 2026-04-24 23:02:21 +01:00
Gustavo Madeira Santana
2f23b84dc4 fix(changelog): remove duplicate diagnostics entry 2026-04-24 18:01:18 -04:00
Gustavo Madeira Santana
72731a37d2 Require full Matrix identity trust (#70401)
Merged via squash.

Prepared head SHA: d13a729681
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-04-24 17:58:57 -04:00
Peter Steinberger
0cce4cf8f6 refactor(slack): share stream fallback delivery bookkeeping 2026-04-24 22:55:39 +01:00
Peter Steinberger
4cca309657 docs: update changelog for PR 71242 2026-04-24 22:54:36 +01:00
RenzoMXD
bad38150cb fix(gateway): fall back to lastCallUsage on /v1/chat/completions 2026-04-24 22:54:36 +01:00
Vincent Koc
139dfd97bb fix(diagnostics-otel): export logs from diagnostic events
Export diagnostics OTEL logs through bounded diagnostic log events while keeping core log records off the public plugin diagnostic stream.\n\nIncludes security hardening for log payload redaction, bounded attributes, prototype-pollution keys, OTEL export failure reporting, and extension SDK seam usage.
2026-04-24 14:51:45 -07:00
martingarramon
150053bc86 fix(slack): route stream-fallback delivery through chunked sender (follow-up to #70370) (#71124)
* fix(slack): route stream-fallback delivery through chunked sender

deliverPendingStreamFallback was calling chat.postMessage directly for
err.pendingText, which bypasses the chunked reply path used everywhere
else. For Slack Connect cases where appendSlackStream throws
SlackStreamNotDeliveredError with a large pending buffer, the single
raw post could fail (msg_too_long) and drop the unsent tail.

Two changes:

1. deliverPendingStreamFallback now routes through deliverReplies so
   long pendingText is chunked by the normal sender and the fallback
   honors the configured replyToMode / identity.

2. The non-benign streaming-error branch in deliverWithStreaming now
   clears the session via markSlackStreamFallbackDelivered before
   falling back to deliverNormally. Without this, pendingText stays
   populated and the post-loop finalize (stopSlackStream →
   SlackStreamNotDeliveredError → fallback) re-posts the same chunk
   that deliverNormally already sent.

Addresses the three Codex P1 findings on #70370 about bypassing the
chunked sender, and the related "avoid reposting buffered text after
append fallback" P1 about duplicate delivery. Tests updated to assert
deliverReplies routing (instead of raw postMessage) and a new case
covers the non-benign-error dedup.

Follow-up to #70370.

* fix(slack): preserve pending buffered text on non-benign stream errors

Address Codex P1 on #71124: `markSlackStreamFallbackDelivered` was
clearing `pendingText` before `deliverNormally` ran, so any earlier
buffered chunk was lost. E.g. chunk A buffered in the SDK, then
appending chunk B throws a generic network error → previous fix
dropped A+B and only sent B via `deliverNormally`, silently truncating
the final reply.

Route the full buffered `pendingText` through
`deliverPendingStreamFallback` with a synthetic
`SlackStreamNotDeliveredError`, then skip `deliverNormally` entirely
(pendingText already contains this payload's text, per
`appendSlackStream` accumulating before throw). If the chunked
fallback fails, fall back to `deliverNormally` so at least the current
payload lands.

Test updated to assert the full pendingText ("first buffered\nsecond
payload") gets routed through the chunked sender, not the
chunk-B-only partial send.

* fix(slack): harden stream fallback docs and chunking test (#71124)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-04-24 22:50:18 +01:00
Peter Steinberger
b0c9810b0f fix(plugins): restore cached command registries 2026-04-24 22:49:40 +01:00
Peter Steinberger
cabdf5bbc4 fix: match codex openai websocket continuation 2026-04-24 22:47:25 +01:00
Peter Steinberger
95a2b0d799 docs(changelog): prepare 2026.4.24 notes 2026-04-24 22:41:12 +01:00
Peter Steinberger
55318df83f fix(slack): share HTTP route registry across module loads
Fixes #67955, #46245, #46246.

Co-authored-by: Axel <axel@kaleidoscope.studio>

Co-authored-by: Cesar Arevalo <cesar@cesararevalo.com>
2026-04-24 22:41:12 +01:00
pashpashpash
11804a484d Fail closed when an explicit agent harness is missing (#71265)
* Fail closed for explicit agent harness selection

* Scope explicit harness fallback opt in
2026-04-25 06:39:57 +09:00
IVY
5adf9d2619 fix(discord): prevent identify race (#68159)
Verified against Carbon 0.16.0 source:
- Client constructor calls plugin.registerClient(this) without awaiting it.
- GatewayPlugin.registerClient publishes client before its awaited metadata fetch.
- identify() silently returns when client is missing.

This patch matches Carbon's ordering in OpenClaw's subclass, avoids a second super.registerClient call if lifecycle connect already opened the socket during metadata loading, and keeps regression coverage for both ws and isConnecting cases.

Local proof:
- pnpm test extensions/discord/src/monitor/provider.proxy.test.ts extensions/discord/src/monitor/gateway-plugin.test.ts
- pnpm lint:tmp:no-raw-channel-fetch
- pnpm check:changed
- pnpm check
- pnpm test

GitHub checks green for 72547825e1.
2026-04-24 22:39:44 +01:00
Peter Steinberger
78b9890ae1 feat(google-meet): add browser create fallback 2026-04-24 22:36:22 +01:00
Peter Steinberger
8a9d02dd82 fix(voice-call): keep outbound realtime streams attached (#71266)
Fixes outbound Twilio realtime conversations so the TwiML fetch returns the realtime <Connect><Stream> path for outbound directions and the answered-call path does not overwrite it with legacy <Say> TwiML.

Local proof:
- pnpm test extensions/voice-call/src/manager.notify.test.ts extensions/voice-call/src/webhook.test.ts
- pnpm check:changed
- pnpm check
- pnpm build
- local VoiceCallWebhookServer + CallManager smoke for Direction=outbound-api

Closes #68713.
2026-04-24 22:35:26 +01:00
Vincent Koc
5b8bd6371c feat(plugins): warn on ignored setup runtime (#71253)
* feat(plugins): warn on ignored setup runtime

* fix(plugins): avoid fallback setup runtime diagnostics

* refactor(plugins): clarify setup runtime lookup
2026-04-24 14:23:19 -07:00
Peter Steinberger
6e985a421d fix(webchat): keep runtime context out of visible transcripts
Keep WebChat runtime context available to the model while persisting only the transcript-facing user prompt across gateway, CLI, queued follow-up, and embedded Pi paths.

Adds regression coverage for history sanitization, CLI transcript persistence, media-only auto-reply prompts, and embedded Pi prompt rewrite against a real SessionManager file.

Co-authored-by: 91wan <91wan@users.noreply.github.com>
2026-04-24 22:17:03 +01:00
Peter Steinberger
b20208fa4c feat(google-meet): create meeting spaces 2026-04-24 22:11:16 +01:00
Val Alexander
86f8c826e2 fix(ui): render assistant identity avatars in chat
Render assistant text avatars from IDENTITY.md consistently in the Control UI chat welcome state and transcript groups.

Also supports authenticated blob avatar URLs in grouped messages and rejects bidi/invisible controls in assistant text avatars.

Verification:
- pnpm test ui/src/ui/chat/grouped-render.test.ts ui/src/ui/views/chat.test.ts ui/src/styles/chat/layout.test.ts
- pnpm check:changed
- GitHub CI green
- Review threads resolved
2026-04-24 15:50:27 -05:00
Peter Steinberger
af46830927 test: split bundled Docker aggregate shards 2026-04-24 21:43:43 +01:00
Val Alexander
245451b6a9 fix(whatsapp): keep QR login state in sync
Keep WhatsApp QR login state synced across gateway, macOS, and UI wait flows.

- Preserve the latest QR data URL/version while login polling rotates codes.
- Keep the wait-result protocol bounded to current QR metadata.
- Stabilize QR rendering and media fixture coverage after rebasing on main.

Validation:
- pnpm test extensions/whatsapp/src/login-qr.test.ts extensions/whatsapp/src/media.test.ts extensions/whatsapp/src/agent-tools-login.test.ts src/gateway/protocol/channels.schema.test.ts src/gateway/server-methods/web.start.test.ts ui/src/ui/controllers/channels.test.ts
- pnpm test:extension whatsapp
- cd apps/macos && swift test --filter ChannelsSettingsSmokeTests
- GitHub PR checks: 62 success, 5 skipped
2026-04-24 15:37:16 -05:00
Vincent Koc
86099ec62a refactor(web-fetch): move readability extraction to plugin
* refactor(web-fetch): move readability extraction to plugin

* fix(web-fetch): cache extractor resolution by config

* fix(test): remove redundant stat assertions
2026-04-24 13:34:37 -07:00
github-actions[bot]
f102ddad0c chore(ui): refresh th control ui locale 2026-04-24 20:30:42 +00:00
github-actions[bot]
b885aa7cd3 chore(ui): refresh pl control ui locale 2026-04-24 20:30:15 +00:00
github-actions[bot]
4b1395b251 chore(ui): refresh uk control ui locale 2026-04-24 20:30:12 +00:00