Skip to content

feat(remote-control): add /agent command for all channels#1696

Merged
zhangmo8 merged 1 commit into
devfrom
remote-agent-cmd
May 28, 2026
Merged

feat(remote-control): add /agent command for all channels#1696
zhangmo8 merged 1 commit into
devfrom
remote-agent-cmd

Conversation

@zhangmo8
Copy link
Copy Markdown
Collaborator

@zhangmo8 zhangmo8 commented May 28, 2026

close #1692

b74f4c16fbf46c56b9c5c892a9373c63

Summary by CodeRabbit

Release Notes

  • New Features

    • Added /agent command to list available agents and switch the active agent across Discord, Feishu, QQBot, Weixin iLink, and Telegram platforms.
  • Documentation

    • Added comprehensive documentation for the /agent remote command, including specifications and implementation details.
  • Tests

    • Added test coverage for agent listing, switching, and error handling across supported platforms.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

📝 Walkthrough

Walkthrough

This PR implements a complete /agent remote control command across all chat platforms. Users can list enabled agents and switch the channel's default agent, which creates a new session bound to the selected agent. The implementation spans shared type contracts, persistent per-channel state, core runner logic with ACP alias resolution and workdir validation, Telegram's interactive inline-menu flow, and text-based routers for Discord, Feishu, QQBot, and Weixin Ilink.

Changes

Remote /agent command feature

Layer / File(s) Summary
Agent menu state types and command contract
src/main/presenter/remoteControlPresenter/types.ts
New TELEGRAM_AGENT_MENU_TTL_MS constant, TelegramAgentOption, TelegramAgentMenuState, and TelegramAgentMenuCallback types, plus callback data builders and parser; /agent command entry added to TELEGRAM_REMOTE_COMMANDS, FEISHU_REMOTE_COMMANDS, QQBOT_REMOTE_COMMANDS, and DISCORD_REMOTE_COMMANDS arrays.
Runner agent listing and switching logic
src/main/presenter/remoteControlPresenter/services/remoteConversationRunner.ts
New listAvailableAgents() returns enabled agents as TelegramAgentOption objects; new setChannelDefaultAgent(endpointKey, candidateId) validates/matches agent id (resolving ACP aliases), enforces ACP workdir guard, persists channel default via store, creates detached session, and returns matched agent with session.
Agent menu state persistence and TTL management
src/main/presenter/remoteControlPresenter/services/remoteBindingStore.ts
New agentMenuStates map for in-memory callback-token-based agent menu state with TTL expiration; methods createAgentMenuState, getAgentMenuState (with TTL check), clearAgentMenuState manage lifecycle; setChannelDefaultAgentId updates channel default agent in persisted configuration; state cleanup integrated into existing binding clear paths.
Telegram /agent command with interactive menu
src/main/presenter/remoteControlPresenter/services/remoteCommandRouter.ts
New case 'agent' in text-command handler loads session, lists agents, creates menu state token, and returns inline keyboard; new handleAgentMenuCallback validates menu state (including TTL and endpoint/session), handles cancellation, routes agent choice to runner, clears state on success, surfaces errors via callback alert; new helpers for building keyboard and formatting menu/button text.
Text-channel /agent command handlers
src/main/presenter/remoteControlPresenter/services/discordCommandRouter.ts, feishuCommandRouter.ts, qqbotCommandRouter.ts, weixinIlinkCommandRouter.ts
Each router adds symmetric handleAgentCommand() that validates session, returns agent overview via formatAgentOverview() when no args provided, or calls setChannelDefaultAgent when agent id supplied and replies with agent switch confirmation including session and provider/model details.
Unit tests
test/main/presenter/remoteControlPresenter/remoteConversationRunner.test.ts, remoteBindingStore.test.ts, remoteCommandRouter.test.ts, feishuCommandRouter.test.ts
Tests for listAvailableAgents() (enabled filtering), setChannelDefaultAgent() (success, unknown agent, ACP workdir guard), agent menu state lifecycle and persistence, Telegram help/menu/callback behavior, and Feishu listing/switching.
Feature specification and documentation
docs/features/remote-agent-switch/plan.md, spec.md, tasks.md
Spec describes /agent command inputs/outputs, channel-specific UI, agent id/alias handling, session semantics, ACP workdir error; plan documents required touch points and routing symmetry; tasks checklist marks completed items with one pending manual e2e step.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1383: This PR directly extends the Telegram remote-control infrastructure by adding /agent command support, modifying the same remoteBindingStore, remoteCommandRouter, and types that were introduced in that foundational PR.
  • ThinkInAIXYZ/deepchat#1463: The new per-channel default-agent switching logic builds on the multi-channel remote foundation and workdir resolution semantics standardized in that PR.
  • ThinkInAIXYZ/deepchat#1694: Both PRs share ACP agent alias resolution and ACP default-workdir validation logic used to guard agent switching in remote contexts.

Poem

🐰 A fluffy feature hops in today,
/agent commands save the day!
Switch and list with Telegram cheer,
Text-channels chime from far and near,
ACP guards stand watch so sound,
New sessions bloom on every ground.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding /agent command support across all remote control channels.
Linked Issues check ✅ Passed The changes fully implement the /agent command requirement from issue #1692, including listing agents, switching agents across all channels, and session management.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the /agent command feature and related supporting infrastructure, with no out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch remote-agent-cmd

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/presenter/remoteControlPresenter/services/discordCommandRouter.ts (1)

314-351: 🏗️ Heavy lift

Consolidate duplicated /agent handler/formatter across routers.

handleAgentCommand + formatAgentOverview are now copy-pasted across four platform routers. Extracting a shared helper (or base utility) would reduce drift risk for future behavior/text changes.

Also applies to: 472-484

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/remoteControlPresenter/services/discordCommandRouter.ts`
around lines 314 - 351, The handleAgentCommand logic and formatAgentOverview
text are duplicated across multiple platform routers; extract a shared helper
module (e.g., remoteControlAgentHelper) that exposes a single function
(handleAgentCommand or handleAgentCommandShared) and a formatter
(formatAgentOverview) and have each router import and call those instead of
duplicate code; update the current handleAgentCommand in discordCommandRouter to
delegate to the new shared function (passing deps, message, endpointKey, and
session retrieval as needed) and remove the copied formatter implementations
from the other routers so all four routers call the common helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/presenter/remoteControlPresenter/services/remoteConversationRunner.ts`:
- Around line 633-635: The code sets the channel default agent via
bindingStore.setChannelDefaultAgentId(endpointKey, matched.id) before creating a
session with createNewSession(endpointKey), so if session creation fails the
default remains changed; change the flow to either (A) delay calling
bindingStore.setChannelDefaultAgentId until after createNewSession(endpointKey)
succeeds, or (B) keep the current order but catch errors from createNewSession
and rollback by calling bindingStore.setChannelDefaultAgentId(endpointKey,
previousAgentId) (ensure you read and store the previous agent id beforehand).
Use the existing symbols bindingStore.setChannelDefaultAgentId,
createNewSession, endpointKey, and matched.id to implement the chosen fix.

---

Nitpick comments:
In `@src/main/presenter/remoteControlPresenter/services/discordCommandRouter.ts`:
- Around line 314-351: The handleAgentCommand logic and formatAgentOverview text
are duplicated across multiple platform routers; extract a shared helper module
(e.g., remoteControlAgentHelper) that exposes a single function
(handleAgentCommand or handleAgentCommandShared) and a formatter
(formatAgentOverview) and have each router import and call those instead of
duplicate code; update the current handleAgentCommand in discordCommandRouter to
delegate to the new shared function (passing deps, message, endpointKey, and
session retrieval as needed) and remove the copied formatter implementations
from the other routers so all four routers call the common helpers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3a19ab0-f1b8-4a80-a6a7-3110784c9f63

📥 Commits

Reviewing files that changed from the base of the PR and between 7c62924 and ad36bcb.

📒 Files selected for processing (15)
  • docs/features/remote-agent-switch/plan.md
  • docs/features/remote-agent-switch/spec.md
  • docs/features/remote-agent-switch/tasks.md
  • src/main/presenter/remoteControlPresenter/services/discordCommandRouter.ts
  • src/main/presenter/remoteControlPresenter/services/feishuCommandRouter.ts
  • src/main/presenter/remoteControlPresenter/services/qqbotCommandRouter.ts
  • src/main/presenter/remoteControlPresenter/services/remoteBindingStore.ts
  • src/main/presenter/remoteControlPresenter/services/remoteCommandRouter.ts
  • src/main/presenter/remoteControlPresenter/services/remoteConversationRunner.ts
  • src/main/presenter/remoteControlPresenter/services/weixinIlinkCommandRouter.ts
  • src/main/presenter/remoteControlPresenter/types.ts
  • test/main/presenter/remoteControlPresenter/feishuCommandRouter.test.ts
  • test/main/presenter/remoteControlPresenter/remoteBindingStore.test.ts
  • test/main/presenter/remoteControlPresenter/remoteCommandRouter.test.ts
  • test/main/presenter/remoteControlPresenter/remoteConversationRunner.test.ts

@zhangmo8 zhangmo8 merged commit d6ddb14 into dev May 28, 2026
3 checks passed
@zhangmo8 zhangmo8 deleted the remote-agent-cmd branch May 28, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] support /agent command to remotely switch agents

1 participant