@trusted-ai/xbot 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/USAGE.md ADDED
@@ -0,0 +1,1002 @@
1
+ # xbot Usage Guide
2
+
3
+ ## 1. Install and Initialize
4
+
5
+ From the project root:
6
+
7
+ ```bash
8
+ cd xbot
9
+ cargo run --release -- onboard
10
+ ```
11
+
12
+ For packaged installs through npm, `.deb`, or `cargo install`, see [Installation](./INSTALLATION.md).
13
+
14
+ This creates:
15
+
16
+ - `~/.xbot/config.json`
17
+ - `~/.xbot/workspace/`
18
+ - a hidden runtime state directory at `<workspace>/.xbot/`
19
+ - workspace bootstrap files such as `.xbot/AGENTS.md`, `.xbot/SOUL.md`, `.xbot/USER.md`, `.xbot/TOOLS.md`, `.xbot/HEARTBEAT.md`, and memory files
20
+ - starter workspace skills under `.xbot/skills/`, including a memory-hygiene skill and editable project templates
21
+
22
+ ## 2. Interactive Configuration
23
+
24
+ Instead of manually editing `~/.xbot/config.json`, you can use the interactive CLI:
25
+
26
+ ### 2.1 Provider Configuration
27
+
28
+ Configure your LLM providers (OpenAI, Anthropic, OpenRouter, Ollama, vLLM, etc.):
29
+
30
+ ```bash
31
+ cargo run --release -- config --provider
32
+ ```
33
+
34
+ The CLI will guide you through:
35
+ 1. Selecting a provider from the list.
36
+ 2. Entering your API key (if required).
37
+ 3. Fetching and selecting from available models.
38
+ 4. Setting the default model and provider for the agent.
39
+ 5. Optionally configuring a separate provider/API base or model for background subagents.
40
+
41
+ ### 2.2 Channel Configuration
42
+
43
+ Configure communication channels (Telegram, Slack, Email, etc.):
44
+
45
+ ```bash
46
+ cargo run --release -- config --channel
47
+ ```
48
+
49
+ You can selectively enable channels, set permissions (`allowFrom`), and provide necessary tokens or secrets interactively.
50
+
51
+ ## 3. Choose a Provider (Manual)
52
+
53
+ `xbot` talks to providers through an OpenAI-compatible chat interface.
54
+
55
+ Supported practical modes:
56
+
57
+ - Remote API providers such as OpenAI-compatible gateways
58
+ - Local engines such as Ollama and vLLM
59
+ - Custom local or remote OpenAI-compatible servers
60
+
61
+ ### Openrouter example
62
+
63
+ ```json
64
+ {
65
+ "agents": {
66
+ "defaults": {
67
+ "model": "minimax/minimax-m2.7",
68
+ "provider": "openrouter"
69
+ }
70
+ },
71
+ "providers": {
72
+ "openrouter": {
73
+ "apiKey": "sk-or-v1-...",
74
+ "extraHeaders": {}
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ### OpenAI-compatible remote example
81
+
82
+ ```json
83
+ {
84
+ "agents": {
85
+ "defaults": {
86
+ "model": "openai/gpt-4.1-mini",
87
+ "provider": "openai"
88
+ }
89
+ },
90
+ "providers": {
91
+ "openai": {
92
+ "apiKey": "sk-..."
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### Ollama example
99
+
100
+ `xbot` supports Ollama as a local provider without requiring an API key.
101
+
102
+ Start Ollama first:
103
+
104
+ ```bash
105
+ ollama serve
106
+ ollama pull qwen2.5-coder:7b
107
+ ```
108
+
109
+ Then configure:
110
+
111
+ ```json
112
+ {
113
+ "agents": {
114
+ "defaults": {
115
+ "model": "ollama/qwen2.5-coder:7b",
116
+ "provider": "ollama"
117
+ }
118
+ },
119
+ "providers": {
120
+ "ollama": {
121
+ "apiBase": "http://localhost:11434/v1"
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ ### vLLM example
128
+
129
+ If you are serving a model with vLLM on port `8000`:
130
+
131
+ ```json
132
+ {
133
+ "agents": {
134
+ "defaults": {
135
+ "model": "vllm/Qwen/Qwen2.5-7B-Instruct",
136
+ "provider": "vllm"
137
+ }
138
+ },
139
+ "providers": {
140
+ "vllm": {
141
+ "apiBase": "http://localhost:8000/v1"
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### LM Studio or another local OpenAI-compatible server
148
+
149
+ Use the `custom` provider:
150
+
151
+ ```json
152
+ {
153
+ "agents": {
154
+ "defaults": {
155
+ "model": "custom/local-model",
156
+ "provider": "custom"
157
+ }
158
+ },
159
+ "providers": {
160
+ "custom": {
161
+ "apiBase": "http://127.0.0.1:1234/v1",
162
+ "apiKey": ""
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ Notes:
169
+
170
+ - Known local providers such as `ollama` and `vllm` do not require an API key.
171
+ - Custom providers can use an empty API key when the upstream server does not require auth.
172
+ - The model string can be any identifier accepted by the target backend.
173
+
174
+ ### Subagent model/provider override
175
+
176
+ By default, background subagents use the same provider and model as the main task. You can run subagents on a cheaper or faster model by setting `agents.subagents`.
177
+
178
+ For a complete remote-main/local-subagent walkthrough, including DeepSeek `deepseek-v4-pro` as the main model and a local Qwen model for subagents, see [Hybrid Remote Main + Local Subagents](./HYBRID_MODELS.md).
179
+
180
+ Example: main task uses a heavier OpenAI model, while subagents use a local OpenAI-compatible server:
181
+
182
+ ```json
183
+ {
184
+ "agents": {
185
+ "defaults": {
186
+ "model": "openai/gpt-4.1",
187
+ "provider": "openai"
188
+ },
189
+ "subagents": {
190
+ "model": "qwen2.5-coder:7b",
191
+ "provider": "subagent-fast",
192
+ "apiBase": "http://127.0.0.1:8001/v1"
193
+ }
194
+ },
195
+ "providers": {
196
+ "openai": {
197
+ "apiKey": "sk-..."
198
+ },
199
+ "subagent-fast": {
200
+ "apiKey": "",
201
+ "apiBase": "http://127.0.0.1:8001/v1"
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ `agents.subagents.model` is optional. If it is empty or omitted, subagents inherit the main task model. `agents.subagents.provider` defaults to `"auto"`. For an OpenAI-compatible local or remote backend, use a provider key such as `subagent-fast` and set `apiBase` either under `agents.subagents` or in the matching `providers` entry.
208
+
209
+ ## 3. Run Modes
210
+
211
+ ### One-shot prompt
212
+
213
+ ```bash
214
+ cargo run --release -- chat "summarize the codebase"
215
+ ```
216
+
217
+ ### Interactive shell
218
+
219
+ ```bash
220
+ cargo run --release -- repl
221
+ ```
222
+
223
+ The interactive shell is designed for day-to-day agent work:
224
+
225
+ - `repl` and `chat` bootstrap the current directory as a project workspace by creating `<cwd>/.xbot/` by default
226
+ - persistent command history in `<workspace>/.xbot/history.txt`
227
+ - streamed model output instead of waiting for the full reply
228
+ - queued prompts while a turn is already running; queued turns start automatically when the current turn ends
229
+ - local shell commands: `/help`, `/clear`, `/exit`
230
+ - agent commands forwarded to the runtime: `/new`, `/status`, `/stop`
231
+ - multiline input by ending a line with `\`
232
+ - the welcome header shows both the current working directory and the active workspace
233
+ - the header also shows the active hidden state root under `<workspace>/.xbot`
234
+ - tool activity is shown with emoji-based pills such as file, shell, web, message, and cron actions
235
+ - fenced code blocks in replies are syntax-highlighted in the CLI by language when ANSI colors are available
236
+ - CLI session history is scoped by current working directory, so different projects do not share the same chat thread
237
+
238
+ To force `repl` or `chat` to use the configured global workspace, pass `--global`:
239
+
240
+ ```bash
241
+ xbot repl --global
242
+ ```
243
+
244
+ To use a specific workspace path instead, pass `--workspace`:
245
+
246
+ ```bash
247
+ xbot repl --workspace ~/.xbot/workspace
248
+ ```
249
+
250
+ ## 3.1 Workspace Memory
251
+
252
+ `xbot` uses two memory files inside `workspace/.xbot/`:
253
+
254
+ - `.xbot/memory/MEMORY.md`: permanent memory store, capped at `agents.defaults.memoryMaxBytes` bytes
255
+ - `.xbot/memory/HISTORY.md`: resettable history log for later search and consolidation
256
+
257
+ Operational rule:
258
+
259
+ - completed user tasks are summarized into `MEMORY.md` with title, summary, attention points, and finish time through the `memory-entry-writer` skill
260
+ - explicit `memorize` or `/memorize <text>` requests are summarized through the same skill and stored in `MEMORY.md` as user instructed memory
261
+ - new tasks load only topic-relevant slices from `MEMORY.md`, not the entire file
262
+ - `clear` / `/clear` / `new` / `/new` resets the current session and restores `HISTORY.md` to the default template
263
+
264
+ New workspaces now include starter guidance, an always-on memory skill, and a dedicated `memory-entry-writer` skill so memory writes stay compact instead of copying large reply fragments.
265
+
266
+ Example config:
267
+
268
+ ```json
269
+ {
270
+ "agents": {
271
+ "defaults": {
272
+ "memoryMaxBytes": 32768
273
+ }
274
+ }
275
+ }
276
+ ```
277
+
278
+ ### Long-running backend
279
+
280
+ ```bash
281
+ cargo run --release -- run
282
+ ```
283
+
284
+ `run` uses the workspace configured in `~/.xbot/config.json` by default. To run the backend against a project-local workspace, pass it explicitly:
285
+
286
+ ```bash
287
+ xbot run --workspace .
288
+ ```
289
+
290
+ `run` starts:
291
+
292
+ - the provider client
293
+ - the agent runtime
294
+ - cron jobs
295
+ - heartbeat review
296
+ - enabled channels
297
+ - the HTTP gateway
298
+ - the admin API and UI
299
+ - the metrics endpoint
300
+
301
+ ### Slack without a public webhook
302
+
303
+ Slack supports two practical modes in `xbot`:
304
+
305
+ - `webhook`: Slack sends Events API requests to your public HTTPS endpoint
306
+ - `socket`: `xbot` opens an outbound WebSocket to Slack and does not require a public webhook URL (Public)
307
+
308
+ Example Socket Mode config:
309
+
310
+ ```json
311
+ {
312
+ "channels": {
313
+ "slack": {
314
+ "enabled": true,
315
+ "mode": "socket",
316
+ "allowFrom": ["*"],
317
+ "botToken": "xoxb-...",
318
+ "appToken": "xapp-...",
319
+ "replyInThread": true,
320
+ "groupPolicy": "mention"
321
+ }
322
+ }
323
+ }
324
+ ```
325
+
326
+ Notes:
327
+
328
+ - `mode: "socket"` requires both `botToken` and `appToken`
329
+ - you do not need `signingSecret` or a public `/slack/events` URL in socket mode
330
+ - in webhook mode, you still need a public HTTPS URL configured in Slack Event Subscriptions
331
+
332
+ ## 4. Gateway Endpoints
333
+
334
+ When `run` is active, the gateway exposes:
335
+
336
+ - `GET /healthz`
337
+ - `GET /readyz`
338
+ - `GET /status`
339
+ - `GET /metrics`
340
+ - `GET /admin`
341
+ - `GET /api/admin/overview`
342
+ - `GET /api/admin/sessions`
343
+ - `GET /api/admin/cron`
344
+
345
+ The bind address comes from:
346
+
347
+ ```json
348
+ {
349
+ "gateway": {
350
+ "host": "0.0.0.0",
351
+ "port": 18790
352
+ }
353
+ }
354
+ ```
355
+
356
+ Admin and metrics paths can also be customized:
357
+
358
+ ```json
359
+ {
360
+ "gateway": {
361
+ "admin": {
362
+ "enabled": true,
363
+ "path": "/admin"
364
+ },
365
+ "metrics": {
366
+ "enabled": true,
367
+ "path": "/metrics"
368
+ }
369
+ }
370
+ }
371
+ ```
372
+
373
+ ## 5. Channel Configuration
374
+
375
+ ### Email
376
+
377
+ Email is polling-driven and does not require webhooks.
378
+
379
+ ```json
380
+ {
381
+ "channels": {
382
+ "email": {
383
+ "enabled": true,
384
+ "allowFrom": ["*"],
385
+ "consentGranted": true,
386
+ "imapHost": "imap.example.com",
387
+ "imapPort": 993,
388
+ "imapUsername": "bot@example.com",
389
+ "imapPassword": "...",
390
+ "imapMailbox": "INBOX",
391
+ "imapUseSsl": true,
392
+ "smtpHost": "smtp.example.com",
393
+ "smtpPort": 587,
394
+ "smtpUsername": "bot@example.com",
395
+ "smtpPassword": "...",
396
+ "smtpUseTls": true,
397
+ "fromAddress": "bot@example.com",
398
+ "autoReplyEnabled": true,
399
+ "pollIntervalSeconds": 30
400
+ }
401
+ }
402
+ }
403
+ ```
404
+
405
+ ### Slack
406
+
407
+ Slack is currently webhook-driven in `xbot`.
408
+
409
+ ```json
410
+ {
411
+ "channels": {
412
+ "sendProgress": true,
413
+ "sendToolHints": false,
414
+ "slack": {
415
+ "enabled": true,
416
+ "allowFrom": ["*"],
417
+ "botToken": "xoxb-...",
418
+ "signingSecret": "...",
419
+ "webhookPath": "/slack/events",
420
+ "replyInThread": true,
421
+ "groupPolicy": "mention"
422
+ }
423
+ }
424
+ }
425
+ ```
426
+
427
+ Operational notes:
428
+
429
+ - `signingSecret` is required for startup validation.
430
+ - Point Slack event subscriptions at `http://<host>:<port>/slack/events`.
431
+ - Send software-development tasks as normal messages or mentions, for example: `review this repo, run tests, and fix failures`.
432
+ - `channels.sendToolHints` defaults to `false`; in that mode, `xbot` sends a muted-tool notice on the first tool call and batch summaries every 10 tool calls or before the next non-tool reply.
433
+ - Set `channels.sendToolHints` to `true` if you want every tool execution hint sent back to Slack while a task is running.
434
+
435
+ ### Telegram
436
+
437
+ Telegram is currently webhook-driven in `xbot`.
438
+
439
+ ```json
440
+ {
441
+ "channels": {
442
+ "sendProgress": true,
443
+ "sendToolHints": false,
444
+ "telegram": {
445
+ "enabled": true,
446
+ "allowFrom": ["*"],
447
+ "token": "<bot-token>",
448
+ "webhookPath": "/telegram/webhook",
449
+ "webhookSecret": "optional-shared-secret",
450
+ "replyToMessage": true,
451
+ "groupPolicy": "mention"
452
+ }
453
+ }
454
+ }
455
+ ```
456
+
457
+ Set the Telegram webhook externally to:
458
+
459
+ `https://<your-domain>/telegram/webhook`
460
+
461
+ If `webhookSecret` is configured, Telegram requests must include the matching secret header.
462
+
463
+ Usage notes:
464
+
465
+ - Send development or analysis tasks as plain messages to the bot.
466
+ - In groups, `groupPolicy: "mention"` keeps the bot from reacting to every message.
467
+ - `channels.sendToolHints` defaults to `false`; in that mode, `xbot` sends a muted-tool notice on the first tool call and batch summaries every 10 tool calls or before the next non-tool reply.
468
+ - Set `channels.sendToolHints` to `true` if you want every tool execution hint sent back to Telegram while a task is running.
469
+
470
+ ### Feishu
471
+
472
+ Feishu runs through the webhook gateway and supports inbound text, post, interactive cards, replies, and media/resource download.
473
+
474
+ ```json
475
+ {
476
+ "channels": {
477
+ "sendProgress": true,
478
+ "sendToolHints": false,
479
+ "feishu": {
480
+ "enabled": true,
481
+ "allowFrom": ["*"],
482
+ "appId": "cli_xxx",
483
+ "appSecret": "...",
484
+ "verificationToken": "...",
485
+ "webhookPath": "/feishu/events",
486
+ "groupPolicy": "mention",
487
+ "replyToMessage": true,
488
+ "reactEmoji": "THUMBSUP"
489
+ }
490
+ }
491
+ }
492
+ ```
493
+
494
+ Point Feishu event subscriptions at:
495
+
496
+ `https://<your-domain>/feishu/events`
497
+
498
+ Usage notes:
499
+
500
+ - Mention the bot in group chats when using `groupPolicy: "mention"`.
501
+ - Development tasks can be sent as normal text instructions, and Feishu replies can include dedicated tool-hint cards during execution.
502
+ - `channels.sendToolHints` defaults to `false`; in that mode, `xbot` sends a muted-tool notice on the first tool call and batch summaries every 10 tool calls or before the next non-tool reply.
503
+ - Set `channels.sendToolHints` to `true` if you want every tool execution hint card sent back during execution. Non-tool progress messages are still controlled by `channels.sendProgress`.
504
+
505
+ ## 6. Combined Example
506
+
507
+ ```json
508
+ {
509
+ "agents": {
510
+ "defaults": {
511
+ "workspace": "~/.xbot/workspace",
512
+ "model": "ollama/qwen2.5-coder:7b",
513
+ "provider": "ollama",
514
+ "maxToolIterations": 0,
515
+ "contextWindowTokens": 65536
516
+ },
517
+ "subagents": {
518
+ "model": "",
519
+ "provider": "auto"
520
+ }
521
+ },
522
+ "providers": {
523
+ "ollama": {
524
+ "apiBase": "http://localhost:11434/v1"
525
+ }
526
+ },
527
+ "gateway": {
528
+ "host": "0.0.0.0",
529
+ "port": 18790,
530
+ "heartbeat": {
531
+ "enabled": true,
532
+ "intervalS": 1800
533
+ }
534
+ },
535
+ "channels": {
536
+ "telegram": {
537
+ "enabled": true,
538
+ "allowFrom": ["*"],
539
+ "token": "<bot-token>",
540
+ "webhookPath": "/telegram/webhook"
541
+ }
542
+ }
543
+ }
544
+ ```
545
+
546
+ `maxToolIterations: 0` means the agent loop is unbounded. Use a positive number only when you want a hard ceiling on tool calls.
547
+
548
+ ## 7. MCP Tool Servers
549
+
550
+ `xbot` supports MCP over `stdio`. Enabled MCP tools are registered as native tools using names like `mcp_<server>_<tool>`.
551
+
552
+ Example:
553
+
554
+ ```json
555
+ {
556
+ "tools": {
557
+ "mcpServers": {
558
+ "github": {
559
+ "enabled": true,
560
+ "type": "stdio",
561
+ "command": "npx",
562
+ "args": ["-y", "@modelcontextprotocol/server-github"],
563
+ "enabledTools": ["*"],
564
+ "toolTimeout": 30
565
+ }
566
+ }
567
+ }
568
+ }
569
+ ```
570
+
571
+ Current scope:
572
+
573
+ - `stdio` transport is supported
574
+ - startup validation fails fast if an enabled MCP server has no command
575
+ - unsupported transports are rejected during startup
576
+
577
+ ## 8. Built-in Skills
578
+
579
+ Built-in skills ship with the repository under `xbot/skills/`.
580
+
581
+ Current built-in set:
582
+
583
+ - `memory-hygiene` (always-on)
584
+ - `memory` (always-on)
585
+ - `memory-entry-writer`
586
+ - `workspace-operator`
587
+ - `software-engineer`
588
+ - `data-analyst`
589
+ - `github-cli`
590
+ - `github`
591
+ - `scheduled-ops`
592
+ - `cron`
593
+ - `clawhub`
594
+ - `skill-creator`
595
+ - `summarize`
596
+ - `weather`
597
+ - `tmux`
598
+
599
+ Behavior:
600
+
601
+ - always-on skills are injected automatically
602
+ - relevant task-specific skills are suggested and loaded based on prompt keywords
603
+ - skills with unmet requirements (missing binaries, env vars, or OS) are marked unavailable
604
+ - workspace-local skills live under `<workspace>/.xbot/skills/<name>/SKILL.md`
605
+ - new workspaces also get starter workspace skill templates that you can edit for project-specific context and delivery rules
606
+
607
+ ### Skill Management
608
+
609
+ List all skills and their availability:
610
+
611
+ ```bash
612
+ cargo run -- skills list
613
+ ```
614
+
615
+ Scaffold a new skill:
616
+
617
+ ```bash
618
+ cargo run -- skills init my-custom-skill
619
+ ```
620
+
621
+ This creates `<workspace>/.xbot/skills/my-custom-skill/SKILL.md` with a starter template.
622
+
623
+ ## 9. Useful Commands
624
+
625
+ Print the resolved config:
626
+
627
+ ```bash
628
+ cargo run -- print-config
629
+ ```
630
+
631
+ Run a different model without changing config:
632
+
633
+ ```bash
634
+ cargo run --release -- run --model ollama/qwen2.5-coder:7b
635
+ ```
636
+
637
+ Start a one-shot request against a specific model:
638
+
639
+ ```bash
640
+ cargo run --release -- chat --model ollama/qwen2.5-coder:7b "list the next implementation tasks"
641
+ ```
642
+
643
+ Inspect runtime state without starting the daemon:
644
+
645
+ ```bash
646
+ cargo run -- sessions # List active chat sessions
647
+ cargo run -- jobs # List scheduled cron jobs
648
+ cargo run -- print-config # Print current resolved config
649
+ cargo run -- config --provider # Interactive provider setup
650
+ cargo run -- config --channel # Interactive channel setup
651
+ ```
652
+
653
+ ### Channel Management
654
+
655
+ ```bash
656
+ cargo run -- channels list # List all available channels
657
+ cargo run -- channels status # Show enabled/disabled state per channel
658
+ cargo run -- channels login # Interactive login (e.g. Weixin QR code scan)
659
+ cargo run -- channels login weixin # Login to a specific channel
660
+ cargo run -- channels setup # Show setup instructions for a channel
661
+ cargo run -- channels setup discord # Setup instructions for a specific channel
662
+ ```
663
+
664
+ ### Skill Management
665
+
666
+ ```bash
667
+ cargo run -- skills list # List skills with availability status
668
+ cargo run -- skills init NAME # Scaffold a new skill directory
669
+ ```
670
+
671
+ ## 10. Operational Notes
672
+
673
+ - `run` validates enabled channel config before startup.
674
+ - `run` also validates enabled MCP server configuration before startup.
675
+ - Local providers are accepted without API keys when the provider is recognized as local.
676
+ - Outbound runtime/system errors are surfaced through the runtime logs instead of being silently dropped.
677
+ - Feishu media downloads are stored under `~/.xbot/media/feishu`.
678
+ - The admin UI polls the runtime every few seconds and exposes channel controls plus heartbeat triggering.
679
+ - The metrics endpoint exposes Prometheus-compatible counters and gauges for message counts, provider requests, token totals, latency, and throughput.
680
+
681
+ ## 11. Additional Channel Configuration
682
+
683
+ Each channel section below includes how to obtain the required credentials and the config format. You can also run `xbot channels setup <name>` to see setup instructions in the terminal.
684
+
685
+ ### DingTalk
686
+
687
+ DingTalk uses the Stream gateway WebSocket protocol.
688
+
689
+ **How to obtain credentials:**
690
+
691
+ 1. Go to <https://open-dev.dingtalk.com> and create a robot application
692
+ 2. Under **Credentials**, copy the Client ID (AppKey) and Client Secret (AppSecret)
693
+ 3. Under **Robot**, enable the robot and copy the Robot Code
694
+
695
+ ```json
696
+ {
697
+ "channels": {
698
+ "dingtalk": {
699
+ "enabled": true,
700
+ "allowFrom": ["*"],
701
+ "clientId": "<AppKey from developer console>",
702
+ "clientSecret": "<AppSecret from developer console>",
703
+ "robotCode": "<Robot Code>"
704
+ }
705
+ }
706
+ }
707
+ ```
708
+
709
+ ### Discord
710
+
711
+ Discord connects via the Gateway v10 WebSocket.
712
+
713
+ **How to obtain credentials:**
714
+
715
+ 1. Go to <https://discord.com/developers/applications> and create an application
716
+ 2. Under **Bot**, click "Add Bot" and copy the bot token
717
+ 3. Under **Bot**, enable "Message Content Intent" in Privileged Gateway Intents
718
+ 4. Under **OAuth2 > URL Generator**, select `bot` scope with `Send Messages` permission
719
+ 5. Use the generated URL to invite the bot to your server
720
+
721
+ ```json
722
+ {
723
+ "channels": {
724
+ "discord": {
725
+ "enabled": true,
726
+ "allowFrom": ["*"],
727
+ "botToken": "<your-bot-token>",
728
+ "groupPolicy": "mention"
729
+ }
730
+ }
731
+ }
732
+ ```
733
+
734
+ `groupPolicy` options: `"mention"` (respond only when @mentioned), `"open"` (respond to all messages).
735
+
736
+ ### Matrix
737
+
738
+ Matrix uses the CS API v3 long-poll `/sync` endpoint.
739
+
740
+ **How to obtain credentials:**
741
+
742
+ 1. Create a bot account on your Matrix homeserver
743
+ 2. Obtain an access token (e.g. via Element: Settings > Help & About > Access Token)
744
+ 3. Note the full user ID (e.g. `@bot:example.com`)
745
+ 4. Invite the bot to the rooms where it should respond
746
+
747
+ ```json
748
+ {
749
+ "channels": {
750
+ "matrix": {
751
+ "enabled": true,
752
+ "allowFrom": ["*"],
753
+ "homeserverUrl": "https://matrix.example.com",
754
+ "accessToken": "<your-access-token>",
755
+ "userId": "@bot:example.com"
756
+ }
757
+ }
758
+ }
759
+ ```
760
+
761
+ Note: End-to-end encrypted rooms (`m.room.encrypted`) are not supported; the bot will skip encrypted messages.
762
+
763
+ ### WhatsApp
764
+
765
+ WhatsApp connects to a Node.js Baileys bridge via WebSocket.
766
+
767
+ **Setup steps:**
768
+
769
+ 1. Install Node.js v18+
770
+ 2. Clone the Baileys bridge: `git clone https://github.com/nicepkg/whatsapp-bridge`
771
+ 3. `cd whatsapp-bridge && npm install && npm start`
772
+ 4. Scan the QR code displayed in the bridge terminal with WhatsApp
773
+ 5. The bridge saves auth state — subsequent starts reconnect automatically
774
+
775
+ Run `xbot channels login whatsapp` for step-by-step guidance.
776
+
777
+ ```json
778
+ {
779
+ "channels": {
780
+ "whatsapp": {
781
+ "enabled": true,
782
+ "allowFrom": ["*"],
783
+ "bridgeUrl": "ws://localhost:3001",
784
+ "bridgeToken": "",
785
+ "groupPolicy": "open"
786
+ }
787
+ }
788
+ }
789
+ ```
790
+
791
+ The bridge must be running before `xbot run`. Set `bridgeToken` if your bridge instance requires authentication.
792
+
793
+ ### QQ
794
+
795
+ QQ uses the QQ Bot API with WebSocket gateway.
796
+
797
+ **How to obtain credentials:**
798
+
799
+ 1. Go to <https://q.qq.com> and register as a QQ Bot developer
800
+ 2. Create a bot application and obtain the App ID and Secret
801
+ 3. Configure the bot's intents and permissions in the developer console
802
+
803
+ ```json
804
+ {
805
+ "channels": {
806
+ "qq": {
807
+ "enabled": true,
808
+ "allowFrom": ["*"],
809
+ "appId": "<your-app-id>",
810
+ "secret": "<your-secret>"
811
+ }
812
+ }
813
+ }
814
+ ```
815
+
816
+ ### WeCom
817
+
818
+ WeCom (Enterprise WeChat) uses the AI Bot WebSocket protocol.
819
+
820
+ **How to obtain credentials:**
821
+
822
+ 1. Log in to <https://work.weixin.qq.com> admin console
823
+ 2. Create a self-built application under **App Management**
824
+ 3. Note the Corp ID (from **My Enterprise**), Agent ID, and Secret
825
+
826
+ ```json
827
+ {
828
+ "channels": {
829
+ "wecom": {
830
+ "enabled": true,
831
+ "allowFrom": ["*"],
832
+ "corpId": "<your-corp-id>",
833
+ "agentId": "<your-agent-id>",
834
+ "secret": "<your-secret>"
835
+ }
836
+ }
837
+ }
838
+ ```
839
+
840
+ All three fields (`corpId`, `agentId`, `secret`) are required — `agentId`/`secret` for WebSocket auth, `corpId` for outbound message delivery.
841
+
842
+ ### Weixin
843
+
844
+ Weixin (personal WeChat) uses HTTP long-poll with QR code login via the ilinkai API.
845
+
846
+ **Login flow:**
847
+
848
+ 1. Enable the channel in config (no token needed initially)
849
+ 2. Run `xbot channels login weixin` — a QR code URL will be printed
850
+ 3. Open the URL in WeChat and scan to authorize
851
+ 4. The token is saved to `<stateDir>/account.json` for future sessions
852
+
853
+ Alternatively, run `xbot run` and the QR login starts automatically if no saved token is found.
854
+
855
+ ```json
856
+ {
857
+ "channels": {
858
+ "weixin": {
859
+ "enabled": true,
860
+ "allowFrom": ["*"]
861
+ }
862
+ }
863
+ }
864
+ ```
865
+
866
+ ### Mochat
867
+
868
+ Mochat connects to a Mochat/OpenClaw instance via HTTP polling.
869
+
870
+ **How to obtain credentials:**
871
+
872
+ 1. Obtain a Claw Token from your Mochat or OpenClaw instance admin
873
+ 2. Note the session IDs and/or panel IDs you want the bot to monitor
874
+
875
+ ```json
876
+ {
877
+ "channels": {
878
+ "mochat": {
879
+ "enabled": true,
880
+ "allowFrom": ["*"],
881
+ "baseUrl": "https://your-instance.com",
882
+ "clawToken": "<your-token>",
883
+ "sessions": ["session-id-1"],
884
+ "panels": []
885
+ }
886
+ }
887
+ }
888
+ ```
889
+
890
+ ## 12. Additional Provider Configuration
891
+
892
+ ### Anthropic
893
+
894
+ Anthropic is supported natively with the Messages API:
895
+
896
+ ```json
897
+ {
898
+ "agents": {
899
+ "defaults": {
900
+ "model": "anthropic/claude-sonnet-4-20250514",
901
+ "provider": "anthropic"
902
+ }
903
+ },
904
+ "providers": {
905
+ "anthropic": {
906
+ "apiKey": "sk-ant-..."
907
+ }
908
+ }
909
+ }
910
+ ```
911
+
912
+ Optional `reasoningEffort` can be set to control extended thinking behavior.
913
+
914
+ ### GitHub Copilot
915
+
916
+ GitHub Copilot is an OAuth provider and does not require an API key:
917
+
918
+ ```json
919
+ {
920
+ "agents": {
921
+ "defaults": {
922
+ "model": "github_copilot/gpt-4o",
923
+ "provider": "github_copilot"
924
+ }
925
+ },
926
+ "providers": {
927
+ "github_copilot": {}
928
+ }
929
+ }
930
+ ```
931
+
932
+ ### Cursor
933
+
934
+ Cursor requires an explicit `apiBase`:
935
+
936
+ ```json
937
+ {
938
+ "agents": {
939
+ "defaults": {
940
+ "model": "cursor/gpt-4o",
941
+ "provider": "cursor"
942
+ }
943
+ },
944
+ "providers": {
945
+ "cursor": {
946
+ "apiKey": "your-key",
947
+ "apiBase": "https://your-cursor-api-base"
948
+ }
949
+ }
950
+ }
951
+ ```
952
+
953
+ ## 13. Concurrency Configuration
954
+
955
+ Control how many inbound messages are processed concurrently:
956
+
957
+ ```json
958
+ {
959
+ "agents": {
960
+ "defaults": {
961
+ "maxConcurrentRequests": 3
962
+ }
963
+ }
964
+ }
965
+ ```
966
+
967
+ Messages for the same session are always serialized regardless of this setting.
968
+
969
+ ## 14. Channel Delivery Configuration
970
+
971
+ Configure outbound delivery behavior:
972
+
973
+ ```json
974
+ {
975
+ "channels": {
976
+ "sendProgress": true,
977
+ "sendToolHints": false,
978
+ "sendMaxRetries": 3
979
+ }
980
+ }
981
+ ```
982
+
983
+ - `sendMaxRetries`: number of delivery attempts with exponential backoff (1s, 2s, 4s...) before giving up.
984
+
985
+ ## 15. Current Scope
986
+
987
+ The supported production channel set in this repository is:
988
+
989
+ - `email`
990
+ - `slack`
991
+ - `telegram`
992
+ - `feishu`
993
+ - `dingtalk`
994
+ - `discord`
995
+ - `matrix`
996
+ - `whatsapp`
997
+ - `qq`
998
+ - `wecom`
999
+ - `weixin`
1000
+ - `mochat`
1001
+
1002
+ The runtime is designed so additional providers and transports can be added behind the same trait boundaries without changing the agent loop.