Commit Graph

48 Commits

Author SHA1 Message Date
Peter Steinberger 62edfdffbd refactor: deduplicate reply payload handling 2026-03-18 18:14:57 +00:00
Peter Steinberger 7bea559166 refactor: unify reply content checks 2026-03-16 05:54:16 +00:00
Peter Steinberger 2580b81bd2
refactor: move channel capability diagnostics into plugins 2026-03-15 22:53:03 -07:00
Peter Steinberger ad97c581e2
refactor: move channel messaging hooks into plugins 2026-03-15 22:39:00 -07:00
Vincent Koc 14b7187c33 Reply: route shared interactive payloads outbound 2026-03-15 21:55:45 -07:00
Nimrod Gutman 9aac55d306
Add /btw side questions (#45444)
* feat(agent): add /btw side questions

* fix(agent): gate and log /btw reviews

* feat(btw): isolate side-question delivery

* test(reply): update route reply runtime mocks

* fix(btw): complete side-result delivery across clients

* fix(gateway): handle streamed btw side results

* fix(telegram): unblock btw side questions

* fix(reply): make external btw replies explicit

* fix(chat): keep btw side results ephemeral in internal history

* fix(btw): address remaining review feedback

* fix(chat): preserve btw history on mobile refresh

* fix(acp): keep btw replies out of prompt history

* refactor(btw): narrow side questions to live channels

* fix(btw): preserve channel typing indicators

* fix(btw): keep side questions isolated in chat

* fix(outbound): restore typed channel send deps

* fix(btw): avoid blocking replies on transcript persistence

* fix(btw): keep side questions fast

* docs(commands): document btw slash command

* docs(changelog): add btw side questions entry

* test(outbound): align session transcript mocks
2026-03-14 17:27:54 +02:00
scoootscooob 439c21e078
refactor: remove channel shim directories, point all imports to extensions (#45967)
* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers
2026-03-14 03:43:07 -07:00
Teconomix 0c926a2c5e
fix(mattermost): carry thread context to non-inbound reply paths (#44283)
Merged via squash.

Prepared head SHA: 2846a6cfa9
Co-authored-by: teconomix <6959299+teconomix@users.noreply.github.com>
Co-authored-by: mukhtharcm <56378562+mukhtharcm@users.noreply.github.com>
Reviewed-by: @mukhtharcm
2026-03-14 12:23:23 +05:30
Vincent Koc a976cc2e95
Slack: add opt-in interactive reply directives (#44607)
* Reply: add Slack interactive directive parser

* Reply: wire Slack directives into normalization

* Reply: cover Slack directive parsing

* Reply: test Slack directive normalization

* Slack: hint interactive reply directives

* Config: add Slack interactive reply capability type

* Config: validate Slack interactive reply capability

* Reply: gate Slack directives behind capability

* Slack: gate interactive reply hints by capability

* Tests: cover Slack interactive reply capability gating

* Changelog: note opt-in Slack interactive replies

* Slack: fix interactive reply review findings

* Slack: harden interactive reply routing and limits

* Slack: harden interactive reply trust and validation
2026-03-13 14:08:04 -07:00
Gustavo Madeira Santana 21e8d88c1d
build: fix ineffective dynamic imports with lazy boundaries (#33690)
Merged via squash.

Prepared head SHA: 38b3c23d6f
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 20:14:41 -05:00
Eric Lytle b5102ba4f9 fix(hooks): add isGroup and groupId to message:sent context
Adds group context fields to MessageSentHookContext so hooks can
correlate sent events with received events for the same conversation.

Previously, message:received included isGroup/groupId but message:sent
did not, forcing hooks to use mismatched identifiers (e.g. groupId vs
numeric chat ID) when tracking conversations.

Fields are derived from MsgContext in dispatch-from-config and threaded
through route-reply and deliver via the mirror parameter.

Addresses feedback from matskevich (production user, 550+ events)
reported on PR #6797.
2026-03-02 22:34:43 +00:00
Peter Steinberger a1628d89ec refactor: unify outbound session context wiring 2026-02-26 21:03:28 +01:00
Peter Steinberger 5c6b2cbc8e refactor: extract iMessage echo cache and unify suppression guards 2026-02-25 00:53:39 +00:00
Peter Steinberger 2a11c09a8d fix: harden iMessage echo dedupe and reasoning suppression (#25897) 2026-02-25 00:46:56 +00:00
Peter Steinberger b8b43175c5 style: align formatting with oxfmt 0.33 2026-02-18 01:34:35 +00:00
Peter Steinberger 31f9be126c style: run oxfmt and fix gate failures 2026-02-18 01:29:02 +00:00
cpojer d0cb8c19b2
chore: wtf. 2026-02-17 13:36:48 +09:00
Sebastian ed11e93cf2 chore(format) 2026-02-16 23:20:16 -05:00
cpojer 90ef2d6bdf
chore: Update formatting. 2026-02-17 09:18:40 +09:00
Mr. Guy e927fd1e35
fix: allow agent workspace directories in media local roots (#17136)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 7545ef1e19
Co-authored-by: MisterGuy420 <255743668+MisterGuy420@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-15 10:53:45 -05:00
mudrii 5d82c82313
feat: per-channel responsePrefix override (#9001)
* feat: per-channel responsePrefix override

Add responsePrefix field to all channel config types and Zod schemas,
enabling per-channel and per-account outbound response prefix overrides.

Resolution cascade (most specific wins):
  L1: channels.<ch>.accounts.<id>.responsePrefix
  L2: channels.<ch>.responsePrefix
  L3: (reserved for channels.defaults)
  L4: messages.responsePrefix (existing global)

Semantics:
  - undefined -> inherit from parent level
  - empty string -> explicitly no prefix (stops cascade)
  - "auto" -> derive [identity.name] from routed agent

Changes:
  - Core logic: resolveResponsePrefix() in identity.ts accepts
    optional channel/accountId and walks the cascade
  - resolveEffectiveMessagesConfig() passes channel context through
  - Types: responsePrefix added to WhatsApp, Telegram, Discord, Slack,
    Signal, iMessage, Google Chat, MS Teams, Feishu, BlueBubbles configs
  - Zod schemas: responsePrefix added for config validation
  - All channel handlers wired: telegram, discord, slack, signal,
    imessage, line, heartbeat runner, route-reply, native commands
  - 23 new tests covering backward compat, channel/account levels,
    full cascade, auto keyword, empty string stops, unknown fallthrough

Fully backward compatible - no existing config is affected.
Fixes #8857

* fix: address CI lint + review feedback

- Replace Record<string, any> with proper typed helpers (no-explicit-any)
- Add curly braces to single-line if returns (eslint curly)
- Fix JSDoc: 'Per-channel' → 'channel/account' on shared config types
- Extract getChannelConfig() helper for type-safe dynamic key access

* fix: finish responsePrefix overrides (#9001) (thanks @mudrii)

* fix: normalize prefix wiring and types (#9001) (thanks @mudrii)

---------

Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
2026-02-04 16:16:34 -05:00
cpojer f06dd8df06
chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cpojer 5ceff756e1
chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
Peter Steinberger 9a7160786a refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
Peter Steinberger 6d16a658e5 refactor: rename clawdbot to moltbot with legacy compat 2026-01-27 12:21:02 +00:00
Peter Steinberger 875b018ea1 fix: stop sending tool summaries to channels 2026-01-25 11:54:29 +00:00
Peter Steinberger d9a467fe3b feat: move TTS into core (#1559) (thanks @Glucksberg) 2026-01-24 08:00:44 +00:00
Glucksberg df09e583aa feat(telegram-tts): add auto-TTS hook and provider switching
- Integrate message_sending hook into Telegram delivery path
- Send text first, then audio as voice message after
- Add /tts_provider command to switch between OpenAI and ElevenLabs
- Implement automatic fallback when primary provider fails
- Use gpt-4o-mini-tts as default OpenAI model
- Add hook integration to route-reply.ts for other channels

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 08:00:44 +00:00
Peter Steinberger 02ca148583 fix: preserve subagent thread routing (#1241)
Thanks @gnarco.

Co-authored-by: gnarco <gnarco@users.noreply.github.com>
2026-01-20 17:22:07 +00:00
Peter Steinberger fdaeada3ec feat: mirror delivered outbound messages (#1031)
Co-authored-by: T Savo <TSavo@users.noreply.github.com>
2026-01-17 02:03:18 +00:00
Peter Steinberger 725a6b71dc feat: add matrix channel plugin 2026-01-15 08:40:37 +00:00
Peter Steinberger 2b4a68e276 feat: load channel plugins 2026-01-15 02:42:44 +00:00
Peter Steinberger c379191f80 chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
2026-01-14 15:02:19 +00:00
Peter Steinberger 90342a4f3a refactor!: rename chat providers to channels 2026-01-13 08:40:39 +00:00
Peter Steinberger 7acd26a2fc
Move provider to a plugin-architecture (#661)
* refactor: introduce provider plugin registry

* refactor: move provider CLI to plugins

* docs: add provider plugin implementation notes

* refactor: shift provider runtime logic into plugins

* refactor: add plugin defaults and summaries

* docs: update provider plugin notes

* feat(commands): add /commands slash list

* Auto-reply: tidy help message

* Auto-reply: fix status command lint

* Tests: align google shared expectations

* Auto-reply: tidy help message

* Auto-reply: fix status command lint

* refactor: move provider routing into plugins

* test: align agent routing expectations

* docs: update provider plugin notes

* refactor: route replies via provider plugins

* docs: note route-reply plugin hooks

* refactor: extend provider plugin contract

* refactor: derive provider status from plugins

* refactor: unify gateway provider control

* refactor: use plugin metadata in auto-reply

* fix: parenthesize cron target selection

* refactor: derive gateway methods from plugins

* refactor: generalize provider logout

* refactor: route provider logout through plugins

* refactor: move WhatsApp web login methods into plugin

* refactor: generalize provider log prefixes

* refactor: centralize default chat provider

* refactor: derive provider lists from registry

* refactor: move provider reload noops into plugins

* refactor: resolve web login provider via alias

* refactor: derive CLI provider options from plugins

* refactor: derive prompt provider list from plugins

* style: apply biome lint fixes

* fix: resolve provider routing edge cases

* docs: update provider plugin refactor notes

* fix(gateway): harden agent provider routing

* refactor: move provider routing into plugins

* refactor: move provider CLI to plugins

* refactor: derive provider lists from registry

* fix: restore slash command parsing

* refactor: align provider ids for schema

* refactor: unify outbound target resolution

* fix: keep outbound labels stable

* feat: add msteams to cron surfaces

* fix: clean up lint build issues

* refactor: localize chat provider alias normalization

* refactor: drive gateway provider lists from plugins

* docs: update provider plugin notes

* style: format message-provider

* fix: avoid provider registry init cycles

* style: sort message-provider imports

* fix: relax provider alias map typing

* refactor: move provider routing into plugins

* refactor: add plugin pairing/config adapters

* refactor: route pairing and provider removal via plugins

* refactor: align auto-reply provider typing

* test: stabilize telegram media mocks

* docs: update provider plugin refactor notes

* refactor: pluginize outbound targets

* refactor: pluginize provider selection

* refactor: generalize text chunk limits

* docs: update provider plugin notes

* refactor: generalize group session/config

* fix: normalize provider id for room detection

* fix: avoid provider init in system prompt

* style: formatting cleanup

* refactor: normalize agent delivery targets

* test: update outbound delivery labels

* chore: fix lint regressions

* refactor: extend provider plugin adapters

* refactor: move elevated/block streaming defaults to plugins

* refactor: defer outbound send deps to plugins

* docs: note plugin-driven streaming/elevated defaults

* refactor: centralize webchat provider constant

* refactor: add provider setup adapters

* refactor: delegate provider add config to plugins

* docs: document plugin-driven provider add

* refactor: add plugin state/binding metadata

* refactor: build agent provider status from plugins

* docs: note plugin-driven agent bindings

* refactor: centralize internal provider constant usage

* fix: normalize WhatsApp targets for groups and E.164 (#631) (thanks @imfing)

* refactor: centralize default chat provider

* refactor: centralize WhatsApp target normalization

* refactor: move provider routing into plugins

* refactor: normalize agent delivery targets

* chore: fix lint regressions

* fix: normalize WhatsApp targets for groups and E.164 (#631) (thanks @imfing)

* feat: expand provider plugin adapters

* refactor: route auto-reply via provider plugins

* fix: align WhatsApp target normalization

* fix: normalize WhatsApp targets for groups and E.164 (#631) (thanks @imfing)

* refactor: centralize WhatsApp target normalization

* feat: add /config chat config updates

* docs: add /config get alias

* feat(commands): add /commands slash list

* refactor: centralize default chat provider

* style: apply biome lint fixes

* chore: fix lint regressions

* fix: clean up whatsapp allowlist typing

* style: format config command helpers

* refactor: pluginize tool threading context

* refactor: normalize session announce targets

* docs: note new plugin threading and announce hooks

* refactor: pluginize message actions

* docs: update provider plugin actions notes

* fix: align provider action adapters

* refactor: centralize webchat checks

* style: format message provider helpers

* refactor: move provider onboarding into adapters

* docs: note onboarding provider adapters

* feat: add msteams onboarding adapter

* style: organize onboarding imports

* fix: normalize msteams allowFrom types

* feat: add plugin text chunk limits

* refactor: use plugin chunk limit fallbacks

* feat: add provider mention stripping hooks

* style: organize provider plugin type imports

* refactor: generalize health snapshots

* refactor: update macOS health snapshot handling

* docs: refresh health snapshot notes

* style: format health snapshot updates

* refactor: drive security warnings via plugins

* docs: note provider security adapter

* style: format provider security adapters

* refactor: centralize provider account defaults

* refactor: type gateway client identity constants

* chore: regen gateway protocol swift

* fix: degrade health on failed provider probe

* refactor: centralize pairing approve hint

* docs: add plugin CLI command references

* refactor: route auth and tool sends through plugins

* docs: expand provider plugin hooks

* refactor: document provider docking touchpoints

* refactor: normalize internal provider defaults

* refactor: streamline outbound delivery wiring

* refactor: make provider onboarding plugin-owned

* refactor: support provider-owned agent tools

* refactor: move telegram draft chunking into telegram module

* refactor: infer provider tool sends via extractToolSend

* fix: repair plugin onboarding imports

* refactor: de-dup outbound target normalization

* style: tidy plugin and agent imports

* refactor: data-drive provider selection line

* fix: satisfy lint after provider plugin rebase

* test: deflake gateway-cli coverage

* style: format gateway-cli coverage test

* refactor(provider-plugins): simplify provider ids

* test(pairing-cli): avoid provider-specific ternary

* style(macos): swiftformat HealthStore

* refactor(sandbox): derive provider tool denylist

* fix(sandbox): avoid plugin init in defaults

* refactor(provider-plugins): centralize provider aliases

* style(test): satisfy biome

* refactor(protocol): v3 providers.status maps

* refactor(ui): adapt to protocol v3

* refactor(macos): adapt to protocol v3

* test: update providers.status v3 fixtures

* refactor(gateway): map provider runtime snapshot

* test(gateway): update reload runtime snapshot

* refactor(whatsapp): normalize heartbeat provider id

* docs(refactor): update provider plugin notes

* style: satisfy biome after rebase

* fix: describe sandboxed elevated in prompt

* feat(gateway): add agent image attachments + live probe

* refactor: derive CLI provider options from plugins

* fix(gateway): harden agent provider routing

* fix(gateway): harden agent provider routing

* refactor: align provider ids for schema

* fix(protocol): keep agent provider string

* fix(gateway): harden agent provider routing

* fix(protocol): keep agent provider string

* refactor: normalize agent delivery targets

* refactor: support provider-owned agent tools

* refactor(config): provider-keyed elevated allowFrom

* style: satisfy biome

* fix(gateway): appease provider narrowing

* style: satisfy biome

* refactor(reply): move group intro hints into plugin

* fix(reply): avoid plugin registry init cycle

* refactor(providers): add lightweight provider dock

* refactor(gateway): use typed client id in connect

* refactor(providers): document docks and avoid init cycles

* refactor(providers): make media limit helper generic

* fix(providers): break plugin registry import cycles

* style: satisfy biome

* refactor(status-all): build providers table from plugins

* refactor(gateway): delegate web login to provider plugin

* refactor(provider): drop web alias

* refactor(provider): lazy-load monitors

* style: satisfy lint/format

* style: format status-all providers table

* style: swiftformat gateway discovery model

* test: make reload plan plugin-driven

* fix: avoid token stringification in status-all

* refactor: make provider IDs explicit in status

* feat: warn on signal/imessage provider runtime errors

* test: cover gateway provider runtime warnings in status

* fix: add runtime kind to provider status issues

* test: cover health degradation on probe failure

* fix: keep routeReply lightweight

* style: organize routeReply imports

* refactor(web): extract auth-store helpers

* refactor(whatsapp): lazy login imports

* refactor(outbound): route replies via plugin outbound

* docs: update provider plugin notes

* style: format provider status issues

* fix: make sandbox scope warning wrap-safe

* refactor: load outbound adapters from provider plugins

* docs: update provider plugin outbound notes

* style(macos): fix swiftformat lint

* docs: changelog for provider plugins

* fix(macos): satisfy swiftformat

* fix(macos): open settings via menu action

* style: format after rebase

* fix(macos): open Settings via menu action

---------

Co-authored-by: LK <luke@kyohere.com>
Co-authored-by: Luke K (pr-0f3t) <2609441+lc0rp@users.noreply.github.com>
Co-authored-by: Xin <xin@imfing.com>
2026-01-11 11:45:25 +00:00
Peter Steinberger 623d1e11f1 refactor: centralize session agent resolution 2026-01-10 01:57:54 +01:00
Peter Steinberger 2977b296e6 feat(messages): add whatsapp messagePrefix and responsePrefix auto 2026-01-09 19:29:04 +00:00
Peter Steinberger 36bdec0f2c refactor(messages): centralize per-agent prefixes 2026-01-09 16:54:54 +01:00
Peter Steinberger 66bbb723c5 fix: derive prefixes from routed identity (#578) (thanks @p6l-richard) 2026-01-09 16:39:32 +01:00
Peter Steinberger c2d185aab7 fix: normalize routed replies 2026-01-09 13:55:27 +01:00
Onur d6256a388e feat(msteams): wire up proactive messaging in routeReply for queued replies 2026-01-09 11:06:49 +01:00
Onur 1c73d45106 feat(msteams): wire agent integration for Teams messages
- Integrate dispatchReplyFromConfig() for full agent routing
- Add msteams to TextChunkProvider and OriginatingChannelType
- Add msteams case to route-reply (proactive not yet supported)
- Strip @mention HTML tags from Teams messages
- Fix session key to exclude messageid suffix
- Add typing indicator support
- Add proper logging for debugging
2026-01-09 11:05:34 +01:00
Josh Palmer cc94db458c
🤖 codex: fix block reply ordering (#503)
What: serialize block reply sends, make typing non-blocking, add timeout fallback + abort-aware routing, and add regression tests.
Why: prevent out-of-order streamed blocks while keeping final fallback on timeouts.
Tests: ./node_modules/.bin/vitest run src/auto-reply/reply.block-streaming.test.ts src/auto-reply/reply/route-reply.test.ts
Tests: corepack pnpm lint && corepack pnpm build (pass). corepack pnpm test (ran locally; failure observed during run).

Co-authored-by: Josh Palmer <joshp123@users.noreply.github.com>
2026-01-08 19:30:24 +01:00
Peter Steinberger 05b8679c8b feat: add providers CLI and multi-account onboarding 2026-01-08 01:55:59 +01:00
Peter Steinberger 17d052bcda fix: polish reply threading + tool dedupe (thanks @mneves75) (#326) 2026-01-08 00:50:47 +00:00
Peter Steinberger cb2a72f8a9 test(routing): add route-reply coverage 2026-01-07 05:07:53 +00:00
Peter Steinberger 3668388912 fix(routing): harden originating reply routing 2026-01-07 05:02:34 +00:00
Josh Lehman 9d50ebad7d feat(routing): route replies to originating channel
Implement reply routing based on OriginatingChannel/OriginatingTo fields.
This ensures replies go back to the provider where the message originated
instead of using the session's lastChannel.

Changes:
- Add OriginatingChannel/OriginatingTo fields to MsgContext (templating.ts)
- Add originatingChannel/originatingTo fields to FollowupRun (queue.ts)
- Create route-reply.ts with provider-agnostic router
- Update all providers (Telegram, Slack, Discord, Signal, iMessage)
  to pass originating channel info
- Update reply.ts to pass originating channel to followupRun
- Update followup-runner.ts to use route-reply for originating channels

This addresses the issue where messages from one provider (e.g., Slack)
would receive replies on a different provider (e.g., Telegram) because
the queue used the last active dispatcher instead of the originating one.
2026-01-07 04:51:33 +00:00