返回 DeepSeek-Reasonix
BOT_GUIDE.md
根目录 / docs / BOT_GUIDE.md
1 # Reasonix Bot Guide
2
3 <a href="../README.md">README</a>
4 &nbsp;·&nbsp;
5 <a href="./BOT_GUIDE.zh-CN.md">简体中文</a>
6 &nbsp;·&nbsp;
7 <a href="./GUIDE.md">General guide</a>
8
9 > For desktop and CLI users. This guide explains how to connect Feishu, Lark,
10 > WeChat, and QQ bots, how to use Reasonix from IM, and how approvals, Ask
11 > questions, YOLO, and bot commands work.
12
13 ## Contents
14
15 - [What the bot does](#what-the-bot-does)
16 - [Where it runs](#where-it-runs)
17 - [Connect the four channels](#connect-the-four-channels)
18 - [Run the bot headlessly](#run-the-bot-headlessly)
19 - [Usage flow](#usage-flow)
20 - [Channel interaction differences](#channel-interaction-differences)
21 - [Command quick reference](#command-quick-reference)
22 - [Approvals and YOLO](#approvals-and-yolo)
23 - [Do upgrades require rebinding?](#do-upgrades-require-rebinding)
24 - [Troubleshooting](#troubleshooting)
25
26 ## What the bot does
27
28 After a bot is connected, you can send Reasonix messages from Feishu, Lark,
29 WeChat, or QQ. The desktop app or `reasonix bot start` process handles the
30 model, tools, permissions, sandboxing, and local context, then sends progress
31 and results back to the IM channel.
32
33 Common uses:
34
35 - Ask Reasonix to inspect code, read docs, explain errors, or summarize findings.
36 - Trigger tool calls from IM and receive progress or final results in the chat.
37 - Approve or deny sensitive actions such as file writes or shell commands.
38 - Enable YOLO for trusted temporary work so ordinary tool approvals are skipped.
39 - Open the matching desktop IM session to inspect context, cost, tokens, and tool
40 traces.
41
42 ## Where it runs
43
44 The bot gateway is a shared Go runtime. The same core behavior works on
45 Windows, macOS, and Linux; platform differences mostly come from each IM
46 provider's credentials, network reachability, callback/WebSocket setup, and
47 saved local account state.
48
49 There are two supported entry points:
50
51 - **Desktop runtime**: configure bots in **Settings -> Bots**. The desktop app
52 starts the gateway, keeps status in the app, persists per-connection tool
53 approval mode changes, and lets you open matching local IM sessions.
54 - **CLI runtime**: run `reasonix bot start` for a headless long-lived process.
55 It uses the same config, allowlist, routes, queue settings, pairing store,
56 adapters, and project/session index as the desktop runtime.
57
58 The normal `reasonix run` command does not automatically start the IM gateway.
59 Remote bot behavior is active only while the desktop bot runtime is running or
60 while a `reasonix bot start` process is alive.
61
62 ## Connect the four channels
63
64 Open the Reasonix desktop app and go to **Settings -> Bots**. In **Add IM Bot**,
65 choose a channel and scan the QR code.
66
67 ```mermaid
68 flowchart LR
69 A["Open desktop settings"] --> B["Bots"]
70 B --> C["Add IM Bot"]
71 C --> D{"Choose channel"}
72 D --> E["Scan with Feishu to create a PersonalAgent"]
73 D --> F["Scan with Lark to create a PersonalAgent"]
74 D --> G["Scan with WeChat to sign in Bot Assistant"]
75 D --> H["Manual setup for QQ Bot"]
76 E --> I["Connection is saved locally"]
77 F --> I
78 G --> I
79 H --> I
80 I --> J["Send the first IM message"]
81 J --> K["Desktop creates the matching session"]
82 ```
83
84 ### Feishu
85
86 1. In **Settings -> Bots -> Add IM Bot**, choose **Feishu**.
87 2. Generate a QR code.
88 3. Scan it with Feishu and finish authorization.
89 4. Wait until the page shows the connection as connected.
90 5. Send the bot a message such as `hello` or `please inspect this error`.
91
92 ### Lark
93
94 1. In **Settings -> Bots -> Add IM Bot**, choose **Lark**.
95 2. Generate a QR code.
96 3. Scan it with Lark and finish authorization.
97 4. Wait until the page shows the connection as connected.
98 5. Send the Lark bot a message.
99
100 Feishu and Lark share the same capability set, but they are saved as separate
101 connections. You can give them different models, working directories, or tool
102 approval modes. Bot text replies are sent as standalone Interactive Card JSON
103 2.0 markdown, which avoids Feishu/Lark platform quote prefixes while preserving
104 CommonMark formatting. If a card is too large for the platform limit, Reasonix
105 falls back to plain text automatically.
106
107 For webhook mode, configure a verification token. Incoming webhook events are
108 verified fail-closed: an empty or missing configured token rejects callers
109 instead of silently opening the webhook.
110
111 ### WeChat
112
113 1. In **Settings -> Bots -> Add IM Bot**, choose **WeChat**.
114 2. Generate a QR code.
115 3. Scan it with WeChat to sign in to Bot Assistant.
116 4. Wait until the page shows the connection as connected.
117 5. Send the WeChat bot a message.
118
119 WeChat does not provide interactive card buttons here, so approvals use numeric
120 or text commands. Ask questions can be answered by replying with normal text,
121 option numbers, or `/answer <id> <answer>`.
122
123 ### QQ
124
125 1. In **Settings -> Bots -> Add IM Bot**, choose **QQ**.
126 2. Fill in the **App ID** and **App Secret** (or set the env var `QQ_BOT_APP_SECRET`).
127 3. Click **Save** to store the credentials.
128 4. Wait until the page shows the connection as connected.
129 5. Send the QQ bot a message.
130
131 QQ Bot uses the official QQ Bot platform API. It supports inline keyboard
132 buttons for approvals. Ask questions are sent as text; reply with normal text,
133 option numbers, or `/answer <id> <answer>`. When a button expires or the
134 platform reports an action failure, copy the ID shown in the card and send the
135 equivalent text command.
136
137 QQ does not support QR-code scanning for connection setup. You must configure
138 the App ID and App Secret manually. The adapter reads only the configured
139 `app_secret_env` value; it does not fall back to an unrelated `QQ_SECRET`
140 environment variable. QQ and WeChat HTTP calls use bounded clients so a stalled
141 provider request cannot block the gateway indefinitely.
142
143 ## Run the bot headlessly
144
145 The desktop app is the easiest way to create and test bot connections, but the
146 runtime itself can also run as a long-lived headless gateway:
147
148 ```sh
149 reasonix bot doctor
150 reasonix bot doctor --deep
151 reasonix bot start --channels qq,feishu,lark,weixin --dir /path/to/project
152 ```
153
154 Use `--channels` to choose which configured IM inputs to accept. `feishu` and
155 `lark` select the matching Feishu-family connection; `weixin` selects the saved
156 WeChat iLink account; `qq` selects the configured QQ bot. Use `--dir` to attach
157 incoming messages to a project workspace and `--model` to override the default
158 model for this process.
159
160 The headless gateway uses the same config records as the desktop app:
161
162 - `[[bot.connections]]` identifies each IM input. `provider` is the adapter
163 family (`feishu`, `weixin`, or `qq`), while `domain` distinguishes variants
164 such as Feishu vs Lark.
165 - `credential.app_id`, `credential.app_secret_env`, `credential.account_id`,
166 and `credential.token_env` point to app IDs, app secrets, saved accounts, and
167 tokens. Secrets stay in environment variables or the Reasonix user credentials
168 store.
169 - `workspace_root`, `model`, and `tool_approval_mode` can be set per
170 connection. This lets different IM channels route to different local projects
171 or approval postures.
172 - `access` can also be set per connection with `enabled`, `allow_all`,
173 `pairing_enabled`, `users`, `groups`, `admins`, and `approvers`. When a
174 connection has active access settings, they are checked before the legacy
175 global `[bot.allowlist]`.
176 - `[[bot.routes]]` adds finer routing by connection, platform, chat type, chat
177 ID, user ID, or thread ID. Empty match fields are wildcards; the first matching
178 route wins and can override `workspace_root`, `model`, and
179 `tool_approval_mode`.
180 - `session_mappings` are filled from inbound messages with the remote chat ID
181 and scope. The desktop UI can open the matching conversation once the mapping
182 also has a local `session_id` target, such as a saved `path:` session target
183 from a desktop-managed bot runtime or a manually configured mapping.
184 - The bot's project/session index is intentionally bounded to configured
185 `workspace_root` values, route workspaces, active bot sessions, and saved
186 `session_mappings`. Commands such as `/use project` and `/attach session`
187 can only jump to those indexed targets; arbitrary local directories are not
188 accepted from IM text.
189
190 Access control is still mandatory. New desktop-created bots should normally set
191 access inside that bot's own detail panel, which saves to `[[bot.connections]]`
192 or `[bot.qq].access`. The legacy global `[bot.allowlist]` remains a fallback for
193 older configs and for connections without active per-bot access. You can
194 deliberately set `allow_all = true`, or enable `pairing_enabled` for a single
195 bot / `[bot.pairing]` globally so an unknown DM sender receives a one-time
196 pairing code. That code must be approved locally with
197 `reasonix bot pairing approve <code>` before the sender can drive the bot; when
198 the request is tied to a connection, approval adds the sender to that
199 connection's access list. Users listed in `admins` / `approvers` or the legacy
200 `*_admins` / `*_approvers` also receive base bot admission, so they do not need
201 to be duplicated in `users` / `*_users`. Group chats are not opened by DM
202 pairing or role admission; group IDs remain an additional narrowing layer.
203 Use these commands to manage pending requests:
204
205 ```sh
206 reasonix bot pairing list
207 reasonix bot pairing approve CODE
208 reasonix bot pairing reject CODE
209 ```
210
211 If `qq_admins`, `feishu_admins`, `weixin_admins`, or the matching
212 `*_approvers` lists are configured, `/yolo` and `/mode` are admin-only while
213 `/projects`, `/use project`, `/sessions`, `/attach session`, and `/search all`
214 are also admin-only. `/approve` and `/deny` require an approver or admin. When
215 no role lists are set, existing allowlisted users keep the previous command
216 behavior for compatibility. Remote users go through the same controller,
217 permission policy, tool approval mode, and sandbox rules as local desktop or CLI
218 turns.
219
220 ```toml
221 [bot.allowlist]
222 enabled = true
223 feishu_users = ["ou_member"]
224 feishu_admins = ["ou_admin"]
225 feishu_approvers = ["ou_approver"]
226 ```
227
228 `ignore_self_messages = true` is enabled by default. The gateway remembers the
229 platform `message_id` values it just sent and ignores matching echo events. If a
230 platform does not echo the same message ID reliably, configure the bot's own user
231 IDs under `[bot.self_user_ids]` as a second layer of loop protection. `/status`
232 also includes the current queue mode and adapter health, such as
233 `feishu-lark=running` or `weixin-weixin=degraded`.
234
235 The optional `[bot.control]` section exposes a local loopback HTTP API and is
236 disabled by default. When enabled, `token_env` must point to an environment
237 variable and every request must include `Authorization: Bearer <token>`. The
238 server only binds to `localhost`, `127.0.0.1`, or `::1`. Current endpoints are
239 `GET /status` for session and adapter health snapshots, `GET /metrics` for
240 Prometheus text metrics, and `POST /send` for sending text or media through a
241 configured connection.
242
243 Example:
244
245 ```sh
246 export REASONIX_BOT_CONTROL_TOKEN="change-me"
247
248 curl -H "Authorization: Bearer $REASONIX_BOT_CONTROL_TOKEN" \
249 http://127.0.0.1:37913/status
250
251 curl -X POST http://127.0.0.1:37913/send \
252 -H "Authorization: Bearer $REASONIX_BOT_CONTROL_TOKEN" \
253 -H "Content-Type: application/json" \
254 -d '{
255 "connection_id": "feishu-lark",
256 "domain": "lark",
257 "chat_id": "oc_xxx",
258 "chat_type": "dm",
259 "text": "hello from local control API"
260 }'
261 ```
262
263 ## Usage flow
264
265 ```mermaid
266 sequenceDiagram
267 participant U as "User"
268 participant IM as "Feishu / Lark / WeChat / QQ"
269 participant R as "Reasonix desktop or bot start"
270 participant T as "Local tools and model"
271
272 U->>IM: "Send a request"
273 IM->>R: "Message enters the local bot gateway"
274 R->>T: "Model reasons and calls tools"
275 alt "Normal reply"
276 R-->>IM: "Send answer"
277 else "Approval required"
278 R-->>IM: "Send approval card or approval text"
279 U->>IM: "Allow or deny"
280 IM->>R: "Approval command"
281 R->>T: "Continue or stop the tool call"
282 R-->>IM: "Send result"
283 else "User choice required"
284 R-->>IM: "Send Ask question"
285 U->>IM: "Choose an option or reply with /answer"
286 R-->>IM: "Continue and send result"
287 end
288 ```
289
290 The **Bots** entry in the desktop sidebar lists connected bots. After the first
291 IM message arrives, you can open the matching local session from there to inspect
292 context, tool traces, cost, and runtime metrics.
293
294 ## Channel interaction differences
295
296 The following images are synthetic examples. They show the interaction shape
297 without exposing real account IDs, local paths, or private chat content.
298
299 ![Feishu approval card example](./assets/bot-feishu-approval.svg)
300
301 ![Lark YOLO mode example](./assets/bot-lark-yolo.svg)
302
303 ![WeChat text command example](./assets/bot-weixin-text-commands.svg)
304
305 ![QQ approval card example](./assets/bot-qq-approval.svg)
306
307 | Channel | Connection | Approval | Ask questions | Best for |
308 | --- | --- | --- | --- | --- |
309 | Feishu | Scan to create a PersonalAgent | Interactive card buttons, or commands | Interactive card buttons, or commands | Feishu workspaces, DMs, and groups |
310 | Lark | Scan to create a PersonalAgent | Interactive card buttons, or commands | Interactive card buttons, or commands | International Lark workspaces |
311 | WeChat | Scan with WeChat | Reply `1` / `2`, or commands | Reply with normal text, option numbers, or commands | Lightweight personal/mobile testing |
312 | QQ | Manual setup (App ID + App Secret) | Inline keyboard buttons, numeric replies, or commands | Reply with normal text, option numbers, or commands | QQ groups, DMs, and official QQ Bot platform |
313
314 Feishu and Lark card buttons are converted into commands such as
315 `/approve <id>`, `/deny <id>`, or `/answer <id> <option>`. QQ approval buttons
316 work the same way. If a button expires or the platform reports an action
317 failure, copy the ID shown in the card and send the equivalent text command.
318
319 ## Command quick reference
320
321 These commands work in Feishu, Lark, WeChat, and QQ.
322
323 | Command | Purpose | Example |
324 | --- | --- | --- |
325 | `/help` | Show available commands | `/help` |
326 | `/status` | Show active tasks, queue state, tool approval mode, and adapter health | `/status` |
327 | `/stop` | Stop the current task | `/stop` |
328 | `/new` | Start a fresh session | `/new` |
329 | `/reset` | Reset the current session | `/reset` |
330 | `/approve <id>` | Approve a pending operation | `/approve 1` |
331 | `/deny <id>` | Deny a pending operation | `/deny 1` |
332 | `/answer <id> <option>` | Answer an Ask question | `/answer ask-1 2` |
333 | `/yolo` | Enable YOLO | `/yolo` |
334 | `/yolo on` | Enable YOLO | `/yolo on` |
335 | `/yolo off` | Return to Ask mode | `/yolo off` |
336 | `/yolo auto` | Switch to Auto approval mode | `/yolo auto` |
337 | `/yolo status` | Show the current tool approval mode | `/yolo status` |
338 | `/mode yolo` | Switch to YOLO | `/mode yolo` |
339 | `/mode ask` | Switch to Ask mode | `/mode ask` |
340 | `/mode auto` | Switch to Auto mode | `/mode auto` |
341 | `/queue status` | Show the current queue mode | `/queue status` |
342 | `/queue steer` | Treat mid-run messages as guidance for the current task | `/queue steer` |
343 | `/queue followup` | Queue mid-run messages as later turns | `/queue followup` |
344 | `/queue collect` | Merge queued messages into one later turn | `/queue collect` |
345 | `/queue interrupt` | Cancel the current task and keep the newest message | `/queue interrupt` |
346 | `/projects [query]` | List indexed project workspaces | `/projects reasonix` |
347 | `/use project <id\|name>` | Route this remote session to an indexed project | `/use project p1` |
348 | `/use project default` | Clear the project override and return to configured routing | `/use project default` |
349 | `/sessions search <query>` | Search indexed desktop/bot sessions | `/sessions search release bug` |
350 | `/attach session <id\|query>` | Continue this remote session from an indexed `path:` transcript | `/attach session s1` |
351 | `/search all <query>` | Search file contents across indexed project roots | `/search all TODO` |
352
353 Shortcut replies:
354
355 - When an approval is pending, reply `1` to approve and `2` to deny.
356 - When an Ask question is pending, reply with any normal non-slash text. Option
357 numbers still work for choice questions.
358 - Slash commands such as `/stop`, `/mode`, or `/answer ...` are not captured as
359 Ask shortcut replies.
360 - If there is no pending operation, `1` / `2` are treated as normal text or
361 produce guidance.
362
363 The default queue mode is `steer`: when the same session is already running, a
364 new message is injected as mid-turn guidance instead of waiting for the whole
365 turn to finish. `queue_cap` and `queue_drop` bound backlog growth in config.
366 `reasonix bot doctor --deep` reports queue, pairing, and role diagnostics.
367
368 Queue modes:
369
370 - `steer`: mid-run messages become guidance for the current turn when possible.
371 - `followup`: mid-run messages are queued as later turns.
372 - `collect`: queued messages are merged into one later turn.
373 - `interrupt`: the active turn is canceled and the newest message is kept as the
374 next turn.
375
376 Project and session navigation:
377
378 - `/projects [query]` lists workspaces from configured bot routes, connection
379 workspaces, active bot sessions, and saved session mappings.
380 - `/use project <id|name>` pins the current remote session to one indexed
381 project. `/use project default` clears the override.
382 - `/sessions search <query>` searches indexed desktop and bot session metadata.
383 - `/attach session <id|query>` continues the remote session from an indexed
384 `path:` transcript.
385 - `/search all <query>` searches file contents across indexed project roots.
386 Reasonix uses `rg` when available and falls back to a bounded Go scanner.
387
388 These navigation commands never accept arbitrary paths typed from IM. They only
389 jump to indexed targets and, when role lists are configured, require an admin.
390
391 When an adapter supplies media URLs, the gateway downloads those files into the
392 current workspace's `.reasonix/attachments` directory and passes them to
393 Reasonix as `@.reasonix/attachments/...` references. If an attachment cannot be
394 saved, the bot sends a short warning and continues with the available text. The
395 built-in Feishu, Weixin, and QQ adapters currently focus on text events; ordinary
396 IM attachment extraction can be added at the adapter layer.
397
398 ## Approvals and YOLO
399
400 Reasonix bots use the same permission system as the desktop app. Ask mode is the
401 default: sensitive tool calls such as file writes and shell commands request
402 confirmation first.
403
404 ```mermaid
405 flowchart TD
406 A["Model prepares a tool call"] --> B{"Matches a deny rule?"}
407 B -- "Yes" --> C["Block immediately"]
408 B -- "No" --> D{"Tool approval mode"}
409 D -- "Ask" --> E["Send approval to IM"]
410 D -- "Auto" --> F["Auto-allow when policy permits"]
411 D -- "YOLO" --> G["Skip ordinary tool approvals"]
412 E --> H{"User choice"}
413 H -- "Allow" --> I["Run tool"]
414 H -- "Deny" --> J["Stop that operation"]
415 F --> I
416 G --> I
417 ```
418
419 YOLO boundaries:
420
421 - YOLO skips ordinary tool approval prompts.
422 - YOLO does not bypass hard `deny` rules.
423 - YOLO does not answer model Ask questions for you.
424 - YOLO does not approve plan-mode plan approvals for you.
425
426 Recommendations:
427
428 - Use `/yolo` for temporary trusted debugging or fast local iteration.
429 - Use `/mode ask` for risky work, production code, or anything uncertain.
430 - Use `/mode auto` when you want fewer routine prompts while keeping policy
431 decisions.
432
433 ## Do upgrades require rebinding?
434
435 No. A normal Reasonix app upgrade or overwrite install does not require
436 rebinding.
437
438 Bindings are stored in the user's Reasonix data, not inside the app bundle:
439
440 - Bot connections, remote IDs, allowlists, model choices, and approval modes are
441 stored in the user config.
442 - Feishu and Lark secrets are stored in Reasonix's global
443 `<Reasonix home>/.env`, shared by CLI and desktop.
444 - The WeChat scanned account token is stored in the Reasonix user data
445 directory.
446 - The QQ App ID is stored in user config; the App Secret is stored under the
447 configured env var, `QQ_BOT_APP_SECRET` by default, in the global credentials
448 file.
449
450 You may need to bind again if:
451
452 - The Reasonix user config directory was deleted.
453 - You changed machines or OS users.
454 - Authorization was revoked on the platform side.
455 - The WeChat token expired.
456 - Feishu or Lark app secrets were cleared.
457 - The QQ App ID changed, or the configured QQ App Secret env var was cleared.
458
459 ## Troubleshooting
460
461 | Symptom | What to check |
462 | --- | --- |
463 | QR code says the link expired | Generate a new QR code in Settings; QR codes expire (Feishu, Lark, WeChat only — QQ uses manual setup and has no QR code). |
464 | Connected but no reply | Make sure the desktop bot runtime or `reasonix bot start` process is running, the bot connection is enabled, and the sender ID is allowlisted, paired, or access is open. |
465 | Feishu or Lark button action fails | Send the text command from the card, such as `/approve <id>` or `/deny <id>`. |
466 | QQ button action fails | Same as Feishu/Lark — send the text command from the card, such as `/approve <id>` or `/deny <id>`. |
467 | WeChat reply `1` does nothing | Numeric shortcuts only work when an approval or Ask is pending; use the full command if needed. |
468 | QQ reply `1` does nothing | Same as WeChat — numeric shortcuts only work when an approval or Ask is pending; use the full command if needed. |
469 | Need to confirm the current mode | Send `/status` or `/yolo status`. |
470 | Need a fresh context | Send `/new` or `/reset`. |
471 | Need to stop the current task | Send `/stop`. |
472
473 If connectivity still fails, open the connection's advanced settings in
474 **Settings -> Bots** and use the configuration check, test send, and runtime
475 settings to locate the issue.
476
476 lines MARKDOWN