diff --git a/README.md b/README.md index 45a20abff..887ee0c5d 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,7 @@ picoclaw gateway **4. Telegram command menu (auto-registered at startup)** PicoClaw now keeps command definitions in one shared registry. On startup, Telegram will automatically register supported bot commands (for example `/start`, `/help`, `/new`, `/session`, `/show`, `/list`) so command menu and runtime behavior stay in sync. +Telegram command menu registration remains channel-local discovery UX; generic command execution is handled centrally in the agent loop via the commands executor. If command registration fails (network/API transient errors), the channel still starts and PicoClaw retries registration in the background. @@ -663,6 +664,13 @@ Use `session.dm_scope` to control DM session isolation and `session.backlog_limi `/new` (or `/reset`) starts a fresh active session for the current scope. `/session list` and `/session resume ` operate within that same scope. +### Unified Command Execution Policy + +- Generic slash commands are executed through a single path in `pkg/agent/loop.go` via `commands.Executor`. +- Channel adapters no longer consume generic commands locally; they forward inbound text to the bus/agent path. Telegram still auto-registers supported commands at startup. +- Unknown slash command (for example `/foo`) passes through to normal LLM processing. +- Registered but unsupported command on the current channel (for example `/show` on WhatsApp) returns an explicit user-facing error and stops further processing. + ### 🔒 Security Sandbox PicoClaw runs in a sandboxed environment by default. The agent can only access files and execute commands within the configured workspace. diff --git a/README.zh.md b/README.zh.md index 63189837e..5a28e1891 100644 --- a/README.zh.md +++ b/README.zh.md @@ -308,6 +308,7 @@ PicoClaw 支持多种聊天平台,使您的 Agent 能够连接到任何地方 ### Telegram 命令注册(启动时自动同步) PicoClaw 现在使用统一的命令定义来源。启动时会自动将 Telegram 支持的命令(例如 `/start`、`/help`、`/new`、`/session`、`/show`、`/list`)注册到 Bot 命令菜单,确保菜单展示与实际行为一致。 +Telegram 侧保留的是命令菜单注册能力;通用命令的实际执行统一走 Agent Loop 中的 commands executor。 如果注册因网络或 API 短暂异常失败,不会阻塞 channel 启动;系统会在后台自动重试。 @@ -356,6 +357,13 @@ PicoClaw 将数据存储在您配置的工作区中(默认:`~/.picoclaw/work `/new`(或 `/reset`)会在当前作用域创建新会话;`/session list` 和 `/session resume ` 只在当前作用域内生效。 +### 统一命令执行策略 + +- 通用斜杠命令通过 `pkg/agent/loop.go` 中的 `commands.Executor` 统一执行。 +- Channel 适配器不再在本地消费通用命令;它们只负责把入站文本转发到 bus/agent 路径。Telegram 仍会在启动时自动注册其支持的命令菜单。 +- 未注册的斜杠命令(例如 `/foo`)会透传给 LLM 按普通输入处理。 +- 已注册但当前 channel 不支持的命令(例如 WhatsApp 上的 `/show`)会返回明确的用户可见错误,并停止后续处理。 + ### 心跳 / 周期性任务 (Heartbeat) PicoClaw 可以自动执行周期性任务。在工作区创建 `HEARTBEAT.md` 文件: diff --git a/docs/plans/2026-03-01-command-centralization-design.md b/docs/plans/2026-03-01-command-centralization-design.md index a04b9d735..64a725362 100644 --- a/docs/plans/2026-03-01-command-centralization-design.md +++ b/docs/plans/2026-03-01-command-centralization-design.md @@ -2,16 +2,18 @@ ## Background -Current command behavior is split across two execution paths: +This centralization is now implemented for generic slash commands. -- `pkg/commands` owns command definitions and dispatcher matching. -- `pkg/agent/loop.go` still executes command business logic through a hardcoded `handleCommand` switch. +- `pkg/commands` owns command definitions, channel support metadata, parser behavior, and handlers. +- `pkg/agent/loop.go` invokes `commands.Executor` for generic slash command execution before LLM flow. +- Channel adapters forward inbound text to the bus/agent path and do not consume generic commands locally. +- Telegram command menu registration still exists and is sourced from command definitions. -This creates drift between "registered commands" and "actually executable commands", especially when channel filtering is defined in `pkg/commands` but bypassed by `AgentLoop` fallback handling. +This document captures the resulting runtime policy and architecture. ## Goals -- Make generic commands (`/start`, `/help`, `/new`, `/session`, `/show`, `/list`) consistently available across channels. +- Make generic command execution policy consistent across channels while keeping per-command channel support explicit in command definitions. - Centralize command definition and execution in one domain (`pkg/commands`). - Keep architecture extensible and easy to reason about: channel adapters do transport, agent does orchestration, commands do command policy + execution. @@ -26,7 +28,7 @@ This creates drift between "registered commands" and "actually executable comman - Unknown slash command (e.g. `/foo`) must pass through to LLM as normal user input. - Registered command that is unsupported on current channel must return explicit user-facing error and stop further processing. -## Root Cause Summary +## Historical Root Cause Summary (Before Centralization) The mismatch comes from mixed responsibilities: @@ -38,7 +40,7 @@ Result: command registry is not authoritative for behavior. ## Design Decision -Adopt **Agent-central execution with Commands-domain authority**: +Adopted **Agent-central execution with Commands-domain authority**: - `pkg/commands` is the only source of command metadata, support scope, parser behavior, and handler execution. - `AgentLoop` becomes an orchestrator that invokes `commands.Executor` before LLM execution. @@ -117,7 +119,7 @@ type Runtime interface { } ``` -## Migration Strategy +## Implemented Migration Strategy 1. Add executor tri-state contract in `pkg/commands` with tests. 2. Move `/new` and `/session` logic from `AgentLoop` into command handlers using runtime session ops. @@ -147,10 +149,10 @@ type Runtime interface { - Telegram startup command registration unaffected. - WhatsApp/WhatsApp native no longer diverge due to local command execution. -## Acceptance Criteria +## Acceptance Criteria (Implemented) - Command behavior is determined only by `pkg/commands` definitions + executor. -- No generic command business logic remains in `AgentLoop.handleCommand`. +- Generic command behavior (`/start`, `/help`, `/new`, `/session`, `/show`, `/list`) is executed via `commands.Executor` rather than channel-local business paths. - Unknown slash commands continue to LLM. - Unsupported registered commands return explicit errors. - README command behavior statements align with runtime behavior.