Skip to content

bug: Messaging bot commands with arguments (/workspace <name>, /model <id>) are never intercepted — parsed as plain chat text #235

Description

@Chengzhi-Yang

Body:

Summary

Commands sent to a messaging bot (Discord/Telegram/etc.) that take an argument — /workspace <name> and /model <id> — are never intercepted by the bot's command layer. They fall through to normal message dispatch and reach the agent as plain text, so the documented behavior (/workspace <name> switches the bot's workspace and starts a new chat) never happens.

Bare commands without arguments (/new, /stop, /retry, /help, /workspaces) work fine.

Environment

  • cptr version: 0.9.21 (pip package cptr, installed via venv)
  • Platform: Discord bot (bug is in the shared bridge core, so it affects all platforms: Telegram, Discord, Slack, WhatsApp, Signal)
  • Docs that document the command: https://docs.openwebui.com/ecosystem/computer/automate/messaging-bots/ ("Commands" table lists /workspace <name> — Switch workspace (fuzzy match) and start a new chat)

Steps to reproduce

  1. Create a bot in Settings → Admin → Bots (platform: Discord, workspace: /projects), start it.
  2. In the Discord channel, send: /workspace jellyfin-storage
  3. Observe: no "✨ Switched to ... New conversation started." reply. Instead, the message is treated as a normal user message — the agent receives /workspace jellyfin-storage as plain text and responds to it conversationally.
  4. Same result for /model <id>.

Root cause

In cptr/utils/bridge.py, BotManager._handle_message, the command is extracted like this:

# Normalize: strip Discord bot mention prefix (<@123456>)
# and Telegram command suffix (/cmd@BotName → /cmd)
import re
clean = re.sub(r"<@!?\d+>\s*", "", text).strip()
cmd = clean.split("@")[0].lower() if clean.startswith("/") else ""

clean.split("@")[0] only strips a Telegram-style @BotName suffix — it does not split on whitespace. So:

  • /workspace jellyfin-storagecmd = "/workspace jellyfin-storage"cmd == "/workspace" is False → falls through to chat dispatch
  • /model gpt-4ocmd = "/model gpt-4o"cmd == "/model" is False → falls through

The command handler for /workspace exists and is correct (it matches by name/path suffix, updates the bot config, and starts a new chat) — it's just unreachable because the parser never produces a bare /workspace.

Suggested fix

One line in cptr/utils/bridge.py:

cmd = clean.split()[0].split("@")[0].lower() if clean.startswith("/") else ""

Verified: this yields cmd == "/workspace" for /workspace jellyfin-storage, still strips @BotName suffixes (/cmd@BotName/cmd), and leaves bare commands and non-slash messages unchanged.

Workaround (for users on affected versions)

Set the bot's workspace directly in Settings → Admin → Bots instead of using /workspace, or patch the single line above (note: it lives in the container's writable layer and is lost on container rebuild).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions