ACP: add persistent Discord channel and Telegram topic bindings (#34873)

* docs: add ACP persistent binding experiment plan

* docs: align ACP persistent binding spec to channel-local config

* docs: scope Telegram ACP bindings to forum topics only

* docs: lock bound /new and /reset behavior to in-place ACP reset

* ACP: add persistent discord/telegram conversation bindings

* ACP: fix persistent binding reuse and discord thread parent context

* docs: document channel-specific persistent ACP bindings

* ACP: split persistent bindings and share conversation id helpers

* ACP: defer configured binding init until preflight passes

* ACP: fix discord thread parent fallback and explicit disable inheritance

* ACP: keep bound /new and /reset in-place

* ACP: honor configured bindings in native command flows

* ACP: avoid configured fallback after runtime bind failure

* docs: refine ACP bindings experiment config examples

* acp: cut over to typed top-level persistent bindings

* ACP bindings: harden reset recovery and native command auth

* Docs: add ACP bound command auth proposal

* Tests: normalize i18n registry zh-CN assertion encoding

* ACP bindings: address review findings for reset and fallback routing

* ACP reset: gate hooks on success and preserve /new arguments

* ACP bindings: fix auth and binding-priority review findings

* Telegram ACP: gate ensure on auth and accepted messages

* ACP bindings: fix session-key precedence and unavailable handling

* ACP reset/native commands: honor fallback targets and abort on bootstrap failure

* Config schema: validate ACP binding channel and Telegram topic IDs

* Discord ACP: apply configured DM bindings to native commands

* ACP reset tails: dispatch through ACP after command handling

* ACP tails/native reset auth: fix target dispatch and restore full auth

* ACP reset detection: fallback to active ACP keys for DM contexts

* Tests: type runTurn mock input in ACP dispatch test

* ACP: dedup binding route bootstrap and reset target resolution

* reply: align ACP reset hooks with bound session key

* docs: replace personal discord ids with placeholders

* fix: add changelog entry for ACP persistent bindings (#34873) (thanks @dutifulbob)

---------

Co-authored-by: Onur <2453968+osolmaz@users.noreply.github.com>
This commit is contained in:
Bob
2026-03-05 09:38:12 +01:00
committed by GitHub
parent 2c8ee593b9
commit 6a705a37f2
50 changed files with 4830 additions and 186 deletions

View File

@@ -204,6 +204,20 @@ export const FIELD_HELP: Record<string, string> = {
"Shared default settings inherited by agents unless overridden per entry in agents.list. Use defaults to enforce consistent baseline behavior and reduce duplicated per-agent configuration.",
"agents.list":
"Explicit list of configured agents with IDs and optional overrides for model, tools, identity, and workspace. Keep IDs stable over time so bindings, approvals, and session routing remain deterministic.",
"agents.list[].runtime":
"Optional runtime descriptor for this agent. Use embedded for default OpenClaw execution or acp for external ACP harness defaults.",
"agents.list[].runtime.type":
'Runtime type for this agent: "embedded" (default OpenClaw runtime) or "acp" (ACP harness defaults).',
"agents.list[].runtime.acp":
"ACP runtime defaults for this agent when runtime.type=acp. Binding-level ACP overrides still take precedence per conversation.",
"agents.list[].runtime.acp.agent":
"Optional ACP harness agent id to use for this OpenClaw agent (for example codex, claude).",
"agents.list[].runtime.acp.backend":
"Optional ACP backend override for this agent's ACP sessions (falls back to global acp.backend).",
"agents.list[].runtime.acp.mode":
"Optional ACP session mode default for this agent (persistent or oneshot).",
"agents.list[].runtime.acp.cwd":
"Optional default working directory for this agent's ACP sessions.",
"agents.list[].identity.avatar":
"Avatar image path (relative to the agent workspace only) or a remote URL/data URL.",
"agents.defaults.heartbeat.suppressToolErrorWarnings":
@@ -397,7 +411,9 @@ export const FIELD_HELP: Record<string, string> = {
"audio.transcription.timeoutSeconds":
"Maximum time allowed for the transcription command to finish before it is aborted. Increase this for longer recordings, and keep it tight in latency-sensitive deployments.",
bindings:
"Static routing bindings that pin inbound conversations to specific agent IDs by match rules. Use bindings for deterministic ownership when dynamic routing should not decide.",
"Top-level binding rules for routing and persistent ACP conversation ownership. Use type=route for normal routing and type=acp for persistent ACP harness bindings.",
"bindings[].type":
'Binding kind. Use "route" (or omit for legacy route entries) for normal routing, and "acp" for persistent ACP conversation bindings.',
"bindings[].agentId":
"Target agent ID that receives traffic when the corresponding binding match rule is satisfied. Use valid configured agent IDs only so routing does not fail at runtime.",
"bindings[].match":
@@ -418,6 +434,14 @@ export const FIELD_HELP: Record<string, string> = {
"Optional team/workspace ID constraint used by providers that scope chats under teams. Add this when you need bindings isolated to one workspace context.",
"bindings[].match.roles":
"Optional role-based filter list used by providers that attach roles to chat context. Use this to route privileged or operational role traffic to specialized agents.",
"bindings[].acp":
"Optional per-binding ACP overrides for bindings[].type=acp. This layer overrides agents.list[].runtime.acp defaults for the matched conversation.",
"bindings[].acp.mode": "ACP session mode override for this binding (persistent or oneshot).",
"bindings[].acp.label":
"Human-friendly label for ACP status/diagnostics in this bound conversation.",
"bindings[].acp.cwd": "Working directory override for ACP sessions created from this binding.",
"bindings[].acp.backend":
"ACP backend override for this binding (falls back to agent runtime ACP backend, then global acp.backend).",
broadcast:
"Broadcast routing map for sending the same outbound message to multiple peer IDs per source conversation. Keep this minimal and audited because one source can fan out to many destinations.",
"broadcast.strategy":