diff --git a/docs/explanation/architecture.md b/docs/explanation/architecture.md
index 60d3b7b..2aa78aa 100644
--- a/docs/explanation/architecture.md
+++ b/docs/explanation/architecture.md
@@ -165,7 +165,7 @@ sequenceDiagram
Command->>RunnerBridge: run_one/run_many (optional)
RunnerBridge->>Telegram: Send progress/final
else Default routing
- Bridge->>Bridge: Parse directives
(/engine, /project, @branch)
+ Bridge->>Bridge: Parse directives
(/<engine-id>, /<project-alias>, @branch)
Bridge->>Bridge: Extract resume token
from reply
Bridge->>Bridge: Resolve worktree
(if @branch)
diff --git a/docs/explanation/plugin-system.md b/docs/explanation/plugin-system.md
index eeeaff8..f3326c8 100644
--- a/docs/explanation/plugin-system.md
+++ b/docs/explanation/plugin-system.md
@@ -72,7 +72,7 @@ This lets you:
## IDs and collisions
-Entrypoint names become plugin IDs and appear in user-facing surfaces (CLI subcommands, Telegram commands, `/engine` directives).
+Entrypoint names become plugin IDs and appear in user-facing surfaces (CLI subcommands, Telegram commands, `/` directives).
Takopi validates IDs and rejects collisions with reserved names.
Plugin IDs must match:
diff --git a/docs/explanation/routing-and-sessions.md b/docs/explanation/routing-and-sessions.md
index f42d03c..42dfa05 100644
--- a/docs/explanation/routing-and-sessions.md
+++ b/docs/explanation/routing-and-sessions.md
@@ -27,7 +27,7 @@ Reply-to-continue works even if topics or chat sessions are enabled.
For each message, Takopi:
-- parses directive prefixes (`/engine`, `/project`, `@branch`) from the first non-empty line
+- parses directive prefixes (`/`, `/`, `@branch`) from the first non-empty line
- attempts to extract a resume token by polling available runners
- if a resume token is found, routes to the matching runner; otherwise uses the configured default engine
diff --git a/docs/how-to/switch-engines.md b/docs/how-to/switch-engines.md
index e0fcdd7..afe9f30 100644
--- a/docs/how-to/switch-engines.md
+++ b/docs/how-to/switch-engines.md
@@ -29,7 +29,7 @@ Use `/agent`:
- In normal chats, it affects the whole chat.
- In group chats, only admins can change defaults.
-Selection precedence (highest to lowest): resume token → `/engine` directive → topic default → chat default → project default → global default.
+Selection precedence (highest to lowest): resume token → `/` directive → topic default → chat default → project default → global default.
## Engine installation
@@ -40,4 +40,3 @@ Takopi shells out to engine CLIs. Install them and make sure they’re on your `
- [Commands & directives](../reference/commands-and-directives.md)
- [Config reference](../reference/config.md)
-
diff --git a/docs/how-to/topics.md b/docs/how-to/topics.md
index 85ee424..0b37c21 100644
--- a/docs/how-to/topics.md
+++ b/docs/how-to/topics.md
@@ -1,6 +1,6 @@
# Topics
-Topics bind Telegram **forum threads** to a project/branch context. Each topic keeps its own session and default agent, which is ideal for teams or multi-project work.
+Topics bind Telegram **forum threads** to a project/branch context. Each topic keeps its own session and default engine, which is ideal for teams or multi-project work.
!!! tip "Workspace workflow"
If you chose the **workspace** workflow during [onboarding](../tutorials/install.md), topics are already enabled. This guide covers advanced topic configuration and usage.
@@ -9,7 +9,7 @@ Topics bind Telegram **forum threads** to a project/branch context. Each topic k
- Keep each thread tied to a repo + branch
- Avoid context collisions in busy team chats
-- Set a default agent per topic with `/agent set`
+- Set a default engine per topic with `/agent set`
## Requirements checklist
@@ -76,7 +76,7 @@ Note: Outside topics (private chats or main group chats), `/ctx` binds the chat
Use `/new` inside the topic to clear stored sessions for that thread.
-## Set a default agent per topic
+## Set a default engine per topic
Use `/agent set` inside the topic:
diff --git a/docs/how-to/worktrees.md b/docs/how-to/worktrees.md
index 2db9e3d..c495cea 100644
--- a/docs/how-to/worktrees.md
+++ b/docs/how-to/worktrees.md
@@ -44,7 +44,7 @@ echo ".worktrees/" >> ~/.config/git/ignore
## Context persistence
When project/worktree context is active, Takopi includes a `ctx:` footer in messages.
-When you reply, this context carries forward (you usually don’t need to repeat `/project @branch`).
+When you reply, this context carries forward (you usually don’t need to repeat `/ @branch`).
## Related
diff --git a/docs/how-to/write-a-plugin.md b/docs/how-to/write-a-plugin.md
index 998acdc..f3d498f 100644
--- a/docs/how-to/write-a-plugin.md
+++ b/docs/how-to/write-a-plugin.md
@@ -24,7 +24,9 @@ mytransport = "mytransport.backend:BACKEND"
mycommand = "mycommand.backend:BACKEND"
```
-## Engine backend plugin (runner)
+## Engine backend plugin
+
+An engine backend builds a `Runner` via `build_runner(...)`.
Minimal example:
diff --git a/docs/index.md b/docs/index.md
index 710c3eb..99da224 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -68,7 +68,7 @@ Step-by-step guides for new users:
1. [Install & onboard](tutorials/install.md) — set up Takopi and your bot
2. [First run](tutorials/first-run.md) — send a task, watch it stream, continue the conversation
3. [Projects & branches](tutorials/projects-and-branches.md) — target repos from anywhere, run on feature branches
-4. [Multi-engine](tutorials/multi-engine.md) — use different agents for different tasks
+4. [Multi-engine](tutorials/multi-engine.md) — use different engines for different tasks
## How-to guides
diff --git a/docs/reference/commands-and-directives.md b/docs/reference/commands-and-directives.md
index 99a7b76..00b8018 100644
--- a/docs/reference/commands-and-directives.md
+++ b/docs/reference/commands-and-directives.md
@@ -8,8 +8,8 @@ Takopi parses the first non-empty line of a message for a directive prefix.
| Directive | Example | Effect |
|----------|---------|--------|
-| `/engine` | `/codex fix flaky test` | Select an engine for this message. |
-| `/project` | `/happy-gadgets add escape-pod` | Select a project alias. |
+| `/` | `/codex fix flaky test` | Select an engine for this message. |
+| `/` | `/happy-gadgets add escape-pod` | Select a project alias. |
| `@branch` | `@feat/happy-camera rewind to checkpoint` | Run in a worktree for the branch. |
| Combined | `/happy-gadgets @feat/flower-pin observe unseen` | Project + branch. |
@@ -35,7 +35,7 @@ This line is parsed from replies and takes precedence over new directives.
| Command | Description |
|---------|-------------|
| `/cancel` | Reply to the progress message to stop the current run. |
-| `/agent` | Show/set the default agent for the current scope. |
+| `/agent` | Show/set the default engine for the current scope. |
| `/model` | Show/set the model override for the current scope. |
| `/reasoning` | Show/set the reasoning override for the current scope. |
| `/trigger` | Show/set trigger mode (mentions-only vs all). |
diff --git a/docs/reference/context-resolution.md b/docs/reference/context-resolution.md
index a43002a..83d4335 100644
--- a/docs/reference/context-resolution.md
+++ b/docs/reference/context-resolution.md
@@ -92,8 +92,8 @@ Takopi parses the first non-empty line of a message for a directive prefix.
Supported directives:
-- `/engine` or `/engine@bot`: chooses the engine
-- `/project`: chooses a project alias
+- `/` or `/@bot`: chooses the engine
+- `/`: chooses a project alias
- `@branch`: chooses a git branch/worktree
Rules:
@@ -117,7 +117,7 @@ The `ctx:` line is parsed from replies and takes precedence over new directives.
When a message arrives in a chat whose `chat_id` matches `projects..chat_id`,
Takopi defaults the project context to that alias unless a reply `ctx:` or explicit
-`/project` directive is present.
+`/` directive is present.
In non-topic chats, `/ctx` can bind a chat context. That bound context is treated as
ambient and takes precedence over the default project mapping until cleared.
diff --git a/docs/reference/index.md b/docs/reference/index.md
index 9759e15..6c899b6 100644
--- a/docs/reference/index.md
+++ b/docs/reference/index.md
@@ -8,7 +8,7 @@ If you’re trying to understand the *why*, use **[Explanation](../explanation/i
## Most-used reference pages
- [Commands & directives](commands-and-directives.md)
- - Message prefixes like `/engine`, `/project`, and `@branch`
+ - Message prefixes like `/`, `/`, and `@branch`
- In-chat commands like `/cancel`, `/new`, `/ctx`, `/file …`, `/topic …`
- [Configuration](config.md)
- `takopi.toml` options and defaults
diff --git a/docs/reference/transports/telegram.md b/docs/reference/transports/telegram.md
index eb99d66..74bb594 100644
--- a/docs/reference/transports/telegram.md
+++ b/docs/reference/transports/telegram.md
@@ -65,7 +65,7 @@ To restore “only respond when invoked” behavior, use trigger mode:
Explicit invocation includes any of:
- `@botname` mention in the message.
-- `/engine` or `/project_alias` as the first token.
+- `/` or `/` as the first token.
- Replying to a bot message.
- Built-in or plugin slash commands (for example `/agent`, `/model`, `/reasoning`, `/file`, `/trigger`).
diff --git a/docs/tutorials/conversation-modes.md b/docs/tutorials/conversation-modes.md
index 3cd3f84..1ead408 100644
--- a/docs/tutorials/conversation-modes.md
+++ b/docs/tutorials/conversation-modes.md
@@ -38,7 +38,7 @@ To pin a project or branch for the chat, use:
`/new` clears the session but keeps the bound context.
-Tip: set a default agent for this chat with `/agent set claude`.
+Tip: set a default engine for this chat with `/agent set claude`.
## Stateless (reply-to-continue)
diff --git a/docs/tutorials/first-run.md b/docs/tutorials/first-run.md
index 20e0358..b763eb6 100644
--- a/docs/tutorials/first-run.md
+++ b/docs/tutorials/first-run.md
@@ -19,7 +19,7 @@ Takopi keeps running in your terminal. In Telegram, your bot will post a startup
🐙 takopi is ready
default: codex
- agents: codex, claude
+ engines: codex, claude
projects: none
mode: chat
topics: disabled
@@ -29,7 +29,7 @@ Takopi keeps running in your terminal. In Telegram, your bot will post a startup
The engines/projects list reflects your setup. This tells you:
- Which engine is the default
-- Which agents are available (and any missing ones)
+- Which engines are available (and any missing ones)
- Which projects are registered
- Which directory Takopi will run in
@@ -131,7 +131,7 @@ If a resume token was already issued (and resume lines are enabled), it will sti
## 7. Try a different engine
-Want to use a different agent for one message? Prefix your message with `/`:
+Want to use a different engine for one message? Prefix your message with `/`:
!!! user "You"
/claude explain the error handling in this codebase
diff --git a/docs/tutorials/install.md b/docs/tutorials/install.md
index 3dc8f8e..22d9a72 100644
--- a/docs/tutorials/install.md
+++ b/docs/tutorials/install.md
@@ -228,9 +228,9 @@ Once Takopi receives your message:
Takopi scans your PATH for installed agent CLIs:
```
-step 4: default agent
+step 4: default engine
-takopi runs these agents on your computer. switch anytime with /agent.
+takopi runs these engines on your computer. switch anytime with /agent.
engine status install command
───────────────────────────────────────────
@@ -239,7 +239,7 @@ takopi runs these agents on your computer. switch anytime with /agent.
opencode ✗ not found npm install -g opencode-ai@latest
pi ✗ not found npm install -g @mariozechner/pi-coding-agent
-? choose default agent:
+? choose default engine:
❯ codex
claude
```
diff --git a/docs/tutorials/multi-engine.md b/docs/tutorials/multi-engine.md
index ee40d0c..837adcd 100644
--- a/docs/tutorials/multi-engine.md
+++ b/docs/tutorials/multi-engine.md
@@ -1,14 +1,14 @@
# Multi-engine workflows
-This tutorial shows you how to use different agents for different tasks and set up defaults so you don't have to think about it.
+This tutorial shows you how to use different engines for different tasks and set up defaults so you don't have to think about it.
-**What you'll learn:** Engine directives, persistent defaults, and when to use which agent.
+**What you'll learn:** Engine directives, persistent defaults, and when to use which engine.
## Why multiple engines?
-Different agents have different strengths:
+Different engines have different strengths:
-| Agent | Good at |
+| Engine | Good at |
|-------|---------|
| **Codex** | Fast edits, shell commands, quick fixes |
| **Claude Code** | Complex refactors, architecture, long context |
@@ -65,7 +65,7 @@ Use `/agent set` to change the default for the current scope:
Response:
!!! takopi "Takopi"
- chat default agent set to claude
+ chat default engine set to claude
Now all new conversations in this chat use Claude (unless you explicitly override with `/codex`).
@@ -77,7 +77,7 @@ Check the current default:
Example response:
!!! takopi "Takopi"
- agent: claude (chat default)
+ engine: claude (chat default)
defaults: topic: none, chat: claude, project: none, global: codex
available: codex, claude, opencode, pi
@@ -89,7 +89,7 @@ Clear it:
Response:
!!! takopi "Takopi"
- chat default agent cleared.
+ chat default engine cleared.
## 4. Defaults in topics
diff --git a/docs/tutorials/projects-and-branches.md b/docs/tutorials/projects-and-branches.md
index ca2452a..18d099a 100644
--- a/docs/tutorials/projects-and-branches.md
+++ b/docs/tutorials/projects-and-branches.md
@@ -2,7 +2,7 @@
This tutorial shows you how to register repos as projects and run tasks on feature branches without switching directories.
-**What you'll learn:** How to target repos from anywhere with `/project`, and run on branches with `@branch`.
+**What you'll learn:** How to target repos from anywhere with `/`, and run on branches with `@branch`.
## The problem
@@ -123,7 +123,7 @@ Replies stay on the same branch. Your main checkout is untouched.
## 5. Context persistence
-Once you've set a context (via `/project @branch` or by replying), it sticks:
+Once you've set a context (via `/ @branch` or by replying), it sticks:
!!! user "You"
/happy-gadgets @feat/new-login add tests
@@ -155,7 +155,7 @@ If you mostly work in one repo, set it as the default:
default_project = "happy-gadgets"
```
-Now messages without a `/project` prefix go to that repo:
+Now messages without a `/` prefix go to that repo:
!!! user "You"
add a health check endpoint
diff --git a/src/takopi/telegram/backend.py b/src/takopi/telegram/backend.py
index 9783f36..98c37b4 100644
--- a/src/takopi/telegram/backend.py
+++ b/src/takopi/telegram/backend.py
@@ -71,7 +71,7 @@ def _build_startup_message(
return (
f"\N{OCTOPUS} **takopi is ready**\n\n"
f"default: `{runtime.default_engine}` \n"
- f"agents: `{engine_list}` \n"
+ f"engines: `{engine_list}` \n"
f"projects: `{project_list}` \n"
f"mode: `{session_mode}` \n"
f"topics: `{topics_label}` \n"
diff --git a/src/takopi/telegram/commands/agent.py b/src/takopi/telegram/commands/agent.py
index a01ae68..6b237b3 100644
--- a/src/takopi/telegram/commands/agent.py
+++ b/src/takopi/telegram/commands/agent.py
@@ -25,17 +25,17 @@ async def _check_agent_permissions(
reply = make_reply(cfg, msg)
sender_id = msg.sender_id
if sender_id is None:
- await reply(text="cannot verify sender for agent defaults.")
+ await reply(text="cannot verify sender for engine defaults.")
return False
if msg.is_private:
return True
member = await cfg.bot.get_chat_member(msg.chat_id, sender_id)
if member is None:
- await reply(text="failed to verify agent permissions.")
+ await reply(text="failed to verify engine permissions.")
return False
if member.status in {"creator", "administrator"}:
return True
- await reply(text="changing default agents is restricted to group admins.")
+ await reply(text="changing default engines is restricted to group admins.")
return False
@@ -86,7 +86,7 @@ async def _handle_agent_command(
"project_default": "project default",
"global_default": "global default",
}
- agent_line = f"agent: {selection.engine} ({source_labels[selection.source]})"
+ agent_line = f"engine: {selection.engine} ({source_labels[selection.source]})"
topic_override = None
if tkey is not None and topic_store is not None:
topic_override = await topic_store.get_engine_override(
@@ -159,7 +159,7 @@ async def _handle_agent_command(
if engine not in cfg.runtime.engine_ids:
available = ", ".join(cfg.runtime.engine_ids)
await reply(
- text=f"unknown engine `{engine}`.\navailable agents: `{available}`",
+ text=f"unknown engine `{engine}`.\navailable engines: `{available}`",
)
return
if tkey is not None:
@@ -167,13 +167,13 @@ async def _handle_agent_command(
await reply(text="topic defaults are unavailable.")
return
await topic_store.set_default_engine(tkey[0], tkey[1], engine)
- await reply(text=f"topic default agent set to `{engine}`")
+ await reply(text=f"topic default engine set to `{engine}`")
return
if chat_prefs is None:
await reply(text="chat defaults are unavailable (no config path).")
return
await chat_prefs.set_default_engine(msg.chat_id, engine)
- await reply(text=f"chat default agent set to `{engine}`")
+ await reply(text=f"chat default engine set to `{engine}`")
return
if action == "clear":
@@ -184,13 +184,13 @@ async def _handle_agent_command(
await reply(text="topic defaults are unavailable.")
return
await topic_store.clear_default_engine(tkey[0], tkey[1])
- await reply(text="topic default agent cleared.")
+ await reply(text="topic default engine cleared.")
return
if chat_prefs is None:
await reply(text="chat defaults are unavailable (no config path).")
return
await chat_prefs.clear_default_engine(msg.chat_id)
- await reply(text="chat default agent cleared.")
+ await reply(text="chat default engine cleared.")
return
await reply(text=AGENT_USAGE)
diff --git a/src/takopi/telegram/commands/menu.py b/src/takopi/telegram/commands/menu.py
index 1341b47..5bbf52b 100644
--- a/src/takopi/telegram/commands/menu.py
+++ b/src/takopi/telegram/commands/menu.py
@@ -29,7 +29,7 @@ def build_bot_commands(
cmd = engine_id.lower()
if cmd in seen:
continue
- commands.append({"command": cmd, "description": f"use agent: {cmd}"})
+ commands.append({"command": cmd, "description": f"use engine: {cmd}"})
seen.add(cmd)
for alias in runtime.project_aliases():
cmd = alias.lower()
@@ -73,7 +73,7 @@ def build_bot_commands(
for cmd, description in [
("new", "start a new thread"),
("ctx", "show or update context"),
- ("agent", "set default agent"),
+ ("agent", "set default engine"),
("model", "set model override"),
("reasoning", "set reasoning override"),
("trigger", "set trigger mode"),
diff --git a/src/takopi/telegram/commands/model.py b/src/takopi/telegram/commands/model.py
index 81a2a97..41b9ed0 100644
--- a/src/takopi/telegram/commands/model.py
+++ b/src/takopi/telegram/commands/model.py
@@ -122,7 +122,7 @@ async def _handle_model_command(
if engine not in engine_ids:
available = ", ".join(cfg.runtime.engine_ids)
await reply(
- text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
+ text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
)
return
scope = await apply_engine_override(
@@ -187,7 +187,7 @@ async def _handle_model_command(
if engine not in engine_ids:
available = ", ".join(cfg.runtime.engine_ids)
await reply(
- text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
+ text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
)
return
scope = await apply_engine_override(
diff --git a/src/takopi/telegram/commands/reasoning.py b/src/takopi/telegram/commands/reasoning.py
index be726f8..9a9cebe 100644
--- a/src/takopi/telegram/commands/reasoning.py
+++ b/src/takopi/telegram/commands/reasoning.py
@@ -130,7 +130,7 @@ async def _handle_reasoning_command(
if engine not in engine_ids:
available = ", ".join(cfg.runtime.engine_ids)
await reply(
- text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
+ text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
)
return
normalized_level = level.strip().lower()
@@ -206,7 +206,7 @@ async def _handle_reasoning_command(
if engine not in engine_ids:
available = ", ".join(cfg.runtime.engine_ids)
await reply(
- text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
+ text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
)
return
scope = await apply_engine_override(
diff --git a/src/takopi/telegram/onboarding.py b/src/takopi/telegram/onboarding.py
index 02ceb2f..8827d76 100644
--- a/src/takopi/telegram/onboarding.py
+++ b/src/takopi/telegram/onboarding.py
@@ -877,7 +877,7 @@ async def step_capture_chat(ui: UI, svc: Services, state: OnboardingState) -> No
async def step_default_engine(ui: UI, svc: Services, state: OnboardingState) -> None:
- ui.print("takopi runs these agents on your computer. switch anytime with /agent.")
+ ui.print("takopi runs these engines on your computer. switch anytime with /agent.")
rows = svc.list_engines()
render_engine_table(ui, rows)
installed_ids = [engine_id for engine_id, installed, _ in rows if installed]
@@ -885,13 +885,13 @@ async def step_default_engine(ui: UI, svc: Services, state: OnboardingState) ->
if installed_ids:
ui.print("")
default_engine = await ui.select(
- "choose default agent:",
+ "choose default engine:",
choices=[(engine_id, engine_id) for engine_id in installed_ids],
)
state.default_engine = require_value(default_engine)
return
- ui.print("no agents found. install one and rerun --onboard.")
+ ui.print("no engines found. install one and rerun --onboard.")
ui.print("")
save_anyway = await ui.confirm("save config anyway?", default=False)
if not save_anyway:
@@ -945,7 +945,7 @@ STEPS: list[OnboardingStep] = [
OnboardingStep("bot token", 1, step_token_and_bot),
OnboardingStep("pick your workflow", 2, step_persona),
OnboardingStep("connect chat", 3, step_capture_chat),
- OnboardingStep("default agent", 4, step_default_engine),
+ OnboardingStep("default engine", 4, step_default_engine),
OnboardingStep("save config", 5, step_save_config),
]
diff --git a/tests/test_telegram_agent_trigger_commands.py b/tests/test_telegram_agent_trigger_commands.py
index d6dc8a0..47c95f2 100644
--- a/tests/test_telegram_agent_trigger_commands.py
+++ b/tests/test_telegram_agent_trigger_commands.py
@@ -62,7 +62,7 @@ async def test_agent_show_private_defaults() -> None:
)
text = _last_text(transport)
- assert "agent: codex" in text
+ assert "engine: codex" in text
assert "available: codex" in text
@@ -83,7 +83,7 @@ async def test_agent_set_clear_group_admin(tmp_path: Path) -> None:
)
assert await prefs.get_default_engine(msg.chat_id) == "codex"
- assert "chat default agent set" in _last_text(transport)
+ assert "chat default engine set" in _last_text(transport)
await _handle_agent_command(
cfg,
@@ -95,7 +95,7 @@ async def test_agent_set_clear_group_admin(tmp_path: Path) -> None:
)
assert await prefs.get_default_engine(msg.chat_id) is None
- assert "chat default agent cleared" in _last_text(transport)
+ assert "chat default engine cleared" in _last_text(transport)
@pytest.mark.anyio
@@ -135,7 +135,7 @@ async def test_agent_set_invalid_engine(tmp_path: Path) -> None:
text = _last_text(transport)
assert "unknown engine" in text
- assert "available agents" in text
+ assert "available engines" in text
@pytest.mark.anyio
diff --git a/tests/test_telegram_backend.py b/tests/test_telegram_backend.py
index b2638d1..00058b6 100644
--- a/tests/test_telegram_backend.py
+++ b/tests/test_telegram_backend.py
@@ -50,7 +50,7 @@ def test_build_startup_message_includes_missing_engines(tmp_path: Path) -> None:
)
assert "takopi is ready" in message
- assert "agents: `codex (not installed: pi)`" in message
+ assert "engines: `codex (not installed: pi)`" in message
assert "projects: `none`" in message
@@ -92,7 +92,7 @@ def test_build_startup_message_surfaces_unavailable_engine_reasons(
topics=TelegramTopicsSettings(),
)
- assert "agents: `codex" in message
+ assert "engines: `codex" in message
assert "misconfigured: pi" in message
assert "failed to load: claude" in message
diff --git a/tests/test_telegram_bridge.py b/tests/test_telegram_bridge.py
index e83c358..f0385b2 100644
--- a/tests/test_telegram_bridge.py
+++ b/tests/test_telegram_bridge.py
@@ -136,7 +136,7 @@ def test_build_bot_commands_includes_cancel_and_engine() -> None:
assert {"command": "file", "description": "upload or fetch files"} in commands
assert {"command": "new", "description": "start a new thread"} in commands
assert {"command": "ctx", "description": "show or update context"} in commands
- assert {"command": "agent", "description": "set default agent"} in commands
+ assert {"command": "agent", "description": "set default engine"} in commands
assert any(cmd["command"] == "codex" for cmd in commands)