Commit Graph

350 Commits

Author SHA1 Message Date
Onur Solmaz a7929abad8
Discord: thread bindings idle + max-age lifecycle (#27845) (thanks @osolmaz)
* refactor discord thread bindings to idle and max-age lifecycle

* fix: migrate legacy thread binding expiry and reduce hot-path disk writes

* refactor: remove remaining thread-binding ttl legacy paths

* fix: harden thread-binding lifecycle persistence

* Discord: fix thread binding types in message/reply paths

* Infra: handle win32 unknown inode in file identity checks

* Infra: relax win32 guarded-open identity checks

* Config: migrate threadBindings ttlHours to idleHours

* Revert "Infra: relax win32 guarded-open identity checks"

This reverts commit de94126771.

* Revert "Infra: handle win32 unknown inode in file identity checks"

This reverts commit 96fc5ddfb3.

* Discord: re-read live binding state before sweep unbind

* fix: add changelog note for thread binding lifecycle update (#27845) (thanks @osolmaz)

---------

Co-authored-by: Onur Solmaz <onur@textcortex.com>
2026-02-27 10:02:39 +01:00
Peter Steinberger bce643a0bd refactor(security): enforce account-scoped pairing APIs 2026-02-26 21:57:52 +01:00
Peter Steinberger 273973d374 refactor: unify typing dispatch lifecycle and policy boundaries 2026-02-26 17:36:16 +01:00
Peter Steinberger 37a138c554 fix: harden typing lifecycle and cross-channel suppression 2026-02-26 17:01:09 +01:00
Peter Steinberger 892a9c24b0 refactor(security): centralize channel allowlist auth policy 2026-02-26 13:06:33 +01:00
Peter Steinberger 8bdda7a651 fix(security): keep DM pairing allowlists out of group auth 2026-02-26 12:58:18 +01:00
Peter Steinberger 0231cac957 feat(typing): add TTL safety-net for stuck indicators (land #27428, thanks @Crpdim)
Co-authored-by: Crpdim <crpdim@users.noreply.github.com>
2026-02-26 11:48:50 +00:00
Onur Solmaz a7d56e3554
feat: ACP thread-bound agents (#23580)
* docs: add ACP thread-bound agents plan doc

* docs: expand ACP implementation specification

* feat(acp): route ACP sessions through core dispatch and lifecycle cleanup

* feat(acp): add /acp commands and Discord spawn gate

* ACP: add acpx runtime plugin backend

* fix(subagents): defer transient lifecycle errors before announce

* Agents: harden ACP sessions_spawn and tighten spawn guidance

* Agents: require explicit ACP target for runtime spawns

* docs: expand ACP control-plane implementation plan

* ACP: harden metadata seeding and spawn guidance

* ACP: centralize runtime control-plane manager and fail-closed dispatch

* ACP: harden runtime manager and unify spawn helpers

* Commands: route ACP sessions through ACP runtime in agent command

* ACP: require persisted metadata for runtime spawns

* Sessions: preserve ACP metadata when updating entries

* Plugins: harden ACP backend registry across loaders

* ACPX: make availability probe compatible with adapters

* E2E: add manual Discord ACP plain-language smoke script

* ACPX: preserve streamed spacing across Discord delivery

* Docs: add ACP Discord streaming strategy

* ACP: harden Discord stream buffering for thread replies

* ACP: reuse shared block reply pipeline for projector

* ACP: unify streaming config and adopt coalesceIdleMs

* Docs: add temporary ACP production hardening plan

* Docs: trim temporary ACP hardening plan goals

* Docs: gate ACP thread controls by backend capabilities

* ACP: add capability-gated runtime controls and /acp operator commands

* Docs: remove temporary ACP hardening plan

* ACP: fix spawn target validation and close cache cleanup

* ACP: harden runtime dispatch and recovery paths

* ACP: split ACP command/runtime internals and centralize policy

* ACP: harden runtime lifecycle, validation, and observability

* ACP: surface runtime and backend session IDs in thread bindings

* docs: add temp plan for binding-service migration

* ACP: migrate thread binding flows to SessionBindingService

* ACP: address review feedback and preserve prompt wording

* ACPX plugin: pin runtime dependency and prefer bundled CLI

* Discord: complete binding-service migration cleanup and restore ACP plan

* Docs: add standalone ACP agents guide

* ACP: route harness intents to thread-bound ACP sessions

* ACP: fix spawn thread routing and queue-owner stall

* ACP: harden startup reconciliation and command bypass handling

* ACP: fix dispatch bypass type narrowing

* ACP: align runtime metadata to agentSessionId

* ACP: normalize session identifier handling and labels

* ACP: mark thread banner session ids provisional until first reply

* ACP: stabilize session identity mapping and startup reconciliation

* ACP: add resolved session-id notices and cwd in thread intros

* Discord: prefix thread meta notices consistently

* Discord: unify ACP/thread meta notices with gear prefix

* Discord: split thread persona naming from meta formatting

* Extensions: bump acpx plugin dependency to 0.1.9

* Agents: gate ACP prompt guidance behind acp.enabled

* Docs: remove temp experiment plan docs

* Docs: scope streaming plan to holy grail refactor

* Docs: refactor ACP agents guide for human-first flow

* Docs/Skill: add ACP feature-flag guidance and direct acpx telephone-game flow

* Docs/Skill: add OpenCode and Pi to ACP harness lists

* Docs/Skill: align ACP harness list with current acpx registry

* Dev/Test: move ACP plain-language smoke script and mark as keep

* Docs/Skill: reorder ACP harness lists with Pi first

* ACP: split control-plane manager into core/types/utils modules

* Docs: refresh ACP thread-bound agents plan

* ACP: extract dispatch lane and split manager domains

* ACP: centralize binding context and remove reverse deps

* Infra: unify system message formatting

* ACP: centralize error boundaries and session id rendering

* ACP: enforce init concurrency cap and strict meta clear

* Tests: fix ACP dispatch binding mock typing

* Tests: fix Discord thread-binding mock drift and ACP request id

* ACP: gate slash bypass and persist cleared overrides

* ACPX: await pre-abort cancel before runTurn return

* Extension: pin acpx runtime dependency to 0.1.11

* Docs: add pinned acpx install strategy for ACP extension

* Extensions/acpx: enforce strict local pinned startup

* Extensions/acpx: tighten acp-router install guidance

* ACPX: retry runtime test temp-dir cleanup

* Extensions/acpx: require proactive ACPX repair for thread spawns

* Extensions/acpx: require restart offer after acpx reinstall

* extensions/acpx: remove workspace protocol devDependency

* extensions/acpx: bump pinned acpx to 0.1.13

* extensions/acpx: sync lockfile after dependency bump

* ACPX: make runtime spawn Windows-safe

* fix: align doctor-config-flow repair tests with default-account migration (#23580) (thanks @osolmaz)
2026-02-26 11:00:09 +01:00
Gustavo Madeira Santana dfa0b5b4fc
Channels: move single-account config into accounts.default (#27334)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771808
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-26 04:06:03 -05:00
Gustavo Madeira Santana 96c7702526
Agents: add account-scoped bind and routing commands (#27195)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: ad35a458a5
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-26 02:36:56 -05:00
Gustavo Madeira Santana f08fe02a1b
Onboarding: support plugin-owned interactive channel flows (#27191)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 53872cf8e7
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-26 01:14:57 -05:00
Ubuntu a182afcf97 style: expand curly braces per oxfmt 2026-02-25 14:49:21 +02:00
Ubuntu ae658aa84c style: add curly braces to satisfy eslint(curly) 2026-02-25 14:49:21 +02:00
Ubuntu 97eb5542e8 fix(typing): guard fireStart against post-close invocation
The existing `closed` flag in `createTypingCallbacks` guards
`onReplyStart` but not `fireStart` itself. If a keepalive tick is
already in-flight when `fireStop` sets `closed = true` and calls
`keepaliveLoop.stop()`, the running `onTick → fireStart` callback
still completes and sends a stale `sendChatAction('typing')` after
the reply message has been delivered.

On Telegram (which has no cancel-typing API), this causes the typing
indicator to linger ~5 seconds after the bot's message appears.

Add a `closed` early-return in `fireStart` as defense-in-depth so
that even an in-flight tick is suppressed once cleanup has started.
2026-02-25 14:49:21 +02:00
Nimrod Gutman a0fa283839 fix(discord): prevent stuck typing indicator 2026-02-25 10:21:52 +02:00
Peter Steinberger d42ef2ac62 refactor: consolidate typing lifecycle and queue policy 2026-02-25 02:16:03 +00:00
Peter Steinberger e0201c2774 fix: keep channel typing active during long inference (#25886, thanks @stakeswky)
Co-authored-by: stakeswky <stakeswky@users.noreply.github.com>
2026-02-25 02:03:27 +00:00
Peter Steinberger 7a42558a3e fix: harden legacy plugin schema compatibility tests (#24933) (thanks @pandego) 2026-02-24 03:50:53 +00:00
pandego 9f4764cd41 fix(plugins): guard legacy zod schemas without toJSONSchema 2026-02-24 03:50:53 +00:00
Peter Steinberger f97c0922e1 fix(security): harden account-key handling against prototype pollution 2026-02-24 01:09:31 +00:00
Peter Steinberger cfa44ea6b4
fix(security): make allowFrom id-only by default with dangerous name opt-in (#24907)
* fix(channels): default allowFrom to id-only; add dangerous name opt-in

* docs(security): align channel allowFrom docs with id-only default
2026-02-24 01:01:51 +00:00
Peter Steinberger 0183610db3 refactor: de-duplicate channel runtime and payload helpers 2026-02-23 21:25:28 +00:00
LI SHANXIN c1b75ab8e2
fix(telegram): make reaction handling soft-fail and message-id resilient (#20236)
* Telegram: soft-fail reactions and fallback to inbound message id

* Telegram: soft-fail missing reaction message id

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-02-23 10:25:14 -05:00
Vignesh Natarajan 9ea740afb6 Sessions: canonicalize mixed-case session keys 2026-02-22 23:27:08 -08:00
Ayaan Zaidi d5105ca456 fix(telegram): unify topic target normalization path 2026-02-23 11:45:18 +05:30
Ayaan Zaidi fddc60d174 fix(telegram): preserve legacy prefixed messaging targets 2026-02-23 11:45:18 +05:30
Ayaan Zaidi dcc52850c3 fix: persist resolved telegram delivery targets at runtime 2026-02-23 11:45:18 +05:30
Peter Steinberger 7bbd597383 fix(media): enforce agent media roots in plugin send actions
Co-authored-by: Oliver Drobnik <333270+odrobnik@users.noreply.github.com>
Co-authored-by: thisischappy <257418353+thisischappy@users.noreply.github.com>
2026-02-22 22:24:27 +01:00
Tak Hoffman f8171ffcdc
Config UI: tag filters and complete schema help/labels coverage (#23796)
* Config UI: add tag filters and complete schema help/labels

* Config UI: finalize tags/help polish and unblock test suite

* Protocol: regenerate Swift gateway models
2026-02-22 15:17:07 -06:00
Peter Steinberger 5547a2275c fix(security): harden toolsBySender sender-key matching 2026-02-22 21:04:37 +01:00
Peter Steinberger 53ed7a0f5c test: dedupe repeated test fixtures and assertions 2026-02-22 18:37:25 +00:00
Vincent Koc 89a1e99815
fix(slack): finalize replyToMode off threading behavior (#23799)
* fix: make replyToMode 'off' actually prevent threading in Slack

Three independent bugs caused Slack replies to always create threads
even when replyToMode was set to 'off':

1. Typing indicator created threads via statusThreadTs fallback (#16868)
   - resolveSlackThreadTargets fell back to messageTs for statusThreadTs
   - 'is typing...' was posted as thread reply, creating a thread
   - Fix: remove messageTs fallback, let statusThreadTs be undefined

2. [[reply_to_current]] tags bypassed replyToMode entirely (#16080)
   - Slack dock had allowExplicitReplyTagsWhenOff: true
   - Reply tags from system prompt always threaded regardless of config
   - Fix: set allowExplicitReplyTagsWhenOff to false for Slack

3. Contradictory replyToMode defaults in codebase (#20827)
   - monitor/provider.ts defaulted to 'all'
   - accounts.ts defaulted to 'off' (matching docs)
   - Fix: align provider.ts default to 'off' per documentation

Fixes: openclaw/openclaw#16868, openclaw/openclaw#16080, openclaw/openclaw#20827

* fix(slack): respect replyToMode in DMs even with typing indicator thread

When replyToMode is 'off' in DMs, replies should stay in the main
conversation even when the typing indicator creates a thread context.

Previously, when incomingThreadTs was set (from the typing indicator's
thread), replyToMode was forced to 'all', causing all replies to go
into the thread.

Now, for direct messages, the user's configured replyToMode is always
respected. For channels/groups, the existing behavior is preserved
(stay in thread if already in one).

This fix:
- Keeps the typing indicator working (statusThreadTs fallback preserved)
- Prevents DM replies from being forced into threads
- Maintains channel thread continuity

Fixes #16868

* refactor(slack): eliminate redundant resolveSlackThreadContext call

- Add isThreadReply to resolveSlackThreadTargets return value
- Remove duplicate call in dispatch.ts
- Addresses greptile review feedback with cleaner DRY approach

* docs(slack): add JSDoc to resolveSlackThreadTargets

Document return values including isThreadReply distinction between
genuine user thread replies vs bot status message thread context.

* docs(changelog): record Slack replyToMode off threading fixes

---------

Co-authored-by: James <jamesrp13@gmail.com>
Co-authored-by: theoseo <suhong.seo@gmail.com>
2026-02-22 13:27:50 -05:00
Peter Steinberger 66f814a0af refactor(channels): dedupe plugin routing and channel helpers 2026-02-22 14:08:51 +00:00
Peter Steinberger 32a1273d82 refactor(onboarding): dedupe channel allowlist flows 2026-02-22 11:29:31 +00:00
Peter Steinberger 1cd3b30907 fix: stop hardcoded channel fallback and auto-pick sole configured channel (#23357) (thanks @lbo728)
Co-authored-by: lbo728 <extreme0728@gmail.com>
2026-02-22 11:21:43 +01:00
Peter Steinberger 0c1a52307c fix: align draft/outbound typings and tests 2026-02-22 08:03:29 +00:00
Peter Steinberger e16e7be85b test(core): trim redundant mock resets in heartbeat suites 2026-02-22 08:01:16 +00:00
Peter Steinberger 75c1bfbae8 refactor(channels): dedupe message routing and telegram helpers 2026-02-22 07:44:57 +00:00
Peter Steinberger ad1c07e7c0 refactor: eliminate remaining duplicate blocks across draft streams and tests 2026-02-22 07:44:57 +00:00
Peter Steinberger f37a09a9e6 test(discord): use lightweight clears in outbound plugin setup 2026-02-22 07:35:55 +00:00
Pierre 4f700e96af
Fix Telegram DM last-route metadata leakage (#19491)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 16b025b3aa
Co-authored-by: guirguispierre <22091706+guirguispierre@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
2026-02-22 11:29:59 +05:30
Peter Steinberger 01ec832f78 test(actions): table-drive telegram and signal mappings 2026-02-21 23:28:06 +00:00
Peter Steinberger 884c6afc26 test(telegram): table-drive channel override and id helper cases 2026-02-21 23:28:06 +00:00
Peter Steinberger 8cdb184f10 test(actions): table-drive discord forwarding cases 2026-02-21 23:28:06 +00:00
Peter Steinberger 843a037532 fix(test): repair readonly case table typing 2026-02-22 00:10:07 +01:00
Peter Steinberger 5164822cd5 test: table-drive status reactions and session key cases 2026-02-21 23:02:44 +00:00
Peter Steinberger 4a2ff03f49 test: dedupe channel/web cases and tighten gateway e2e waits 2026-02-21 23:02:44 +00:00
Peter Steinberger c708a18b0f test: table-drive utils and channel-match cases 2026-02-21 23:02:44 +00:00
Peter Steinberger 0bd9f0d4ac
fix: enforce strict allowlist across pairing stores (#23017) 2026-02-22 00:00:23 +01:00
Peter Steinberger 58254b3b57 test: dedupe channel and transport adapters 2026-02-21 21:44:01 +00:00