Commit Graph

45 Commits

Author SHA1 Message Date
Peter Steinberger 4b6cdd1d3c fix: normalize session keys and outbound mirroring 2026-01-24 11:57:11 +00:00
Peter Steinberger dbf139d14e test: cover explicit mention gating across channels 2026-01-24 11:09:33 +00:00
Peter Steinberger d905ca0e02 fix: enforce explicit mention gating across channels 2026-01-24 11:09:33 +00:00
Dave Lauer f9cf508cff feat(heartbeat): add configurable visibility for heartbeat responses
Add per-channel and per-account heartbeat visibility settings:
- showOk: hide/show HEARTBEAT_OK messages (default: false)
- showAlerts: hide/show alert messages (default: true)
- useIndicator: emit typing indicator events (default: true)

Config precedence: per-account > per-channel > channel-defaults > global

This allows silencing routine heartbeat acks while still surfacing
alerts when something needs attention.
2026-01-24 09:07:03 +00:00
Peter Steinberger 1113f17d4c refactor: share reply prefix context 2026-01-23 23:34:30 +00:00
Peter Steinberger 521ea4ae5b refactor: unify pending history helpers 2026-01-23 23:33:32 +00:00
Peter Steinberger 892197c43e refactor: reuse ack reaction helper for whatsapp 2026-01-23 22:24:31 +00:00
Peter Steinberger b77e730657 fix: add per-channel markdown table conversion (#1495) (thanks @odysseus0) 2026-01-23 18:39:25 +00:00
Echo c415ccaed5
feat(sessions): add channelIdleMinutes config for per-channel session idle durations (#1353)
* feat(sessions): add channelIdleMinutes config for per-channel session idle durations

Add new `channelIdleMinutes` config option to allow different session idle
timeouts per channel. For example, Discord sessions can now be configured
to last 7 days (10080 minutes) while other channels use shorter defaults.

Config example:
  sessions:
    channelIdleMinutes:
      discord: 10080  # 7 days

The channel-specific idle is passed as idleMinutesOverride to the existing
resolveSessionResetPolicy, integrating cleanly with the new reset policy
architecture.

* fix

* feat: add per-channel session reset overrides (#1353) (thanks @cash-echo-bot)

---------

Co-authored-by: Cash Williams <cashwilliams@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-01-21 19:10:31 +00:00
Peter Steinberger 6d5195c890 refactor: normalize cli command hints 2026-01-20 07:43:00 +00:00
Peter Steinberger 50fdd514ae refactor(logging): split config + subsystem imports 2026-01-19 00:15:44 +00:00
Peter Steinberger 690bb192e6 style: format code 2026-01-18 19:36:46 +00:00
Peter Steinberger 744d1329cb feat: make inbound envelopes configurable
Co-authored-by: Shiva Prasad <shiv19@users.noreply.github.com>
2026-01-18 18:50:37 +00:00
Peter Steinberger f86b24c511 refactor(session): centralize thread reset detection
Co-authored-by: Austin Mudd <austinm911@gmail.com>
2026-01-18 06:55:04 +00:00
Peter Steinberger 367826f6e4 feat(session): add daily reset policy
Co-authored-by: Austin Mudd <austinm911@gmail.com>
2026-01-18 06:37:37 +00:00
Peter Steinberger 82e49af5a7 fix: resolve plugin tool meta typing 2026-01-18 04:24:16 +00:00
Peter Steinberger 0d9172d761 fix: persist session origin metadata 2026-01-18 03:41:51 +00:00
Peter Steinberger 34590d2144 feat: persist session origin metadata across connectors 2026-01-18 02:42:10 +00:00
Peter Steinberger 69ba2765de refactor(security): harden CommandAuthorized plumbing 2026-01-17 10:19:34 +00:00
Peter Steinberger b6ea5895b6 fix: gate image tool and deepgram audio payload 2026-01-17 09:34:40 +00:00
Peter Steinberger 13b931c006 refactor: prune legacy group prefixes 2026-01-17 08:47:25 +00:00
Peter Steinberger 56f3a2de25 fix(security): default-deny command execution 2026-01-17 08:28:09 +00:00
Peter Steinberger 7cebe7a506 style: run oxfmt 2026-01-17 08:00:05 +00:00
Peter Steinberger 1f3a09b43b fix: persist deliveryContext on last-route updates
Co-authored-by: Adam Holt <mail@adamholt.co.nz>
2026-01-17 06:54:31 +00:00
Peter Steinberger 6a3ed5c850 fix(security): gate slash/control commands 2026-01-17 06:49:34 +00:00
Peter Steinberger e59d8c5436 style: oxfmt format 2026-01-17 05:48:56 +00:00
Peter Steinberger f7089cde54 fix: unify inbound sender labels 2026-01-17 05:21:09 +00:00
Peter Steinberger bc49c20434 fix: finalize inbound contexts 2026-01-17 05:06:39 +00:00
Peter Steinberger a2b5b1f0cb refactor: normalize inbound context 2026-01-17 04:05:33 +00:00
Peter Steinberger a82217a5f3 chore: format + regenerate protocol 2026-01-17 03:40:49 +00:00
Peter Steinberger 3af391eec7 refactor: centralize group sender identity 2026-01-17 03:32:48 +00:00
Peter Steinberger e31251293b fix: scope history injection to pending-only 2026-01-16 23:52:42 +00:00
Peter Steinberger 76d3d58b5c chore: oxfmt 2026-01-16 22:33:47 +00:00
Peter Steinberger 05d149a49b fix: treat reply-to-bot as implicit mention across channels 2026-01-16 21:51:01 +00:00
Wilkins bb14b19922
fix: truncate skill command descriptions to 100 chars for Discord (#1018)
* fix: truncate skill command descriptions to 100 chars for Discord

Discord slash commands have a 100 character limit for descriptions.
Skill descriptions were not being truncated, causing command registration
to fail with an empty error from the Discord API.

* style: format

* style: format
2026-01-16 10:01:59 -06:00
Peter Steinberger 19bcbf85df fix: scope whatsapp self-chat response prefix 2026-01-16 10:54:11 +00:00
Ubuntu ca9688b5cc feat(session): add dmScope for multi-user DM isolation
Co-authored-by: Alphonse-arianee <Alphonse-arianee@users.noreply.github.com>
2026-01-16 04:13:10 +00:00
Peter Steinberger 688a0ce439 refactor: harden session store updates
Co-authored-by: Tyler Yust <tyler6204@users.noreply.github.com>
2026-01-15 23:41:34 +00:00
juanpablodlc 4a99b9b651
feat(whatsapp): add debounceMs for batching rapid messages (#971)
* feat(whatsapp): add debounceMs for batching rapid messages

Add a `debounceMs` configuration option to WhatsApp channel settings
that batches rapid consecutive messages from the same sender into a
single response. This prevents triggering separate agent runs for
each message when a user sends multiple short messages in quick
succession (e.g., "Hey!", "how are you?", "I was wondering...").

Changes:
- Add `debounceMs` config to WhatsAppConfig and WhatsAppAccountConfig
- Implement message buffering in `monitorWebInbox` with:
  - Map-based buffer keyed by sender (DM) or chat ID (groups)
  - Debounce timer that resets on each new message
  - Message combination with newline separator
  - Single message optimization (no modification if only one message)
- Wire `debounceMs` through account resolution and monitor tuning
- Add UI hints and schema documentation

Usage example:
{
  "channels": {
    "whatsapp": {
      "debounceMs": 5000  // 5 second window
    }
  }
}

Default behavior: `debounceMs: 0` (disabled by default)

Verified: All existing tests pass (3204 tests), TypeScript compilation
succeeds with no errors.

Implemented with assistance from AI coding tools.

Closes #967

* chore: wip inbound debounce

* fix: debounce inbound messages across channels (#971) (thanks @juanpablodlc)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-01-15 23:07:19 +00:00
Peter Steinberger 8dacafce7f fix: harden whatsapp command auth 2026-01-15 07:54:39 +00:00
Christian A. Rodriguez 7a683a4b62 feat(whatsapp): add sendReadReceipts config option
Add option to disable automatic read receipts for WhatsApp messages.
When set to false, Clawdbot will not mark messages as read (blue ticks).

Closes #344

Changes:
- Add sendReadReceipts to WhatsAppConfig and WhatsAppAccountConfig types
- Add sendReadReceipts to zod schemas for validation
- Add sendReadReceipts to ResolvedWhatsAppAccount with fallback chain
- Pass sendReadReceipts through to monitorWebInbox
- Gate sock.readMessages() call based on config option

Default behavior (true) is preserved - only explicitly setting false
will disable read receipts.
2026-01-15 06:22:09 +00:00
Sebastian 113eea5047 fix: mutate prefixContext object instead of reassigning for closure correctness 2026-01-14 23:20:19 -05:00
Sebastian d0a4cce41e feat: add dynamic template variables to messages.responsePrefix (#923)
Adds support for template variables in `messages.responsePrefix` that
resolve dynamically at runtime with the actual model used (including
after fallback).

Supported variables (case-insensitive):
- {model} - short model name (e.g., "claude-opus-4-5", "gpt-4o")
- {modelFull} - full model identifier (e.g., "anthropic/claude-opus-4-5")
- {provider} - provider name (e.g., "anthropic", "openai")
- {thinkingLevel} or {think} - thinking level ("high", "low", "off")
- {identity.name} or {identityName} - agent identity name

Example: "[{model} | think:{thinkingLevel}]" → "[claude-opus-4-5 | think:high]"

Variables show the actual model used after fallback, not the intended
model. Unresolved variables remain as literal text.

Implementation:
- New module: src/auto-reply/reply/response-prefix-template.ts
- Template interpolation in normalize-reply.ts via context provider
- onModelSelected callback in agent-runner-execution.ts
- Updated all 6 provider message handlers (web, signal, discord,
  telegram, slack, imessage)
- 27 unit tests covering all variables and edge cases
- Documentation in docs/gateway/configuration.md and JSDoc

Fixes #923
2026-01-14 23:05:08 -05: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 bcbfb357be refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00