mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-16 15:43:57 -06:00
285a792aa87f0aa4e69bc7f951ee41a67e02bb67
897 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c317fd2bd7 | docs(imessage): document SSH wrapper TCC send failure (#88758) | ||
|
|
3491834d49 |
Migrate iMessage monitor state to SQLite (#88797)
* refactor: move imessage monitor state to sqlite * test: use OpenClaw temp root in iMessage state helper * test: avoid pending promise lint in chat tests * test: harden gateway ci flakes * test: align session list merge expectation |
||
|
|
090ca19c05 |
refactor: make Telegram message cache SQLite-only
Remove Telegram runtime JSON sidecar read/write fallback for the prompt-context message cache. Keep legacy sidecar parsing for doctor import into SQLite plugin state and update docs/tests to match. |
||
|
|
73bb84e4bf | fix: preserve explicit Feishu bitable gates | ||
|
|
1e08af453a |
fix(sms): add Twilio webhook diagnostics
* fix(sms): diagnose Twilio webhook setup * test(sms): satisfy diagnostic lint gates * fix(sms): redact recent probe participants * docs(sms): refresh SecretRef credential matrix * fix(sms): probe Messaging Service webhooks * fix(sms): resolve env-backed SecretRefs |
||
|
|
92b6af76d9 |
fix(reply): deliver plugin binding replies
Deliver plugin-owned bound-thread replies even when the source room is configured for `message_tool` visible replies. Normal agent final text still stays private unless the agent calls `message(action=send)`. Document the distinction in the group/channel docs and root routing policy, and keep ambient room-event plus unauthorized text-slash suppression covered by regression tests. Fixes #87721. |
||
|
|
6699e7331a |
docs: document scoped mention patterns
## Summary - Document scoped configured mention-pattern policy on the Groups page, including allow/deny mode semantics, supported conversation IDs, account-level precedence, and native-mention behavior. - Add config UI help for `mentionPatterns.mode`, `allowIn`, and `denyIn` on Discord, Matrix, Slack, Telegram, and WhatsApp. - Regenerate channel config/docs/plugin SDK metadata baselines for the new hint copy. Refs #70864. ## Verification - git diff --check - pnpm format:docs:check - pnpm docs:check-mdx - pnpm docs:check-links - pnpm config:channels:check - pnpm config:docs:check - pnpm plugin-sdk:api:check - node scripts/run-vitest.mjs src/config/schema.hints.test.ts - .agents/skills/autoreview/scripts/autoreview --mode local ## Real behavior proof Behavior addressed: Documentation and config UI metadata for scoped configured mention-pattern policy. Real environment tested: Local OpenClaw checkout on macOS. Exact steps or command run after this patch: The verification commands listed above. Evidence after fix: Docs formatting, MDX, link audit, generated config/channel/API baselines, and config hint tests passed; autoreview reported no accepted/actionable findings. Observed result after fix: The Groups page now explains how to scope `messages.groupChat.mentionPatterns` with `channels.<channel>.mentionPatterns`, and config metadata exposes field help for the supported channels. What was not tested: Live Discord, Matrix, Slack, Telegram, or WhatsApp inbound messages; this PR is documentation/config metadata only and follows the already-landed runtime behavior from #70864. |
||
|
|
75ea8b5094 | docs: clarify message-tool-only visible replies | ||
|
|
9c1adf4e51 |
feat: scope group mention patterns by channel
Provider-scoped configured regex mention patterns for Discord, Matrix, Slack, Telegram, and WhatsApp. Native platform mentions keep their existing behavior, and unsupported channels do not opt into the new regex policy path. The new policy supports per-channel allow/deny routing through mentionPatterns.mode with allowIn and denyIn so group auto-reply regexes can be limited without broad global blast radius. Refs #70864. Supersedes #87200. Thanks @patrick-slimelab. |
||
|
|
ea11b8ad3d | docs: expand SMS channel setup guide | ||
|
|
3513e8bfd9 |
feat: add Twilio SMS channel
Add a bundled SMS channel backed by Twilio inbound webhooks and outbound text delivery. Includes signed webhook validation, pairing/allowlist access, Messaging Service sender support, chunked plain-text SMS delivery, default target support, docs, config metadata, labeler updates, and focused SMS coverage. Verification: - pnpm exec tsgo -p extensions/sms/tsconfig.json --noEmit - OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-sms-land-fix2 node scripts/run-vitest.mjs extensions/sms/src/phone.test.ts extensions/sms/src/accounts.test.ts extensions/sms/src/twilio.test.ts extensions/sms/src/inbound.test.ts extensions/sms/src/gateway.test.ts extensions/sms/src/channel.test.ts extensions/sms/src/send.test.ts extensions/sms/src/webhook.test.ts --reporter=verbose - pnpm config:channels:check - pnpm plugins:inventory:check - git diff --check - .agents/skills/autoreview/scripts/autoreview --mode local - .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main |
||
|
|
0f1767a26a |
fix(telegram): support media message edits
Fixes #86161. Route Telegram media-message edits through the Telegram caption/reply-markup APIs instead of always calling `editMessageText`. Button-only edits now update reply markup, explicit captions use `editMessageCaption`, and text edits can fall back to caption edits when Telegram reports the message has no editable text. Also documents the edit behavior, adds regression coverage, tightens timer-spy cleanup for the affected agents test lane, and removes a stale loader helper from the current base that broke core typecheck. Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com> |
||
|
|
a2b2c4a76c |
refactor(msteams): persist conversation and poll stores in sqlite
Move MSTeams conversation and poll plugin-local stores to plugin-state SQLite. Legacy JSON stores import once without overwriting existing SQLite state; conversation and poll IDs are hashed for plugin-state keys; poll votes are sharded with bounded row-cap headroom and prune cleanup; MSTeams docs now describe SQLite storage. SSO and delegated token stores are unchanged. Verified with focused MSTeams tests, docs sanity, autoreview, Testbox check:changed, and green PR CI. |
||
|
|
d92b3b5cc2 |
refactor: unify OpenAI provider identity
Refactor OpenAI provider identity so OpenAI remains the canonical provider for API-key and OAuth-backed flows while legacy openai-codex state is doctor/migration-only. Keeps OpenAI Codex Responses as an API/transport class rather than a provider identity, moves auth aliases through providerAuthAliases, updates doctor repair sequencing for old auth/profile state, and refreshes tests/docs around the canonical OpenAI behavior. |
||
|
|
fbf900c746 |
refactor: move plugin state consumers to sqlite
Summary:
- add plugin-state runtime SDK subpaths backed by the existing sidecar DB
- migrate Discord model-picker preferences and Feishu dedup state to plugin-state keyed stores
- wire doctor legacy-state migration imports, including TTL preservation, for existing plugin JSON state
Verification:
- pnpm plugin-sdk:api:check
- focused plugin-state, doctor, Discord, Feishu, and package-boundary Vitest suites
- git diff --check origin/main...HEAD
- env -u OPENCLAW_TESTBOX pnpm check:changed
- autoreview --mode branch --base origin/main
- GitHub Actions PR checks green on
|
||
|
|
b620c58e65 |
fix: remove telegram-only reasoning stream copy
Remove stale Telegram-only wording from the reasoning stream acknowledgement and docs so channel-neutral behavior is reflected. Fixes #68305. Co-authored-by: Lanzhi <lizhan3@xiaomi.com> |
||
|
|
27b15a19e8 |
refactor(voice): catalog voice models through providers (#87794)
* refactor(providers): catalog voice models * feat(tts): route speech through voice models * refactor(tts): rename speaker selection fields * refactor(tts): mark default speech models * test(tts): type migrated speaker config assertions * refactor(providers): avoid catalog merge map spread * fix(tts): honor voice model fallbacks * refactor(tts): move speech core into package * chore(tts): register speech core knip workspace * fix(tts): show migrated speaker voice in status * fix(tts): satisfy speech core lint * fix(tts): preserve explicit model aliases * test(tts): narrow provider config assertion * test(doctor): allow slow commitments repair check --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> |
||
|
|
4df1fcf7b3 |
feat(discord): show commentary in progress drafts (#85200)
Adds opt-in Discord progress-draft commentary for assistant preambles while keeping commentary hidden by default and final delivery unchanged. Keeps commentary config Discord-specific, strips directive tags/NO_REPLY, and clears stale commentary rows without stopping the active draft stream. Thanks @bryanpearson. Co-authored-by: bryanpearson <bryanmpearson@gmail.com> |
||
|
|
04c2982535 |
fix(msteams): rebase TeamsSDK patterns to simplify Teams Integration (#76262)
* fix(msteams): rebase SDK migration onto current main Reapply the msteams SDK migration (originally on feat/msteams-sdk-migration) on top of upstream/main, resolving conflicts with parallel msteams work that landed upstream during our session. What got applied vs decisions made: CLEANLY APPLIED (3-way patch): - monitor.ts, monitor-handler.ts, polls.ts, reply-stream-controller.ts/.test.ts, reply-dispatcher.ts, attachments/download.ts, monitor.lifecycle.test.ts, monitor-handler/message-handler.ts, monitor-handler.types.ts, etc. - streaming-message.ts + .test.ts deletions WHOLESALE TAKE FROM ORIGINAL BRANCH (partial 3-way left broken cross-refs): - sdk.ts, sdk.test.ts, messenger.ts, feedback-reflection.ts, send-context.ts, send.test.ts KEPT UPSTREAM (deferred for separate cleanup): - extensions/msteams/package.json (still has jsonwebtoken/jwks-rsa per Peter's |
||
|
|
7c4601ec73 |
feat(slack): render progress as native task cards
Render Slack progress-mode updates as native task-card progress blocks, with bounded Slack chunk text and stable fallback behavior.
Also deep-merge Slack account streaming objects over top-level defaults while preserving legacy scalar account overrides, and keep the plugin SDK fetch runtime import path from evaluating guarded-fetch dispatcher code.
Verification:
- pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts
- pnpm lint --threads=8
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR checks green on #87748 at
|
||
|
|
bb46b79d3c |
refactor: internalize OpenClaw agent runtime (#85341)
* refactor: extract agent core package Introduce packages/agent-core as the OpenClaw-owned home for reusable agent loop, harness, session, prompt, and runtime dependency contracts. * refactor: extract shared llm runtime Move provider model registries, stream wrappers, OAuth helpers, and LLM utilities into src/llm with plugin-sdk barrels instead of depending on the old embedded runtime layout. * refactor: remove pi runtime internals Rename remaining Pi-shaped agent surfaces to OpenClaw agent runtime names, delete obsolete Pi docs and package graph checks, and add the third-party notice for incorporated code. * refactor: tighten agent session runtime Make agent-core/runtime dependencies explicit, consolidate compaction and session transcript helpers, and move model/session helpers behind OpenClaw-owned contracts. * refactor: remove static model and pi auth paths Drop static model catalogs and Pi auth bridges, move model/provider facts to manifest-owned runtime contracts, and harden internal embedded-agent utilities. * refactor: remove legacy provider compat paths * docs: remove agent parity notes * fix: skip provider wildcard metadata parsing * refactor: share session extension sdk loading * refactor: inline acpx proxy error formatter * refactor: fold edit recovery into edit tool * fix: accept extension batch separator * test: align startup provider plugin expectations * fix: restore provider-scoped release discovery * test: align static asset packaging expectations * fix: run static provider catalogs during scoped discovery * fix: add provider entry catalogs for scoped live discovery * fix: load lightweight provider catalog entries * fix: refresh provider-scoped plugin metadata * fix: keep provider catalog entries on release live path * fix: keep static manifest models in release live checks * fix: harden release model discovery * fix: reduce OpenAI live cache probe reasoning * fix: disable OpenAI cache probe reasoning * ci: extend OpenAI gateway live timeout * fix: extend live gateway model budget * fix: stabilize release validation regressions * fix: honor provider aliases in model rows * fix: stabilize release validation lanes * fix: stabilize release memory qa * ci: stabilize release validation lanes * ci: prefer ipv4 for live docker node calls * fix: restore shared tool-call stream wrapper * ci: remove legacy pi test shard alias * fix: clean up embedded agent test drift * fix: stabilize runtime alias status * fix: clean up embedded agent ci drift * fix: restore release ci invariants * fix: clean up post-rebase runtime drift * fix: restore release ci checks * fix: restore release ci after rebase * fix: remove stale pi runtime path * test: align compaction runtime expectations * test: update plugin prerelease expectations * fix: handle claude live tool approvals * fix: stabilize release validation gates * fix: finish agent runtime import * test: finish post-rebase agent runtime mocks * fix: keep codex compaction native * fix: stabilize codex app-server hook tests * test: isolate codex diagnostic active run * test: remove codex diagnostic completion race # Conflicts: # extensions/codex/src/app-server/run-attempt.test.ts * ci: fix full release manifest performance run id * refactor: narrow llm plugin sdk boundary * chore: drop generated google boundary stamps * fix: repair rebase fallout * fix: clean up rebased runtime references * fix: decode codex jwt payloads as base64url * fix: preserve shipped pi runtime alias * fix: add scoped sdk virtual modules * fix: decode llm codex oauth jwt as base64url * fix: avoid stale vertex adc negative cache * fix: harden tool arg decoding and codeql path * fix: keep vertex adc negative checks live * refactor: consolidate codex jwt and edit helpers * fix: await codex oauth node runtime imports * fix: preserve sdk tool and notice contracts * fix: preserve shipped compat config boundaries * fix: align codex oauth callback host * fix: terminate agent-core loop streams on failure * fix: keep codex oauth callback alive during fallback * ci: include session tools in critical codeql scans * fix: keep Cloudflare Anthropic provider auth header * docs: redirect legacy pi runtime pages * fix: honor bundled web provider compat discovery * fix: protect session output spill files * fix: keep legacy agent dir env blocked * fix: contain auto-discovered skill symlinks * fix: harden agent core sdk proxy surfaces * fix: restore approval reaction sdk compat * fix: keep live docker runs bounded * fix: keep codex oauth redirect host aligned * fix: resolve post-rebase agent runtime drift * fix: redact anthropic oauth parse failures * fix: preserve responses strict tool shaping * fix: repair agent runtime rebase cleanup * docs: redirect retired parity pages * fix: bound auto-discovered resources to roots * fix: repair post-rebase agent test drift * fix: preserve bundled provider allowlist migration * fix: preserve manifest-owned provider aliases * fix: declare photon image dependency * fix: keep provider headers out of proxy body * fix: preserve shipped env aliases * fix: refresh control ui i18n generated state * fix: quote read fallback paths * fix: preview edits through configured backend * test: satisfy core test typecheck * fix: preserve ZAI usage auth fallback * test: repair codex diagnostic test * fix: repair agent runtime rebase drift * test: finish embedded runner import rename * fix: repair agent runtime rebase integrations * test: align compaction oauth fallback expectations * fix: allow sdk-auth session models * fix: update doctor tool schema import * fix: preserve bedrock plugin region * fix: stream harmony-like prose immediately * ci: include session runtime in codeql shards * fix: repair latest rebase integrations * fix: honor explicit codex websocket transport * fix: keep openai-compatible credentials provider-scoped * fix: refresh sdk api baseline after rebase * fix: route cli runtime aliases through openclaw harness * test: rename stale harness mock expectation * test: rename embedded agent overflow calls * test: clean embedded auth test wording * test: use openclaw stream types in deepinfra cache test * fix: refresh sdk api baseline on latest main * fix: honor bundled discovery compat allowlists * fix: refresh sdk api baseline after latest rebase * fix: remove stale rebase imports * test: rename stale model catalog mock * test: mock renamed doctor runtime modules * fix: map canonical kimi env auth * fix: use internal model registry in bench script * fix: migrate deepinfra provider catalog entry * fix: enforce builtin tool suppression * fix: route compaction auth and proxy payloads safely * refactor: prune unused llm registry leftovers * test: update codex hooks session import * test: fix model picker ci coverage * test: align model picker auth mock types |
||
|
|
1507a9701b |
refactor: centralize inbound supplemental context
* refactor: centralize inbound supplemental context * refactor: trim supplemental finalizer typing * docs: clarify supplemental context projection * refactor: move inbound finalization into core * refactor: simplify channel inbound facts * refactor: fold supplemental media into inbound finalizer * refactor: migrate channel inbound callers to builder * docs: mark inbound finalizer compat types deprecated * refactor: wire runtime turn context builder * refactor: replace channel turn runtime API * fix: respect discord quote visibility * fix: avoid deprecated line dispatch helper * refactor: deprecate channel message SDK seams * docs: trim channel outbound SDK page * test: migrate irc inbound assertion * refactor: deprecate outbound SDK facades * refactor: deprecate channel helper SDK facades * refactor: deprecate channel streaming SDK facade * refactor: move direct dm helpers into inbound SDK * chore: mark legacy test-utils SDK alias deprecated * refactor: remove unused allow-from read helper * refactor: route remaining channel dispatch through core * refactor: enforce modern extension SDK imports * test: give slow image root tests more time * ci: support node fallback on windows * fix: add transcripts tool display metadata * refactor: trim legacy channel test seams * fix: preserve channel compat after rebase * fix: keep deprecated channel inbound aliases * fix: preserve discord thread context visibility * fix: clean final rebase conflicts * fix: preserve channel message dispatch aliases * fix: sync channel refactor after rebase * fix: sync channel refactor after latest main * fix: dedupe memory-core subagent mock * test: align clickclack inbound dispatch assertions * fix: sync plugin sdk api hash after rebase * fix: sync channel refactor after latest main * fix: sync plugin sdk api hash after rebase * fix: sync plugin sdk api hash after latest main * test: remove stale inbound context awaits |
||
|
|
08a73dbe4b |
fix(qqbot): gate fallback approval buttons (#87154)
QQBot fallback approval buttons now reuse the same slash-command authorization path as real commands, including access groups and default-account config merging.
Verification:
- node scripts/test-extension.mjs qqbot
- node --max-old-space-size=8192 --import tsx scripts/generate-plugin-sdk-api-baseline.ts --check && git diff --check
- pnpm lint --threads=8
- node scripts/run-vitest.mjs src/agents/agent-command.live-model-switch.test.ts
- GitHub PR checks for
|
||
|
|
0cfccdb0c7 |
fix(codex): keep WebChat delivery hints out of user requests
Land PR #87003 from @ragesaq with a maintainer fix for routed room events. Co-authored-by: Forge <forge@psiclawops.dev> |
||
|
|
aa117ec4de |
fix(telegram): derive DM topics from bot capability
Remove the Telegram DM thread reply policy config and use Telegram bot capability as the single source of truth for DM topic session splitting. DM messages with message_thread_id now split into thread-scoped sessions only when Telegram getMe reports has_topics_enabled for the bot. Doctor removes retired dm.threadReplies and direct.*.threadReplies keys, docs explain the upgrade behavior, and startup keeps cached bot info as a non-auth fallback when a fresh probe fails. Refs #86513. Thanks @alexph-dev. Verification: - pnpm docs:list - pnpm exec oxfmt --check --threads=1 extensions/telegram/src/channel.ts extensions/telegram/src/channel.gateway.test.ts extensions/telegram/src/doctor-contract.ts extensions/telegram/src/doctor.test.ts - git diff --check - node scripts/run-vitest.mjs extensions/telegram/src/channel.gateway.test.ts extensions/telegram/src/doctor.test.ts extensions/telegram/src/bot/helpers.test.ts extensions/telegram/src/bot-message-context.dm-threads.test.ts extensions/telegram/src/config-schema.test.ts - pnpm config:channels:check - pnpm config:docs:check - .agents/skills/autoreview/scripts/autoreview --mode local - GitHub Actions: CI 26468039803, Workflow Sanity 26468040057, OpenGrep 26468039472, Real behavior proof 26468036483, CodeQL 26468039466, CodeQL Critical Quality 26468039473 Known CI caveat: checks-windows-node-test failed before tests because Windows runner setup left Node 22.19.0 active while the job requested Node 24.x; the same setup failure is present on current main CI run 26468063947. |
||
|
|
3452382cc0 |
fix(imessage): seed direct DM history (#86706)
* fix(imessage): seed direct DM history * docs(imessage): clarify DM history override seeding --------- Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com> |
||
|
|
34d862d45d | fix(whatsapp): restore ack emoji identity fallback (#86697) | ||
|
|
0c5f622f9a | perf(discord): use libopus-wasm for voice opus | ||
|
|
321f06ad0e | fix: stabilize discord voice receive recovery | ||
|
|
719ce7f96f |
feat(signal): support reaction approvals (#85894)
* feat(signal): support reaction approvals * fix(signal): harden approval reaction bindings * fix(signal): quiet native approval prompt flow * test(prompts): refresh direct channel snapshots * fix(signal): suppress duplicate exec approval prompts * revert(reply): keep direct inbound metadata * docs: add signal approval changelog * test(prompts): restore direct channel snapshots * fix(signal): allow defaultTo approval reactions |
||
|
|
4e9dac5e00 | fix(discord): stabilize realtime wake-name feedback | ||
|
|
f00a912c25 |
fix: tighten Discord voice wake matching (#86595)
* fix: tighten Discord voice wake matching * test: avoid wildcard model runtime normalization |
||
|
|
5ae91f01fa | fix: speed up Discord voice wake consults | ||
|
|
5c7980fa11 |
feat(imessage): support thumb approval reactions (#85952)
* feat(imessage): support thumb approval reactions Mirrors openclaw#85477 (WhatsApp) for the iMessage channel. iMessage can now deliver exec/plugin approval prompts via the existing imsg/BlueBubbles transport and resolve approvals from 👍 (allow-once) / 👎 (deny) tapbacks. Allow-always remains on the manual /approve <id> allow-always fallback. What changed: - New approval surfaces under extensions/imessage/src/: approval-auth.ts, approval-resolver.ts, approval-reactions.ts, approval-handler.runtime.ts, approval-native.ts (+ tests for each). - channel.ts wires base.approvalCapability to the new iMessage capability. - send.ts appends the 👍/👎 hint to outbound /approve prompts and registers the reaction binding (keyed by accountId + chat_guid/chat_identifier/ chat_id/handle + messageId) after a successful send. - monitor/monitor-provider.ts resolves approval reactions ahead of the normal inbound decision pipeline so resolution bypasses reactionNotifications gating and runs its own actor authorization. - runtime.ts now exports getIMessageRuntime / getOptionalIMessageRuntime so approval-reactions can open a persistent keyed store for binding state across gateway restarts. What did NOT change: - Core approval surfaces in src/gateway/server-methods/* and src/infra/* remain channel-agnostic; the channels.imessage.allowFrom field already exists and is reused as the approver list for reactions. - Other channels and the manual /approve sender-authorized path are untouched. * fix(imessage): address codex review findings on thumb approvals Addresses 15 findings from the multi-angle codex review: Critical (correctness / blocking): - Register CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY in the iMessage monitor so the gateway can actually deliver native approval prompts via approval-handler.runtime.ts (it was dead code without the context lease). - DM tapback approvals never resolved because send keyed by handle while inbound preferred chat_guid. Register and look up under EVERY available conversation key (chat_guid / chat_identifier / chat_id / handle); inbound probes them all and accepts the first hit. - Reaction binding now requires the bridge's GUID string (rejecting numeric ROWIDs) so the binding key matches inbound reacted_to_guid. - Outbound regex now requires both a canonical `ID: <approvalId>` header AND a matching `/approve <id> <decision>` line, so non-approval messages that legitimately mention /approve syntax no longer get a phantom reaction binding (and can no longer resolve a colliding live approval). - Drop is_from_me reaction events so cross-device echoes of the operator's own tap cannot self-approve when their handle is in allowFrom. High (operability / cleanup): - Non-ApprovalNotFound errors now log at warn via the runtime child logger (no longer hidden behind OPENCLAW_LOG_LEVEL=debug). - In-memory binding is cleared on successful resolve so a toggle 👍→👎 (or chat.db replay) does not refire and emit a misleading 'expired approval' log line. Removed tapbacks are also owned by the shortcut and not surfaced as noisy reaction system events. - Move resolveIMessageReactionContext (and its helpers) to a slim monitor/reaction-context.ts so approval-reactions.ts no longer transitively pulls monitor/inbound-processing.ts (14+ heavy runtime modules) into the hot channel.ts entrypoint per extensions/CLAUDE.md. Medium (consistency / future-proofing): - Native runtime exec pending payload now passes agentId, ask, and sessionKey through buildExecApprovalPendingReplyPayload so the two delivery routes produce identical operator-visible prompts. - Both delivery paths now use addIMessageApprovalReactionHintToText (single insertion point after ID:) so the hint cannot be double-emitted by the native runtime path bypassing the idempotency guard. - Extract replaceApprovalIdPlaceholder into a shared approval-text.ts that escapes `$` in the replacement string so an approvalId containing `$&`/`$1`-`$9`/`$$` cannot interpolate into the outbound text. - In-memory Map now stores TTL alongside each entry and prunes expired bindings on each register so the gateway no longer accumulates an unbounded reaction-target Map. - bindPending refuses to bind when accountId is missing or the approval is already expired, with explicit error logs instead of silent no-ops. - Reject chat_id=0 as a synthetic key value (chat.db ROWIDs start at 1). - Drop dead getIMessageRuntime export — only the optional accessor is used. Documentation: - docs/channels/imessage.md gains an 'Approval reactions (👍 / 👎)' accordion documenting the reaction emoji map, allowFrom approver requirement, the /approve <id> allow-always manual fallback, and the deliberate change to /approve command authorization for users with non-empty allowFrom. - CHANGELOG.md entry added under 2026.5.24. Tests: 411 iMessage tests pass (was 406). Added explicit coverage for the DM key-mismatch fix, the regex-tightening fix, the is_from_me guard, the clear-on-success behavior, and the approval-id `$` escape. * test(imessage): match WhatsApp approval-native test coverage Backfills the nine cases from extensions/whatsapp/src/approval-native.test.ts that weren't mirrored in iMessage: - target-mode exec + plugin prompt rendering with the canonical hint - target-mode availability when no iMessage target matches - agentFilter / sessionFilter applied to native handling - account-scoped target enabled/disabled per account - shouldSuppressForwardingFallback session-origin exact-match cases - shouldSuppressForwardingFallback off when native cannot bind (locks down the targets-only forwarding path the Lobster live deploy exercised) - both-mode explicit + unscoped target suppression - group-origin tapback approvals require explicit approvers Tests: extensions/imessage/src/approval-native.test.ts 21 passed (was 11). Total iMessage approval-specific cases now 49 (was 40). * fix(imessage): preserve service-prefixed direct handles as approvers ClawSweeper P1 review finding on #85952. normalizeIMessageApproverId was calling looksLikeIMessageExplicitTargetId() to reject conversation-target prefixes, but that helper also matches the imessage:/sms:/auto: service prefixes — which are valid direct-handle forms. Any allowFrom entry like 'imessage:+15551230000' dropped to undefined, leaving approvers empty, which: - silently denied reaction resolution ('reactions require explicit approvers'), and - let text /approve fall back to implicit same-chat authorization. Fix: normalize first via normalizeIMessageHandle (strips the service prefix), then reject only chat_id:/chat_guid:/chat_identifier: conversation-target shapes that remain after normalization. Tests: - approval-auth.test.ts: assert the resolved approver list contains the normalized handle, plus the corollary that a non-matching sender is explicitly rejected (no longer masked by the implicit-same-chat fallback). Add a separate case covering chat_id/chat_guid/ chat_identifier rejection (with and without a service prefix). - approval-reactions.test.ts: reaction resolution end-to-end with a service-prefixed allowFrom entry — proves resolveIMessageApproval is called rather than silently denied. Focused suite: 48 passed (was 47). * test(imessage): satisfy strict buildPendingPayload signature in render tests CI check:test-types caught that the render.exec/render.plugin buildPendingPayload calls were passing accountId (not in the type signature). The signature is { cfg, request, target, nowMs }. Replace accountId with target on the four render-test sites so the strict test-types pass matches the SDK contract: - it('renders thumbs-only reaction hints in exec approval prompts') - it('renders thumbs-only reaction hints in plugin approval prompts ...') - it('renders target-mode exec prompts with concrete thumbs-only ...') - it('renders target-mode plugin prompts with concrete thumbs-only ...') Verified locally with pnpm check:test-types (tsgo:core:test + tsgo:extensions:test). 49 approval-specific tests still pass. * fix(imessage): probe every tapback GUID form for approval lookup ClawSweeper P1 review finding on #85952. readApprovalReactionEvent was only using reaction.targetGuid (the first/normalized form), but resolveIMessageReactionContext produces reaction.targetGuids = [normalized, raw] for both `abc-123` and `p:0/abc-123` forms. If the imsg bridge returned 'p:0/<guid>' from send() and send.ts registered the binding under that prefixed key, the inbound resolver probing only the unprefixed form would miss and the tapback would silently fall through. Fix: - Surface every GUID candidate in IMessageApprovalReactionEvent (messageIdCandidates). - maybeResolveIMessageApprovalReaction now probes each candidate in precedence order; first hit wins. - On success / ApprovalNotFoundError, clear the binding under all candidate keys so toggle/replay does not refire. Tests: extensions/imessage/src/approval-reactions.test.ts gains a 'resolves a reaction when the binding was registered under a p:0/… prefixed GUID and the tapback surfaces both forms' regression case; 22/22 reaction tests pass. Full iMessage suite: 424/424. * fix(imessage): native approval binding requires GUID, not numeric id ClawSweeper third P1 review finding on #85952. approval-handler.runtime.ts deliverPending was using result.messageId as the approval-reaction binding key, but that field can be a numeric ROWID coerced to a string ('12345') when the imsg bridge returns only message_id. Inbound tapbacks carry reacted_to_guid which is always a GUID, so a numeric-id binding can never match. Fix mirrors the send.ts forwarding-path treatment: - IMessageSendResult now exposes a separate guid?: string field, populated from the same resolveOutboundMessageGuid helper send.ts already uses for the forwarding-path binding. The generic messageId field is unchanged so reply-cache, echo-cache, and receipt-building paths still see the broadest id form. - deliverPending now binds against result.guid; when it's undefined (numeric ROWID or 'ok'/'unknown' placeholders), the function returns null instead of binding against an id the inbound tapback can't possibly match. Tests: approval-handler.runtime.test.ts gets a deliverPending GUID-only binding describe block with three regression cases (numeric ROWID refused, GUID accepted, ok/unknown placeholders refused). vi.mock isolates sendMessageIMessage so the cases run synchronously without spawning imsg. 11 tests pass across handler.runtime + send specs. --------- Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com> |
||
|
|
102555c6e0 |
Advance iMessage catchup cursor after live handling (#85475)
Fixes #85363. Thanks @TurboTheTurtle. |
||
|
|
fdfcb0795a | fix(discord): harden realtime voice wake joins | ||
|
|
17dcdead00 | fix: gate discord realtime voice by wake name (#85915) | ||
|
|
40d36b5bbc |
docs(talk): document realtime active-run control
Co-authored-by: Colin <colin@solvely.net> |
||
|
|
45fbf2d81a |
fix(channels): honor /verbose in group sessions (#85488)
* codex: honor verbose in group dispatch * codex: address group verbose review findings Record the final local review pass for the group /verbose PR. Codex review against origin/main completed clean after tightening the shared group progress gate, keeping public plugin hook types stable, preserving ACP hidden tool boundaries, and adding regressions for live verbose gating and progress-callback suppression. * codex: require explicit group verbose progress Normal group tool/progress summaries now require an explicit session verbose override instead of inherited agent verbose defaults. This addresses the PR review concern that existing verboseDefault configurations could expose group progress after upgrade. DMs and forum-topic behavior continue to use the effective verbose state, while normal groups use the live explicit session verbose state set by /verbose on|full|off. * codex: document Slack group verbose caveat * fix(channels): simplify verbose progress gating * docs(changelog): note verbose channel fix * fix(channels): preserve quiet default for group progress * fix(channels): keep verbose error policy dynamic * fix(channels): default verbose progress off everywhere * fix(channels): keep followup verbose default quiet * fix(channels): latch visible tool-error progress * fix(channels): track failed verbose progress events * fix(channels): latch delivered tool errors * fix(channels): prevent progress opt-out bypass * fix(channels): isolate followup error warning state * fix(channels): keep full verbose followup warnings * fix(channels): latch tool errors after visible progress * fix(channels): require visible followup failure progress * fix(channels): refresh followup verbose state * fix(channels): honor live verbose for error details * test(channels): expect live verbose off warning mode * fix(channels): preserve static tool error suppression semantics * fix(channels): bypass acp for colon verbose commands * fix(channels): narrow dynamic tool warning override * fix(channels): gate compaction notices on live verbose * fix(channels): suppress quiet followup compaction callbacks * fix(channels): suppress tts for hidden tool summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> |
||
|
|
5fbaf2a8a2 |
feat(whatsapp): support thumb approval reactions (#85477)
* feat(whatsapp): support emoji approval reactions * fix(whatsapp): simplify approval resolved text * fix(whatsapp): gate approvals on forwarding config * ci: ignore injected secrets helpers in oxlint * fix(whatsapp): use thumb reactions for approvals * ci: keep secret helpers linted * fix(approvals): preserve plugin turn source routes * docs(approvals): remove whatsapp exec approval field refs |
||
|
|
2c536a8626 | docs: absorb documentation PR sweep | ||
|
|
658be7f1c7 | docs: absorb small documentation PRs | ||
|
|
bb5010b89a |
docs: absorb docs sweep
Co-authored-by: Kai <kai@itskai.dev> Co-authored-by: Weihang <gwh7078@163.com> Co-authored-by: Scott Long <longstoryscott@gmail.com> Co-authored-by: moejaberr <mjaber@uoguelph.ca> Co-authored-by: huihui0822 <109355071+huihui0822@users.noreply.github.com> |
||
|
|
d012065ecf |
docs(feishu): add dynamicAgentCreation and per-user isolation docs (#82793)
Add documentation for the dynamicAgentCreation feature used to create
isolated agents per Feishu/Lark user. Covers:
- dynamicAgentCreation configuration fields (enabled, workspaceTemplate,
agentDirTemplate, maxAgents)
- Automatic agent/workspace creation flow
- Session isolation with dmScope
- Template variables ({agentId}, {userId})
- Verification steps and example deployment
Refs: feature available since OpenClaw 2026.4.25+
Co-authored-by: li <li@lideMac-mini.local>
|
||
|
|
bbbed264b6 |
docs(channels): document ackReactionScope for Slack & Telegram (DM gotcha) (#84233)
* docs(channels/slack,telegram): document ackReactionScope and its DM-excluding default The Slack and Telegram channel docs documented `ackReaction` but not `ackReactionScope`, even though the scope (defaulting to `group-mentions`) silently excludes DMs. People who set `ackReaction` and expect to see an emoji on DMs are surprised when nothing fires. This adds: - The resolution order for `ackReactionScope` (per-account → channel → `messages.ackReactionScope` → default `group-mentions`). - The full list of scope values (`all`, `direct`, `group-all`, `group-mentions`, `off`/`none`). - A Note callout flagging that the default does not react in DMs and that `messages.ackReactionScope` requires a gateway restart to take effect. - A short JSON example for the common case (`ackReactionScope: "all"`). Mirrors the structure already used in `docs/channels/matrix.md`. Found while configuring Slack DMs to show `👀` ack reactions and discovering that the docs covered the emoji but not the scope gate. AI-assisted. * fixup: scope is messages-only for Slack & Telegram (not per-account) Reviewer correctly noted that the Slack and Telegram runtimes only read `cfg.messages?.ackReactionScope` and the per-account/per-channel `ackReactionScope` keys don't exist in those schemas (only Discord and Matrix support them). Drop the misleading resolution-order bullets and document `messages.ackReactionScope` only. Verified against: - extensions/slack/src/monitor/provider.ts:243 - extensions/telegram/src/bot-core.ts:262 - src/config/types.slack.ts (no ackReactionScope in account schema) - src/config/types.telegram.ts (no ackReactionScope in account schema) Keeps the DM-default gotcha, the full enum, and the gateway-restart note, which were the original value of the PR. --------- Co-authored-by: Dr. Claw <drclaw-iq@users.noreply.github.com> |
||
|
|
1008b8213b |
fix(slack): keep approvals in app conversation threads
* fix(slack): keep plugin approvals in app conversation threads * fix(slack): preserve plugin approval routing * fix(slack): keep suppression typing aligned * fix(slack): suppress native dm approval fallback * fix(slack): suppress stored native approval fallback |
||
|
|
7f499643b2 |
enhance(slack): deliver native plugin approvals (#85062)
* fix(slack): deliver native plugin approvals * fix(slack): deliver plugin approvals with native UI * docs: defer slack plugin approval docs |
||
|
|
777a113973 |
fix(codex): await computer use elicitation bridge (#85117)
* fix(codex): bridge computer use elicitations * fix(codex): preserve computer use approval boundary * fix(codex): await app-server elicitation bridge |
||
|
|
4c6fe55d20 | fix(discord): cap component ttl at one day | ||
|
|
c17a48ccfd | docs(discord): document component ttl config |