docs: align engine terminology in telegram and docs (#162)
This commit is contained in:
@@ -165,7 +165,7 @@ sequenceDiagram
|
|||||||
Command->>RunnerBridge: run_one/run_many (optional)
|
Command->>RunnerBridge: run_one/run_many (optional)
|
||||||
RunnerBridge->>Telegram: Send progress/final
|
RunnerBridge->>Telegram: Send progress/final
|
||||||
else Default routing
|
else Default routing
|
||||||
Bridge->>Bridge: Parse directives<br/>(/engine, /project, @branch)
|
Bridge->>Bridge: Parse directives<br/>(/<engine-id>, /<project-alias>, @branch)
|
||||||
Bridge->>Bridge: Extract resume token<br/>from reply
|
Bridge->>Bridge: Extract resume token<br/>from reply
|
||||||
Bridge->>Bridge: Resolve worktree<br/>(if @branch)
|
Bridge->>Bridge: Resolve worktree<br/>(if @branch)
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ This lets you:
|
|||||||
|
|
||||||
## IDs and collisions
|
## 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, `/<engine-id>` directives).
|
||||||
Takopi validates IDs and rejects collisions with reserved names.
|
Takopi validates IDs and rejects collisions with reserved names.
|
||||||
|
|
||||||
Plugin IDs must match:
|
Plugin IDs must match:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Reply-to-continue works even if topics or chat sessions are enabled.
|
|||||||
|
|
||||||
For each message, Takopi:
|
For each message, Takopi:
|
||||||
|
|
||||||
- parses directive prefixes (`/engine`, `/project`, `@branch`) from the first non-empty line
|
- parses directive prefixes (`/<engine-id>`, `/<project-alias>`, `@branch`) from the first non-empty line
|
||||||
- attempts to extract a resume token by polling available runners
|
- 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
|
- if a resume token is found, routes to the matching runner; otherwise uses the configured default engine
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Use `/agent`:
|
|||||||
- In normal chats, it affects the whole chat.
|
- In normal chats, it affects the whole chat.
|
||||||
- In group chats, only admins can change defaults.
|
- 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 → `/<engine-id>` directive → topic default → chat default → project default → global default.
|
||||||
|
|
||||||
## Engine installation
|
## 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)
|
- [Commands & directives](../reference/commands-and-directives.md)
|
||||||
- [Config reference](../reference/config.md)
|
- [Config reference](../reference/config.md)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Topics
|
# 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"
|
!!! 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.
|
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
|
- Keep each thread tied to a repo + branch
|
||||||
- Avoid context collisions in busy team chats
|
- 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
|
## 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.
|
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:
|
Use `/agent set` inside the topic:
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ echo ".worktrees/" >> ~/.config/git/ignore
|
|||||||
## Context persistence
|
## Context persistence
|
||||||
|
|
||||||
When project/worktree context is active, Takopi includes a `ctx:` footer in messages.
|
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 `/<project-alias> @branch`).
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ mytransport = "mytransport.backend:BACKEND"
|
|||||||
mycommand = "mycommand.backend:BACKEND"
|
mycommand = "mycommand.backend:BACKEND"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Engine backend plugin (runner)
|
## Engine backend plugin
|
||||||
|
|
||||||
|
An engine backend builds a `Runner` via `build_runner(...)`.
|
||||||
|
|
||||||
Minimal example:
|
Minimal example:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ Step-by-step guides for new users:
|
|||||||
1. [Install & onboard](tutorials/install.md) — set up Takopi and your bot
|
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
|
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
|
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
|
## How-to guides
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ Takopi parses the first non-empty line of a message for a directive prefix.
|
|||||||
|
|
||||||
| Directive | Example | Effect |
|
| Directive | Example | Effect |
|
||||||
|----------|---------|--------|
|
|----------|---------|--------|
|
||||||
| `/engine` | `/codex fix flaky test` | Select an engine for this message. |
|
| `/<engine-id>` | `/codex fix flaky test` | Select an engine for this message. |
|
||||||
| `/project` | `/happy-gadgets add escape-pod` | Select a project alias. |
|
| `/<project-alias>` | `/happy-gadgets add escape-pod` | Select a project alias. |
|
||||||
| `@branch` | `@feat/happy-camera rewind to checkpoint` | Run in a worktree for the branch. |
|
| `@branch` | `@feat/happy-camera rewind to checkpoint` | Run in a worktree for the branch. |
|
||||||
| Combined | `/happy-gadgets @feat/flower-pin observe unseen` | Project + 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 |
|
| Command | Description |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `/cancel` | Reply to the progress message to stop the current run. |
|
| `/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. |
|
| `/model` | Show/set the model override for the current scope. |
|
||||||
| `/reasoning` | Show/set the reasoning override for the current scope. |
|
| `/reasoning` | Show/set the reasoning override for the current scope. |
|
||||||
| `/trigger` | Show/set trigger mode (mentions-only vs all). |
|
| `/trigger` | Show/set trigger mode (mentions-only vs all). |
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ Takopi parses the first non-empty line of a message for a directive prefix.
|
|||||||
|
|
||||||
Supported directives:
|
Supported directives:
|
||||||
|
|
||||||
- `/engine` or `/engine@bot`: chooses the engine
|
- `/<engine-id>` or `/<engine-id>@bot`: chooses the engine
|
||||||
- `/project`: chooses a project alias
|
- `/<project-alias>`: chooses a project alias
|
||||||
- `@branch`: chooses a git branch/worktree
|
- `@branch`: chooses a git branch/worktree
|
||||||
|
|
||||||
Rules:
|
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.<alias>.chat_id`,
|
When a message arrives in a chat whose `chat_id` matches `projects.<alias>.chat_id`,
|
||||||
Takopi defaults the project context to that alias unless a reply `ctx:` or explicit
|
Takopi defaults the project context to that alias unless a reply `ctx:` or explicit
|
||||||
`/project` directive is present.
|
`/<project-alias>` directive is present.
|
||||||
|
|
||||||
In non-topic chats, `/ctx` can bind a chat context. That bound context is treated as
|
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.
|
ambient and takes precedence over the default project mapping until cleared.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ If you’re trying to understand the *why*, use **[Explanation](../explanation/i
|
|||||||
## Most-used reference pages
|
## Most-used reference pages
|
||||||
|
|
||||||
- [Commands & directives](commands-and-directives.md)
|
- [Commands & directives](commands-and-directives.md)
|
||||||
- Message prefixes like `/engine`, `/project`, and `@branch`
|
- Message prefixes like `/<engine-id>`, `/<project-alias>`, and `@branch`
|
||||||
- In-chat commands like `/cancel`, `/new`, `/ctx`, `/file …`, `/topic …`
|
- In-chat commands like `/cancel`, `/new`, `/ctx`, `/file …`, `/topic …`
|
||||||
- [Configuration](config.md)
|
- [Configuration](config.md)
|
||||||
- `takopi.toml` options and defaults
|
- `takopi.toml` options and defaults
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ To restore “only respond when invoked” behavior, use trigger mode:
|
|||||||
Explicit invocation includes any of:
|
Explicit invocation includes any of:
|
||||||
|
|
||||||
- `@botname` mention in the message.
|
- `@botname` mention in the message.
|
||||||
- `/engine` or `/project_alias` as the first token.
|
- `/<engine-id>` or `/<project-alias>` as the first token.
|
||||||
- Replying to a bot message.
|
- Replying to a bot message.
|
||||||
- Built-in or plugin slash commands (for example `/agent`, `/model`, `/reasoning`, `/file`, `/trigger`).
|
- Built-in or plugin slash commands (for example `/agent`, `/model`, `/reasoning`, `/file`, `/trigger`).
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ To pin a project or branch for the chat, use:
|
|||||||
|
|
||||||
`/new` clears the session but keeps the bound context.
|
`/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)
|
## Stateless (reply-to-continue)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Takopi keeps running in your terminal. In Telegram, your bot will post a startup
|
|||||||
🐙 takopi is ready
|
🐙 takopi is ready
|
||||||
|
|
||||||
default: codex<br>
|
default: codex<br>
|
||||||
agents: codex, claude<br>
|
engines: codex, claude<br>
|
||||||
projects: none<br>
|
projects: none<br>
|
||||||
mode: chat<br>
|
mode: chat<br>
|
||||||
topics: disabled<br>
|
topics: disabled<br>
|
||||||
@@ -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:
|
The engines/projects list reflects your setup. This tells you:
|
||||||
|
|
||||||
- Which engine is the default
|
- 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 projects are registered
|
||||||
- Which directory Takopi will run in
|
- 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
|
## 7. Try a different engine
|
||||||
|
|
||||||
Want to use a different agent for one message? Prefix your message with `/<engine>`:
|
Want to use a different engine for one message? Prefix your message with `/<engine>`:
|
||||||
|
|
||||||
!!! user "You"
|
!!! user "You"
|
||||||
/claude explain the error handling in this codebase
|
/claude explain the error handling in this codebase
|
||||||
|
|||||||
@@ -228,9 +228,9 @@ Once Takopi receives your message:
|
|||||||
Takopi scans your PATH for installed agent CLIs:
|
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
|
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
|
opencode ✗ not found npm install -g opencode-ai@latest
|
||||||
pi ✗ not found npm install -g @mariozechner/pi-coding-agent
|
pi ✗ not found npm install -g @mariozechner/pi-coding-agent
|
||||||
|
|
||||||
? choose default agent:
|
? choose default engine:
|
||||||
❯ codex
|
❯ codex
|
||||||
claude
|
claude
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# Multi-engine workflows
|
# 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?
|
## 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 |
|
| **Codex** | Fast edits, shell commands, quick fixes |
|
||||||
| **Claude Code** | Complex refactors, architecture, long context |
|
| **Claude Code** | Complex refactors, architecture, long context |
|
||||||
@@ -65,7 +65,7 @@ Use `/agent set` to change the default for the current scope:
|
|||||||
Response:
|
Response:
|
||||||
|
|
||||||
!!! takopi "Takopi"
|
!!! 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`).
|
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:
|
Example response:
|
||||||
|
|
||||||
!!! takopi "Takopi"
|
!!! takopi "Takopi"
|
||||||
agent: claude (chat default)<br>
|
engine: claude (chat default)<br>
|
||||||
defaults: topic: none, chat: claude, project: none, global: codex<br>
|
defaults: topic: none, chat: claude, project: none, global: codex<br>
|
||||||
available: codex, claude, opencode, pi
|
available: codex, claude, opencode, pi
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ Clear it:
|
|||||||
Response:
|
Response:
|
||||||
|
|
||||||
!!! takopi "Takopi"
|
!!! takopi "Takopi"
|
||||||
chat default agent cleared.
|
chat default engine cleared.
|
||||||
|
|
||||||
## 4. Defaults in topics
|
## 4. Defaults in topics
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This tutorial shows you how to register repos as projects and run tasks on feature branches without switching directories.
|
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 `/<project-alias>`, and run on branches with `@branch`.
|
||||||
|
|
||||||
## The problem
|
## The problem
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ Replies stay on the same branch. Your main checkout is untouched.
|
|||||||
|
|
||||||
## 5. Context persistence
|
## 5. Context persistence
|
||||||
|
|
||||||
Once you've set a context (via `/project @branch` or by replying), it sticks:
|
Once you've set a context (via `/<project-alias> @branch` or by replying), it sticks:
|
||||||
|
|
||||||
!!! user "You"
|
!!! user "You"
|
||||||
/happy-gadgets @feat/new-login add tests
|
/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"
|
default_project = "happy-gadgets"
|
||||||
```
|
```
|
||||||
|
|
||||||
Now messages without a `/project` prefix go to that repo:
|
Now messages without a `/<project-alias>` prefix go to that repo:
|
||||||
|
|
||||||
!!! user "You"
|
!!! user "You"
|
||||||
add a health check endpoint
|
add a health check endpoint
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def _build_startup_message(
|
|||||||
return (
|
return (
|
||||||
f"\N{OCTOPUS} **takopi is ready**\n\n"
|
f"\N{OCTOPUS} **takopi is ready**\n\n"
|
||||||
f"default: `{runtime.default_engine}` \n"
|
f"default: `{runtime.default_engine}` \n"
|
||||||
f"agents: `{engine_list}` \n"
|
f"engines: `{engine_list}` \n"
|
||||||
f"projects: `{project_list}` \n"
|
f"projects: `{project_list}` \n"
|
||||||
f"mode: `{session_mode}` \n"
|
f"mode: `{session_mode}` \n"
|
||||||
f"topics: `{topics_label}` \n"
|
f"topics: `{topics_label}` \n"
|
||||||
|
|||||||
@@ -25,17 +25,17 @@ async def _check_agent_permissions(
|
|||||||
reply = make_reply(cfg, msg)
|
reply = make_reply(cfg, msg)
|
||||||
sender_id = msg.sender_id
|
sender_id = msg.sender_id
|
||||||
if sender_id is None:
|
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
|
return False
|
||||||
if msg.is_private:
|
if msg.is_private:
|
||||||
return True
|
return True
|
||||||
member = await cfg.bot.get_chat_member(msg.chat_id, sender_id)
|
member = await cfg.bot.get_chat_member(msg.chat_id, sender_id)
|
||||||
if member is None:
|
if member is None:
|
||||||
await reply(text="failed to verify agent permissions.")
|
await reply(text="failed to verify engine permissions.")
|
||||||
return False
|
return False
|
||||||
if member.status in {"creator", "administrator"}:
|
if member.status in {"creator", "administrator"}:
|
||||||
return True
|
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
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ async def _handle_agent_command(
|
|||||||
"project_default": "project default",
|
"project_default": "project default",
|
||||||
"global_default": "global 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
|
topic_override = None
|
||||||
if tkey is not None and topic_store is not None:
|
if tkey is not None and topic_store is not None:
|
||||||
topic_override = await topic_store.get_engine_override(
|
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:
|
if engine not in cfg.runtime.engine_ids:
|
||||||
available = ", ".join(cfg.runtime.engine_ids)
|
available = ", ".join(cfg.runtime.engine_ids)
|
||||||
await reply(
|
await reply(
|
||||||
text=f"unknown engine `{engine}`.\navailable agents: `{available}`",
|
text=f"unknown engine `{engine}`.\navailable engines: `{available}`",
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if tkey is not None:
|
if tkey is not None:
|
||||||
@@ -167,13 +167,13 @@ async def _handle_agent_command(
|
|||||||
await reply(text="topic defaults are unavailable.")
|
await reply(text="topic defaults are unavailable.")
|
||||||
return
|
return
|
||||||
await topic_store.set_default_engine(tkey[0], tkey[1], engine)
|
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
|
return
|
||||||
if chat_prefs is None:
|
if chat_prefs is None:
|
||||||
await reply(text="chat defaults are unavailable (no config path).")
|
await reply(text="chat defaults are unavailable (no config path).")
|
||||||
return
|
return
|
||||||
await chat_prefs.set_default_engine(msg.chat_id, engine)
|
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
|
return
|
||||||
|
|
||||||
if action == "clear":
|
if action == "clear":
|
||||||
@@ -184,13 +184,13 @@ async def _handle_agent_command(
|
|||||||
await reply(text="topic defaults are unavailable.")
|
await reply(text="topic defaults are unavailable.")
|
||||||
return
|
return
|
||||||
await topic_store.clear_default_engine(tkey[0], tkey[1])
|
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
|
return
|
||||||
if chat_prefs is None:
|
if chat_prefs is None:
|
||||||
await reply(text="chat defaults are unavailable (no config path).")
|
await reply(text="chat defaults are unavailable (no config path).")
|
||||||
return
|
return
|
||||||
await chat_prefs.clear_default_engine(msg.chat_id)
|
await chat_prefs.clear_default_engine(msg.chat_id)
|
||||||
await reply(text="chat default agent cleared.")
|
await reply(text="chat default engine cleared.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await reply(text=AGENT_USAGE)
|
await reply(text=AGENT_USAGE)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def build_bot_commands(
|
|||||||
cmd = engine_id.lower()
|
cmd = engine_id.lower()
|
||||||
if cmd in seen:
|
if cmd in seen:
|
||||||
continue
|
continue
|
||||||
commands.append({"command": cmd, "description": f"use agent: {cmd}"})
|
commands.append({"command": cmd, "description": f"use engine: {cmd}"})
|
||||||
seen.add(cmd)
|
seen.add(cmd)
|
||||||
for alias in runtime.project_aliases():
|
for alias in runtime.project_aliases():
|
||||||
cmd = alias.lower()
|
cmd = alias.lower()
|
||||||
@@ -73,7 +73,7 @@ def build_bot_commands(
|
|||||||
for cmd, description in [
|
for cmd, description in [
|
||||||
("new", "start a new thread"),
|
("new", "start a new thread"),
|
||||||
("ctx", "show or update context"),
|
("ctx", "show or update context"),
|
||||||
("agent", "set default agent"),
|
("agent", "set default engine"),
|
||||||
("model", "set model override"),
|
("model", "set model override"),
|
||||||
("reasoning", "set reasoning override"),
|
("reasoning", "set reasoning override"),
|
||||||
("trigger", "set trigger mode"),
|
("trigger", "set trigger mode"),
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ async def _handle_model_command(
|
|||||||
if engine not in engine_ids:
|
if engine not in engine_ids:
|
||||||
available = ", ".join(cfg.runtime.engine_ids)
|
available = ", ".join(cfg.runtime.engine_ids)
|
||||||
await reply(
|
await reply(
|
||||||
text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
|
text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
scope = await apply_engine_override(
|
scope = await apply_engine_override(
|
||||||
@@ -187,7 +187,7 @@ async def _handle_model_command(
|
|||||||
if engine not in engine_ids:
|
if engine not in engine_ids:
|
||||||
available = ", ".join(cfg.runtime.engine_ids)
|
available = ", ".join(cfg.runtime.engine_ids)
|
||||||
await reply(
|
await reply(
|
||||||
text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
|
text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
scope = await apply_engine_override(
|
scope = await apply_engine_override(
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ async def _handle_reasoning_command(
|
|||||||
if engine not in engine_ids:
|
if engine not in engine_ids:
|
||||||
available = ", ".join(cfg.runtime.engine_ids)
|
available = ", ".join(cfg.runtime.engine_ids)
|
||||||
await reply(
|
await reply(
|
||||||
text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
|
text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
normalized_level = level.strip().lower()
|
normalized_level = level.strip().lower()
|
||||||
@@ -206,7 +206,7 @@ async def _handle_reasoning_command(
|
|||||||
if engine not in engine_ids:
|
if engine not in engine_ids:
|
||||||
available = ", ".join(cfg.runtime.engine_ids)
|
available = ", ".join(cfg.runtime.engine_ids)
|
||||||
await reply(
|
await reply(
|
||||||
text=f"unknown engine `{engine}`.\navailable agents: `{available}`"
|
text=f"unknown engine `{engine}`.\navailable engines: `{available}`"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
scope = await apply_engine_override(
|
scope = await apply_engine_override(
|
||||||
|
|||||||
@@ -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:
|
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()
|
rows = svc.list_engines()
|
||||||
render_engine_table(ui, rows)
|
render_engine_table(ui, rows)
|
||||||
installed_ids = [engine_id for engine_id, installed, _ in rows if installed]
|
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:
|
if installed_ids:
|
||||||
ui.print("")
|
ui.print("")
|
||||||
default_engine = await ui.select(
|
default_engine = await ui.select(
|
||||||
"choose default agent:",
|
"choose default engine:",
|
||||||
choices=[(engine_id, engine_id) for engine_id in installed_ids],
|
choices=[(engine_id, engine_id) for engine_id in installed_ids],
|
||||||
)
|
)
|
||||||
state.default_engine = require_value(default_engine)
|
state.default_engine = require_value(default_engine)
|
||||||
return
|
return
|
||||||
|
|
||||||
ui.print("no agents found. install one and rerun --onboard.")
|
ui.print("no engines found. install one and rerun --onboard.")
|
||||||
ui.print("")
|
ui.print("")
|
||||||
save_anyway = await ui.confirm("save config anyway?", default=False)
|
save_anyway = await ui.confirm("save config anyway?", default=False)
|
||||||
if not save_anyway:
|
if not save_anyway:
|
||||||
@@ -945,7 +945,7 @@ STEPS: list[OnboardingStep] = [
|
|||||||
OnboardingStep("bot token", 1, step_token_and_bot),
|
OnboardingStep("bot token", 1, step_token_and_bot),
|
||||||
OnboardingStep("pick your workflow", 2, step_persona),
|
OnboardingStep("pick your workflow", 2, step_persona),
|
||||||
OnboardingStep("connect chat", 3, step_capture_chat),
|
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),
|
OnboardingStep("save config", 5, step_save_config),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ async def test_agent_show_private_defaults() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
text = _last_text(transport)
|
text = _last_text(transport)
|
||||||
assert "agent: codex" in text
|
assert "engine: codex" in text
|
||||||
assert "available: 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 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(
|
await _handle_agent_command(
|
||||||
cfg,
|
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 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
|
@pytest.mark.anyio
|
||||||
@@ -135,7 +135,7 @@ async def test_agent_set_invalid_engine(tmp_path: Path) -> None:
|
|||||||
|
|
||||||
text = _last_text(transport)
|
text = _last_text(transport)
|
||||||
assert "unknown engine" in text
|
assert "unknown engine" in text
|
||||||
assert "available agents" in text
|
assert "available engines" in text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ def test_build_startup_message_includes_missing_engines(tmp_path: Path) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert "takopi is ready" in message
|
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
|
assert "projects: `none`" in message
|
||||||
|
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ def test_build_startup_message_surfaces_unavailable_engine_reasons(
|
|||||||
topics=TelegramTopicsSettings(),
|
topics=TelegramTopicsSettings(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert "agents: `codex" in message
|
assert "engines: `codex" in message
|
||||||
assert "misconfigured: pi" in message
|
assert "misconfigured: pi" in message
|
||||||
assert "failed to load: claude" in message
|
assert "failed to load: claude" in message
|
||||||
|
|
||||||
|
|||||||
@@ -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": "file", "description": "upload or fetch files"} in commands
|
||||||
assert {"command": "new", "description": "start a new thread"} in commands
|
assert {"command": "new", "description": "start a new thread"} in commands
|
||||||
assert {"command": "ctx", "description": "show or update context"} 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)
|
assert any(cmd["command"] == "codex" for cmd in commands)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user