Merge branch 'main' into version

This commit is contained in:
Cytown
2026-03-19 14:55:30 +08:00
266 changed files with 30364 additions and 9696 deletions
+13 -11
View File
@@ -13,25 +13,27 @@
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
"allow_from": [],
"is_lark": false
}
}
}
```
| 字段 | 类型 | 必填 | 描述 |
| ------------------ | ------ | ---- | -------------------------------- |
| enabled | bool | 是 | 是否启用飞书频道 |
| app_id | string | 是 | 飞书应用的 App ID(以cli\_开头) |
| app_secret | string | 是 | 飞书应用的 App Secret |
| encrypt_key | string | 否 | 事件回调加密密钥 |
| verification_token | string | 否 | 用于Webhook事件验证的Token |
| allow_from | array | 否 | 用户ID白名单,空表示所有用户 |
| random_reaction_emoji | array | 否 | 随机添加的表情列表,空则使用默认 "Pin" |
| 字段 | 类型 | 必填 | 描述 |
| --------------------- | ------ | ---- | ------------------------------------------------------------------------------------------------ |
| enabled | bool | 是 | 是否启用飞书频道 |
| app_id | string | 是 | 飞书应用的 App ID(以cli\_开头) |
| app_secret | string | 是 | 飞书应用的 App Secret |
| encrypt_key | string | 否 | 事件回调加密密钥 |
| verification_token | string | 否 | 用于Webhook事件验证的Token |
| allow_from | array | 否 | 用户ID白名单,空表示所有用户 |
| random_reaction_emoji | array | 否 | 随机添加的表情列表,空则使用默认 "Pin" |
| is_lark | bool | 否 | 是否使用 Lark 国际版域名(`open.larksuite.com`),默认为 `false`(使用飞书域名 `open.feishu.cn` |
## 设置流程
1. 前往 [飞书开放平台](https://open.feishu.cn/)创建应用程序
1. 前往 [飞书开放平台](https://open.feishu.cn/)(国际版用户请前往 [Lark 开放平台](https://open.larksuite.com/)创建应用程序
2. 获取 App ID 和 App Secret
3. 配置事件订阅和Webhook URL
4. 设置加密(可选,生产环境建议启用)
+431
View File
@@ -0,0 +1,431 @@
# 💬 Chat Apps Configuration
> Back to [README](../README.md)
## 💬 Chat Apps
Talk to your picoclaw through Telegram, Discord, WhatsApp, Matrix, QQ, DingTalk, LINE, WeCom, Feishu, Slack, IRC, OneBot, MaixCam, or Pico (native protocol)
> **Note**: All webhook-based channels (LINE, WeCom, etc.) are served on a single shared Gateway HTTP server (`gateway.host`:`gateway.port`, default `127.0.0.1:18790`). There are no per-channel ports to configure. Note: Feishu uses WebSocket/SDK mode and does not use the shared HTTP webhook server.
| Channel | Setup |
| ------------ | ---------------------------------- |
| **Telegram** | Easy (just a token) |
| **Discord** | Easy (bot token + intents) |
| **WhatsApp** | Easy (native: QR scan; or bridge URL) |
| **Matrix** | Medium (homeserver + bot access token) |
| **QQ** | Easy (AppID + AppSecret) |
| **DingTalk** | Medium (app credentials) |
| **LINE** | Medium (credentials + webhook URL) |
| **WeCom AI Bot** | Medium (Token + AES key) |
| **Feishu** | Medium (App ID + Secret, WebSocket mode) |
| **Slack** | Medium (Bot token + App token) |
| **IRC** | Medium (server + TLS config) |
| **OneBot** | Medium (QQ via OneBot protocol) |
| **MaixCam** | Easy (Sipeed hardware integration) |
| **Pico** | Native PicoClaw protocol |
<details>
<summary><b>Telegram</b> (Recommended)</summary>
**1. Create a bot**
* Open Telegram, search `@BotFather`
* Send `/newbot`, follow prompts
* Copy the token
**2. Configure**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"],
"use_markdown_v2": false,
}
}
}
```
> Get your user ID from `@userinfobot` on Telegram.
**3. Run**
```bash
picoclaw gateway
```
**4. Telegram command menu (auto-registered at startup)**
PicoClaw now keeps command definitions in one shared registry. On startup, Telegram will automatically register supported bot commands (for example `/start`, `/help`, `/show`, `/list`) so command menu and runtime behavior stay in sync.
Telegram command menu registration remains channel-local discovery UX; generic command execution is handled centrally in the agent loop via the commands executor.
If command registration fails (network/API transient errors), the channel still starts and PicoClaw retries registration in the background.
**4. Advanced Formatting**
You can set use_markdown_v2: true to enable enhanced formatting options. This allows the bot to utilize the full range of Telegram MarkdownV2 features, including nested styles, spoilers, and custom fixed-width blocks.
</details>
<details>
<summary><b>Discord</b></summary>
**1. Create a bot**
* Go to <https://discord.com/developers/applications>
* Create an application → Bot → Add Bot
* Copy the bot token
**2. Enable intents**
* In the Bot settings, enable **MESSAGE CONTENT INTENT**
* (Optional) Enable **SERVER MEMBERS INTENT** if you plan to use allow lists based on member data
**3. Get your User ID**
* Discord Settings → Advanced → enable **Developer Mode**
* Right-click your avatar → **Copy User ID**
**4. Configure**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. Invite the bot**
* OAuth2 → URL Generator
* Scopes: `bot`
* Bot Permissions: `Send Messages`, `Read Message History`
* Open the generated invite URL and add the bot to your server
**Optional: Group trigger mode**
By default the bot responds to all messages in a server channel. To restrict responses to @-mentions only, add:
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
You can also trigger by keyword prefixes (e.g. `!bot`):
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. Run**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b> (native via whatsmeow)</summary>
PicoClaw can connect to WhatsApp in two ways:
- **Native (recommended):** In-process using [whatsmeow](https://github.com/tulir/whatsmeow). No separate bridge. Set `"use_native": true` and leave `bridge_url` empty. On first run, scan the QR code with WhatsApp (Linked Devices). Session is stored under your workspace (e.g. `workspace/whatsapp/`). The native channel is **optional** to keep the default binary small; build with `-tags whatsapp_native` (e.g. `make build-whatsapp-native` or `go build -tags whatsapp_native ./cmd/...`).
- **Bridge:** Connect to an external WebSocket bridge. Set `bridge_url` (e.g. `ws://localhost:3001`) and keep `use_native` false.
**Configure (native)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
If `session_store_path` is empty, the session is stored in `<workspace>/whatsapp/`. Run `picoclaw gateway`; on first run, scan the QR code printed in the terminal with WhatsApp → Linked Devices.
</details>
<details>
<summary><b>QQ</b></summary>
**1. Create a bot**
- Go to [QQ Open Platform](https://q.qq.com/#)
- Create an application → Get **AppID** and **AppSecret**
**2. Configure**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> Set `allow_from` to empty to allow all users, or specify QQ numbers to restrict access.
**3. Run**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Create a bot**
* Go to [Open Platform](https://open.dingtalk.com/)
* Create an internal app
* Copy Client ID and Client Secret
**2. Configure**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> Set `allow_from` to empty to allow all users, or specify DingTalk user IDs to restrict access.
**3. Run**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Matrix</b></summary>
**1. Prepare bot account**
* Use your preferred homeserver (e.g. `https://matrix.org` or self-hosted)
* Create a bot user and obtain its access token
**2. Configure**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. Run**
```bash
picoclaw gateway
```
For full options (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), see [Matrix Channel Configuration Guide](docs/channels/matrix/README.md).
</details>
<details>
<summary><b>LINE</b></summary>
**1. Create a LINE Official Account**
- Go to [LINE Developers Console](https://developers.line.biz/)
- Create a provider → Create a Messaging API channel
- Copy **Channel Secret** and **Channel Access Token**
**2. Configure**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> LINE webhook is served on the shared Gateway server (`gateway.host`:`gateway.port`, default `127.0.0.1:18790`).
**3. Set up Webhook URL**
LINE requires HTTPS for webhooks. Use a reverse proxy or tunnel:
```bash
# Example with ngrok (gateway default port is 18790)
ngrok http 18790
```
Then set the Webhook URL in LINE Developers Console to `https://your-domain/webhook/line` and enable **Use webhook**.
**4. Run**
```bash
picoclaw gateway
```
> In group chats, the bot responds only when @mentioned. Replies quote the original message.
</details>
<details>
<summary><b>WeCom (企业微信)</b></summary>
PicoClaw supports three types of WeCom integration:
**Option 1: WeCom Bot (Bot)** - Easier setup, supports group chats
**Option 2: WeCom App (Custom App)** - More features, proactive messaging, private chat only
**Option 3: WeCom AI Bot (AI Bot)** - Official AI Bot, streaming replies, supports group & private chat
See [WeCom AI Bot Configuration Guide](docs/channels/wecom/wecom_aibot/README.zh.md) for detailed setup instructions.
**Quick Setup - WeCom Bot:**
**1. Create a bot**
* Go to WeCom Admin Console → Group Chat → Add Group Bot
* Copy the webhook URL (format: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`)
**2. Configure**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> WeCom webhook is served on the shared Gateway server (`gateway.host`:`gateway.port`, default `127.0.0.1:18790`).
**Quick Setup - WeCom App:**
**1. Create an app**
* Go to WeCom Admin Console → App Management → Create App
* Copy **AgentId** and **Secret**
* Go to "My Company" page, copy **CorpID**
**2. Configure receive message**
* In App details, click "Receive Message" → "Set API"
* Set URL to `http://your-server:18790/webhook/wecom-app`
* Generate **Token** and **EncodingAESKey**
**3. Configure**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. Run**
```bash
picoclaw gateway
```
> **Note**: WeCom webhook callbacks are served on the Gateway port (default 18790). Use a reverse proxy for HTTPS.
**Quick Setup - WeCom AI Bot:**
**1. Create an AI Bot**
* Go to WeCom Admin Console → App Management → AI Bot
* In the AI Bot settings, configure callback URL: `http://your-server:18791/webhook/wecom-aibot`
* Copy **Token** and click "Random Generate" for **EncodingAESKey**
**2. Configure**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "Hello! How can I help you?"
}
}
}
```
**3. Run**
```bash
picoclaw gateway
```
> **Note**: WeCom AI Bot uses streaming pull protocol — no reply timeout concerns. Long tasks (>30 seconds) automatically switch to `response_url` push delivery.
</details>
+220
View File
@@ -0,0 +1,220 @@
# ⚙️ Configuration Guide
> Back to [README](../README.md)
## ⚙️ Configuration
Config file: `~/.picoclaw/config.json`
### Environment Variables
You can override default paths using environment variables. This is useful for portable installations, containerized deployments, or running picoclaw as a system service. These variables are independent and control different paths.
| Variable | Description | Default Path |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | Overrides the path to the configuration file. This directly tells picoclaw which `config.json` to load, ignoring all other locations. | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | Overrides the root directory for picoclaw data. This changes the default location of the `workspace` and other data directories. | `~/.picoclaw` |
**Examples:**
```bash
# Run picoclaw using a specific config file
# The workspace path will be read from within that config file
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# Run picoclaw with all its data stored in /opt/picoclaw
# Config will be loaded from the default ~/.picoclaw/config.json
# Workspace will be created at /opt/picoclaw/workspace
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# Use both for a fully customized setup
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### Workspace Layout
PicoClaw stores data in your configured workspace (default: `~/.picoclaw/workspace`):
```
~/.picoclaw/workspace/
├── sessions/ # Conversation sessions and history
├── memory/ # Long-term memory (MEMORY.md)
├── state/ # Persistent state (last channel, etc.)
├── cron/ # Scheduled jobs database
├── skills/ # Custom skills
├── AGENT.md # Agent behavior guide
├── HEARTBEAT.md # Periodic task prompts (checked every 30 min)
├── IDENTITY.md # Agent identity
├── SOUL.md # Agent soul
└── USER.md # User preferences
```
> **Note:** Changes to `AGENT.md`, `SOUL.md`, `USER.md` and `memory/MEMORY.md` are automatically detected at runtime via file modification time (mtime) tracking. You do **not** need to restart the gateway after editing these files — the agent picks up the new content on the next request.
### Skill Sources
By default, skills are loaded from:
1. `~/.picoclaw/workspace/skills` (workspace)
2. `~/.picoclaw/skills` (global)
3. `<current-working-directory>/skills` (builtin)
For advanced/test setups, you can override the builtin skills root with:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### Unified Command Execution Policy
- Generic slash commands are executed through a single path in `pkg/agent/loop.go` via `commands.Executor`.
- Channel adapters no longer consume generic commands locally; they forward inbound text to the bus/agent path. Telegram still auto-registers supported commands at startup.
- Unknown slash command (for example `/foo`) passes through to normal LLM processing.
- Registered but unsupported command on the current channel (for example `/show` on WhatsApp) returns an explicit user-facing error and stops further processing.
### 🔒 Security Sandbox
PicoClaw runs in a sandboxed environment by default. The agent can only access files and execute commands within the configured workspace.
#### Default Configuration
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| Option | Default | Description |
| ----------------------- | ----------------------- | ----------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Working directory for the agent |
| `restrict_to_workspace` | `true` | Restrict file/command access to workspace |
#### Protected Tools
When `restrict_to_workspace: true`, the following tools are sandboxed:
| Tool | Function | Restriction |
| ------------- | ---------------- | -------------------------------------- |
| `read_file` | Read files | Only files within workspace |
| `write_file` | Write files | Only files within workspace |
| `list_dir` | List directories | Only directories within workspace |
| `edit_file` | Edit files | Only files within workspace |
| `append_file` | Append to files | Only files within workspace |
| `exec` | Execute commands | Command paths must be within workspace |
#### Additional Exec Protection
Even with `restrict_to_workspace: false`, the `exec` tool blocks these dangerous commands:
* `rm -rf`, `del /f`, `rmdir /s` — Bulk deletion
* `format`, `mkfs`, `diskpart` — Disk formatting
* `dd if=` — Disk imaging
* Writing to `/dev/sd[a-z]` — Direct disk writes
* `shutdown`, `reboot`, `poweroff` — System shutdown
* Fork bomb `:(){ :|:& };:`
### File Access Control
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.allow_read_paths` | string[] | `[]` | Additional paths allowed for reading outside workspace |
| `tools.allow_write_paths` | string[] | `[]` | Additional paths allowed for writing outside workspace |
### Exec Security
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.exec.allow_remote` | bool | `false` | Allow exec tool from remote channels (Telegram/Discord etc.) |
| `tools.exec.enable_deny_patterns` | bool | `true` | Enable dangerous command interception |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | Custom regex patterns to block |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | Custom regex patterns to allow |
> **Security Note:** Symlink protection is enabled by default — all file paths are resolved through `filepath.EvalSymlinks` before whitelist matching, preventing symlink escape attacks.
#### Known Limitation: Child Processes From Build Tools
The exec safety guard only inspects the command line PicoClaw launches directly. It does not recursively inspect child
processes spawned by allowed developer tools such as `make`, `go run`, `cargo`, `npm run`, or custom build scripts.
That means a top-level command can still compile or launch other binaries after it passes the initial guard check. In
practice, treat build scripts, Makefiles, package scripts, and generated binaries as executable code that needs the same
level of review as a direct shell command.
For higher-risk environments:
* Review build scripts before execution.
* Prefer approval/manual review for compile-and-run workflows.
* Run PicoClaw inside a container or VM if you need stronger isolation than the built-in guard provides.
#### Error Examples
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### Disabling Restrictions (Security Risk)
If you need the agent to access paths outside the workspace:
**Method 1: Config file**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**Method 2: Environment variable**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **Warning**: Disabling this restriction allows the agent to access any path on your system. Use with caution in controlled environments only.
#### Security Boundary Consistency
The `restrict_to_workspace` setting applies consistently across all execution paths:
| Execution Path | Security Boundary |
| ---------------- | ---------------------------- |
| Main Agent | `restrict_to_workspace` ✅ |
| Subagent / Spawn | Inherits same restriction ✅ |
| Heartbeat tasks | Inherits same restriction ✅ |
All paths share the same workspace restriction — there's no way to bypass the security boundary through subagents or scheduled tasks.
### Heartbeat (Periodic Tasks)
PicoClaw can perform periodic tasks automatically. Create a `HEARTBEAT.md` file in your workspace:
```markdown
# Periodic Tasks
- Check my email for important messages
- Review my calendar for upcoming events
- Check the weather forecast
```
The agent will read this file every 30 minutes (configurable) and execute any tasks using available tools.
#### Async Tasks with Spawn
For long-running tasks (web search, API calls), use the `spawn` tool to create a **subagent**:
```markdown
# Periodic Tasks
+168
View File
@@ -0,0 +1,168 @@
# Credential Encryption
PicoClaw supports encrypting `api_key` values in `model_list` configuration entries.
Encrypted keys are stored as `enc://<base64>` strings and decrypted automatically at startup.
---
## Quick Start
**1. Set your passphrase**
```bash
export PICOCLAW_KEY_PASSPHRASE="your-passphrase"
```
**2. Encrypt an API key**
Run `picoclaw onboard` — it prompts for your passphrase and generates the SSH key,
then automatically re-encrypts any plaintext `api_key` entries in your config on
the next `SaveConfig` call. The resulting `enc://` value will look like:
```
enc://AAAA...base64...
```
**3. Paste the output into your config**
```json
{
"model_list": [
{
"model_name": "gpt-4o",
"api_key": "enc://AAAA...base64...",
"base_url": "https://api.openai.com/v1"
}
]
}
```
---
## Supported `api_key` Formats
| Format | Example | Behaviour |
|--------|---------|-----------|
| Plaintext | `sk-abc123` | Used as-is |
| File reference | `file://openai.key` | Content read from the same directory as the config file |
| Encrypted | `enc://<base64>` | Decrypted at startup using `PICOCLAW_KEY_PASSPHRASE` |
| Empty | `""` | Passed through unchanged (used with `auth_method: oauth`) |
---
## Cryptographic Design
### Key Derivation
Encryption uses **HKDF-SHA256** with an optional SSH private key as a second factor.
```
Without SSH key (passphrase only):
ikm = SHA256(passphrase)
aes_key = HKDF-SHA256(ikm, salt, info="picoclaw-credential-v1", 32 bytes)
With SSH key (recommended):
sshHash = SHA256(ssh_private_key_file_bytes)
ikm = HMAC-SHA256(key=sshHash, message=passphrase)
aes_key = HKDF-SHA256(ikm, salt, info="picoclaw-credential-v1", 32 bytes)
```
### Encryption
```
AES-256-GCM(key=aes_key, nonce=random[12], plaintext=api_key)
```
### Wire Format
```
enc://<base64( salt[16] + nonce[12] + ciphertext )>
```
| Field | Size | Description |
|-------|------|-------------|
| `salt` | 16 bytes | Random per encryption; fed into HKDF |
| `nonce` | 12 bytes | Random per encryption; AES-GCM IV |
| `ciphertext` | variable | AES-256-GCM ciphertext + 16-byte authentication tag |
The GCM authentication tag is appended to the ciphertext automatically. Any tampering causes decryption to fail with an error rather than returning corrupt plaintext.
### Performance
| Operation | Time (ARM Cortex-A) |
|-----------|---------------------|
| Key derivation (HKDF) | < 1 ms |
| AES-256-GCM decrypt | < 1 ms |
| **Total startup overhead** | **< 2 ms per key** |
---
## Two-Factor Security with SSH Key
When a SSH private key is provided, breaking the encryption requires **both**:
1. The **passphrase** (`PICOCLAW_KEY_PASSPHRASE`)
2. The **SSH private key file**
This means a leaked config file alone is not sufficient to recover the API key, even if the passphrase is weak. The SSH key contributes 256 bits of entropy (Ed25519) regardless of passphrase strength.
### Threat Model
| Attacker Has | Can Decrypt? |
|---|---|
| Config file only | No — needs passphrase + SSH key |
| SSH key only | No — needs passphrase |
| Passphrase only | No — needs SSH key |
| Config file + SSH key + passphrase | Yes — full compromise |
---
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `PICOCLAW_KEY_PASSPHRASE` | Yes (for `enc://`) | Passphrase used for key derivation |
| `PICOCLAW_SSH_KEY_PATH` | No | Path to SSH private key. Set to `""` to disable auto-detection and use passphrase-only mode |
### SSH Key Auto-Detection
If `PICOCLAW_SSH_KEY_PATH` is not set, PicoClaw looks for the picoclaw-specific key:
```
~/.ssh/picoclaw_ed25519.key
```
This dedicated file avoids conflicts with the user's existing SSH keys.
Run `picoclaw onboard` to generate it automatically.
`os.UserHomeDir()` is used for cross-platform home directory resolution (reads `USERPROFILE` on Windows, `HOME` on Unix/macOS).
To explicitly disable SSH key usage and use passphrase-only mode:
```bash
export PICOCLAW_SSH_KEY_PATH=""
```
---
## Migration
Because the only secret material is `PICOCLAW_KEY_PASSPHRASE` and the SSH private key file, migration is straightforward:
1. Copy the config file to the new machine.
2. Set `PICOCLAW_KEY_PASSPHRASE` to the same value.
3. Copy the SSH private key file to the same path (or set `PICOCLAW_SSH_KEY_PATH` to its new location).
No re-encryption is needed.
---
## Security Considerations
- **Passphrase strength matters in passphrase-only mode.** Without an SSH key, a weak passphrase can be brute-forced offline. Use `PICOCLAW_SSH_KEY_PATH=""` only in environments where no SSH key is available and the passphrase is sufficiently strong (≥ 32 random characters).
- **The SSH key is read-only at runtime.** PicoClaw never writes to or modifies the SSH key file.
- **Plaintext keys remain supported.** Existing configs without `enc://` are unaffected.
- **The `enc://` format is versioned** via the HKDF `info` field (`picoclaw-credential-v1`), allowing future algorithm upgrades without breaking existing encrypted values.
+6 -6
View File
@@ -66,7 +66,7 @@ Problem: Agent needs to know both `provider` and `model`, adding complexity.
Inspired by [LiteLLM](https://docs.litellm.ai/docs/proxy/configs) design:
1. **Model-centric**: Users care about models, not providers
2. **Protocol prefix**: Use `protocol/model_name` format, e.g., `openai/gpt-5.2`, `anthropic/claude-sonnet-4.6`
2. **Protocol prefix**: Use `protocol/model_name` format, e.g., `openai/gpt-5.4`, `anthropic/claude-sonnet-4.6`
3. **Configuration-driven**: Adding new Providers only requires config changes, no code changes
### 2.2 New Configuration Structure
@@ -81,8 +81,8 @@ Inspired by [LiteLLM](https://docs.litellm.ai/docs/proxy/configs) design:
"api_key": "sk-xxx"
},
{
"model_name": "gpt-5.2",
"model": "openai/gpt-5.2",
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-xxx"
},
{
@@ -128,7 +128,7 @@ type Config struct {
type ModelConfig struct {
// Required
ModelName string `json:"model_name"` // user-facing name (alias)
Model string `json:"model"` // protocol/model, e.g., openai/gpt-5.2
Model string `json:"model"` // protocol/model, e.g., openai/gpt-5.4
// Common config
APIBase string `json:"api_base,omitempty"`
@@ -180,7 +180,7 @@ Identify protocol via prefix in `model` field:
"model": "deepseek-chat"
},
"coder": {
"model": "gpt-5.2",
"model": "gpt-5.4",
"system_prompt": "You are a coding assistant..."
},
"translator": {
@@ -200,7 +200,7 @@ Each Agent only needs to specify `model` (corresponds to `model_name` in `model_
model_list:
- model_name: gpt-4o
litellm_params:
model: openai/gpt-5.2
model: openai/gpt-5.4
api_key: xxx
- model_name: my-custom
litellm_params:
+166
View File
@@ -0,0 +1,166 @@
# 🐳 Docker & Quick Start Guide
> Back to [README](../README.md)
## 🐳 Docker Compose
You can also run PicoClaw using Docker Compose without installing anything locally.
```bash
# 1. Clone this repo
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. First run — auto-generates docker/data/config.json then exits
docker compose -f docker/docker-compose.yml --profile gateway up
# The container prints "First-run setup complete." and stops.
# 3. Set your API keys
vim docker/data/config.json # Set provider API keys, bot tokens, etc.
# 4. Start
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Docker Users**: By default, the Gateway listens on `127.0.0.1` which is not accessible from the host. If you need to access the health endpoints or expose ports, set `PICOCLAW_GATEWAY_HOST=0.0.0.0` in your environment or update `config.json`.
```bash
# 5. Check logs
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. Stop
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Launcher Mode (Web Console)
The `launcher` image includes all three binaries (`picoclaw`, `picoclaw-launcher`, `picoclaw-launcher-tui`) and starts the web console by default, which provides a browser-based UI for configuration and chat.
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
Open http://localhost:18800 in your browser. The launcher manages the gateway process automatically.
> [!WARNING]
> The web console does not yet support authentication. Avoid exposing it to the public internet.
### Agent Mode (One-shot)
```bash
# Ask a question
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "What is 2+2?"
# Interactive mode
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### Update
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
### 🚀 Quick Start
> [!TIP]
> Set your API Key in `~/.picoclaw/config.json`. Get API Keys: [Volcengine (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM). Web search is optional — get a free [Tavily API](https://tavily.com) (1000 free queries/month) or [Brave Search API](https://brave.com/search/api) (2000 free queries/month).
**1. Initialize**
```bash
picoclaw onboard
```
**2. Configure** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **New**: The `model_list` configuration format allows zero-code provider addition. See [Model Configuration](#model-configuration-model_list) for details.
> `request_timeout` is optional and uses seconds. If omitted or set to `<= 0`, PicoClaw uses the default timeout (120s).
**3. Get API Keys**
* **LLM Provider**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **Web Search** (optional):
* [Brave Search](https://brave.com/search/api) - Paid ($5/1000 queries, ~$5-6/month)
* [Perplexity](https://www.perplexity.ai) - AI-powered search with chat interface
* [SearXNG](https://github.com/searxng/searxng) - Self-hosted metasearch engine (free, no API key needed)
* [Tavily](https://tavily.com) - Optimized for AI Agents (1000 requests/month)
* DuckDuckGo - Built-in fallback (no API key required)
> **Note**: See `config.example.json` for a complete configuration template.
**4. Chat**
```bash
picoclaw agent -m "What is 2+2?"
```
That's it! You have a working AI assistant in 2 minutes.
---
+588
View File
@@ -0,0 +1,588 @@
# 💬 Configuration des Applications de Chat
> Retour au [README](../../README.fr.md)
## 💬 Applications de Chat
Communiquez avec votre PicoClaw via Telegram, Discord, WhatsApp, Matrix, QQ, DingTalk, LINE, WeCom, Feishu, Slack, IRC, OneBot ou MaixCam.
> **Note** : Tous les canaux basés sur les webhooks (LINE, WeCom, etc.) sont servis sur un seul serveur HTTP Gateway partagé (`gateway.host`:`gateway.port`, par défaut `127.0.0.1:18790`). Il n'y a pas de ports par canal à configurer. Note : Feishu utilise le mode WebSocket/SDK et n'utilise pas le serveur HTTP webhook partagé.
| Canal | Configuration |
| ------------ | -------------------------------------- |
| **Telegram** | Facile (juste un token) |
| **Discord** | Facile (bot token + intents) |
| **WhatsApp** | Facile (natif : scan QR ; ou bridge URL) |
| **Matrix** | Moyen (homeserver + bot access token) |
| **QQ** | Facile (AppID + AppSecret) |
| **DingTalk** | Moyen (identifiants de l'application) |
| **LINE** | Moyen (identifiants + webhook URL) |
| **WeCom AI Bot** | Moyen (Token + clé AES) |
| **Feishu** | Moyen (App ID + Secret, mode WebSocket) |
| **Slack** | Moyen (Bot token + App token) |
| **IRC** | Moyen (serveur + configuration TLS) |
| **OneBot** | Moyen (QQ via protocole OneBot) |
| **MaixCam** | Facile (intégration matérielle Sipeed) |
| **Pico** | Native PicoClaw protocol |
<details>
<summary><b>Telegram</b> (Recommandé)</summary>
**1. Créer un bot**
* Ouvrez Telegram, recherchez `@BotFather`
* Envoyez `/newbot`, suivez les instructions
* Copiez le token
**2. Configurer**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
> Obtenez votre identifiant utilisateur via `@userinfobot` sur Telegram.
**3. Lancer**
```bash
picoclaw gateway
```
**4. Menu de commandes Telegram (enregistré automatiquement au démarrage)**
PicoClaw conserve les définitions de commandes dans un registre partagé unique. Au démarrage, Telegram enregistre automatiquement les commandes bot prises en charge (par exemple `/start`, `/help`, `/show`, `/list`) afin que le menu de commandes et le comportement à l'exécution restent synchronisés.
L'enregistrement du menu de commandes Telegram reste une découverte UX locale au canal ; l'exécution générique des commandes est gérée de manière centralisée dans la boucle agent via l'exécuteur de commandes.
Si l'enregistrement des commandes échoue (erreurs transitoires réseau/API), le canal démarre quand même et PicoClaw réessaie l'enregistrement en arrière-plan.
</details>
<details>
<summary><b>Discord</b></summary>
**1. Créer un bot**
* Allez sur <https://discord.com/developers/applications>
* Créez une application → Bot → Add Bot
* Copiez le token du bot
**2. Activer les intents**
* Dans les paramètres du Bot, activez **MESSAGE CONTENT INTENT**
* (Optionnel) Activez **SERVER MEMBERS INTENT** si vous prévoyez d'utiliser des listes d'autorisation basées sur les données des membres
**3. Obtenir votre identifiant utilisateur**
* Paramètres Discord → Avancé → activez **Developer Mode**
* Clic droit sur votre avatar → **Copy User ID**
**4. Configurer**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. Inviter le bot**
* OAuth2 → URL Generator
* Scopes : `bot`
* Bot Permissions : `Send Messages`, `Read Message History`
* Ouvrez l'URL d'invitation générée et ajoutez le bot à votre serveur
**Mode déclenchement en groupe (optionnel)**
Par défaut, le bot répond à tous les messages dans un canal de serveur. Pour limiter les réponses aux @mentions uniquement, ajoutez :
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
Vous pouvez également déclencher par préfixes de mots-clés (par ex. `!bot`) :
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b> (natif via whatsmeow)</summary>
PicoClaw peut se connecter à WhatsApp de deux manières :
- **Natif (recommandé) :** En processus via [whatsmeow](https://github.com/tulir/whatsmeow). Pas de bridge séparé. Définissez `"use_native": true` et laissez `bridge_url` vide. Au premier lancement, scannez le code QR avec WhatsApp (Appareils liés). La session est stockée dans votre workspace (par ex. `workspace/whatsapp/`). Le canal natif est **optionnel** pour garder le binaire par défaut léger ; compilez avec `-tags whatsapp_native` (par ex. `make build-whatsapp-native` ou `go build -tags whatsapp_native ./cmd/...`).
- **Bridge :** Connectez-vous à un bridge WebSocket externe. Définissez `bridge_url` (par ex. `ws://localhost:3001`) et gardez `use_native` à false.
**Configurer (natif)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
Si `session_store_path` est vide, la session est stockée dans `<workspace>/whatsapp/`. Lancez `picoclaw gateway` ; au premier lancement, scannez le code QR affiché dans le terminal avec WhatsApp → Appareils liés.
</details>
<details>
<summary><b>QQ</b></summary>
**1. Créer un bot**
- Allez sur [QQ Open Platform](https://q.qq.com/#)
- Créez une application → Obtenez **AppID** et **AppSecret**
**2. Configurer**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> Définissez `allow_from` vide pour autoriser tous les utilisateurs, ou spécifiez des numéros QQ pour restreindre l'accès.
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Créer un bot**
* Allez sur [Open Platform](https://open.dingtalk.com/)
* Créez une application interne
* Copiez le Client ID et le Client Secret
**2. Configurer**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> Définissez `allow_from` vide pour autoriser tous les utilisateurs, ou spécifiez des identifiants DingTalk pour restreindre l'accès.
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Matrix</b></summary>
**1. Préparer le compte bot**
* Utilisez votre homeserver préféré (par ex. `https://matrix.org` ou auto-hébergé)
* Créez un utilisateur bot et obtenez son access token
**2. Configurer**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. Lancer**
```bash
picoclaw gateway
```
Pour toutes les options (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), voir le [Guide de Configuration du Canal Matrix](docs/channels/matrix/README.md).
</details>
<details>
<summary><b>LINE</b></summary>
**1. Créer un compte officiel LINE**
- Allez sur [LINE Developers Console](https://developers.line.biz/)
- Créez un provider → Créez un canal Messaging API
- Copiez le **Channel Secret** et le **Channel Access Token**
**2. Configurer**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> Le webhook LINE est servi sur le serveur Gateway partagé (`gateway.host`:`gateway.port`, par défaut `127.0.0.1:18790`).
**3. Configurer l'URL du Webhook**
LINE nécessite HTTPS pour les webhooks. Utilisez un reverse proxy ou un tunnel :
```bash
# Exemple avec ngrok (le port par défaut du gateway est 18790)
ngrok http 18790
```
Puis définissez l'URL du Webhook dans la console LINE Developers à `https://your-domain/webhook/line` et activez **Use webhook**.
**4. Lancer**
```bash
picoclaw gateway
```
> Dans les discussions de groupe, le bot ne répond que lorsqu'il est @mentionné. Les réponses citent le message original.
</details>
<details>
<summary><b>WeCom (企业微信)</b></summary>
PicoClaw prend en charge trois types d'intégration WeCom :
**Option 1 : WeCom Bot (Bot)** - Configuration plus facile, prend en charge les discussions de groupe
**Option 2 : WeCom App (Application personnalisée)** - Plus de fonctionnalités, messagerie proactive, chat privé uniquement
**Option 3 : WeCom AI Bot (Bot IA)** - Bot IA officiel, réponses en streaming, prend en charge les discussions de groupe et privées
Voir le [Guide de Configuration WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.zh.md) pour les instructions détaillées.
**Configuration rapide - WeCom Bot :**
**1. Créer un bot**
* Allez dans la console d'administration WeCom → Discussion de groupe → Ajouter un bot de groupe
* Copiez l'URL du webhook (format : `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`)
**2. Configurer**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> Le webhook WeCom est servi sur le serveur Gateway partagé (`gateway.host`:`gateway.port`, par défaut `127.0.0.1:18790`).
**Configuration rapide - WeCom App :**
**1. Créer une application**
* Allez dans la console d'administration WeCom → Gestion des applications → Créer une application
* Copiez **AgentId** et **Secret**
* Allez sur la page "Mon entreprise", copiez **CorpID**
**2. Configurer la réception des messages**
* Dans les détails de l'application, cliquez sur "Recevoir les messages" → "Configurer l'API"
* Définissez l'URL à `http://your-server:18790/webhook/wecom-app`
* Générez **Token** et **EncodingAESKey**
**3. Configurer**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. Lancer**
```bash
picoclaw gateway
```
> **Note** : Les callbacks webhook WeCom sont servis sur le port Gateway (par défaut 18790). Utilisez un reverse proxy pour HTTPS.
**Configuration rapide - WeCom AI Bot :**
**1. Créer un AI Bot**
* Allez dans la console d'administration WeCom → Gestion des applications → AI Bot
* Dans les paramètres du AI Bot, configurez l'URL de callback : `http://your-server:18791/webhook/wecom-aibot`
* Copiez **Token** et cliquez sur "Générer aléatoirement" pour **EncodingAESKey**
**2. Configurer**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "Hello! How can I help you?"
}
}
}
```
**3. Lancer**
```bash
picoclaw gateway
```
> **Note** : WeCom AI Bot utilise le protocole streaming pull — pas de problème de timeout de réponse. Les tâches longues (>30 secondes) basculent automatiquement vers la livraison push via `response_url`.
</details>
<details>
<summary><b>Feishu (飞书)</b></summary>
**1. Créer une application**
* Allez sur [Feishu Open Platform](https://open.feishu.cn/)
* Créez une application → Obtenez **App ID** et **App Secret**
**2. Configurer**
```json
{
"channels": {
"feishu": {
"enabled": true,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
}
}
}
```
> Feishu utilise le mode WebSocket/SDK et ne nécessite pas de serveur webhook.
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Slack</b></summary>
**1. Créer une application Slack**
* Allez sur [Slack API](https://api.slack.com/apps)
* Créez une nouvelle application
* Obtenez le **Bot Token** et l'**App Token**
**2. Configurer**
```json
{
"channels": {
"slack": {
"enabled": true,
"bot_token": "xoxb-your-bot-token",
"app_token": "xapp-your-app-token",
"allow_from": []
}
}
}
```
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>IRC</b></summary>
**1. Configurer le serveur IRC**
* Préparez les informations de votre serveur IRC (adresse, port, canal)
**2. Configurer**
```json
{
"channels": {
"irc": {
"enabled": true,
"server": "irc.example.com:6697",
"nick": "picoclaw-bot",
"channel": "#your-channel",
"use_tls": true,
"allow_from": []
}
}
}
```
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>OneBot</b></summary>
**1. Configurer OneBot**
* Installez une implémentation OneBot compatible (par ex. go-cqhttp, Lagrange)
* Configurez la connexion WebSocket
**2. Configurer**
```json
{
"channels": {
"onebot": {
"enabled": true,
"ws_url": "ws://localhost:8080",
"allow_from": []
}
}
}
```
> OneBot permet d'utiliser QQ via le protocole OneBot standard.
**3. Lancer**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>MaixCam</b></summary>
**1. Préparer le matériel**
* Obtenez un appareil [Sipeed MaixCam](https://wiki.sipeed.com/maixcam)
**2. Configurer**
```json
{
"channels": {
"maixcam": {
"enabled": true,
"allow_from": []
}
}
}
```
> MaixCam est une intégration matérielle Sipeed pour l'interaction IA embarquée.
**3. Lancer**
```bash
picoclaw gateway
```
</details>
+218
View File
@@ -0,0 +1,218 @@
# ⚙️ Guide de Configuration
> Retour au [README](../../README.fr.md)
## ⚙️ Configuration
Fichier de configuration : `~/.picoclaw/config.json`
### Variables d'Environnement
Vous pouvez remplacer les chemins par défaut à l'aide de variables d'environnement. Ceci est utile pour les installations portables, les déploiements conteneurisés ou l'exécution de PicoClaw en tant que service système. Ces variables sont indépendantes et contrôlent des chemins différents.
| Variable | Description | Chemin par défaut |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | Remplace le chemin vers le fichier de configuration. Indique directement à PicoClaw quel `config.json` charger, en ignorant tous les autres emplacements. | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | Remplace le répertoire racine des données PicoClaw. Change l'emplacement par défaut du `workspace` et des autres répertoires de données. | `~/.picoclaw` |
**Exemples :**
```bash
# Run picoclaw using a specific config file
# The workspace path will be read from within that config file
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# Run picoclaw with all its data stored in /opt/picoclaw
# Config will be loaded from the default ~/.picoclaw/config.json
# Workspace will be created at /opt/picoclaw/workspace
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# Use both for a fully customized setup
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### Structure du Workspace
PicoClaw stocke les données dans votre workspace configuré (par défaut : `~/.picoclaw/workspace`) :
```
~/.picoclaw/workspace/
├── sessions/ # Sessions de conversation et historique
├── memory/ # Mémoire à long terme (MEMORY.md)
├── state/ # État persistant (dernier canal, etc.)
├── cron/ # Base de données des tâches planifiées
├── skills/ # Compétences personnalisées
├── AGENT.md # Guide de comportement de l'agent
├── HEARTBEAT.md # Invites de tâches périodiques (vérifiées toutes les 30 min)
├── SOUL.md # Âme de l'agent
└── USER.md # Préférences utilisateur
```
> **Remarque :** Les modifications apportées à `AGENT.md`, `SOUL.md`, `USER.md` et `memory/MEMORY.md` sont détectées automatiquement au moment de l'exécution via le suivi de la date de modification (mtime). Il n'est **pas nécessaire de redémarrer le gateway** après avoir modifié ces fichiers — l'agent charge le nouveau contenu à la prochaine requête.
### Sources de Compétences
Par défaut, les compétences sont chargées depuis :
1. `~/.picoclaw/workspace/skills` (workspace)
2. `~/.picoclaw/skills` (global)
3. `<current-working-directory>/skills` (builtin)
Pour les configurations avancées/de test, vous pouvez remplacer la racine des compétences builtin avec :
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### Politique Unifiée d'Exécution des Commandes
- Les commandes slash génériques sont exécutées via un chemin unique dans `pkg/agent/loop.go` via `commands.Executor`.
- Les adaptateurs de canaux ne consomment plus les commandes génériques localement ; ils transmettent le texte entrant au chemin bus/agent. Telegram enregistre toujours automatiquement les commandes prises en charge au démarrage.
- Une commande slash inconnue (par exemple `/foo`) passe au traitement LLM normal.
- Une commande enregistrée mais non prise en charge sur le canal actuel (par exemple `/show` sur WhatsApp) renvoie une erreur explicite à l'utilisateur et arrête le traitement ultérieur.
### 🔒 Sandbox de Sécurité
PicoClaw s'exécute dans un environnement sandboxé par défaut. L'agent ne peut accéder aux fichiers et exécuter des commandes que dans le workspace configuré.
#### Configuration par Défaut
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| Option | Par défaut | Description |
| ----------------------- | ----------------------- | ------------------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Répertoire de travail de l'agent |
| `restrict_to_workspace` | `true` | Restreindre l'accès fichiers/commandes au workspace |
#### Outils Protégés
Lorsque `restrict_to_workspace: true`, les outils suivants sont sandboxés :
| Outil | Fonction | Restriction |
| ------------- | --------------------- | ---------------------------------------------- |
| `read_file` | Lire des fichiers | Uniquement les fichiers dans le workspace |
| `write_file` | Écrire des fichiers | Uniquement les fichiers dans le workspace |
| `list_dir` | Lister les répertoires| Uniquement les répertoires dans le workspace |
| `edit_file` | Modifier des fichiers | Uniquement les fichiers dans le workspace |
| `append_file` | Ajouter aux fichiers | Uniquement les fichiers dans le workspace |
| `exec` | Exécuter des commandes| Les chemins de commande doivent être dans le workspace |
#### Protection Exec Supplémentaire
Même avec `restrict_to_workspace: false`, l'outil `exec` bloque ces commandes dangereuses :
* `rm -rf`, `del /f`, `rmdir /s` — Suppression en masse
* `format`, `mkfs`, `diskpart` — Formatage de disque
* `dd if=` — Imagerie de disque
* Écriture vers `/dev/sd[a-z]` — Écritures directes sur disque
* `shutdown`, `reboot`, `poweroff` — Arrêt du système
* Fork bomb `:(){ :|:& };:`
### Contrôle d'Accès aux Fichiers
| Clé de configuration | Type | Par défaut | Description |
|----------------------|------|------------|-------------|
| `tools.allow_read_paths` | string[] | `[]` | Chemins supplémentaires autorisés en lecture en dehors du workspace |
| `tools.allow_write_paths` | string[] | `[]` | Chemins supplémentaires autorisés en écriture en dehors du workspace |
### Sécurité Exec
| Clé de configuration | Type | Par défaut | Description |
|----------------------|------|------------|-------------|
| `tools.exec.allow_remote` | bool | `false` | Autoriser l'outil exec depuis les canaux distants (Telegram/Discord etc.) |
| `tools.exec.enable_deny_patterns` | bool | `true` | Activer l'interception des commandes dangereuses |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | Patterns regex personnalisés à bloquer |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | Patterns regex personnalisés à autoriser |
> **Note de sécurité :** La protection Symlink est activée par défaut — tous les chemins de fichiers sont résolus via `filepath.EvalSymlinks` avant la correspondance avec la liste blanche, empêchant les attaques d'évasion par symlink.
#### Limitation Connue : Processus Enfants des Outils de Build
Le garde de sécurité exec n'inspecte que la ligne de commande lancée directement par PicoClaw. Il n'inspecte pas récursivement les processus enfants générés par les outils de développement autorisés tels que `make`, `go run`, `cargo`, `npm run` ou les scripts de build personnalisés.
Cela signifie qu'une commande de niveau supérieur peut toujours compiler ou lancer d'autres binaires après avoir passé la vérification initiale du garde. En pratique, traitez les scripts de build, les Makefiles, les scripts de packages et les binaires générés comme du code exécutable nécessitant le même niveau de revue qu'une commande shell directe.
Pour les environnements à haut risque :
* Examinez les scripts de build avant l'exécution.
* Préférez l'approbation/revue manuelle pour les workflows de compilation et d'exécution.
* Exécutez PicoClaw dans un conteneur ou une VM si vous avez besoin d'une isolation plus forte que celle fournie par le garde intégré.
#### Exemples d'Erreurs
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### Désactiver les Restrictions (Risque de Sécurité)
Si vous avez besoin que l'agent accède à des chemins en dehors du workspace :
**Méthode 1 : Fichier de configuration**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**Méthode 2 : Variable d'environnement**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **Avertissement** : Désactiver cette restriction permet à l'agent d'accéder à n'importe quel chemin sur votre système. À utiliser avec précaution dans des environnements contrôlés uniquement.
#### Cohérence des Limites de Sécurité
Le paramètre `restrict_to_workspace` s'applique de manière cohérente à tous les chemins d'exécution :
| Chemin d'exécution | Limite de sécurité |
| ------------------ | -------------------------------- |
| Main Agent | `restrict_to_workspace` ✅ |
| Subagent / Spawn | Hérite de la même restriction ✅ |
| Heartbeat tasks | Hérite de la même restriction ✅ |
Tous les chemins partagent la même restriction de workspace — il n'y a aucun moyen de contourner la limite de sécurité via les subagents ou les tâches planifiées.
### Heartbeat (Tâches Périodiques)
PicoClaw peut effectuer des tâches périodiques automatiquement. Créez un fichier `HEARTBEAT.md` dans votre workspace :
```markdown
# Periodic Tasks
- Check my email for important messages
- Review my calendar for upcoming events
- Check the weather forecast
```
L'agent lira ce fichier toutes les 30 minutes (configurable) et exécutera toutes les tâches en utilisant les outils disponibles.
#### Tâches Asynchrones avec Spawn
Pour les tâches longues (recherche web, appels API), utilisez l'outil `spawn` pour créer un **subagent** :
```markdown
# Periodic Tasks
```
+166
View File
@@ -0,0 +1,166 @@
# 🐳 Docker et Démarrage Rapide
> Retour au [README](../../README.fr.md)
## 🐳 Docker Compose
Vous pouvez également exécuter PicoClaw avec Docker Compose sans rien installer localement.
```bash
# 1. Cloner ce dépôt
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. Premier lancement — génère automatiquement docker/data/config.json puis s'arrête
docker compose -f docker/docker-compose.yml --profile gateway up
# Le conteneur affiche "First-run setup complete." et s'arrête.
# 3. Configurer vos clés API
vim docker/data/config.json # Set provider API keys, bot tokens, etc.
# 4. Démarrer
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Utilisateurs Docker** : Par défaut, le Gateway écoute sur `127.0.0.1`, ce qui n'est pas accessible depuis l'hôte. Si vous devez accéder aux endpoints de santé ou exposer des ports, définissez `PICOCLAW_GATEWAY_HOST=0.0.0.0` dans votre environnement ou mettez à jour `config.json`.
```bash
# 5. Vérifier les logs
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. Arrêter
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Mode Launcher (Console Web)
L'image `launcher` inclut les trois binaires (`picoclaw`, `picoclaw-launcher`, `picoclaw-launcher-tui`) et démarre la console web par défaut, qui fournit une interface navigateur pour la configuration et le chat.
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
Ouvrez http://localhost:18800 dans votre navigateur. Le launcher gère automatiquement le processus gateway.
> [!WARNING]
> La console web ne prend pas encore en charge l'authentification. Évitez de l'exposer sur Internet public.
### Mode Agent (One-shot)
```bash
# Poser une question
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "What is 2+2?"
# Mode interactif
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### Mise à jour
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
### 🚀 Démarrage Rapide
> [!TIP]
> Configurez votre clé API dans `~/.picoclaw/config.json`. Obtenir des clés API : [Volcengine (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM). La recherche web est optionnelle — obtenez gratuitement une [API Tavily](https://tavily.com) (1000 requêtes gratuites/mois) ou une [API Brave Search](https://brave.com/search/api) (2000 requêtes gratuites/mois).
**1. Initialiser**
```bash
picoclaw onboard
```
**2. Configurer** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **Nouveau** : Le format de configuration `model_list` permet l'ajout de fournisseurs sans modification de code. Voir [Configuration des Modèles](#configuration-des-modèles-model_list) pour plus de détails.
> `request_timeout` est optionnel et utilise les secondes. S'il est omis ou défini à `<= 0`, PicoClaw utilise le timeout par défaut (120s).
**3. Obtenir des clés API**
* **Fournisseur LLM** : [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **Recherche Web** (optionnel) :
* [Brave Search](https://brave.com/search/api) - Payant ($5/1000 requêtes, ~$5-6/mois)
* [Perplexity](https://www.perplexity.ai) - Recherche alimentée par l'IA avec interface de chat
* [SearXNG](https://github.com/searxng/searxng) - Métamoteur auto-hébergé (gratuit, pas de clé API nécessaire)
* [Tavily](https://tavily.com) - Optimisé pour les agents IA (1000 requêtes/mois)
* DuckDuckGo - Solution de repli intégrée (pas de clé API requise)
> **Note** : Voir `config.example.json` pour un modèle de configuration complet.
**4. Discuter**
```bash
picoclaw agent -m "What is 2+2?"
```
C'est tout ! Vous avez un assistant IA fonctionnel en 2 minutes.
---
+434
View File
@@ -0,0 +1,434 @@
# 🔌 Fournisseurs et Configuration des Modèles
> Retour au [README](../../README.fr.md)
### Fournisseurs
> [!NOTE]
> Groq fournit la transcription vocale gratuite via Whisper. Si configuré, les messages audio de n'importe quel canal seront automatiquement transcrits au niveau de l'agent.
| Provider | Purpose | Get API Key |
| ------------ | --------------------------------------- | ------------------------------------------------------------ |
| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM (Volcengine direct) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid direct) | [vivgrid.com](https://vivgrid.com) |
| `moonshot` | LLM (Kimi/Moonshot direct) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax direct) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian direct) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope direct) | [modelscope.cn](https://modelscope.cn) |
### Configuration des Modèles (model_list)
> **Nouveauté** PicoClaw utilise désormais une approche de configuration **centrée sur le modèle**. Spécifiez simplement le format `vendor/model` (par ex. `zhipu/glm-4.7`) pour ajouter de nouveaux fournisseurs — **aucune modification de code requise !**
Cette conception permet également le **support multi-agents** avec une sélection flexible de fournisseurs :
- **Différents agents, différents fournisseurs** : Chaque agent peut utiliser son propre fournisseur LLM
- **Modèles de repli** : Configurez des modèles principaux et de repli pour la résilience
- **Répartition de charge** : Distribuez les requêtes entre plusieurs endpoints
- **Configuration centralisée** : Gérez tous les fournisseurs en un seul endroit
#### 📋 Tous les Vendors Supportés
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) |
| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | Your LiteLLM proxy key |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) |
| **VolcEngine (Doubao)** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [Get Key](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [Get Key](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [Get Key](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [Get Token](https://modelscope.cn/my/tokens) |
| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### Configuration de Base
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### Exemples par Vendor
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**VolcEngine (Doubao)**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (avec clé API)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
}
```
> Exécutez `picoclaw auth login --provider anthropic` pour coller votre token API.
**API Anthropic Messages (format natif)**
Pour l'accès direct à l'API Anthropic ou les endpoints personnalisés qui ne prennent en charge que le format de message natif d'Anthropic :
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> Utilisez le protocole `anthropic-messages` lorsque :
> - Vous utilisez des proxys tiers qui ne prennent en charge que l'endpoint natif `/v1/messages` d'Anthropic (pas le format compatible OpenAI `/v1/chat/completions`)
> - Vous vous connectez à des services comme MiniMax, Synthetic qui nécessitent le format de message natif d'Anthropic
> - Le protocole `anthropic` existant renvoie des erreurs 404 (indiquant que l'endpoint ne prend pas en charge le format compatible OpenAI)
>
> **Note :** Le protocole `anthropic` utilise le format compatible OpenAI (`/v1/chat/completions`), tandis que `anthropic-messages` utilise le format natif d'Anthropic (`/v1/messages`). Choisissez en fonction du format pris en charge par votre endpoint.
**Ollama (local)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**Proxy/API Personnalisé**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
PicoClaw ne supprime que le préfixe externe `litellm/` avant d'envoyer la requête, donc les alias de proxy comme `litellm/lite-gpt4` envoient `lite-gpt4`, tandis que `litellm/openai/gpt-4o` envoie `openai/gpt-4o`.
#### Répartition de Charge
Configurez plusieurs endpoints pour le même nom de modèle — PicoClaw effectuera automatiquement un round-robin entre eux :
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### Migration depuis l'Ancienne Configuration `providers`
L'ancienne configuration `providers` est **dépréciée** mais toujours prise en charge pour la compatibilité ascendante.
**Ancienne configuration (dépréciée) :**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**Nouvelle configuration (recommandée) :**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
Pour un guide de migration détaillé, voir [docs/migration/model-list-migration.md](docs/migration/model-list-migration.md).
### Architecture des Fournisseurs
PicoClaw route les fournisseurs par famille de protocoles :
- Protocole compatible OpenAI : OpenRouter, passerelles compatibles OpenAI, Groq, Zhipu et endpoints de type vLLM.
- Protocole Anthropic : Comportement natif de l'API Claude.
- Chemin Codex/OAuth : Route d'authentification OAuth/token OpenAI.
Cela maintient le runtime léger tout en faisant des nouveaux backends compatibles OpenAI principalement une opération de configuration (`api_base` + `api_key`).
<details>
<summary><b>Zhipu</b></summary>
**1. Obtenir la clé API et l'URL de base**
* Obtenir la [clé API](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
**2. Configurer**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. Lancer**
```bash
picoclaw agent -m "Hello"
```
</details>
<details>
<summary><b>Exemple de configuration complète</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 Comparaison des Clés API
| Service | Pricing | Use Case |
| ---------------- | ------------------------ | ------------------------------------- |
| **OpenRouter** | Free: 200K tokens/month | Multiple models (Claude, GPT-4, etc.) |
| **Volcengine CodingPlan** | ¥9.9/first month | Best for Chinese users, multiple SOTA models (Doubao, DeepSeek, etc.) |
| **Zhipu** | Free: 200K tokens/month | Suitable for Chinese users |
| **Brave Search** | $5/1000 queries | Web search functionality |
| **SearXNG** | Free (self-hosted) | Privacy-focused metasearch (70+ engines) |
| **Groq** | Free tier available | Fast inference (Llama, Mixtral) |
| **Cerebras** | Free tier available | Fast inference (Llama, Qwen, etc.) |
| **LongCat** | Free: up to 5M tokens/day | Fast inference |
| **ModelScope** | Free: 2000 requests/day | Inference (Qwen, GLM, DeepSeek, etc.) |
---
<div align="center">
<img src="assets/logo.jpg" alt="PicoClaw Meme" width="512">
</div>
+61
View File
@@ -0,0 +1,61 @@
# 🔄 Tâches Asynchrones et Spawn
> Retour au [README](../../README.fr.md)
## Tâches Rapides (réponse directe)
- Rapporter l'heure actuelle
## Tâches Longues (utiliser spawn pour l'asynchrone)
- Rechercher sur le web des actualités IA et résumer
- Vérifier les emails et rapporter les messages importants
```
**Comportements clés :**
| Fonctionnalité | Description |
| ----------------------- | --------------------------------------------------------------- |
| **spawn** | Crée un subagent asynchrone, ne bloque pas le heartbeat |
| **Independent context** | Le subagent a son propre contexte, pas d'historique de session |
| **message tool** | Le subagent communique directement avec l'utilisateur via l'outil message |
| **Non-blocking** | Après le spawn, le heartbeat continue à la tâche suivante |
#### Fonctionnement de la Communication du Subagent
```
Heartbeat se déclenche
L'agent lit HEARTBEAT.md
Pour une tâche longue : spawn subagent
↓ ↓
Continue à la tâche suivante Le subagent travaille indépendamment
↓ ↓
Toutes les tâches terminées Le subagent utilise l'outil "message"
↓ ↓
Répond HEARTBEAT_OK L'utilisateur reçoit le résultat directement
```
Le subagent a accès aux outils (message, web_search, etc.) et peut communiquer avec l'utilisateur indépendamment sans passer par l'agent principal.
**Configuration :**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| Option | Par défaut | Description |
| ---------- | ---------- | ---------------------------------------------- |
| `enabled` | `true` | Activer/désactiver le heartbeat |
| `interval` | `30` | Intervalle de vérification en minutes (min: 5) |
**Variables d'environnement :**
* `PICOCLAW_HEARTBEAT_ENABLED=false` pour désactiver
* `PICOCLAW_HEARTBEAT_INTERVAL=60` pour changer l'intervalle
+336
View File
@@ -0,0 +1,336 @@
# 🔧 Configuration des Outils
> Retour au [README](../../README.fr.md)
La configuration des outils de PicoClaw se trouve dans le champ `tools` de `config.json`.
## Structure du répertoire
```json
{
"tools": {
"web": {
...
},
"mcp": {
...
},
"exec": {
...
},
"cron": {
...
},
"skills": {
...
}
}
}
```
## Outils Web
Les outils web sont utilisés pour la recherche et la récupération de pages web.
### Web Fetcher
Paramètres généraux pour la récupération et le traitement du contenu des pages web.
| Config | Type | Par défaut | Description |
|---------------------|--------|---------------|-----------------------------------------------------------------------------------------------|
| `enabled` | bool | true | Activer la capacité de récupération de pages web. |
| `fetch_limit_bytes` | int | 10485760 | Taille maximale du contenu de la page web à récupérer, en octets (par défaut 10 Mo). |
| `format` | string | "plaintext" | Format de sortie du contenu récupéré. Options : `plaintext` ou `markdown` (recommandé). |
### Brave
| Config | Type | Par défaut | Description |
|---------------|--------|------------|---------------------------|
| `enabled` | bool | false | Activer la recherche Brave |
| `api_key` | string | - | Clé API Brave Search |
| `max_results` | int | 5 | Nombre maximum de résultats |
### DuckDuckGo
| Config | Type | Par défaut | Description |
|---------------|------|------------|--------------------------------|
| `enabled` | bool | true | Activer la recherche DuckDuckGo |
| `max_results` | int | 5 | Nombre maximum de résultats |
### Perplexity
| Config | Type | Par défaut | Description |
|---------------|--------|------------|--------------------------------|
| `enabled` | bool | false | Activer la recherche Perplexity |
| `api_key` | string | - | Clé API Perplexity |
| `max_results` | int | 5 | Nombre maximum de résultats |
## Outil Exec
L'outil exec est utilisé pour exécuter des commandes shell.
| Config | Type | Par défaut | Description |
|------------------------|-------|------------|------------------------------------------------|
| `enable_deny_patterns` | bool | true | Activer le blocage par défaut des commandes dangereuses |
| `custom_deny_patterns` | array | [] | Modèles de refus personnalisés (expressions régulières) |
### Fonctionnalité
- **`enable_deny_patterns`** : Définir à `false` pour désactiver complètement les modèles de blocage par défaut des commandes dangereuses
- **`custom_deny_patterns`** : Ajouter des modèles regex de refus personnalisés ; les commandes correspondantes seront bloquées
### Modèles de commandes bloquées par défaut
Par défaut, PicoClaw bloque les commandes dangereuses suivantes :
- Commandes de suppression : `rm -rf`, `del /f/q`, `rmdir /s`
- Opérations disque : `format`, `mkfs`, `diskpart`, `dd if=`, écriture vers `/dev/sd*`
- Opérations système : `shutdown`, `reboot`, `poweroff`
- Substitution de commandes : `$()`, `${}`, backticks
- Pipe vers shell : `| sh`, `| bash`
- Élévation de privilèges : `sudo`, `chmod`, `chown`
- Contrôle de processus : `pkill`, `killall`, `kill -9`
- Opérations distantes : `curl | sh`, `wget | sh`, `ssh`
- Gestion de paquets : `apt`, `yum`, `dnf`, `npm install -g`, `pip install --user`
- Conteneurs : `docker run`, `docker exec`
- Git : `git push`, `git force`
- Autres : `eval`, `source *.sh`
### Limitation architecturale connue
Le garde exec ne valide que la commande de niveau supérieur envoyée à PicoClaw. Il n'inspecte **pas** récursivement les processus enfants générés par les outils de build ou les scripts après le démarrage de cette commande.
Exemples de workflows pouvant contourner le garde de commande directe une fois la commande initiale autorisée :
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
Cela signifie que le garde est utile pour bloquer les commandes directes manifestement dangereuses, mais ce n'est **pas** un bac à sable complet pour les pipelines de build non vérifiés. Si votre modèle de menace inclut du code non fiable dans l'espace de travail, utilisez une isolation plus forte comme des conteneurs, des VM ou un flux d'approbation autour des commandes de build et d'exécution.
### Exemple de configuration
```json
{
"tools": {
"exec": {
"enable_deny_patterns": true,
"custom_deny_patterns": [
"\\brm\\s+-r\\b",
"\\bkillall\\s+python"
]
}
}
}
```
## Outil Cron
L'outil cron est utilisé pour planifier des tâches périodiques.
| Config | Type | Par défaut | Description |
|------------------------|------|------------|----------------------------------------------------|
| `exec_timeout_minutes` | int | 5 | Délai d'expiration en minutes, 0 signifie sans limite |
## Outil MCP
L'outil MCP permet l'intégration avec des serveurs Model Context Protocol externes.
### Découverte d'outils (chargement paresseux)
Lors de la connexion à plusieurs serveurs MCP, exposer simultanément des centaines d'outils peut épuiser la fenêtre de contexte du LLM et augmenter les coûts API. La fonctionnalité **Discovery** résout ce problème en gardant les outils MCP *masqués* par défaut.
Au lieu de charger tous les outils, le LLM reçoit un outil de recherche léger (utilisant la correspondance par mots-clés BM25 ou les expressions régulières). Lorsque le LLM a besoin d'une capacité spécifique, il recherche dans la bibliothèque masquée. Les outils correspondants sont alors temporairement « déverrouillés » et injectés dans le contexte pour un nombre configuré de tours (`ttl`).
### Configuration globale
| Config | Type | Par défaut | Description |
|-------------|--------|------------|----------------------------------------------|
| `enabled` | bool | false | Activer l'intégration MCP globalement |
| `discovery` | object | `{}` | Configuration de la découverte d'outils (voir ci-dessous) |
| `servers` | object | `{}` | Mappage du nom de serveur à la configuration du serveur |
### Configuration Discovery (`discovery`)
| Config | Type | Par défaut | Description |
|----------------------|------|------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `enabled` | bool | false | Si true, les outils MCP sont masqués et chargés à la demande via la recherche. Si false, tous les outils sont chargés |
| `ttl` | int | 5 | Nombre de tours de conversation pendant lesquels un outil découvert reste déverrouillé |
| `max_search_results` | int | 5 | Nombre maximum d'outils retournés par requête de recherche |
| `use_bm25` | bool | true | Activer l'outil de recherche par langage naturel/mots-clés (`tool_search_tool_bm25`). **Attention** : consomme plus de ressources que la recherche regex |
| `use_regex` | bool | false | Activer l'outil de recherche par motif regex (`tool_search_tool_regex`) |
> **Note :** Si `discovery.enabled` est `true`, vous **devez** activer au moins un moteur de recherche (`use_bm25` ou `use_regex`),
> sinon l'application ne démarrera pas.
### Configuration par serveur
| Config | Type | Requis | Description |
|------------|--------|----------|--------------------------------------------|
| `enabled` | bool | oui | Activer ce serveur MCP |
| `type` | string | non | Type de transport : `stdio`, `sse`, `http` |
| `command` | string | stdio | Commande exécutable pour le transport stdio |
| `args` | array | non | Arguments de commande pour le transport stdio |
| `env` | object | non | Variables d'environnement pour le processus stdio |
| `env_file` | string | non | Chemin vers le fichier d'environnement pour le processus stdio |
| `url` | string | sse/http | URL du point de terminaison pour le transport `sse`/`http` |
| `headers` | object | non | En-têtes HTTP pour le transport `sse`/`http` |
### Comportement du transport
- Si `type` est omis, le transport est détecté automatiquement :
- `url` est défini → `sse`
- `command` est défini → `stdio`
- `http` et `sse` utilisent tous deux `url` + `headers` optionnels.
- `env` et `env_file` ne sont appliqués qu'aux serveurs `stdio`.
### Exemples de configuration
#### 1) Serveur MCP Stdio
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"filesystem": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp"
]
}
}
}
}
}
```
#### 2) Serveur MCP distant SSE/HTTP
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"remote-mcp": {
"enabled": true,
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
}
}
```
#### 3) Configuration MCP massive avec découverte d'outils activée
*Dans cet exemple, le LLM ne verra que `tool_search_tool_bm25`. Il recherchera et déverrouillera dynamiquement les outils Github ou Postgres uniquement lorsque l'utilisateur le demande.*
```json
{
"tools": {
"mcp": {
"enabled": true,
"discovery": {
"enabled": true,
"ttl": 5,
"max_search_results": 5,
"use_bm25": true,
"use_regex": false
},
"servers": {
"github": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN"
}
},
"postgres": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost/dbname"
]
},
"slack": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-slack"
],
"env": {
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
}
}
}
}
}
}
```
## Outil Skills
L'outil skills configure la découverte et l'installation de compétences via des registres comme ClawHub.
### Registres
| Config | Type | Par défaut | Description |
|------------------------------------|--------|----------------------|----------------------------------------------|
| `registries.clawhub.enabled` | bool | true | Activer le registre ClawHub |
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | URL de base ClawHub |
| `registries.clawhub.auth_token` | string | `""` | Jeton Bearer optionnel pour des limites de débit plus élevées |
| `registries.clawhub.search_path` | string | `/api/v1/search` | Chemin de l'API de recherche |
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Chemin de l'API Skills |
| `registries.clawhub.download_path` | string | `/api/v1/download` | Chemin de l'API de téléchargement |
### Exemple de configuration
```json
{
"tools": {
"skills": {
"registries": {
"clawhub": {
"enabled": true,
"base_url": "https://clawhub.ai",
"auth_token": "",
"search_path": "/api/v1/search",
"skills_path": "/api/v1/skills",
"download_path": "/api/v1/download"
}
}
}
}
}
```
## Variables d'environnement
Toutes les options de configuration peuvent être remplacées via des variables d'environnement au format `PICOCLAW_TOOLS_<SECTION>_<KEY>` :
Par exemple :
- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true`
- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false`
- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10`
- `PICOCLAW_TOOLS_MCP_ENABLED=true`
Note : La configuration de type map imbriquée (par exemple `tools.mcp.servers.<name>.*`) est configurée dans `config.json` plutôt que via des variables d'environnement.
+45
View File
@@ -0,0 +1,45 @@
# 🐛 Dépannage
> Retour au [README](../../README.fr.md)
## "model ... not found in model_list" ou OpenRouter "free is not a valid model ID"
**Symptôme :** Vous voyez l'une des erreurs suivantes :
- `Error creating provider: model "openrouter/free" not found in model_list`
- OpenRouter retourne 400 : `"free is not a valid model ID"`
**Cause :** Le champ `model` dans votre entrée `model_list` est ce qui est envoyé à l'API. Pour OpenRouter, vous devez utiliser l'identifiant de modèle **complet**, pas un raccourci.
- **Incorrect :** `"model": "free"` → OpenRouter reçoit `free` et le rejette.
- **Correct :** `"model": "openrouter/free"` → OpenRouter reçoit `openrouter/free` (routage automatique du niveau gratuit).
**Correction :** Dans `~/.picoclaw/config.json` (ou votre chemin de configuration) :
1. **agents.defaults.model** doit correspondre à un `model_name` dans `model_list` (par ex. `"openrouter-free"`).
2. Le **model** de cette entrée doit être un identifiant de modèle OpenRouter valide, par exemple :
- `"openrouter/free"` niveau gratuit automatique
- `"google/gemini-2.0-flash-exp:free"`
- `"meta-llama/llama-3.1-8b-instruct:free"`
Exemple :
```json
{
"agents": {
"defaults": {
"model": "openrouter-free"
}
},
"model_list": [
{
"model_name": "openrouter-free",
"model": "openrouter/free",
"api_key": "sk-or-v1-YOUR_OPENROUTER_KEY",
"api_base": "https://openrouter.ai/api/v1"
}
]
}
```
Obtenez votre clé sur [OpenRouter Keys](https://openrouter.ai/keys).
+219
View File
@@ -0,0 +1,219 @@
# ⚙️ Guida alla Configurazione
> Torna al [README](../../README.md)
## ⚙️ Configurazione
File di configurazione: `~/.picoclaw/config.json`
### Variabili d'Ambiente
Puoi sovrascrivere i percorsi predefiniti usando variabili d'ambiente. Questo è utile per installazioni portatili, distribuzioni containerizzate, o per eseguire picoclaw come servizio di sistema. Queste variabili sono indipendenti e controllano percorsi diversi.
| Variabile | Descrizione | Percorso Predefinito |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | Sovrascrive il percorso al file di configurazione. Indica direttamente a picoclaw quale `config.json` caricare, ignorando tutte le altre posizioni. | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | Sovrascrive la directory radice per i dati di picoclaw. Modifica la posizione predefinita del `workspace` e delle altre directory dati. | `~/.picoclaw` |
**Esempi:**
```bash
# Esegui picoclaw usando un file di configurazione specifico
# Il percorso del workspace verrà letto da quel file di configurazione
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# Esegui picoclaw con tutti i dati salvati in /opt/picoclaw
# La configurazione verrà caricata dal percorso predefinito ~/.picoclaw/config.json
# Il workspace verrà creato in /opt/picoclaw/workspace
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# Usa entrambi per un setup completamente personalizzato
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### Struttura del Workspace
PicoClaw salva i dati nel workspace configurato (predefinito: `~/.picoclaw/workspace`):
```
~/.picoclaw/workspace/
├── sessions/ # Sessioni di conversazione e cronologia
├── memory/ # Memoria a lungo termine (MEMORY.md)
├── state/ # Stato persistente (ultimo canale, ecc.)
├── cron/ # Database dei job pianificati
├── skills/ # Skill personalizzate
├── AGENTS.md # Guida al comportamento dell'agent
├── HEARTBEAT.md # Prompt per task periodici (controllato ogni 30 min)
├── IDENTITY.md # Identità dell'agent
├── SOUL.md # Anima dell'agent
└── USER.md # Preferenze dell'utente
```
> **Nota:** Le modifiche a `AGENTS.md`, `SOUL.md`, `USER.md`, `IDENTITY.md` e `memory/MEMORY.md` vengono rilevate automaticamente a runtime tramite il tracciamento della data di modifica (mtime). **Non è necessario riavviare il gateway** dopo aver modificato questi file — l'agent caricherà il nuovo contenuto alla prossima richiesta.
### Sorgenti delle Skill
Per impostazione predefinita, le skill vengono caricate da:
1. `~/.picoclaw/workspace/skills` (workspace)
2. `~/.picoclaw/skills` (globale)
3. `<current-working-directory>/skills` (builtin)
Per configurazioni avanzate/di test, puoi sovrascrivere la directory radice delle skill builtin con:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### Politica Unificata di Esecuzione dei Comandi
- I comandi slash generici vengono eseguiti tramite un unico percorso in `pkg/agent/loop.go` via `commands.Executor`.
- Gli adattatori dei canali non consumano più localmente i comandi generici; inoltrano il testo in entrata al percorso bus/agent. Telegram registra ancora automaticamente i comandi supportati all'avvio.
- Un comando slash sconosciuto (ad esempio `/foo`) viene passato all'elaborazione LLM come se fosse un messaggio dell'utente.
- Un comando registrato ma non supportato sul canale corrente (ad esempio `/show` su WhatsApp) restituisce un errore esplicito all'utente e interrompe l'elaborazione.
### 🔒 Sandbox di Sicurezza
PicoClaw esegue in un ambiente sandboxed per impostazione predefinita. L'agent può accedere solo ai file ed eseguire comandi all'interno del workspace configurato.
#### Configurazione Predefinita
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| Opzione | Predefinito | Descrizione |
| ----------------------- | ----------------------- | ---------------------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Directory di lavoro dell'agent |
| `restrict_to_workspace` | `true` | Limita l'accesso a file/comandi al workspace |
#### Strumenti Protetti
Quando `restrict_to_workspace: true`, i seguenti strumenti sono in sandbox:
| Strumento | Funzione | Restrizione |
| ------------- | ------------------------- | ---------------------------------------------------- |
| `read_file` | Legge file | Solo file all'interno del workspace |
| `write_file` | Scrive file | Solo file all'interno del workspace |
| `list_dir` | Elenca directory | Solo directory all'interno del workspace |
| `edit_file` | Modifica file | Solo file all'interno del workspace |
| `append_file` | Aggiunge ai file | Solo file all'interno del workspace |
| `exec` | Esegue comandi | I percorsi dei comandi devono essere nel workspace |
#### Protezione Exec Aggiuntiva
Anche con `restrict_to_workspace: false`, lo strumento `exec` blocca questi comandi pericolosi:
* `rm -rf`, `del /f`, `rmdir /s` — Cancellazione di massa
* `format`, `mkfs`, `diskpart` — Formattazione del disco
* `dd if=` — Imaging del disco
* Scrittura su `/dev/sd[a-z]` — Scritture dirette su disco
* `shutdown`, `reboot`, `poweroff` — Spegnimento del sistema
* Fork bomb `:(){ :|:& };:`
### Controllo Accesso ai File
| Chiave di configurazione | Tipo | Predefinito | Descrizione |
|--------------------------|------|-------------|-------------|
| `tools.allow_read_paths` | string[] | `[]` | Percorsi aggiuntivi consentiti per la lettura al di fuori del workspace |
| `tools.allow_write_paths` | string[] | `[]` | Percorsi aggiuntivi consentiti per la scrittura al di fuori del workspace |
### Sicurezza Exec
| Chiave di configurazione | Tipo | Predefinito | Descrizione |
|--------------------------|------|-------------|-------------|
| `tools.exec.allow_remote` | bool | `false` | Consente lo strumento exec da canali remoti (Telegram/Discord ecc.) |
| `tools.exec.enable_deny_patterns` | bool | `true` | Abilita l'intercettazione dei comandi pericolosi |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | Pattern regex personalizzati da bloccare |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | Pattern regex personalizzati da consentire |
> **Nota di sicurezza:** La protezione dei symlink è abilitata per impostazione predefinita — tutti i percorsi file vengono risolti tramite `filepath.EvalSymlinks` prima del confronto con la whitelist, prevenendo attacchi di escape tramite symlink.
#### Limitazione Nota: Processi Figlio degli Strumenti di Build
Il controllo di sicurezza exec ispeziona solo la riga di comando avviata direttamente da PicoClaw. Non ispeziona ricorsivamente i processi figlio generati da strumenti di sviluppo consentiti come `make`, `go run`, `cargo`, `npm run` o script di build personalizzati.
Ciò significa che un comando di primo livello può comunque compilare o avviare altri binari dopo aver superato il controllo iniziale. In pratica, tratta gli script di build, i Makefile, gli script di pacchetti e i binari generati come codice eseguibile che richiede lo stesso livello di revisione di un comando shell diretto.
Per ambienti ad alto rischio:
* Esamina gli script di build prima dell'esecuzione.
* Preferisci l'approvazione/revisione manuale per i workflow di compilazione ed esecuzione.
* Esegui PicoClaw in un container o VM se hai bisogno di un isolamento più forte di quello fornito dal controllo integrato.
#### Esempi di Errore
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### Disabilitare le Restrizioni (Rischio di Sicurezza)
Se hai bisogno che l'agent acceda a percorsi al di fuori del workspace:
**Metodo 1: File di configurazione**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**Metodo 2: Variabile d'ambiente**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **Attenzione**: Disabilitare questa restrizione consente all'agent di accedere a qualsiasi percorso sul tuo sistema. Usare con cautela solo in ambienti controllati.
#### Coerenza dei Confini di Sicurezza
L'impostazione `restrict_to_workspace` si applica in modo coerente a tutti i percorsi di esecuzione:
| Percorso di esecuzione | Confine di sicurezza |
| ---------------------- | --------------------------------- |
| Main Agent | `restrict_to_workspace` ✅ |
| Subagent / Spawn | Eredita la stessa restrizione ✅ |
| Heartbeat tasks | Eredita la stessa restrizione ✅ |
Tutti i percorsi condividono la stessa restrizione del workspace — non è possibile aggirare il confine di sicurezza tramite subagent o task pianificati.
### Heartbeat (Task Periodici)
PicoClaw può eseguire task periodici automaticamente. Crea un file `HEARTBEAT.md` nel tuo workspace:
```markdown
# Periodic Tasks
- Check my email for important messages
- Review my calendar for upcoming events
- Check the weather forecast
```
L'agent leggerà questo file ogni 30 minuti (configurabile) ed eseguirà tutti i task usando gli strumenti disponibili.
#### Task Asincroni con Spawn
Per task di lunga durata (ricerca web, chiamate API), usa lo strumento `spawn` per creare un **subagent**:
```markdown
# Periodic Tasks
```
+574
View File
@@ -0,0 +1,574 @@
# 💬 チャットアプリ設定
> [README](../../README.ja.md) に戻る
## 💬 チャットアプリ連携
PicoClaw は複数のチャットプラットフォームをサポートしており、Agent をどこにでも接続できます。
> **注意**: すべての Webhook ベースのチャネル(LINE、WeCom など)は、共有 Gateway HTTP サーバー(`gateway.host`:`gateway.port`、デフォルト `127.0.0.1:18790`)上で提供されます。チャネルごとにポートを設定する必要はありません。注意:飛書(Feishu)は WebSocket/SDK モードを使用し、共有 HTTP Webhook サーバーは使用しません。
### チャネル一覧
| チャネル | セットアップ難易度 | 特徴 | ドキュメント |
| -------------------- | ------------------ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| **Telegram** | ⭐ 簡単 | 推奨、音声テキスト変換対応、ロングポーリング(公開 IP 不要) | [ドキュメント](../channels/telegram/README.zh.md) |
| **Discord** | ⭐ 簡単 | Socket Mode、グループ/DM 対応、Bot エコシステム充実 | [ドキュメント](../channels/discord/README.zh.md) |
| **WhatsApp** | ⭐ 簡単 | ネイティブ (QR スキャン) または Bridge URL | [ドキュメント](../channels/whatsapp/README.zh.md) |
| **Slack** | ⭐ 簡単 | **Socket Mode** (公開 IP 不要)、エンタープライズ対応 | [ドキュメント](../channels/slack/README.zh.md) |
| **Matrix** | ⭐⭐ 中程度 | フェデレーションプロトコル、セルフホスト対応 | [ドキュメント](../channels/matrix/README.zh.md) |
| **QQ** | ⭐⭐ 中程度 | 公式ボット API、中国コミュニティ向け | [ドキュメント](../channels/qq/README.zh.md) |
| **DingTalk** | ⭐⭐ 中程度 | Stream モード(公開 IP 不要)、企業向け | [ドキュメント](../channels/dingtalk/README.zh.md) |
| **LINE** | ⭐⭐⭐ やや難 | HTTPS Webhook が必要 | [ドキュメント](../channels/line/README.zh.md) |
| **WeCom (企業微信)** | ⭐⭐⭐ やや難 | グループ Bot (Webhook)、カスタムアプリ (API)、AI Bot 対応 | [Bot](../channels/wecom/wecom_bot/README.zh.md) / [App](../channels/wecom/wecom_app/README.zh.md) / [AI Bot](../channels/wecom/wecom_aibot/README.zh.md) |
| **Feishu (飛書)** | ⭐⭐⭐ やや難 | エンタープライズコラボレーション、機能豊富 | [ドキュメント](../channels/feishu/README.zh.md) |
| **IRC** | ⭐⭐ 中程度 | サーバー + TLS 設定 | - |
| **OneBot** | ⭐⭐ 中程度 | NapCat/Go-CQHTTP 互換、コミュニティエコシステム充実 | [ドキュメント](../channels/onebot/README.zh.md) |
| **MaixCam** | ⭐ 簡単 | Sipeed AI カメラハードウェア統合チャネル | [ドキュメント](../channels/maixcam/README.zh.md) |
| **Pico** | ⭐ 簡単 | PicoClaw ネイティブプロトコルチャネル | |
---
<details>
<summary><b>Telegram</b>(推奨)</summary>
**1. Bot を作成**
* Telegram を開き、`@BotFather` を検索
* `/newbot` を送信し、プロンプトに従う
* Token をコピー
**2. 設定**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
> Telegram の `@userinfobot` から User ID を取得できます。
**3. 実行**
```bash
picoclaw gateway
```
**4. Telegram コマンドメニュー(起動時に自動登録)**
PicoClaw は統一されたコマンド定義を使用します。起動時に Telegram がサポートするコマンド(例: `/start``/help``/show``/list`)を Bot コマンドメニューに自動登録し、メニュー表示と実際の動作を一致させます。
Telegram 側はコマンドメニュー登録機能を保持し、汎用コマンドの実行は Agent Loop 内の commands executor で統一的に処理されます。
ネットワークや API の一時的なエラーで登録に失敗しても、チャネルの起動はブロックされません。システムがバックグラウンドで自動リトライします。
</details>
<details>
<summary><b>Discord</b></summary>
**1. Bot を作成**
* <https://discord.com/developers/applications> にアクセス
* アプリケーションを作成 → Bot → Bot を追加
* Bot Token をコピー
**2. Intents を有効化**
* Bot 設定で **MESSAGE CONTENT INTENT** を有効化
* (オプション)メンバーデータに基づくホワイトリストが必要な場合は **SERVER MEMBERS INTENT** を有効化
**3. User ID を取得**
* Discord 設定 → 詳細設定 → **開発者モード** を有効化
* アバターを右クリック → **ユーザー ID をコピー**
**4. 設定**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. Bot を招待**
* OAuth2 → URL Generator
* Scopes: `bot`
* Bot Permissions: `Send Messages`, `Read Message History`
* 生成された招待リンクを開き、Bot をサーバーに追加
**オプション:グループトリガーモード**
デフォルトでは Bot はサーバーチャネル内のすべてのメッセージに応答します。@メンション時のみ応答するには
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
キーワードプレフィックスでトリガーすることもできます(例: `!bot`):
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b>(ネイティブ whatsmeow</summary>
PicoClaw は 2 つの WhatsApp 接続方式をサポートしています:
- **ネイティブ(推奨):** プロセス内で [whatsmeow](https://github.com/tulir/whatsmeow) を使用。独立した Bridge は不要です。`"use_native": true` に設定し、`bridge_url` を空にします。初回実行時に WhatsApp で QR コードをスキャン(リンクデバイス)。セッションはワークスペース配下(例: `workspace/whatsapp/`)に保存されます。ネイティブチャネルは**オプション**ビルドで、`-tags whatsapp_native` でコンパイルします(例: `make build-whatsapp-native` または `go build -tags whatsapp_native ./cmd/...`)。
- **Bridge** 外部 WebSocket Bridge に接続。`bridge_url`(例: `ws://localhost:3001`)を設定し、`use_native` を false のままにします。
**設定(ネイティブ)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
`session_store_path` が空の場合、セッションは `<workspace>/whatsapp/` に保存されます。`picoclaw gateway` を実行し、初回実行時にターミナルに表示される QR コードをスキャンしてください(WhatsApp → リンクデバイス)。
</details>
<details>
<summary><b>Matrix</b></summary>
**1. Bot アカウントを準備**
* お好みの homeserver(例: `https://matrix.org` またはセルフホスト)を使用
* Bot ユーザーを作成し、access token を取得
**2. 設定**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. 実行**
```bash
picoclaw gateway
```
すべてのオプション(`device_id``join_on_invite``group_trigger``placeholder``reasoning_channel_id`)については [Matrix チャネル設定ガイド](../channels/matrix/README.md) を参照してください。
</details>
<details>
<summary><b>QQ</b></summary>
**1. Bot を作成**
- [QQ 開放プラットフォーム](https://q.qq.com/#) にアクセス
- アプリケーションを作成 → **AppID****AppSecret** を取得
**2. 設定**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` を空にするとすべてのユーザーを許可します。QQ 番号を指定してアクセスを制限することもできます。
**3. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Slack</b></summary>
**1. Slack App を作成**
* [Slack API](https://api.slack.com/apps) でアプリを作成
* **Socket Mode** を有効化
* **Bot Token** と **App-Level Token** を取得
**2. 設定**
```json
{
"channels": {
"slack": {
"enabled": true,
"bot_token": "xoxb-YOUR_BOT_TOKEN",
"app_token": "xapp-YOUR_APP_TOKEN",
"allow_from": []
}
}
}
```
**3. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>IRC</b></summary>
**1. 設定**
```json
{
"channels": {
"irc": {
"enabled": true,
"server": "irc.libera.chat:6697",
"nick": "picoclaw-bot",
"use_tls": true,
"channels_to_join": ["#your-channel"],
"allow_from": []
}
}
}
```
**2. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Bot を作成**
* [開放プラットフォーム](https://open.dingtalk.com/) にアクセス
* 内部アプリを作成
* Client ID と Client Secret をコピー
**2. 設定**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` を空にするとすべてのユーザーを許可します。DingTalk ユーザー ID を指定してアクセスを制限することもできます。
**3. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>LINE</b></summary>
**1. LINE 公式アカウントを作成**
- [LINE Developers Console](https://developers.line.biz/) にアクセス
- Provider を作成 → Messaging API チャネルを作成
- **Channel Secret** と **Channel Access Token** をコピー
**2. 設定**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> LINE Webhook は共有 Gateway サーバー(`gateway.host`:`gateway.port`、デフォルト `127.0.0.1:18790`)上で提供されます。
**3. Webhook URL を設定**
LINE は HTTPS Webhook が必要です。リバースプロキシまたはトンネルを使用してください:
```bash
# 例:ngrok を使用(Gateway デフォルトポートは 18790)
ngrok http 18790
```
LINE Developers Console で Webhook URL を `https://your-domain/webhook/line` に設定し、**Use webhook** を有効にしてください。
**4. 実行**
```bash
picoclaw gateway
```
> グループチャットでは、Bot は @メンション時のみ応答します。返信は元のメッセージを引用します。
</details>
<details>
<summary><b>Feishu (飛書)</b></summary>
**1. アプリを作成**
* [飛書開放プラットフォーム](https://open.feishu.cn/) にアクセス
* 企業カスタムアプリを作成
* **App ID** と **App Secret** を取得
**2. 設定**
```json
{
"channels": {
"feishu": {
"enabled": true,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
}
}
}
```
**3. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WeCom (企業微信)</b></summary>
PicoClaw は 3 種類の WeCom 統合をサポートしています:
**方式 1: グループ Bot (Bot)** — セットアップ簡単、グループチャット対応
**方式 2: カスタムアプリ (App)** — より多機能、プロアクティブメッセージング、プライベートチャットのみ
**方式 3: AI Bot** — 公式 AI Bot、ストリーミング返信、グループ・プライベートチャット対応
詳細なセットアップ手順は [WeCom AI Bot 設定ガイド](../channels/wecom/wecom_aibot/README.zh.md) を参照してください。
**クイックセットアップ — グループ Bot:**
**1. Bot を作成**
* WeCom 管理コンソール → グループチャット → グループ Bot を追加
* Webhook URL をコピー(形式:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`
**2. 設定**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> WeCom Webhook は共有 Gateway サーバー(`gateway.host`:`gateway.port`、デフォルト `127.0.0.1:18790`)上で提供されます。
**クイックセットアップ — カスタムアプリ:**
**1. アプリを作成**
* WeCom 管理コンソール → アプリ管理 → アプリを作成
* **AgentId** と **Secret** をコピー
* 「マイ企業」ページで **CorpID** をコピー
**2. メッセージ受信を設定**
* アプリ詳細で「メッセージ受信」→「API を設定」をクリック
* URL を `http://your-server:18790/webhook/wecom-app` に設定
* **Token** と **EncodingAESKey** を生成
**3. 設定**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. 実行**
```bash
picoclaw gateway
```
> **注意**: WeCom Webhook コールバックは Gateway ポート(デフォルト 18790)で提供されます。HTTPS にはリバースプロキシを使用してください。
**クイックセットアップ — AI Bot:**
**1. AI Bot を作成**
* WeCom 管理コンソール → アプリ管理 → AI Bot
* AI Bot 設定でコールバック URL を設定:`http://your-server:18791/webhook/wecom-aibot`
* **Token** をコピーし、「ランダム生成」をクリックして **EncodingAESKey** を取得
**2. 設定**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "こんにちは!何かお手伝いできますか?"
}
}
}
```
**3. 実行**
```bash
picoclaw gateway
```
> **注意**: WeCom AI Bot はストリーミングプルプロトコルを使用しており、返信タイムアウトの心配はありません。長時間タスク(30 秒超)は自動的に `response_url` プッシュ配信に切り替わります。
</details>
<details>
<summary><b>OneBot</b></summary>
**1. 設定**
NapCat / Go-CQHTTP などの OneBot 実装と互換性があります。
```json
{
"channels": {
"onebot": {
"enabled": true,
"allow_from": []
}
}
}
```
**2. 実行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>MaixCam</b></summary>
Sipeed AI カメラハードウェア向けの統合チャネルです。
```json
{
"channels": {
"maixcam": {
"enabled": true
}
}
}
```
```bash
picoclaw gateway
```
</details>
+258
View File
@@ -0,0 +1,258 @@
# ⚙️ 設定ガイド
> [README](../../README.ja.md) に戻る
## ⚙️ 設定詳細
設定ファイルパス: `~/.picoclaw/config.json`
### 環境変数
環境変数を使用してデフォルトパスを上書きできます。ポータブルインストール、コンテナ化デプロイ、または picoclaw をシステムサービスとして実行する場合に便利です。これらの変数は独立しており、異なるパスを制御します。
| 変数 | 説明 | デフォルトパス |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | 設定ファイルのパスを上書きします。picoclaw がどの `config.json` を読み込むかを直接指定し、他のすべての場所を無視します。 | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | picoclaw データのルートディレクトリを上書きします。`workspace` やその他のデータディレクトリのデフォルト場所を変更します。 | `~/.picoclaw` |
**例:**
```bash
# 特定の設定ファイルで picoclaw を実行
# ワークスペースパスはその設定ファイル内から読み込まれます
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# /opt/picoclaw にすべてのデータを保存して picoclaw を実行
# 設定はデフォルトの ~/.picoclaw/config.json から読み込まれます
# ワークスペースは /opt/picoclaw/workspace に作成されます
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# 両方を使用して完全にカスタマイズ
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### ワークスペースレイアウト
PicoClaw は設定されたワークスペース(デフォルト: `~/.picoclaw/workspace`)にデータを保存します:
```
~/.picoclaw/workspace/
├── sessions/ # 会話セッションと履歴
├── memory/ # 長期記憶 (MEMORY.md)
├── state/ # 永続化状態 (最後のチャネルなど)
├── cron/ # スケジュールジョブデータベース
├── skills/ # カスタムスキル
├── AGENT.md # Agent 動作ガイド
├── HEARTBEAT.md # 定期タスクプロンプト (30 分ごとにチェック)
├── IDENTITY.md # Agent アイデンティティ
├── SOUL.md # Agent ソウル/性格
└── USER.md # ユーザー設定
```
> **注意:** `AGENT.md`、`SOUL.md`、`USER.md` および `memory/MEMORY.md` への変更は、ファイル更新時刻(mtime)の追跡により実行時に自動検出されます。これらのファイルを編集した後に **gateway を再起動する必要はありません** — Agent は次のリクエスト時に最新の内容を自動的に読み込みます。
### スキルソース
デフォルトでは、スキルは以下の順序で読み込まれます:
1. `~/.picoclaw/workspace/skills`(ワークスペース)
2. `~/.picoclaw/skills`(グローバル)
3. `<current-working-directory>/skills`(ビルトイン)
高度な/テスト用セットアップでは、以下の環境変数でビルトインスキルのルートを上書きできます:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### 統一コマンド実行ポリシー
- 汎用スラッシュコマンドは `pkg/agent/loop.go` 内の `commands.Executor` を通じて統一的に実行されます。
- チャネルアダプターはローカルで汎用コマンドを消費しなくなりました。受信テキストを bus/agent パスに転送するだけです。Telegram は起動時にサポートするコマンドメニューを自動登録します。
- 未登録のスラッシュコマンド(例: `/foo`)は通常の LLM 処理にパススルーされます。
- 登録済みだが現在のチャネルでサポートされていないコマンド(例: WhatsApp での `/show`)は、明示的なユーザー向けエラーを返し、以降の処理を停止します。
### 🔒 セキュリティサンドボックス
PicoClaw はデフォルトでサンドボックス環境で実行されます。Agent は設定されたワークスペース内のファイルアクセスとコマンド実行のみが可能です。
#### デフォルト設定
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| オプション | デフォルト値 | 説明 |
| ----------------------- | ----------------------- | ------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Agent の作業ディレクトリ |
| `restrict_to_workspace` | `true` | ファイル/コマンドアクセスをワークスペース内に制限 |
#### 保護されたツール
`restrict_to_workspace: true` の場合、以下のツールがサンドボックス化されます:
| ツール | 機能 | 制限 |
| ------------- | ---------------- | ---------------------------------- |
| `read_file` | ファイル読み取り | ワークスペース内のファイルのみ |
| `write_file` | ファイル書き込み | ワークスペース内のファイルのみ |
| `list_dir` | ディレクトリ一覧 | ワークスペース内のディレクトリのみ |
| `edit_file` | ファイル編集 | ワークスペース内のファイルのみ |
| `append_file` | ファイル追記 | ワークスペース内のファイルのみ |
| `exec` | コマンド実行 | コマンドパスはワークスペース内必須 |
#### 追加の Exec 保護
`restrict_to_workspace: false` の場合でも、`exec` ツールは以下の危険なコマンドをブロックします:
* `rm -rf``del /f``rmdir /s` — 一括削除
* `format``mkfs``diskpart` — ディスクフォーマット
* `dd if=` — ディスクイメージング
* `/dev/sd[a-z]` への書き込み — 直接ディスク書き込み
* `shutdown``reboot``poweroff` — システムシャットダウン
* Fork bomb `:(){ :|:& };:`
### ファイルアクセス制御
| 設定キー | 型 | デフォルト値 | 説明 |
|----------|------|-------------|------|
| `tools.allow_read_paths` | string[] | `[]` | ワークスペース外で読み取りを許可する追加パス |
| `tools.allow_write_paths` | string[] | `[]` | ワークスペース外で書き込みを許可する追加パス |
### Exec セキュリティ設定
| 設定キー | 型 | デフォルト値 | 説明 |
|----------|------|-------------|------|
| `tools.exec.allow_remote` | bool | `false` | リモートチャネル(Telegram/Discord など)からの exec ツール実行を許可 |
| `tools.exec.enable_deny_patterns` | bool | `true` | 危険なコマンドのインターセプトを有効化 |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | カスタムブロック正規表現パターン |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | カスタム許可正規表現パターン |
> **セキュリティ注意:** Symlink 保護はデフォルトで有効です。すべてのファイルパスはホワイトリストマッチング前に `filepath.EvalSymlinks` で解決され、シンボリックリンクエスケープ攻撃を防止します。
#### 既知の制限:ビルドツールの子プロセス
exec セキュリティガードは PicoClaw が直接起動するコマンドラインのみを検査します。`make``go run``cargo``npm run`、またはカスタムビルドスクリプトなどの開発ツールが生成する子プロセスは再帰的に検査しません。
つまり、トップレベルのコマンドが初期ガードチェックを通過した後、他のバイナリをコンパイルまたは起動できます。実際には、ビルドスクリプト、Makefile、パッケージスクリプト、生成されたバイナリを、直接のシェルコマンドと同等レベルの実行可能コードとしてレビューする必要があります。
高リスク環境の場合:
* 実行前にビルドスクリプトをレビューしてください。
* コンパイル・実行ワークフローには承認/手動レビューを優先してください。
* ビルトインガードより強力な分離が必要な場合は、コンテナまたは VM 内で PicoClaw を実行してください。
#### エラー例
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### 制限の無効化(セキュリティリスク)
Agent がワークスペース外のパスにアクセスする必要がある場合:
**方法 1: 設定ファイル**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**方法 2: 環境変数**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **警告**: この制限を無効にすると、Agent がシステム上の任意のパスにアクセスできるようになります。管理された環境でのみ慎重に使用してください。
#### セキュリティ境界の一貫性
`restrict_to_workspace` 設定はすべての実行パスで一貫して適用されます:
| 実行パス | セキュリティ境界 |
| ---------------- | ---------------------------- |
| メイン Agent | `restrict_to_workspace` ✅ |
| サブ Agent / Spawn | 同じ制限を継承 ✅ |
| ハートビートタスク | 同じ制限を継承 ✅ |
すべてのパスは同じワークスペース制限を共有しており、サブ Agent やスケジュールタスクを通じてセキュリティ境界を回避することはできません。
### ハートビート(定期タスク)
PicoClaw は定期タスクを自動実行できます。ワークスペースに `HEARTBEAT.md` ファイルを作成してください:
```markdown
# Periodic Tasks
- Check my email for important messages
- Review my calendar for upcoming events
- Check the weather forecast
```
Agent は 30 分ごと(設定可能)にこのファイルを読み取り、利用可能なツールを使用してタスクを実行します。
#### Spawn を使用した非同期タスク
長時間実行タスク(Web 検索、API 呼び出し)には、`spawn` ツールを使用して**サブ Agent (subagent)** を作成します:
```markdown
# Periodic Tasks
## Quick Tasks (respond directly)
- Report current time
## Long Tasks (use spawn for async)
- Search the web for AI news and summarize
- Check email and report important messages
```
**主な動作:**
| 特性 | 説明 |
| ---------------- | -------------------------------------------- |
| **spawn** | 非同期サブ Agent を作成、メインハートビートをブロックしない |
| **独立コンテキスト** | サブ Agent は独自のコンテキストを持ち、セッション履歴なし |
| **message tool** | サブ Agent は message ツールでユーザーと直接通信 |
| **ノンブロッキング** | spawn 後、ハートビートは次のタスクに進む |
**設定:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| オプション | デフォルト値 | 説明 |
| ---------- | ------------ | ------------------------------ |
| `enabled` | `true` | ハートビートの有効/無効 |
| `interval` | `30` | チェック間隔(分単位、最小: 5)|
**環境変数:**
- `PICOCLAW_HEARTBEAT_ENABLED=false` で無効化
- `PICOCLAW_HEARTBEAT_INTERVAL=60` で間隔を変更
+168
View File
@@ -0,0 +1,168 @@
# 🐳 Docker とクイックスタート
> [README](../../README.ja.md) に戻る
## 🐳 Docker Compose
Docker Compose を使用して PicoClaw を実行できます。ローカルに何もインストールする必要はありません。
```bash
# 1. リポジトリをクローン
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. 初回実行 — docker/data/config.json を自動生成して終了
docker compose -f docker/docker-compose.yml --profile gateway up
# コンテナが "First-run setup complete." と表示して停止します
# 3. API Key を設定
vim docker/data/config.json # provider API key、Bot Token などを設定
# 4. 起動
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Docker ユーザー**: デフォルトでは Gateway は `127.0.0.1` でリッスンしており、コンテナ外からはアクセスできません。ヘルスチェックエンドポイントへのアクセスやポート公開が必要な場合は、環境変数で `PICOCLAW_GATEWAY_HOST=0.0.0.0` を設定するか、`config.json` を更新してください。
```bash
# 5. ログを確認
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. 停止
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Launcher モード (Web コンソール)
`launcher` イメージには 3 つのバイナリ(`picoclaw``picoclaw-launcher``picoclaw-launcher-tui`)がすべて含まれており、デフォルトで Web コンソールを起動します。ブラウザベースの設定・チャット画面を提供します。
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
ブラウザで http://localhost:18800 を開いてください。Launcher が Gateway プロセスを自動管理します。
> [!WARNING]
> Web コンソールはまだ認証をサポートしていません。公開インターネットに公開しないでください。
### Agent モード (ワンショット)
```bash
# 質問する
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "2+2は?"
# インタラクティブモード
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### イメージの更新
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
---
## 🚀 クイックスタート
> [!TIP]
> `~/.picoclaw/config.json` に API Key を設定してください。API Key の取得先: [Volcengine (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)。Web 検索は**オプション**です — 無料の [Tavily API](https://tavily.com) (月 1000 回無料) または [Brave Search API](https://brave.com/search/api) (月 2000 回無料) を取得できます。
**1. 初期化**
```bash
picoclaw onboard
```
**2. 設定** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **新機能**: `model_list` 設定形式により、コード変更なしで provider を追加できます。詳細は[モデル設定](providers.md#モデル設定-model_list)を参照してください。
> `request_timeout` はオプションで、単位は秒です。省略または `<= 0` に設定した場合、PicoClaw はデフォルトのタイムアウト(120 秒)を使用します。
**3. API Key の取得**
* **LLM プロバイダー**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **Web 検索** (オプション):
* [Brave Search](https://brave.com/search/api) - 有料 ($5/1000 queries, ~$5-6/month)
* [Perplexity](https://www.perplexity.ai) - AI 搭載の検索・チャットインターフェース
* [SearXNG](https://github.com/searxng/searxng) - セルフホスト型メタ検索エンジン(無料、API Key 不要)
* [Tavily](https://tavily.com) - AI Agent 向けに最適化 (1000 requests/month)
* DuckDuckGo - 組み込みフォールバック(API Key 不要)
> **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。
**4. チャット**
```bash
picoclaw agent -m "2+2は?"
```
以上です!2 分で動作する AI アシスタントが手に入ります。
---
+434
View File
@@ -0,0 +1,434 @@
# 🔌 プロバイダーとモデル設定
> [README](../../README.ja.md) に戻る
### プロバイダー
> [!NOTE]
> Groq は Whisper による無料の音声文字起こしを提供しています。Groq を設定すると、任意のチャネルからの音声メッセージが Agent レベルで自動的にテキストに変換されます。
| プロバイダー | 用途 | API Key の取得 |
| -------------------- | ---------------------------- | -------------------------------------------------------------------- |
| `gemini` | LLM (Gemini 直接接続) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (Zhipu 直接接続) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM (Volcengine 直接接続) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (推奨、全モデルアクセス可) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude 直接接続) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT 直接接続) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek 直接接続) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (Qwen 直接接続) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **音声文字起こし** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras 直接接続) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid 直接接続) | [vivgrid.com](https://vivgrid.com) |
| `moonshot` | LLM (Kimi/Moonshot 直接接続) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax 直接接続) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian 直接接続) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral 直接接続) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat 直接接続) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope 直接接続) | [modelscope.cn](https://modelscope.cn) |
### モデル設定 (model_list)
> **新機能!** PicoClaw は**モデル中心**の設定方式を採用しました。`ベンダー/モデル` 形式(例: `zhipu/glm-4.7`)を指定するだけで新しい provider を追加できます——**コード変更は一切不要です!**
この設計は**マルチ Agent シナリオ**もサポートし、柔軟な Provider 選択を提供します:
- **Agent ごとに異なる Provider**: 各 Agent が独自の LLM provider を使用可能
- **モデルフォールバック**: プライマリモデルとフォールバックモデルを設定し、信頼性を向上
- **ロードバランシング**: 複数の API エンドポイント間でリクエストを分散
- **一元管理**: すべての provider を一箇所で管理
#### 📋 サポートされている全ベンダー
| ベンダー | `model` プレフィックス | デフォルト API Base | プロトコル | API Key の取得 |
| ------------------- | --------------------- | --------------------------------------------------- | ---------- | ----------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [キーを取得](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [キーを取得](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [キーを取得](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [キーを取得](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [キーを取得](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [キーを取得](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [キーを取得](https://platform.moonshot.cn) |
| **通義千問 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [キーを取得](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [キーを取得](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | ローカル(キー不要) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [キーを取得](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | LiteLLM プロキシキー |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | ローカル |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [キーを取得](https://cerebras.ai) |
| **VolcEngine (Doubao)** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [キーを取得](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [キーを取得](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [キーを取得](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [キーを取得](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [トークンを取得](https://modelscope.cn/my/tokens) |
| **Antigravity** | `antigravity/` | Google Cloud | カスタム | OAuth のみ |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### 基本設定
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### ベンダー別設定例
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**VolcEngine (Doubao)**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (API キー使用)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
}
```
> `picoclaw auth login --provider anthropic` を実行して API トークンを設定してください。
**Anthropic Messages API(ネイティブ形式)**
Anthropic API への直接アクセスや、Anthropic のネイティブメッセージ形式のみをサポートするカスタムエンドポイント向け:
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> `anthropic-messages` プロトコルを使用するケース:
> - Anthropic のネイティブ `/v1/messages` エンドポイントのみをサポートするサードパーティプロキシを使用する場合(OpenAI 互換の `/v1/chat/completions` 非対応)
> - MiniMax、Synthetic など Anthropic のネイティブメッセージ形式を必要とするサービスに接続する場合
> - 既存の `anthropic` プロトコルが 404 エラーを返す場合(エンドポイントが OpenAI 互換形式をサポートしていないことを示す)
>
> **注意:** `anthropic` プロトコルは OpenAI 互換形式(`/v1/chat/completions`)を使用し、`anthropic-messages` は Anthropic のネイティブ形式(`/v1/messages`)を使用します。エンドポイントがサポートする形式に応じて選択してください。
**Ollama (ローカル)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**カスタムプロキシ/API**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
PicoClaw はリクエスト送信前に外側の `litellm/` プレフィックスのみを除去するため、`litellm/lite-gpt4``lite-gpt4` を送信し、`litellm/openai/gpt-4o``openai/gpt-4o` を送信します。
#### ロードバランシング
同じモデル名に複数のエンドポイントを設定すると、PicoClaw が自動的にラウンドロビンで分散します:
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### レガシー `providers` 設定からの移行
`providers` 設定形式は**非推奨**ですが、後方互換性のためまだサポートされています。
**旧設定(非推奨):**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**新設定(推奨):**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
詳細な移行ガイドは [docs/migration/model-list-migration.md](../migration/model-list-migration.md) を参照してください。
### Provider アーキテクチャ
PicoClaw はプロトコルファミリーごとに Provider をルーティングします:
- OpenAI 互換プロトコル:OpenRouter、OpenAI 互換ゲートウェイ、Groq、Zhipu、vLLM スタイルのエンドポイント。
- Anthropic プロトコル:Claude ネイティブ API 動作。
- Codex/OAuth パス:OpenAI OAuth/Token 認証ルート。
これによりランタイムを軽量に保ちつつ、新しい OpenAI 互換バックエンドの追加をほぼ設定操作(`api_base` + `api_key`)のみで実現しています。
<details>
<summary><b>Zhipu 設定例</b></summary>
**1. API key と base URL を取得**
- [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) を取得
**2. 設定**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. 実行**
```bash
picoclaw agent -m "こんにちは"
```
</details>
<details>
<summary><b>完全な設定例</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 API Key 比較表
| サービス | Pricing | ユースケース |
| ---------------- | ------------------------ | ------------------------------------- |
| **OpenRouter** | Free: 200K tokens/month | マルチモデル (Claude, GPT-4 など) |
| **Volcengine CodingPlan** | ¥9.9/first month | 中国ユーザー向け、複数の SOTA モデル (Doubao, DeepSeek など) |
| **Zhipu** | Free: 200K tokens/month | 中国ユーザー向け |
| **Brave Search** | $5/1000 queries | Web 検索機能 |
| **SearXNG** | Free (self-hosted) | プライバシー重視のメタ検索 (70+ engines) |
| **Groq** | Free tier available | 高速推論 (Llama, Mixtral) |
| **Cerebras** | Free tier available | 高速推論 (Llama, Qwen など) |
| **LongCat** | Free: up to 5M tokens/day | 高速推論 |
| **ModelScope** | Free: 2000 requests/day | 推論 (Qwen, GLM, DeepSeek など) |
---
<div align="center">
<img src="assets/logo.jpg" alt="PicoClaw Meme" width="512">
</div>
+68
View File
@@ -0,0 +1,68 @@
# 🔄 非同期タスクと Spawn
> [README](../../README.ja.md) に戻る
### Spawn を使用した非同期タスク
長時間実行タスク(Web 検索、API 呼び出し)には、`spawn` ツールを使用して**サブ Agent (subagent)** を作成します:
```markdown
# Periodic Tasks
## Quick Tasks (respond directly)
- Report current time
## Long Tasks (use spawn for async)
- Search the web for AI news and summarize
- Check email and report important messages
```
**主な動作:**
| 特性 | 説明 |
| ---------------- | ------------------------------------------------ |
| **spawn** | 非同期サブ Agent を作成、メインハートビートをブロックしない |
| **独立コンテキスト** | サブ Agent は独自のコンテキストを持ち、セッション履歴なし |
| **message tool** | サブ Agent は message ツールでユーザーと直接通信 |
| **ノンブロッキング** | spawn 後、ハートビートは次のタスクに進む |
#### サブ Agent の通信の仕組み
```
ハートビートトリガー (Heartbeat triggers)
Agent が HEARTBEAT.md を読み取り
長時間タスクの場合: サブ Agent を spawn
↓ ↓
次のタスクに進む サブ Agent が独立して作業
↓ ↓
すべてのタスク完了 サブ Agent が "message" ツールを使用
↓ ↓
HEARTBEAT_OK を応答 ユーザーが直接結果を受信
```
サブ Agent はツール(message、web_search など)にアクセスでき、メイン Agent を経由せずにユーザーと独立して通信できます。
**設定:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| オプション | デフォルト値 | 説明 |
| ---------- | ------------ | ------------------------------ |
| `enabled` | `true` | ハートビートの有効/無効 |
| `interval` | `30` | チェック間隔(分単位、最小: 5)|
**環境変数:**
- `PICOCLAW_HEARTBEAT_ENABLED=false` で無効化
- `PICOCLAW_HEARTBEAT_INTERVAL=60` で間隔を変更
+336
View File
@@ -0,0 +1,336 @@
# 🔧 ツール設定
> [README](../../README.ja.md) に戻る
PicoClaw のツール設定は `config.json``tools` フィールドにあります。
## ディレクトリ構造
```json
{
"tools": {
"web": {
...
},
"mcp": {
...
},
"exec": {
...
},
"cron": {
...
},
"skills": {
...
}
}
}
```
## Web ツール
Web ツールはウェブ検索とフェッチに使用されます。
### Web Fetcher
ウェブページコンテンツの取得と処理に関する一般設定。
| 設定項目 | 型 | デフォルト | 説明 |
|---------------------|--------|---------------|----------------------------------------------------------------------------------------|
| `enabled` | bool | true | ウェブページ取得機能を有効にする。 |
| `fetch_limit_bytes` | int | 10485760 | 取得するウェブページペイロードの最大サイズ(バイト単位、デフォルトは10MB)。 |
| `format` | string | "plaintext" | 取得コンテンツの出力形式。オプション:`plaintext` または `markdown`(推奨)。 |
### Brave
| 設定項目 | 型 | デフォルト | 説明 |
|---------------|--------|------------|-----------------------|
| `enabled` | bool | false | Brave 検索を有効にする |
| `api_key` | string | - | Brave Search API キー |
| `max_results` | int | 5 | 最大結果数 |
### DuckDuckGo
| 設定項目 | 型 | デフォルト | 説明 |
|---------------|------|------------|---------------------------|
| `enabled` | bool | true | DuckDuckGo 検索を有効にする |
| `max_results` | int | 5 | 最大結果数 |
### Perplexity
| 設定項目 | 型 | デフォルト | 説明 |
|---------------|--------|------------|---------------------------|
| `enabled` | bool | false | Perplexity 検索を有効にする |
| `api_key` | string | - | Perplexity API キー |
| `max_results` | int | 5 | 最大結果数 |
## Exec ツール
Exec ツールはシェルコマンドの実行に使用されます。
| 設定項目 | 型 | デフォルト | 説明 |
|------------------------|-------|------------|------------------------------------|
| `enable_deny_patterns` | bool | true | デフォルトの危険コマンドブロックを有効にする |
| `custom_deny_patterns` | array | [] | カスタム拒否パターン(正規表現) |
### 機能
- **`enable_deny_patterns`**`false` に設定すると、デフォルトの危険コマンドブロックパターンを完全に無効にします
- **`custom_deny_patterns`**:カスタム拒否正規表現パターンを追加します。一致するコマンドはブロックされます
### デフォルトでブロックされるコマンドパターン
デフォルトで、PicoClaw は以下の危険なコマンドをブロックします:
- 削除コマンド:`rm -rf``del /f/q``rmdir /s`
- ディスク操作:`format``mkfs``diskpart``dd if=``/dev/sd*` への書き込み
- システム操作:`shutdown``reboot``poweroff`
- コマンド置換:`$()``${}`、バッククォート
- シェルへのパイプ:`| sh``| bash`
- 権限昇格:`sudo``chmod``chown`
- プロセス制御:`pkill``killall``kill -9`
- リモート操作:`curl | sh``wget | sh``ssh`
- パッケージ管理:`apt``yum``dnf``npm install -g``pip install --user`
- コンテナ:`docker run``docker exec`
- Git`git push``git force`
- その他:`eval``source *.sh`
### 既知のアーキテクチャ上の制限
exec ガードは PicoClaw に送信されたトップレベルのコマンドのみを検証します。そのコマンドの実行開始後にビルドツールやスクリプトが生成する子プロセスを再帰的に検査することは**ありません**。
初期コマンドが許可された後、直接コマンドガードをバイパスできるワークフローの例:
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
これは、明らかに危険な直接コマンドのブロックには有用ですが、未レビューのビルドパイプラインに対する完全なサンドボックスでは**ありません**。脅威モデルにワークスペース内の信頼できないコードが含まれる場合は、コンテナ、VM、またはビルド・実行コマンドに対する承認フローなど、より強力な分離を使用してください。
### 設定例
```json
{
"tools": {
"exec": {
"enable_deny_patterns": true,
"custom_deny_patterns": [
"\\brm\\s+-r\\b",
"\\bkillall\\s+python"
]
}
}
}
```
## Cron ツール
Cron ツールは定期タスクのスケジューリングに使用されます。
| 設定項目 | 型 | デフォルト | 説明 |
|------------------------|-----|------------|-----------------------------------------|
| `exec_timeout_minutes` | int | 5 | 実行タイムアウト(分)、0 は無制限 |
## MCP ツール
MCP ツールは外部の Model Context Protocol サーバーとの統合を可能にします。
### ツールディスカバリ(遅延読み込み)
複数の MCP サーバーに接続する場合、数百のツールを同時に公開すると LLM のコンテキストウィンドウを使い果たし、API コストが増加する可能性があります。**Discovery** 機能は、MCP ツールをデフォルトで*非表示*にすることでこの問題を解決します。
すべてのツールを読み込む代わりに、LLM には軽量な検索ツール(BM25 キーワードマッチングまたは正規表現を使用)が提供されます。LLM が特定の機能を必要とする場合、非表示のライブラリを検索します。一致するツールは一時的に「アンロック」され、設定されたターン数(`ttl`)の間コンテキストに注入されます。
### グローバル設定
| 設定項目 | 型 | デフォルト | 説明 |
|-------------|--------|------------|--------------------------------------|
| `enabled` | bool | false | MCP 統合をグローバルに有効にする |
| `discovery` | object | `{}` | ツールディスカバリ設定(下記参照) |
| `servers` | object | `{}` | サーバー名からサーバー設定へのマップ |
### Discovery 設定(`discovery`
| 設定項目 | 型 | デフォルト | 説明 |
|----------------------|------|------------|---------------------------------------------------------------------------------------------------------------|
| `enabled` | bool | false | true の場合、MCP ツールは非表示になり、検索を通じてオンデマンドで読み込まれます。false の場合、すべてのツールが読み込まれます |
| `ttl` | int | 5 | 発見されたツールがアンロック状態を維持する会話ターン数 |
| `max_search_results` | int | 5 | 検索クエリごとに返されるツールの最大数 |
| `use_bm25` | bool | true | 自然言語/キーワード検索ツール(`tool_search_tool_bm25`)を有効にする。**警告**:正規表現検索よりリソースを消費します |
| `use_regex` | bool | false | 正規表現パターン検索ツール(`tool_search_tool_regex`)を有効にする |
> **注意:** `discovery.enabled` が `true` の場合、少なくとも1つの検索エンジン(`use_bm25` または `use_regex`)を有効にする**必要があります**。
> そうしないとアプリケーションの起動に失敗します。
### サーバーごとの設定
| 設定項目 | 型 | 必須 | 説明 |
|------------|--------|----------|----------------------------------------|
| `enabled` | bool | はい | この MCP サーバーを有効にする |
| `type` | string | いいえ | トランスポートタイプ:`stdio``sse``http` |
| `command` | string | stdio | stdio トランスポートの実行コマンド |
| `args` | array | いいえ | stdio トランスポートのコマンド引数 |
| `env` | object | いいえ | stdio プロセスの環境変数 |
| `env_file` | string | いいえ | stdio プロセスの環境ファイルパス |
| `url` | string | sse/http | `sse`/`http` トランスポートのエンドポイント URL |
| `headers` | object | いいえ | `sse`/`http` トランスポートの HTTP ヘッダー |
### トランスポートの動作
- `type` を省略した場合、トランスポートは自動検出されます:
- `url` が設定されている → `sse`
- `command` が設定されている → `stdio`
- `http``sse` はどちらも `url` + オプションの `headers` を使用します。
- `env``env_file``stdio` サーバーにのみ適用されます。
### 設定例
#### 1) Stdio MCP サーバー
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"filesystem": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp"
]
}
}
}
}
}
```
#### 2) リモート SSE/HTTP MCP サーバー
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"remote-mcp": {
"enabled": true,
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
}
}
```
#### 3) ツールディスカバリを有効にした大規模 MCP セットアップ
*この例では、LLM は `tool_search_tool_bm25` のみを認識します。ユーザーからリクエストがあった場合にのみ、Github や Postgres のツールを動的に検索してアンロックします。*
```json
{
"tools": {
"mcp": {
"enabled": true,
"discovery": {
"enabled": true,
"ttl": 5,
"max_search_results": 5,
"use_bm25": true,
"use_regex": false
},
"servers": {
"github": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN"
}
},
"postgres": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost/dbname"
]
},
"slack": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-slack"
],
"env": {
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
}
}
}
}
}
}
```
## Skills ツール
Skills ツールは ClawHub などのレジストリを通じたスキルの発見とインストールを設定します。
### レジストリ
| 設定項目 | 型 | デフォルト | 説明 |
|------------------------------------|--------|----------------------|----------------------------------------------|
| `registries.clawhub.enabled` | bool | true | ClawHub レジストリを有効にする |
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | ClawHub ベース URL |
| `registries.clawhub.auth_token` | string | `""` | より高いレート制限のためのオプションの Bearer トークン |
| `registries.clawhub.search_path` | string | `/api/v1/search` | 検索 API パス |
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Skills API パス |
| `registries.clawhub.download_path` | string | `/api/v1/download` | ダウンロード API パス |
### 設定例
```json
{
"tools": {
"skills": {
"registries": {
"clawhub": {
"enabled": true,
"base_url": "https://clawhub.ai",
"auth_token": "",
"search_path": "/api/v1/search",
"skills_path": "/api/v1/skills",
"download_path": "/api/v1/download"
}
}
}
}
}
```
## 環境変数
すべての設定オプションは `PICOCLAW_TOOLS_<SECTION>_<KEY>` 形式の環境変数で上書きできます:
例:
- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true`
- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false`
- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10`
- `PICOCLAW_TOOLS_MCP_ENABLED=true`
注意:ネストされたマップ形式の設定(例:`tools.mcp.servers.<name>.*`)は環境変数ではなく `config.json` で設定します。
+45
View File
@@ -0,0 +1,45 @@
# 🐛 トラブルシューティング
> [README](../../README.ja.md) に戻る
## "model ... not found in model_list" または OpenRouter "free is not a valid model ID"
**症状:** 以下のいずれかのエラーが表示されます:
- `Error creating provider: model "openrouter/free" not found in model_list`
- OpenRouter が 400 を返す:`"free is not a valid model ID"`
**原因:** `model_list` エントリの `model` フィールドは API に送信される値です。OpenRouter では省略形ではなく、**完全な**モデル ID を使用する必要があります。
- **誤り:** `"model": "free"` → OpenRouter は `free` を受け取り、拒否します。
- **正しい:** `"model": "openrouter/free"` → OpenRouter は `openrouter/free` を受け取ります(自動無料枠ルーティング)。
**修正方法:** `~/.picoclaw/config.json`(またはお使いの設定パス)で:
1. **agents.defaults.model**`model_list` 内の `model_name` と一致する必要があります(例:`"openrouter-free"`)。
2. そのエントリの **model** は有効な OpenRouter モデル ID である必要があります。例:
- `"openrouter/free"` 自動無料枠
- `"google/gemini-2.0-flash-exp:free"`
- `"meta-llama/llama-3.1-8b-instruct:free"`
設定例:
```json
{
"agents": {
"defaults": {
"model": "openrouter-free"
}
},
"model_list": [
{
"model_name": "openrouter-free",
"model": "openrouter/free",
"api_key": "sk-or-v1-YOUR_OPENROUTER_KEY",
"api_base": "https://openrouter.ai/api/v1"
}
]
}
```
キーは [OpenRouter Keys](https://openrouter.ai/keys) で取得できます。
+7 -7
View File
@@ -40,7 +40,7 @@ The new `model_list` configuration offers several advantages:
"agents": {
"defaults": {
"provider": "openai",
"model": "gpt-5.2"
"model": "gpt-5.4"
}
}
}
@@ -53,7 +53,7 @@ The new `model_list` configuration offers several advantages:
"model_list": [
{
"model_name": "gpt4",
"model": "openai/gpt-5.2",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key",
"api_base": "https://api.openai.com/v1"
},
@@ -82,7 +82,7 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
| Prefix | Description | Example |
|--------|-------------|---------|
| `openai/` | OpenAI API (default) | `openai/gpt-5.2` |
| `openai/` | OpenAI API (default) | `openai/gpt-5.4` |
| `anthropic/` | Anthropic API | `anthropic/claude-opus-4` |
| `antigravity/` | Google via Antigravity OAuth | `antigravity/gemini-2.0-flash` |
| `gemini/` | Google Gemini API | `gemini/gemini-2.0-flash-exp` |
@@ -109,7 +109,7 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
| Field | Required | Description |
|-------|----------|-------------|
| `model_name` | Yes | User-facing alias for the model |
| `model` | Yes | Protocol and model identifier (e.g., `openai/gpt-5.2`) |
| `model` | Yes | Protocol and model identifier (e.g., `openai/gpt-5.4`) |
| `api_base` | No | API endpoint URL |
| `api_key` | No* | API authentication key |
| `proxy` | No | HTTP proxy URL |
@@ -130,19 +130,19 @@ Configure multiple endpoints for the same model to distribute load:
"model_list": [
{
"model_name": "gpt4",
"model": "openai/gpt-5.2",
"model": "openai/gpt-5.4",
"api_key": "sk-key1",
"api_base": "https://api1.example.com/v1"
},
{
"model_name": "gpt4",
"model": "openai/gpt-5.2",
"model": "openai/gpt-5.4",
"api_key": "sk-key2",
"api_base": "https://api2.example.com/v1"
},
{
"model_name": "gpt4",
"model": "openai/gpt-5.2",
"model": "openai/gpt-5.4",
"api_key": "sk-key3",
"api_base": "https://api3.example.com/v1"
}
+436
View File
@@ -0,0 +1,436 @@
# 🔌 Providers & Model Configuration
> Back to [README](../README.md)
### Providers
> [!NOTE]
> Groq provides free voice transcription via Whisper. If configured, audio messages from any channel will be automatically transcribed at the agent level.
| Provider | Purpose | Get API Key |
| ------------ | --------------------------------------- | ------------------------------------------------------------ |
| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM(Volcengine direct) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid direct) | [vivgrid.com](https://vivgrid.com) |
| `nvidia` | LLM (NVIDIA NIM) | [build.nvidia.com](https://build.nvidia.com) |
| `moonshot` | LLM (Kimi/Moonshot direct) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax direct) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian direct) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope direct) | [modelscope.cn](https://modelscope.cn) |
### Model Configuration (model_list)
> **What's New?** PicoClaw now uses a **model-centric** configuration approach. Simply specify `vendor/model` format (e.g., `zhipu/glm-4.7`) to add new providers—**zero code changes required!**
This design also enables **multi-agent support** with flexible provider selection:
- **Different agents, different providers**: Each agent can use its own LLM provider
- **Model fallbacks**: Configure primary and fallback models for resilience
- **Load balancing**: Distribute requests across multiple endpoints
- **Centralized configuration**: Manage all providers in one place
#### 📋 All Supported Vendors
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) |
| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | Your LiteLLM proxy key |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) |
| **VolcEngine (Doubao)** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [Get Key](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [Get Key](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [Get Key](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [Get Token](https://modelscope.cn/my/tokens) |
| **Azure OpenAI** | `azure/` | `https://{resource}.openai.azure.com` | Azure | [Get Key](https://portal.azure.com) |
| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### Basic Configuration
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### Vendor-Specific Examples
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**VolcEngine (Doubao)**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (with API key)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
}
```
> Run `picoclaw auth login --provider anthropic` to paste your API token.
**Anthropic Messages API (native format)**
For direct Anthropic API access or custom endpoints that only support Anthropic's native message format:
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> Use `anthropic-messages` protocol when:
> - Using third-party proxies that only support Anthropic's native `/v1/messages` endpoint (not OpenAI-compatible `/v1/chat/completions`)
> - Connecting to services like MiniMax, Synthetic that require Anthropic's native message format
> - The existing `anthropic` protocol returns 404 errors (indicating the endpoint doesn't support OpenAI-compatible format)
>
> **Note:** The `anthropic` protocol uses OpenAI-compatible format (`/v1/chat/completions`), while `anthropic-messages` uses Anthropic's native format (`/v1/messages`). Choose based on your endpoint's supported format.
**Ollama (local)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**Custom Proxy/API**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
PicoClaw strips only the outer `litellm/` prefix before sending the request, so proxy aliases like `litellm/lite-gpt4` send `lite-gpt4`, while `litellm/openai/gpt-4o` sends `openai/gpt-4o`.
#### Load Balancing
Configure multiple endpoints for the same model name—PicoClaw will automatically round-robin between them:
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### Migration from Legacy `providers` Config
The old `providers` configuration is **deprecated** but still supported for backward compatibility.
**Old Config (deprecated):**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**New Config (recommended):**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
For detailed migration guide, see [docs/migration/model-list-migration.md](docs/migration/model-list-migration.md).
### Provider Architecture
PicoClaw routes providers by protocol family:
- OpenAI-compatible protocol: OpenRouter, OpenAI-compatible gateways, Groq, Zhipu, and vLLM-style endpoints.
- Anthropic protocol: Claude-native API behavior.
- Codex/OAuth path: OpenAI OAuth/token authentication route.
This keeps the runtime lightweight while making new OpenAI-compatible backends mostly a config operation (`api_base` + `api_key`).
<details>
<summary><b>Zhipu</b></summary>
**1. Get API key and base URL**
* Get [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
**2. Configure**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. Run**
```bash
picoclaw agent -m "Hello"
```
</details>
<details>
<summary><b>Full config example</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 API Key Comparison
| Service | Pricing | Use Case |
| ---------------- | ------------------------ | ------------------------------------- |
| **OpenRouter** | Free: 200K tokens/month | Multiple models (Claude, GPT-4, etc.) |
| **Volcengine CodingPlan** | ¥9.9/first month | Best for Chinese users, multiple SOTA models (Doubao, DeepSeek, etc.) |
| **Zhipu** | Free: 200K tokens/month | Suitable for Chinese users |
| **Brave Search** | $5/1000 queries | Web search functionality |
| **SearXNG** | Free (self-hosted) | Privacy-focused metasearch (70+ engines) |
| **Groq** | Free tier available | Fast inference (Llama, Mixtral) |
| **Cerebras** | Free tier available | Fast inference (Llama, Qwen, etc.) |
| **LongCat** | Free: up to 5M tokens/day | Fast inference |
| **ModelScope** | Free: 2000 requests/day | Inference (Qwen, GLM, DeepSeek, etc.) |
---
<div align="center">
<img src="assets/logo.jpg" alt="PicoClaw Meme" width="512">
</div>
+427
View File
@@ -0,0 +1,427 @@
# 💬 Configuração de Aplicativos de Chat
> Voltar ao [README](../../README.pt-br.md)
## 💬 Aplicativos de Chat
Converse com seu picoclaw através do Telegram, Discord, WhatsApp, Matrix, QQ, DingTalk, LINE, WeCom, Feishu, Slack, IRC, OneBot ou MaixCam
> **Nota**: Todos os canais baseados em webhook (LINE, WeCom, etc.) são servidos em um único servidor HTTP Gateway compartilhado (`gateway.host`:`gateway.port`, padrão `127.0.0.1:18790`). Não há portas por canal para configurar. Nota: Feishu usa o modo WebSocket/SDK e não utiliza o servidor HTTP webhook compartilhado.
| Channel | Setup |
| ------------ | ---------------------------------- |
| **Telegram** | Easy (just a token) |
| **Discord** | Easy (bot token + intents) |
| **WhatsApp** | Easy (native: QR scan; or bridge URL) |
| **Matrix** | Medium (homeserver + bot access token) |
| **QQ** | Easy (AppID + AppSecret) |
| **DingTalk** | Medium (app credentials) |
| **LINE** | Medium (credentials + webhook URL) |
| **WeCom AI Bot** | Medium (Token + AES key) |
| **Feishu** | Medium (App ID + Secret, WebSocket mode) |
| **Slack** | Medium (Bot token + App token) |
| **IRC** | Medium (server + TLS config) |
| **OneBot** | Medium (QQ via OneBot protocol) |
| **MaixCam** | Easy (Sipeed hardware integration) |
| **Pico** | Native PicoClaw protocol |
<details>
<summary><b>Telegram</b> (Recomendado)</summary>
**1. Criar um bot**
* Abra o Telegram, pesquise `@BotFather`
* Envie `/newbot`, siga as instruções
* Copie o token
**2. Configurar**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
> Obtenha seu ID de usuário com `@userinfobot` no Telegram.
**3. Executar**
```bash
picoclaw gateway
```
**4. Menu de comandos do Telegram (registrado automaticamente na inicialização)**
O PicoClaw agora mantém definições de comandos em um registro compartilhado. Na inicialização, o Telegram registrará automaticamente os comandos de bot suportados (por exemplo `/start`, `/help`, `/show`, `/list`) para que o menu de comandos e o comportamento em tempo de execução permaneçam sincronizados.
O registro do menu de comandos do Telegram permanece como descoberta UX local do canal; a execução genérica de comandos é tratada centralmente no loop do agente via commands executor.
Se o registro de comandos falhar (erros transitórios de rede/API), o canal ainda inicia e o PicoClaw tenta novamente o registro em segundo plano.
</details>
<details>
<summary><b>Discord</b></summary>
**1. Criar um bot**
* Acesse <https://discord.com/developers/applications>
* Crie um aplicativo → Bot → Add Bot
* Copie o token do bot
**2. Habilitar intents**
* Nas configurações do Bot, habilite **MESSAGE CONTENT INTENT**
* (Opcional) Habilite **SERVER MEMBERS INTENT** se planeja usar listas de permissão baseadas em dados de membros
**3. Obter seu User ID**
* Configurações do Discord → Avançado → habilite **Developer Mode**
* Clique com o botão direito no seu avatar → **Copy User ID**
**4. Configurar**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. Convidar o bot**
* OAuth2 → URL Generator
* Scopes: `bot`
* Bot Permissions: `Send Messages`, `Read Message History`
* Abra a URL de convite gerada e adicione o bot ao seu servidor
**Opcional: Modo de ativação em grupo**
Por padrão, o bot responde a todas as mensagens em um canal do servidor. Para restringir respostas apenas a @menções, adicione:
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
Você também pode ativar por prefixos de palavras-chave (ex.: `!bot`):
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. Executar**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b> (nativo via whatsmeow)</summary>
O PicoClaw pode se conectar ao WhatsApp de duas formas:
- **Nativo (recomendado):** In-process usando [whatsmeow](https://github.com/tulir/whatsmeow). Sem bridge separado. Defina `"use_native": true` e deixe `bridge_url` vazio. Na primeira execução, escaneie o QR code com o WhatsApp (Dispositivos Vinculados). A sessão é armazenada no seu workspace (ex.: `workspace/whatsapp/`). O canal nativo é **opcional** para manter o binário padrão pequeno; compile com `-tags whatsapp_native` (ex.: `make build-whatsapp-native` ou `go build -tags whatsapp_native ./cmd/...`).
- **Bridge:** Conecte-se a um bridge WebSocket externo. Defina `bridge_url` (ex.: `ws://localhost:3001`) e mantenha `use_native` como false.
**Configurar (nativo)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
Se `session_store_path` estiver vazio, a sessão é armazenada em `<workspace>/whatsapp/`. Execute `picoclaw gateway`; na primeira execução, escaneie o QR code impresso no terminal com WhatsApp → Dispositivos Vinculados.
</details>
<details>
<summary><b>QQ</b></summary>
**1. Criar um bot**
- Acesse a [QQ Open Platform](https://q.qq.com/#)
- Crie um aplicativo → Obtenha **AppID** e **AppSecret**
**2. Configurar**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> Defina `allow_from` como vazio para permitir todos os usuários, ou especifique números QQ para restringir o acesso.
**3. Executar**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Criar um bot**
* Acesse a [Open Platform](https://open.dingtalk.com/)
* Crie um aplicativo interno
* Copie o Client ID e o Client Secret
**2. Configurar**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> Defina `allow_from` como vazio para permitir todos os usuários, ou especifique IDs de usuário DingTalk para restringir o acesso.
**3. Executar**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Matrix</b></summary>
**1. Preparar conta do bot**
* Use seu homeserver preferido (ex.: `https://matrix.org` ou auto-hospedado)
* Crie um usuário bot e obtenha seu access token
**2. Configurar**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. Executar**
```bash
picoclaw gateway
```
Para opções completas (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), veja o [Guia de Configuração do Canal Matrix](docs/channels/matrix/README.md).
</details>
<details>
<summary><b>LINE</b></summary>
**1. Criar uma Conta Oficial LINE**
- Acesse o [LINE Developers Console](https://developers.line.biz/)
- Crie um provider → Crie um canal Messaging API
- Copie o **Channel Secret** e o **Channel Access Token**
**2. Configurar**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> O webhook do LINE é servido no servidor Gateway compartilhado (`gateway.host`:`gateway.port`, padrão `127.0.0.1:18790`).
**3. Configurar URL do Webhook**
O LINE requer HTTPS para webhooks. Use um proxy reverso ou túnel:
```bash
# Exemplo com ngrok (porta padrão do gateway é 18790)
ngrok http 18790
```
Em seguida, defina a URL do Webhook no LINE Developers Console como `https://your-domain/webhook/line` e habilite **Use webhook**.
**4. Executar**
```bash
picoclaw gateway
```
> Em chats de grupo, o bot responde apenas quando @mencionado. As respostas citam a mensagem original.
</details>
<details>
<summary><b>WeCom (企业微信)</b></summary>
O PicoClaw suporta três tipos de integração WeCom:
**Opção 1: WeCom Bot (Bot)** - Configuração mais fácil, suporta chats de grupo
**Opção 2: WeCom App (App Personalizado)** - Mais recursos, mensagens proativas, apenas chat privado
**Opção 3: WeCom AI Bot (AI Bot)** - AI Bot oficial, respostas em streaming, suporta chat de grupo e privado
Veja o [Guia de Configuração do WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.zh.md) para instruções detalhadas de configuração.
**Configuração Rápida - WeCom Bot:**
**1. Criar um bot**
* Acesse o Console de Administração WeCom → Chat de Grupo → Adicionar Bot de Grupo
* Copie a URL do webhook (formato: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`)
**2. Configurar**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> O webhook do WeCom é servido no servidor Gateway compartilhado (`gateway.host`:`gateway.port`, padrão `127.0.0.1:18790`).
**Configuração Rápida - WeCom App:**
**1. Criar um aplicativo**
* Acesse o Console de Administração WeCom → Gerenciamento de Apps → Criar App
* Copie o **AgentId** e o **Secret**
* Acesse a página "Minha Empresa", copie o **CorpID**
**2. Configurar recebimento de mensagens**
* Nos detalhes do App, clique em "Receber Mensagem" → "Configurar API"
* Defina a URL como `http://your-server:18790/webhook/wecom-app`
* Gere o **Token** e o **EncodingAESKey**
**3. Configurar**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. Executar**
```bash
picoclaw gateway
```
> **Nota**: Os callbacks de webhook do WeCom são servidos na porta do Gateway (padrão 18790). Use um proxy reverso para HTTPS.
**Configuração Rápida - WeCom AI Bot:**
**1. Criar um AI Bot**
* Acesse o Console de Administração WeCom → Gerenciamento de Apps → AI Bot
* Nas configurações do AI Bot, configure a URL de callback: `http://your-server:18791/webhook/wecom-aibot`
* Copie o **Token** e clique em "Gerar Aleatoriamente" para o **EncodingAESKey**
**2. Configurar**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "Hello! How can I help you?"
}
}
}
```
**3. Executar**
```bash
picoclaw gateway
```
> **Nota**: O WeCom AI Bot usa protocolo de streaming pull — sem preocupações com timeout de resposta. Tarefas longas (>30 segundos) mudam automaticamente para entrega via `response_url` push.
</details>
+219
View File
@@ -0,0 +1,219 @@
# ⚙️ Guia de Configuração
> Voltar ao [README](../../README.pt-br.md)
## ⚙️ Configuração
Arquivo de configuração: `~/.picoclaw/config.json`
### Variáveis de Ambiente
Você pode substituir os caminhos padrão usando variáveis de ambiente. Isso é útil para instalações portáteis, implantações em contêineres ou execução do picoclaw como serviço do sistema. Essas variáveis são independentes e controlam caminhos diferentes.
| Variável | Descrição | Caminho Padrão |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | Substitui o caminho para o arquivo de configuração. Isso indica diretamente ao picoclaw qual `config.json` carregar, ignorando todos os outros locais. | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | Substitui o diretório raiz para dados do picoclaw. Isso altera o local padrão do `workspace` e outros diretórios de dados. | `~/.picoclaw` |
**Exemplos:**
```bash
# Executar picoclaw usando um arquivo de configuração específico
# O caminho do workspace será lido de dentro desse arquivo de configuração
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# Executar picoclaw com todos os dados armazenados em /opt/picoclaw
# A configuração será carregada do padrão ~/.picoclaw/config.json
# O workspace será criado em /opt/picoclaw/workspace
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# Usar ambos para uma configuração totalmente personalizada
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### Layout do Workspace
O PicoClaw armazena dados no seu workspace configurado (padrão: `~/.picoclaw/workspace`):
```
~/.picoclaw/workspace/
├── sessions/ # Sessões de conversa e histórico
├── memory/ # Memória de longo prazo (MEMORY.md)
├── state/ # Estado persistente (último canal, etc.)
├── cron/ # Banco de dados de tarefas agendadas
├── skills/ # Skills personalizadas
├── AGENT.md # Guia de comportamento do agente
├── HEARTBEAT.md # Prompts de tarefas periódicas (verificados a cada 30 min)
├── IDENTITY.md # Identidade do agente
├── SOUL.md # Alma do agente
└── USER.md # Preferências do usuário
```
> **Nota:** Alterações em `AGENT.md`, `SOUL.md`, `USER.md` e `memory/MEMORY.md` são detectadas automaticamente em tempo de execução via rastreamento de data de modificação (mtime). **Não é necessário reiniciar o gateway** após editar esses arquivos — o agente carrega o novo conteúdo na próxima requisição.
### Fontes de Skills
Por padrão, as skills são carregadas de:
1. `~/.picoclaw/workspace/skills` (workspace)
2. `~/.picoclaw/skills` (global)
3. `<current-working-directory>/skills` (builtin)
Para configurações avançadas/de teste, você pode substituir o diretório raiz de skills builtin com:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### Política Unificada de Execução de Comandos
- Comandos slash genéricos são executados através de um único caminho em `pkg/agent/loop.go` via `commands.Executor`.
- Os adaptadores de canal não consomem mais comandos genéricos localmente; eles encaminham o texto de entrada para o caminho bus/agent. O Telegram ainda registra automaticamente os comandos suportados na inicialização.
- Comando slash desconhecido (por exemplo `/foo`) passa para o processamento normal do LLM.
- Comando registrado mas não suportado no canal atual (por exemplo `/show` no WhatsApp) retorna um erro explícito ao usuário e interrompe o processamento.
### 🔒 Sandbox de Segurança
O PicoClaw é executado em um ambiente sandbox por padrão. O agente só pode acessar arquivos e executar comandos dentro do workspace configurado.
#### Configuração Padrão
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| Opção | Padrão | Descrição |
| ----------------------- | ----------------------- | ----------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Diretório de trabalho do agente |
| `restrict_to_workspace` | `true` | Restringir acesso a arquivos/comandos ao workspace |
#### Ferramentas Protegidas
Quando `restrict_to_workspace: true`, as seguintes ferramentas são isoladas:
| Ferramenta | Função | Restrição |
| ------------- | ---------------- | -------------------------------------- |
| `read_file` | Ler arquivos | Apenas arquivos dentro do workspace |
| `write_file` | Escrever arquivos| Apenas arquivos dentro do workspace |
| `list_dir` | Listar diretórios| Apenas diretórios dentro do workspace |
| `edit_file` | Editar arquivos | Apenas arquivos dentro do workspace |
| `append_file` | Anexar a arquivos| Apenas arquivos dentro do workspace |
| `exec` | Executar comandos| Caminhos de comando devem estar dentro do workspace |
#### Proteção Adicional do Exec
Mesmo com `restrict_to_workspace: false`, a ferramenta `exec` bloqueia estes comandos perigosos:
* `rm -rf`, `del /f`, `rmdir /s` — Exclusão em massa
* `format`, `mkfs`, `diskpart` — Formatação de disco
* `dd if=` — Imagem de disco
* Escrita em `/dev/sd[a-z]` — Escritas diretas em disco
* `shutdown`, `reboot`, `poweroff` — Desligamento do sistema
* Fork bomb `:(){ :|:& };:`
### Controle de Acesso a Arquivos
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.allow_read_paths` | string[] | `[]` | Additional paths allowed for reading outside workspace |
| `tools.allow_write_paths` | string[] | `[]` | Additional paths allowed for writing outside workspace |
### Segurança do Exec
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.exec.allow_remote` | bool | `false` | Allow exec tool from remote channels (Telegram/Discord etc.) |
| `tools.exec.enable_deny_patterns` | bool | `true` | Enable dangerous command interception |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | Custom regex patterns to block |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | Custom regex patterns to allow |
> **Nota de Segurança:** A proteção contra symlinks é habilitada por padrão — todos os caminhos de arquivo são resolvidos através de `filepath.EvalSymlinks` antes da correspondência com a whitelist, prevenindo ataques de escape via symlink.
#### Limitação Conhecida: Processos Filhos de Ferramentas de Build
O guard de segurança do exec inspeciona apenas a linha de comando que o PicoClaw executa diretamente. Ele não inspeciona recursivamente processos filhos gerados por ferramentas de desenvolvimento permitidas como `make`, `go run`, `cargo`, `npm run` ou scripts de build personalizados.
Isso significa que um comando de nível superior ainda pode compilar ou executar outros binários após passar pela verificação inicial do guard. Na prática, trate scripts de build, Makefiles, scripts de pacotes e binários gerados como código executável que precisa do mesmo nível de revisão que um comando shell direto.
Para ambientes de maior risco:
* Revise scripts de build antes da execução.
* Prefira aprovação/revisão manual para fluxos de trabalho de compilação e execução.
* Execute o PicoClaw dentro de um contêiner ou VM se precisar de isolamento mais forte do que o guard integrado oferece.
#### Exemplos de Erro
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### Desabilitando Restrições (Risco de Segurança)
Se você precisar que o agente acesse caminhos fora do workspace:
**Método 1: Arquivo de configuração**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**Método 2: Variável de ambiente**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **Aviso**: Desabilitar esta restrição permite que o agente acesse qualquer caminho no seu sistema. Use com cautela apenas em ambientes controlados.
#### Consistência do Limite de Segurança
A configuração `restrict_to_workspace` se aplica consistentemente em todos os caminhos de execução:
| Caminho de Execução | Limite de Segurança |
| -------------------- | ---------------------------- |
| Main Agent | `restrict_to_workspace` ✅ |
| Subagent / Spawn | Herda a mesma restrição ✅ |
| Heartbeat tasks | Herda a mesma restrição ✅ |
Todos os caminhos compartilham a mesma restrição de workspace — não há como contornar o limite de segurança através de subagentes ou tarefas agendadas.
### Heartbeat (Tarefas Periódicas)
O PicoClaw pode executar tarefas periódicas automaticamente. Crie um arquivo `HEARTBEAT.md` no seu workspace:
```markdown
# Tarefas Periódicas
- Verificar meu e-mail para mensagens importantes
- Revisar meu calendário para eventos próximos
- Verificar a previsão do tempo
```
O agente lerá este arquivo a cada 30 minutos (configurável) e executará quaisquer tarefas usando as ferramentas disponíveis.
#### Tarefas Assíncronas com Spawn
Para tarefas de longa duração (busca na web, chamadas de API), use a ferramenta `spawn` para criar um **subagente**:
```markdown
# Tarefas Periódicas
```
+166
View File
@@ -0,0 +1,166 @@
# 🐳 Docker e Início Rápido
> Voltar ao [README](../../README.pt-br.md)
## 🐳 Docker Compose
Você também pode executar o PicoClaw usando Docker Compose sem instalar nada localmente.
```bash
# 1. Clone este repositório
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. Primeira execução — gera automaticamente docker/data/config.json e encerra
docker compose -f docker/docker-compose.yml --profile gateway up
# O contêiner exibe "First-run setup complete." e para.
# 3. Configure suas chaves de API
vim docker/data/config.json # Set provider API keys, bot tokens, etc.
# 4. Iniciar
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Usuários Docker**: Por padrão, o Gateway escuta em `127.0.0.1`, que não é acessível a partir do host. Se você precisar acessar os endpoints de saúde ou expor portas, defina `PICOCLAW_GATEWAY_HOST=0.0.0.0` no seu ambiente ou atualize o `config.json`.
```bash
# 5. Verificar logs
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. Parar
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Modo Launcher (Console Web)
A imagem `launcher` inclui os três binários (`picoclaw`, `picoclaw-launcher`, `picoclaw-launcher-tui`) e inicia o console web por padrão, que fornece uma interface baseada em navegador para configuração e chat.
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
Abra http://localhost:18800 no seu navegador. O launcher gerencia o processo do gateway automaticamente.
> [!WARNING]
> O console web ainda não suporta autenticação. Evite expô-lo na internet pública.
### Modo Agent (One-shot)
```bash
# Fazer uma pergunta
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "What is 2+2?"
# Modo interativo
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### Atualização
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
### 🚀 Início Rápido
> [!TIP]
> Configure sua chave de API em `~/.picoclaw/config.json`. Obtenha chaves de API: [Volcengine (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM). A busca na web é opcional — obtenha gratuitamente uma [API Tavily](https://tavily.com) (1000 consultas gratuitas/mês) ou [API Brave Search](https://brave.com/search/api) (2000 consultas gratuitas/mês).
**1. Inicializar**
```bash
picoclaw onboard
```
**2. Configurar** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **Novo**: O formato de configuração `model_list` permite adicionar provedores sem alteração de código. Veja [Configuração de Modelos](#configuração-de-modelos-model_list) para detalhes.
> `request_timeout` é opcional e usa segundos. Se omitido ou definido como `<= 0`, o PicoClaw usa o timeout padrão (120s).
**3. Obter chaves de API**
* **Provedor LLM**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **Busca na Web** (opcional):
* [Brave Search](https://brave.com/search/api) - Pago ($5/1000 consultas, ~$5-6/mês)
* [Perplexity](https://www.perplexity.ai) - Busca com IA e interface de chat
* [SearXNG](https://github.com/searxng/searxng) - Metabuscador auto-hospedado (gratuito, sem necessidade de chave de API)
* [Tavily](https://tavily.com) - Otimizado para agentes de IA (1000 requisições/mês)
* DuckDuckGo - Fallback integrado (sem necessidade de chave de API)
> **Nota**: Veja `config.example.json` para um modelo de configuração completo.
**4. Conversar**
```bash
picoclaw agent -m "What is 2+2?"
```
Pronto! Você tem um assistente de IA funcionando em 2 minutos.
---
+434
View File
@@ -0,0 +1,434 @@
# 🔌 Provedores e Configuração de Modelos
> Voltar ao [README](../../README.pt-br.md)
### Provedores
> [!NOTE]
> O Groq fornece transcrição de voz gratuita via Whisper. Se configurado, mensagens de áudio de qualquer canal serão automaticamente transcritas no nível do agente.
| Provider | Purpose | Get API Key |
| ------------ | --------------------------------------- | ------------------------------------------------------------ |
| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM(Volcengine direct) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid direct) | [vivgrid.com](https://vivgrid.com) |
| `moonshot` | LLM (Kimi/Moonshot direct) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax direct) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian direct) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope direct) | [modelscope.cn](https://modelscope.cn) |
### Configuração de Modelos (model_list)
> **Novidade?** O PicoClaw agora usa uma abordagem de configuração **centrada no modelo**. Basta especificar o formato `vendor/model` (ex.: `zhipu/glm-4.7`) para adicionar novos provedores — **sem necessidade de alteração de código!**
Este design também permite **suporte multi-agente** com seleção flexível de provedores:
- **Agentes diferentes, provedores diferentes**: Cada agente pode usar seu próprio provedor LLM
- **Fallback de modelos**: Configure modelos primários e de fallback para resiliência
- **Balanceamento de carga**: Distribua requisições entre múltiplos endpoints
- **Configuração centralizada**: Gerencie todos os provedores em um só lugar
#### 📋 Todos os Vendors Suportados
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) |
| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | Your LiteLLM proxy key |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) |
| **VolcEngine (Doubao)** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [Get Key](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [Get Key](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [Get Key](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [Get Token](https://modelscope.cn/my/tokens) |
| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### Configuração Básica
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### Exemplos por Vendor
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**VolcEngine (Doubao)**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (com chave de API)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
}
```
> Execute `picoclaw auth login --provider anthropic` para colar seu token de API.
**Anthropic Messages API (formato nativo)**
Para acesso direto à API Anthropic ou endpoints personalizados que suportam apenas o formato de mensagem nativo da Anthropic:
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> Use o protocolo `anthropic-messages` quando:
> - Usar proxies de terceiros que suportam apenas o endpoint nativo `/v1/messages` da Anthropic (não o compatível com OpenAI `/v1/chat/completions`)
> - Conectar a serviços como MiniMax, Synthetic que requerem o formato de mensagem nativo da Anthropic
> - O protocolo `anthropic` existente retorna erros 404 (indicando que o endpoint não suporta formato compatível com OpenAI)
>
> **Nota:** O protocolo `anthropic` usa formato compatível com OpenAI (`/v1/chat/completions`), enquanto `anthropic-messages` usa o formato nativo da Anthropic (`/v1/messages`). Escolha com base no formato suportado pelo seu endpoint.
**Ollama (local)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**Proxy/API Personalizado**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
O PicoClaw remove apenas o prefixo externo `litellm/` antes de enviar a requisição, então aliases de proxy como `litellm/lite-gpt4` enviam `lite-gpt4`, enquanto `litellm/openai/gpt-4o` envia `openai/gpt-4o`.
#### Balanceamento de Carga
Configure múltiplos endpoints para o mesmo nome de modelo — o PicoClaw fará automaticamente round-robin entre eles:
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### Migração da Configuração Legacy `providers`
A configuração antiga `providers` está **descontinuada** mas ainda é suportada para compatibilidade retroativa.
**Configuração Antiga (descontinuada):**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**Configuração Nova (recomendada):**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
Para guia de migração detalhado, veja [docs/migration/model-list-migration.md](docs/migration/model-list-migration.md).
### Arquitetura de Provedores
O PicoClaw roteia provedores por família de protocolo:
- Protocolo compatível com OpenAI: OpenRouter, gateways compatíveis com OpenAI, Groq, Zhipu e endpoints estilo vLLM.
- Protocolo Anthropic: Comportamento nativo da API Claude.
- Caminho Codex/OAuth: Rota de autenticação OAuth/token da OpenAI.
Isso mantém o runtime leve enquanto torna novos backends compatíveis com OpenAI basicamente uma operação de configuração (`api_base` + `api_key`).
<details>
<summary><b>Zhipu</b></summary>
**1. Obter chave de API e URL base**
* Obtenha a [chave de API](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
**2. Configurar**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. Executar**
```bash
picoclaw agent -m "Hello"
```
</details>
<details>
<summary><b>Exemplo de configuração completa</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 Comparação de Chaves de API
| Service | Pricing | Use Case |
| ---------------- | ------------------------ | ------------------------------------- |
| **OpenRouter** | Free: 200K tokens/month | Multiple models (Claude, GPT-4, etc.) |
| **Volcengine CodingPlan** | ¥9.9/first month | Best for Chinese users, multiple SOTA models (Doubao, DeepSeek, etc.) |
| **Zhipu** | Free: 200K tokens/month | Suitable for Chinese users |
| **Brave Search** | $5/1000 queries | Web search functionality |
| **SearXNG** | Free (self-hosted) | Privacy-focused metasearch (70+ engines) |
| **Groq** | Free tier available | Fast inference (Llama, Mixtral) |
| **Cerebras** | Free tier available | Fast inference (Llama, Qwen, etc.) |
| **LongCat** | Free: up to 5M tokens/day | Fast inference |
| **ModelScope** | Free: 2000 requests/day | Inference (Qwen, GLM, DeepSeek, etc.) |
---
<div align="center">
<img src="assets/logo.jpg" alt="PicoClaw Meme" width="512">
</div>
+61
View File
@@ -0,0 +1,61 @@
# 🔄 Tarefas Assíncronas e Spawn
> Voltar ao [README](../../README.pt-br.md)
## Tarefas Rápidas (resposta direta)
- Informar a hora atual
## Tarefas Longas (usar spawn para assíncrono)
- Pesquisar na web notícias sobre IA e resumir
- Verificar e-mail e relatar mensagens importantes
```
**Comportamentos principais:**
| Feature | Description |
| ----------------------- | --------------------------------------------------------- |
| **spawn** | Creates async subagent, doesn't block heartbeat |
| **Independent context** | Subagent has its own context, no session history |
| **message tool** | Subagent communicates with user directly via message tool |
| **Non-blocking** | After spawning, heartbeat continues to next task |
#### Como Funciona a Comunicação do Subagente
```
Heartbeat é acionado
Agente lê HEARTBEAT.md
Para tarefa longa: spawn subagente
↓ ↓
Continua para próxima tarefa Subagente trabalha independentemente
↓ ↓
Todas as tarefas concluídas Subagente usa ferramenta "message"
↓ ↓
Responde HEARTBEAT_OK Usuário recebe resultado diretamente
```
O subagente tem acesso a ferramentas (message, web_search, etc.) e pode se comunicar com o usuário independentemente sem passar pelo agente principal.
**Configuração:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| Option | Default | Description |
| ---------- | ------- | ---------------------------------- |
| `enabled` | `true` | Enable/disable heartbeat |
| `interval` | `30` | Check interval in minutes (min: 5) |
**Variáveis de ambiente:**
* `PICOCLAW_HEARTBEAT_ENABLED=false` para desabilitar
* `PICOCLAW_HEARTBEAT_INTERVAL=60` para alterar o intervalo
+336
View File
@@ -0,0 +1,336 @@
# 🔧 Configuração de Ferramentas
> Voltar ao [README](../../README.pt-br.md)
A configuração de ferramentas do PicoClaw está localizada no campo `tools` do `config.json`.
## Estrutura de diretórios
```json
{
"tools": {
"web": {
...
},
"mcp": {
...
},
"exec": {
...
},
"cron": {
...
},
"skills": {
...
}
}
}
```
## Ferramentas Web
As ferramentas web são usadas para pesquisa e busca de páginas web.
### Web Fetcher
Configurações gerais para busca e processamento de conteúdo de páginas web.
| Config | Tipo | Padrão | Descrição |
|---------------------|--------|---------------|-----------------------------------------------------------------------------------------------|
| `enabled` | bool | true | Habilitar a capacidade de busca de páginas web. |
| `fetch_limit_bytes` | int | 10485760 | Tamanho máximo do payload da página web a ser buscado, em bytes (padrão é 10MB). |
| `format` | string | "plaintext" | Formato de saída do conteúdo buscado. Opções: `plaintext` ou `markdown` (recomendado). |
### Brave
| Config | Tipo | Padrão | Descrição |
|---------------|--------|--------|----------------------------|
| `enabled` | bool | false | Habilitar pesquisa Brave |
| `api_key` | string | - | Chave API do Brave Search |
| `max_results` | int | 5 | Número máximo de resultados |
### DuckDuckGo
| Config | Tipo | Padrão | Descrição |
|---------------|------|--------|--------------------------------|
| `enabled` | bool | true | Habilitar pesquisa DuckDuckGo |
| `max_results` | int | 5 | Número máximo de resultados |
### Perplexity
| Config | Tipo | Padrão | Descrição |
|---------------|--------|--------|--------------------------------|
| `enabled` | bool | false | Habilitar pesquisa Perplexity |
| `api_key` | string | - | Chave API do Perplexity |
| `max_results` | int | 5 | Número máximo de resultados |
## Ferramenta Exec
A ferramenta exec é usada para executar comandos shell.
| Config | Tipo | Padrão | Descrição |
|------------------------|-------|--------|-------------------------------------------------|
| `enable_deny_patterns` | bool | true | Habilitar bloqueio padrão de comandos perigosos |
| `custom_deny_patterns` | array | [] | Padrões de negação personalizados (expressões regulares) |
### Funcionalidade
- **`enable_deny_patterns`**: Defina como `false` para desabilitar completamente os padrões de bloqueio de comandos perigosos padrão
- **`custom_deny_patterns`**: Adicione padrões regex de negação personalizados; comandos correspondentes serão bloqueados
### Padrões de comandos bloqueados por padrão
Por padrão, o PicoClaw bloqueia os seguintes comandos perigosos:
- Comandos de exclusão: `rm -rf`, `del /f/q`, `rmdir /s`
- Operações de disco: `format`, `mkfs`, `diskpart`, `dd if=`, escrita em `/dev/sd*`
- Operações do sistema: `shutdown`, `reboot`, `poweroff`
- Substituição de comandos: `$()`, `${}`, crases
- Pipe para shell: `| sh`, `| bash`
- Escalação de privilégios: `sudo`, `chmod`, `chown`
- Controle de processos: `pkill`, `killall`, `kill -9`
- Operações remotas: `curl | sh`, `wget | sh`, `ssh`
- Gerenciamento de pacotes: `apt`, `yum`, `dnf`, `npm install -g`, `pip install --user`
- Contêineres: `docker run`, `docker exec`
- Git: `git push`, `git force`
- Outros: `eval`, `source *.sh`
### Limitação arquitetural conhecida
O guarda exec apenas valida o comando de nível superior enviado ao PicoClaw. Ele **não** inspeciona recursivamente processos filhos gerados por ferramentas de build ou scripts após o início desse comando.
Exemplos de fluxos de trabalho que podem contornar o guarda de comando direto uma vez que o comando inicial é permitido:
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
Isso significa que o guarda é útil para bloquear comandos diretos obviamente perigosos, mas **não** é um sandbox completo para pipelines de build não revisados. Se seu modelo de ameaça inclui código não confiável no workspace, use isolamento mais forte, como contêineres, VMs ou um fluxo de aprovação em torno de comandos de build e execução.
### Exemplo de configuração
```json
{
"tools": {
"exec": {
"enable_deny_patterns": true,
"custom_deny_patterns": [
"\\brm\\s+-r\\b",
"\\bkillall\\s+python"
]
}
}
}
```
## Ferramenta Cron
A ferramenta cron é usada para agendar tarefas periódicas.
| Config | Tipo | Padrão | Descrição |
|------------------------|------|--------|-----------------------------------------------------|
| `exec_timeout_minutes` | int | 5 | Tempo limite de execução em minutos, 0 significa sem limite |
## Ferramenta MCP
A ferramenta MCP permite a integração com servidores Model Context Protocol externos.
### Descoberta de ferramentas (carregamento preguiçoso)
Ao conectar a vários servidores MCP, expor centenas de ferramentas simultaneamente pode esgotar a janela de contexto do LLM e aumentar os custos de API. O recurso **Discovery** resolve isso mantendo as ferramentas MCP *ocultas* por padrão.
Em vez de carregar todas as ferramentas, o LLM recebe uma ferramenta de pesquisa leve (usando correspondência de palavras-chave BM25 ou Regex). Quando o LLM precisa de uma capacidade específica, ele pesquisa a biblioteca oculta. As ferramentas correspondentes são então temporariamente "desbloqueadas" e injetadas no contexto por um número configurado de turnos (`ttl`).
### Configuração global
| Config | Tipo | Padrão | Descrição |
|-------------|--------|--------|----------------------------------------------|
| `enabled` | bool | false | Habilitar integração MCP globalmente |
| `discovery` | object | `{}` | Configuração de descoberta de ferramentas (veja abaixo) |
| `servers` | object | `{}` | Mapa de nome do servidor para configuração do servidor |
### Configuração Discovery (`discovery`)
| Config | Tipo | Padrão | Descrição |
|----------------------|------|--------|-----------------------------------------------------------------------------------------------------------------------------------|
| `enabled` | bool | false | Se true, as ferramentas MCP ficam ocultas e são carregadas sob demanda via pesquisa. Se false, todas as ferramentas são carregadas |
| `ttl` | int | 5 | Número de turnos de conversa que uma ferramenta descoberta permanece desbloqueada |
| `max_search_results` | int | 5 | Número máximo de ferramentas retornadas por consulta de pesquisa |
| `use_bm25` | bool | true | Habilitar a ferramenta de pesquisa por linguagem natural/palavras-chave (`tool_search_tool_bm25`). **Aviso**: consome mais recursos que a pesquisa regex |
| `use_regex` | bool | false | Habilitar a ferramenta de pesquisa por padrão regex (`tool_search_tool_regex`) |
> **Nota:** Se `discovery.enabled` for `true`, você **deve** habilitar pelo menos um mecanismo de pesquisa (`use_bm25` ou `use_regex`),
> caso contrário a aplicação falhará ao iniciar.
### Configuração por servidor
| Config | Tipo | Obrigatório | Descrição |
|------------|--------|-------------|--------------------------------------------|
| `enabled` | bool | sim | Habilitar este servidor MCP |
| `type` | string | não | Tipo de transporte: `stdio`, `sse`, `http` |
| `command` | string | stdio | Comando executável para transporte stdio |
| `args` | array | não | Argumentos do comando para transporte stdio |
| `env` | object | não | Variáveis de ambiente para processo stdio |
| `env_file` | string | não | Caminho para arquivo de ambiente para processo stdio |
| `url` | string | sse/http | URL do endpoint para transporte `sse`/`http` |
| `headers` | object | não | Cabeçalhos HTTP para transporte `sse`/`http` |
### Comportamento do transporte
- Se `type` for omitido, o transporte é detectado automaticamente:
- `url` está definido → `sse`
- `command` está definido → `stdio`
- `http` e `sse` ambos usam `url` + `headers` opcionais.
- `env` e `env_file` são aplicados apenas a servidores `stdio`.
### Exemplos de configuração
#### 1) Servidor MCP Stdio
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"filesystem": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp"
]
}
}
}
}
}
```
#### 2) Servidor MCP remoto SSE/HTTP
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"remote-mcp": {
"enabled": true,
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
}
}
```
#### 3) Configuração MCP massiva com descoberta de ferramentas habilitada
*Neste exemplo, o LLM verá apenas o `tool_search_tool_bm25`. Ele pesquisará e desbloqueará ferramentas do Github ou Postgres dinamicamente apenas quando solicitado pelo usuário.*
```json
{
"tools": {
"mcp": {
"enabled": true,
"discovery": {
"enabled": true,
"ttl": 5,
"max_search_results": 5,
"use_bm25": true,
"use_regex": false
},
"servers": {
"github": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN"
}
},
"postgres": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost/dbname"
]
},
"slack": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-slack"
],
"env": {
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
}
}
}
}
}
}
```
## Ferramenta Skills
A ferramenta skills configura a descoberta e instalação de habilidades via registros como o ClawHub.
### Registros
| Config | Tipo | Padrão | Descrição |
|------------------------------------|--------|-----------------------|----------------------------------------------|
| `registries.clawhub.enabled` | bool | true | Habilitar registro ClawHub |
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | URL base do ClawHub |
| `registries.clawhub.auth_token` | string | `""` | Token Bearer opcional para limites de taxa mais altos |
| `registries.clawhub.search_path` | string | `/api/v1/search` | Caminho da API de pesquisa |
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Caminho da API de Skills |
| `registries.clawhub.download_path` | string | `/api/v1/download` | Caminho da API de download |
### Exemplo de configuração
```json
{
"tools": {
"skills": {
"registries": {
"clawhub": {
"enabled": true,
"base_url": "https://clawhub.ai",
"auth_token": "",
"search_path": "/api/v1/search",
"skills_path": "/api/v1/skills",
"download_path": "/api/v1/download"
}
}
}
}
}
```
## Variáveis de ambiente
Todas as opções de configuração podem ser substituídas via variáveis de ambiente com o formato `PICOCLAW_TOOLS_<SECTION>_<KEY>`:
Por exemplo:
- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true`
- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false`
- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10`
- `PICOCLAW_TOOLS_MCP_ENABLED=true`
Nota: Configuração de tipo mapa aninhado (por exemplo `tools.mcp.servers.<name>.*`) é configurada no `config.json` em vez de variáveis de ambiente.
+45
View File
@@ -0,0 +1,45 @@
# 🐛 Solução de Problemas
> Voltar ao [README](../../README.pt-br.md)
## "model ... not found in model_list" ou OpenRouter "free is not a valid model ID"
**Sintoma:** Você vê um dos seguintes erros:
- `Error creating provider: model "openrouter/free" not found in model_list`
- OpenRouter retorna 400: `"free is not a valid model ID"`
**Causa:** O campo `model` na sua entrada `model_list` é o que é enviado para a API. Para o OpenRouter, você deve usar o ID de modelo **completo**, não uma abreviação.
- **Errado:** `"model": "free"` → OpenRouter recebe `free` e rejeita.
- **Correto:** `"model": "openrouter/free"` → OpenRouter recebe `openrouter/free` (roteamento automático do nível gratuito).
**Correção:** Em `~/.picoclaw/config.json` (ou seu caminho de configuração):
1. **agents.defaults.model** deve corresponder a um `model_name` em `model_list` (ex.: `"openrouter-free"`).
2. O **model** dessa entrada deve ser um ID de modelo OpenRouter válido, por exemplo:
- `"openrouter/free"` nível gratuito automático
- `"google/gemini-2.0-flash-exp:free"`
- `"meta-llama/llama-3.1-8b-instruct:free"`
Exemplo:
```json
{
"agents": {
"defaults": {
"model": "openrouter-free"
}
},
"model_list": [
{
"model_name": "openrouter-free",
"model": "openrouter/free",
"api_key": "sk-or-v1-YOUR_OPENROUTER_KEY",
"api_base": "https://openrouter.ai/api/v1"
}
]
}
```
Obtenha sua chave em [OpenRouter Keys](https://openrouter.ai/keys).
+61
View File
@@ -0,0 +1,61 @@
# 🔄 Spawn & Async Tasks
> Back to [README](../README.md)
## Quick Tasks (respond directly)
- Report current time
## Long Tasks (use spawn for async)
- Search the web for AI news and summarize
- Check email and report important messages
```
**Key behaviors:**
| Feature | Description |
| ----------------------- | --------------------------------------------------------- |
| **spawn** | Creates async subagent, doesn't block heartbeat |
| **Independent context** | Subagent has its own context, no session history |
| **message tool** | Subagent communicates with user directly via message tool |
| **Non-blocking** | After spawning, heartbeat continues to next task |
#### How Subagent Communication Works
```
Heartbeat triggers
Agent reads HEARTBEAT.md
For long task: spawn subagent
↓ ↓
Continue to next task Subagent works independently
↓ ↓
All tasks done Subagent uses "message" tool
↓ ↓
Respond HEARTBEAT_OK User receives result directly
```
The subagent has access to tools (message, web_search, etc.) and can communicate with the user independently without going through the main agent.
**Configuration:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| Option | Default | Description |
| ---------- | ------- | ---------------------------------- |
| `enabled` | `true` | Enable/disable heartbeat |
| `interval` | `30` | Check interval in minutes (min: 5) |
**Environment variables:**
* `PICOCLAW_HEARTBEAT_ENABLED=false` to disable
* `PICOCLAW_HEARTBEAT_INTERVAL=60` to change interval
+25
View File
@@ -30,6 +30,15 @@ PicoClaw's tools configuration is located in the `tools` field of `config.json`.
Web tools are used for web search and fetching.
### Web Fetcher
General settings for fetching and processing webpage content.
| Config | Type | Default | Description |
|---------------------|--------|---------------|-----------------------------------------------------------------------------------------------|
| `enabled` | bool | true | Enable the webpage fetching capability. |
| `fetch_limit_bytes` | int | 10485760 | Maximum size of the webpage payload to fetch, in bytes (default is 10MB). |
| `format` | string | "plaintext" | Output format of the fetched content. Options: `plaintext` or `markdown` (recommended). |
### Brave
| Config | Type | Default | Description |
@@ -84,6 +93,22 @@ By default, PicoClaw blocks the following dangerous commands:
- Git: `git push`, `git force`
- Other: `eval`, `source *.sh`
### Known Architectural Limitation
The exec guard only validates the top-level command sent to PicoClaw. It does **not** recursively inspect child
processes spawned by build tools or scripts after that command starts running.
Examples of workflows that can bypass the direct command guard once the initial command is allowed:
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
This means the guard is useful for blocking obviously dangerous direct commands, but it is **not** a full sandbox for
unreviewed build pipelines. If your threat model includes untrusted code in the workspace, use stronger isolation such
as containers, VMs, or an approval flow around build-and-run commands.
### Configuration Example
```json
+427
View File
@@ -0,0 +1,427 @@
# 💬 Cấu Hình Ứng Dụng Chat
> Quay lại [README](../../README.vi.md)
## 💬 Ứng Dụng Chat
Trò chuyện với picoclaw của bạn qua Telegram, Discord, WhatsApp, Matrix, QQ, DingTalk, LINE, WeCom, Feishu, Slack, IRC, OneBot hoặc MaixCam
> **Lưu ý**: Tất cả các kênh dựa trên webhook (LINE, WeCom, v.v.) được phục vụ trên một máy chủ HTTP Gateway chung (`gateway.host`:`gateway.port`, mặc định `127.0.0.1:18790`). Không có port riêng cho từng kênh. Lưu ý: Feishu sử dụng chế độ WebSocket/SDK và không sử dụng máy chủ HTTP webhook chung.
| Channel | Setup |
| ------------ | ---------------------------------- |
| **Telegram** | Easy (just a token) |
| **Discord** | Easy (bot token + intents) |
| **WhatsApp** | Easy (native: QR scan; or bridge URL) |
| **Matrix** | Medium (homeserver + bot access token) |
| **QQ** | Easy (AppID + AppSecret) |
| **DingTalk** | Medium (app credentials) |
| **LINE** | Medium (credentials + webhook URL) |
| **WeCom AI Bot** | Medium (Token + AES key) |
| **Feishu** | Medium (App ID + Secret, WebSocket mode) |
| **Slack** | Medium (Bot token + App token) |
| **IRC** | Medium (server + TLS config) |
| **OneBot** | Medium (QQ via OneBot protocol) |
| **MaixCam** | Easy (Sipeed hardware integration) |
| **Pico** | Native PicoClaw protocol |
<details>
<summary><b>Telegram</b> (Khuyến nghị)</summary>
**1. Tạo bot**
* Mở Telegram, tìm `@BotFather`
* Gửi `/newbot`, làm theo hướng dẫn
* Sao chép token
**2. Cấu hình**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
> Lấy user ID của bạn từ `@userinfobot` trên Telegram.
**3. Chạy**
```bash
picoclaw gateway
```
**4. Menu lệnh Telegram (tự động đăng ký khi khởi động)**
PicoClaw hiện lưu trữ định nghĩa lệnh trong một registry chung. Khi khởi động, Telegram sẽ tự động đăng ký các lệnh bot được hỗ trợ (ví dụ `/start`, `/help`, `/show`, `/list`) để menu lệnh và hành vi runtime luôn đồng bộ.
Đăng ký menu lệnh Telegram vẫn là UX khám phá cục bộ của kênh; thực thi lệnh chung được xử lý tập trung trong vòng lặp agent qua commands executor.
Nếu đăng ký lệnh thất bại (lỗi tạm thời mạng/API), kênh vẫn khởi động và PicoClaw thử lại đăng ký trong nền.
</details>
<details>
<summary><b>Discord</b></summary>
**1. Tạo bot**
* Truy cập <https://discord.com/developers/applications>
* Tạo ứng dụng → Bot → Add Bot
* Sao chép bot token
**2. Bật intents**
* Trong cài đặt Bot, bật **MESSAGE CONTENT INTENT**
* (Tùy chọn) Bật **SERVER MEMBERS INTENT** nếu bạn muốn sử dụng danh sách cho phép dựa trên dữ liệu thành viên
**3. Lấy User ID**
* Cài đặt Discord → Nâng cao → bật **Developer Mode**
* Nhấp chuột phải vào avatar → **Copy User ID**
**4. Cấu hình**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. Mời bot**
* OAuth2 → URL Generator
* Scopes: `bot`
* Bot Permissions: `Send Messages`, `Read Message History`
* Mở URL mời được tạo và thêm bot vào server của bạn
**Tùy chọn: Chế độ kích hoạt nhóm**
Mặc định bot phản hồi tất cả tin nhắn trong kênh server. Để giới hạn phản hồi chỉ khi @mention, thêm:
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
Bạn cũng có thể kích hoạt bằng tiền tố từ khóa (ví dụ: `!bot`):
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. Chạy**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b> (native qua whatsmeow)</summary>
PicoClaw có thể kết nối WhatsApp theo hai cách:
- **Native (khuyến nghị):** In-process sử dụng [whatsmeow](https://github.com/tulir/whatsmeow). Không cần bridge riêng. Đặt `"use_native": true` và để trống `bridge_url`. Lần chạy đầu tiên, quét mã QR bằng WhatsApp (Thiết bị liên kết). Phiên được lưu trong workspace (ví dụ: `workspace/whatsapp/`). Kênh native là **tùy chọn** để giữ binary mặc định nhỏ; build với `-tags whatsapp_native` (ví dụ: `make build-whatsapp-native` hoặc `go build -tags whatsapp_native ./cmd/...`).
- **Bridge:** Kết nối đến bridge WebSocket bên ngoài. Đặt `bridge_url` (ví dụ: `ws://localhost:3001`) và giữ `use_native` là false.
**Cấu hình (native)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
Nếu `session_store_path` trống, phiên được lưu tại `<workspace>/whatsapp/`. Chạy `picoclaw gateway`; lần chạy đầu tiên, quét mã QR hiển thị trong terminal bằng WhatsApp → Thiết bị liên kết.
</details>
<details>
<summary><b>QQ</b></summary>
**1. Tạo bot**
- Truy cập [QQ Open Platform](https://q.qq.com/#)
- Tạo ứng dụng → Lấy **AppID****AppSecret**
**2. Cấu hình**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> Đặt `allow_from` trống để cho phép tất cả người dùng, hoặc chỉ định số QQ để giới hạn truy cập.
**3. Chạy**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Tạo bot**
* Truy cập [Open Platform](https://open.dingtalk.com/)
* Tạo ứng dụng nội bộ
* Sao chép Client ID và Client Secret
**2. Cấu hình**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> Đặt `allow_from` trống để cho phép tất cả người dùng, hoặc chỉ định DingTalk user ID để giới hạn truy cập.
**3. Chạy**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Matrix</b></summary>
**1. Chuẩn bị tài khoản bot**
* Sử dụng homeserver ưa thích (ví dụ: `https://matrix.org` hoặc tự host)
* Tạo user bot và lấy access token
**2. Cấu hình**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. Chạy**
```bash
picoclaw gateway
```
Để xem đầy đủ các tùy chọn (`device_id`, `join_on_invite`, `group_trigger`, `placeholder`, `reasoning_channel_id`), xem [Hướng Dẫn Cấu Hình Kênh Matrix](docs/channels/matrix/README.md).
</details>
<details>
<summary><b>LINE</b></summary>
**1. Tạo Tài Khoản LINE Official**
- Truy cập [LINE Developers Console](https://developers.line.biz/)
- Tạo provider → Tạo kênh Messaging API
- Sao chép **Channel Secret****Channel Access Token**
**2. Cấu hình**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> Webhook LINE được phục vụ trên máy chủ Gateway chung (`gateway.host`:`gateway.port`, mặc định `127.0.0.1:18790`).
**3. Thiết lập Webhook URL**
LINE yêu cầu HTTPS cho webhook. Sử dụng reverse proxy hoặc tunnel:
```bash
# Ví dụ với ngrok (port mặc định gateway là 18790)
ngrok http 18790
```
Sau đó đặt Webhook URL trong LINE Developers Console thành `https://your-domain/webhook/line` và bật **Use webhook**.
**4. Chạy**
```bash
picoclaw gateway
```
> Trong chat nhóm, bot chỉ phản hồi khi được @mention. Phản hồi trích dẫn tin nhắn gốc.
</details>
<details>
<summary><b>WeCom (企业微信)</b></summary>
PicoClaw hỗ trợ ba loại tích hợp WeCom:
**Tùy chọn 1: WeCom Bot (Bot)** - Thiết lập dễ hơn, hỗ trợ chat nhóm
**Tùy chọn 2: WeCom App (App Tùy chỉnh)** - Nhiều tính năng hơn, nhắn tin chủ động, chỉ chat riêng
**Tùy chọn 3: WeCom AI Bot (AI Bot)** - AI Bot chính thức, phản hồi streaming, hỗ trợ chat nhóm & riêng
Xem [Hướng Dẫn Cấu Hình WeCom AI Bot](docs/channels/wecom/wecom_aibot/README.zh.md) để biết hướng dẫn thiết lập chi tiết.
**Thiết Lập Nhanh - WeCom Bot:**
**1. Tạo bot**
* Truy cập Console Quản Trị WeCom → Chat Nhóm → Thêm Bot Nhóm
* Sao chép URL webhook (định dạng: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`)
**2. Cấu hình**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> Webhook WeCom được phục vụ trên máy chủ Gateway chung (`gateway.host`:`gateway.port`, mặc định `127.0.0.1:18790`).
**Thiết Lập Nhanh - WeCom App:**
**1. Tạo ứng dụng**
* Truy cập Console Quản Trị WeCom → Quản Lý App → Tạo App
* Sao chép **AgentId****Secret**
* Truy cập trang "Công Ty Của Tôi", sao chép **CorpID**
**2. Cấu hình nhận tin nhắn**
* Trong chi tiết App, nhấp "Nhận Tin Nhắn" → "Cấu Hình API"
* Đặt URL thành `http://your-server:18790/webhook/wecom-app`
* Tạo **Token****EncodingAESKey**
**3. Cấu hình**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. Chạy**
```bash
picoclaw gateway
```
> **Lưu ý**: Callback webhook WeCom được phục vụ trên port Gateway (mặc định 18790). Sử dụng reverse proxy cho HTTPS.
**Thiết Lập Nhanh - WeCom AI Bot:**
**1. Tạo AI Bot**
* Truy cập Console Quản Trị WeCom → Quản Lý App → AI Bot
* Trong cài đặt AI Bot, cấu hình callback URL: `http://your-server:18791/webhook/wecom-aibot`
* Sao chép **Token** và nhấp "Tạo Ngẫu Nhiên" cho **EncodingAESKey**
**2. Cấu hình**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "Hello! How can I help you?"
}
}
}
```
**3. Chạy**
```bash
picoclaw gateway
```
> **Lưu ý**: WeCom AI Bot sử dụng giao thức streaming pull — không lo timeout phản hồi. Tác vụ dài (>30 giây) tự động chuyển sang gửi qua `response_url` push.
</details>
+219
View File
@@ -0,0 +1,219 @@
# ⚙️ Hướng Dẫn Cấu Hình
> Quay lại [README](../../README.vi.md)
## ⚙️ Cấu Hình
File cấu hình: `~/.picoclaw/config.json`
### Biến Môi Trường
Bạn có thể ghi đè các đường dẫn mặc định bằng biến môi trường. Điều này hữu ích cho cài đặt portable, triển khai container, hoặc chạy picoclaw như dịch vụ hệ thống. Các biến này độc lập và kiểm soát các đường dẫn khác nhau.
| Biến | Mô tả | Đường Dẫn Mặc Định |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | Ghi đè đường dẫn đến file cấu hình. Chỉ định trực tiếp cho picoclaw file `config.json` nào cần tải, bỏ qua tất cả vị trí khác. | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | Ghi đè thư mục gốc cho dữ liệu picoclaw. Thay đổi vị trí mặc định của `workspace` và các thư mục dữ liệu khác. | `~/.picoclaw` |
**Ví dụ:**
```bash
# Chạy picoclaw với file cấu hình cụ thể
# Đường dẫn workspace sẽ được đọc từ trong file cấu hình đó
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# Chạy picoclaw với tất cả dữ liệu lưu tại /opt/picoclaw
# Cấu hình sẽ được tải từ mặc định ~/.picoclaw/config.json
# Workspace sẽ được tạo tại /opt/picoclaw/workspace
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# Sử dụng cả hai cho thiết lập tùy chỉnh hoàn toàn
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### Bố Cục Workspace
PicoClaw lưu trữ dữ liệu trong workspace đã cấu hình (mặc định: `~/.picoclaw/workspace`):
```
~/.picoclaw/workspace/
├── sessions/ # Phiên hội thoại và lịch sử
├── memory/ # Bộ nhớ dài hạn (MEMORY.md)
├── state/ # Trạng thái bền vững (kênh cuối, v.v.)
├── cron/ # Cơ sở dữ liệu tác vụ lên lịch
├── skills/ # Skill tùy chỉnh
├── AGENT.md # Hướng dẫn hành vi agent
├── HEARTBEAT.md # Prompt tác vụ định kỳ (kiểm tra mỗi 30 phút)
├── IDENTITY.md # Danh tính agent
├── SOUL.md # Linh hồn agent
└── USER.md # Tùy chọn người dùng
```
> **Lưu ý:** Các thay đổi đối với `AGENT.md`, `SOUL.md`, `USER.md` và `memory/MEMORY.md` được tự động phát hiện trong thời gian chạy thông qua theo dõi thời gian sửa đổi file (mtime). **Không cần khởi động lại gateway** sau khi chỉnh sửa các file này — agent sẽ tải nội dung mới vào yêu cầu tiếp theo.
### Nguồn Skill
Mặc định, skill được tải từ:
1. `~/.picoclaw/workspace/skills` (workspace)
2. `~/.picoclaw/skills` (global)
3. `<current-working-directory>/skills` (builtin)
Cho thiết lập nâng cao/test, bạn có thể ghi đè thư mục gốc skill builtin với:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### Chính Sách Thực Thi Lệnh Thống Nhất
- Lệnh slash chung được thực thi qua một đường dẫn duy nhất trong `pkg/agent/loop.go` qua `commands.Executor`.
- Adapter kênh không còn xử lý lệnh chung cục bộ; chúng chuyển tiếp văn bản đầu vào đến đường dẫn bus/agent. Telegram vẫn tự động đăng ký lệnh được hỗ trợ khi khởi động.
- Lệnh slash không xác định (ví dụ `/foo`) được chuyển sang xử lý LLM bình thường.
- Lệnh đã đăng ký nhưng không được hỗ trợ trên kênh hiện tại (ví dụ `/show` trên WhatsApp) trả về lỗi rõ ràng cho người dùng và dừng xử lý tiếp.
### 🔒 Sandbox Bảo Mật
PicoClaw chạy trong môi trường sandbox mặc định. Agent chỉ có thể truy cập file và thực thi lệnh trong workspace đã cấu hình.
#### Cấu Hình Mặc Định
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| Tùy chọn | Mặc định | Mô tả |
| ----------------------- | ----------------------- | ----------------------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Thư mục làm việc của agent |
| `restrict_to_workspace` | `true` | Giới hạn truy cập file/lệnh trong workspace |
#### Công Cụ Được Bảo Vệ
Khi `restrict_to_workspace: true`, các công cụ sau được sandbox:
| Công cụ | Chức năng | Giới hạn |
| ------------- | ---------------- | -------------------------------------- |
| `read_file` | Đọc file | Chỉ file trong workspace |
| `write_file` | Ghi file | Chỉ file trong workspace |
| `list_dir` | Liệt kê thư mục | Chỉ thư mục trong workspace |
| `edit_file` | Sửa file | Chỉ file trong workspace |
| `append_file` | Nối vào file | Chỉ file trong workspace |
| `exec` | Thực thi lệnh | Đường dẫn lệnh phải trong workspace |
#### Bảo Vệ Exec Bổ Sung
Ngay cả khi `restrict_to_workspace: false`, công cụ `exec` chặn các lệnh nguy hiểm sau:
* `rm -rf`, `del /f`, `rmdir /s` — Xóa hàng loạt
* `format`, `mkfs`, `diskpart` — Định dạng đĩa
* `dd if=` — Tạo ảnh đĩa
* Ghi vào `/dev/sd[a-z]` — Ghi trực tiếp đĩa
* `shutdown`, `reboot`, `poweroff` — Tắt hệ thống
* Fork bomb `:(){ :|:& };:`
### Kiểm Soát Truy Cập File
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.allow_read_paths` | string[] | `[]` | Additional paths allowed for reading outside workspace |
| `tools.allow_write_paths` | string[] | `[]` | Additional paths allowed for writing outside workspace |
### Bảo Mật Exec
| Config Key | Type | Default | Description |
|------------|------|---------|-------------|
| `tools.exec.allow_remote` | bool | `false` | Allow exec tool from remote channels (Telegram/Discord etc.) |
| `tools.exec.enable_deny_patterns` | bool | `true` | Enable dangerous command interception |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | Custom regex patterns to block |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | Custom regex patterns to allow |
> **Lưu ý Bảo Mật:** Bảo vệ symlink được bật mặc định — tất cả đường dẫn file được giải quyết qua `filepath.EvalSymlinks` trước khi so khớp whitelist, ngăn chặn tấn công thoát qua symlink.
#### Hạn Chế Đã Biết: Tiến Trình Con Từ Công Cụ Build
Guard bảo mật exec chỉ kiểm tra dòng lệnh mà PicoClaw khởi chạy trực tiếp. Nó không kiểm tra đệ quy các tiến trình con được tạo bởi công cụ phát triển được phép như `make`, `go run`, `cargo`, `npm run`, hoặc script build tùy chỉnh.
Điều này có nghĩa là lệnh cấp cao nhất vẫn có thể biên dịch hoặc khởi chạy binary khác sau khi vượt qua kiểm tra guard ban đầu. Trong thực tế, hãy coi script build, Makefile, script package, và binary được tạo như mã thực thi cần cùng mức độ review như lệnh shell trực tiếp.
Cho môi trường rủi ro cao hơn:
* Review script build trước khi thực thi.
* Ưu tiên phê duyệt/review thủ công cho quy trình biên dịch và chạy.
* Chạy PicoClaw trong container hoặc VM nếu bạn cần cách ly mạnh hơn guard tích hợp.
#### Ví Dụ Lỗi
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### Tắt Giới Hạn (Rủi Ro Bảo Mật)
Nếu bạn cần agent truy cập đường dẫn ngoài workspace:
**Phương pháp 1: File cấu hình**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**Phương pháp 2: Biến môi trường**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **Cảnh báo**: Tắt giới hạn này cho phép agent truy cập bất kỳ đường dẫn nào trên hệ thống. Chỉ sử dụng cẩn thận trong môi trường được kiểm soát.
#### Tính Nhất Quán Ranh Giới Bảo Mật
Cài đặt `restrict_to_workspace` áp dụng nhất quán trên tất cả đường dẫn thực thi:
| Đường Dẫn Thực Thi | Ranh Giới Bảo Mật |
| -------------------- | ---------------------------- |
| Main Agent | `restrict_to_workspace` ✅ |
| Subagent / Spawn | Kế thừa cùng giới hạn ✅ |
| Heartbeat tasks | Kế thừa cùng giới hạn ✅ |
Tất cả đường dẫn chia sẻ cùng giới hạn workspace — không có cách nào vượt qua ranh giới bảo mật qua subagent hoặc tác vụ lên lịch.
### Heartbeat (Tác Vụ Định Kỳ)
PicoClaw có thể thực hiện tác vụ định kỳ tự động. Tạo file `HEARTBEAT.md` trong workspace:
```markdown
# Tác Vụ Định Kỳ
- Kiểm tra email cho tin nhắn quan trọng
- Xem lịch cho sự kiện sắp tới
- Kiểm tra dự báo thời tiết
```
Agent sẽ đọc file này mỗi 30 phút (có thể cấu hình) và thực thi các tác vụ sử dụng công cụ có sẵn.
#### Tác Vụ Bất Đồng Bộ Với Spawn
Cho tác vụ chạy lâu (tìm kiếm web, gọi API), sử dụng công cụ `spawn` để tạo **subagent**:
```markdown
# Tác Vụ Định Kỳ
```
+166
View File
@@ -0,0 +1,166 @@
# 🐳 Docker và Bắt Đầu Nhanh
> Quay lại [README](../../README.vi.md)
## 🐳 Docker Compose
Bạn cũng có thể chạy PicoClaw bằng Docker Compose mà không cần cài đặt gì trên máy.
```bash
# 1. Clone repo này
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. Lần chạy đầu tiên — tự động tạo docker/data/config.json rồi thoát
docker compose -f docker/docker-compose.yml --profile gateway up
# Container hiển thị "First-run setup complete." và dừng lại.
# 3. Cấu hình API key của bạn
vim docker/data/config.json # Set provider API keys, bot tokens, etc.
# 4. Khởi động
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Người dùng Docker**: Mặc định, Gateway lắng nghe trên `127.0.0.1`, không thể truy cập từ host. Nếu bạn cần truy cập các health endpoint hoặc mở port, hãy đặt `PICOCLAW_GATEWAY_HOST=0.0.0.0` trong môi trường hoặc cập nhật `config.json`.
```bash
# 5. Kiểm tra log
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. Dừng
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Chế Độ Launcher (Web Console)
Image `launcher` bao gồm cả ba binary (`picoclaw`, `picoclaw-launcher`, `picoclaw-launcher-tui`) và khởi động web console mặc định, cung cấp giao diện trình duyệt để cấu hình và chat.
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
Mở http://localhost:18800 trong trình duyệt. Launcher tự động quản lý tiến trình gateway.
> [!WARNING]
> Web console chưa hỗ trợ xác thực. Tránh để lộ ra internet công cộng.
### Chế Độ Agent (One-shot)
```bash
# Đặt câu hỏi
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "What is 2+2?"
# Chế độ tương tác
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### Cập Nhật
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
### 🚀 Bắt Đầu Nhanh
> [!TIP]
> Cấu hình API Key trong `~/.picoclaw/config.json`. Lấy API Key: [Volcengine (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM). Tìm kiếm web là tùy chọn — lấy miễn phí [Tavily API](https://tavily.com) (1000 truy vấn miễn phí/tháng) hoặc [Brave Search API](https://brave.com/search/api) (2000 truy vấn miễn phí/tháng).
**1. Khởi tạo**
```bash
picoclaw onboard
```
**2. Cấu hình** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **Mới**: Định dạng cấu hình `model_list` cho phép thêm provider mà không cần thay đổi code. Xem [Cấu Hình Mô Hình](#cấu-hình-mô-hình-model_list) để biết chi tiết.
> `request_timeout` là tùy chọn và tính bằng giây. Nếu bỏ qua hoặc đặt `<= 0`, PicoClaw sử dụng timeout mặc định (120s).
**3. Lấy API Key**
* **Nhà cung cấp LLM**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **Tìm kiếm Web** (tùy chọn):
* [Brave Search](https://brave.com/search/api) - Trả phí ($5/1000 truy vấn, ~$5-6/tháng)
* [Perplexity](https://www.perplexity.ai) - Tìm kiếm bằng AI với giao diện chat
* [SearXNG](https://github.com/searxng/searxng) - Công cụ tìm kiếm tổng hợp tự host (miễn phí, không cần API key)
* [Tavily](https://tavily.com) - Tối ưu cho AI Agent (1000 yêu cầu/tháng)
* DuckDuckGo - Fallback tích hợp (không cần API key)
> **Lưu ý**: Xem `config.example.json` để có mẫu cấu hình đầy đủ.
**4. Chat**
```bash
picoclaw agent -m "What is 2+2?"
```
Vậy là xong! Bạn có một trợ lý AI hoạt động trong 2 phút.
---
+434
View File
@@ -0,0 +1,434 @@
# 🔌 Nhà Cung Cấp và Cấu Hình Mô Hình
> Quay lại [README](../../README.vi.md)
### Nhà Cung Cấp
> [!NOTE]
> Groq cung cấp chuyển đổi giọng nói miễn phí qua Whisper. Nếu được cấu hình, tin nhắn âm thanh từ bất kỳ kênh nào sẽ được tự động chuyển đổi ở cấp agent.
| Provider | Purpose | Get API Key |
| ------------ | --------------------------------------- | ------------------------------------------------------------ |
| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM(Volcengine direct) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid direct) | [vivgrid.com](https://vivgrid.com) |
| `moonshot` | LLM (Kimi/Moonshot direct) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax direct) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian direct) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope direct) | [modelscope.cn](https://modelscope.cn) |
### Cấu Hình Mô Hình (model_list)
> **Có gì mới?** PicoClaw hiện sử dụng cách tiếp cận cấu hình **tập trung vào mô hình**. Chỉ cần chỉ định định dạng `vendor/model` (ví dụ: `zhipu/glm-4.7`) để thêm provider mới — **không cần thay đổi code!**
Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn provider linh hoạt:
- **Agent khác nhau, provider khác nhau**: Mỗi agent có thể sử dụng provider LLM riêng
- **Fallback mô hình**: Cấu hình mô hình chính và dự phòng cho khả năng phục hồi
- **Cân bằng tải**: Phân phối yêu cầu qua nhiều endpoint
- **Cấu hình tập trung**: Quản lý tất cả provider tại một nơi
#### 📋 Tất Cả Vendor Được Hỗ Trợ
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) |
| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | Your LiteLLM proxy key |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) |
| **VolcEngine (Doubao)** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [Get Key](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [Get Key](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [Get Key](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [Get Token](https://modelscope.cn/my/tokens) |
| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### Cấu Hình Cơ Bản
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### Ví Dụ Theo Vendor
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**VolcEngine (Doubao)**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (với API key)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
}
```
> Chạy `picoclaw auth login --provider anthropic` để dán API token.
**Anthropic Messages API (định dạng native)**
Để truy cập trực tiếp API Anthropic hoặc endpoint tùy chỉnh chỉ hỗ trợ định dạng message native của Anthropic:
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> Sử dụng giao thức `anthropic-messages` khi:
> - Sử dụng proxy bên thứ ba chỉ hỗ trợ endpoint native `/v1/messages` của Anthropic (không tương thích OpenAI `/v1/chat/completions`)
> - Kết nối đến dịch vụ như MiniMax, Synthetic yêu cầu định dạng message native của Anthropic
> - Giao thức `anthropic` hiện tại trả về lỗi 404 (cho thấy endpoint không hỗ trợ định dạng tương thích OpenAI)
>
> **Lưu ý:** Giao thức `anthropic` sử dụng định dạng tương thích OpenAI (`/v1/chat/completions`), trong khi `anthropic-messages` sử dụng định dạng native của Anthropic (`/v1/messages`). Chọn dựa trên định dạng endpoint hỗ trợ.
**Ollama (local)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**Proxy/API Tùy Chỉnh**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
PicoClaw chỉ loại bỏ tiền tố ngoài `litellm/` trước khi gửi yêu cầu, nên alias proxy như `litellm/lite-gpt4` gửi `lite-gpt4`, trong khi `litellm/openai/gpt-4o` gửi `openai/gpt-4o`.
#### Cân Bằng Tải
Cấu hình nhiều endpoint cho cùng tên mô hình — PicoClaw sẽ tự động round-robin giữa chúng:
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### Di Chuyển Từ Cấu Hình Legacy `providers`
Cấu hình `providers` cũ đã **ngừng hỗ trợ** nhưng vẫn được hỗ trợ để tương thích ngược.
**Cấu hình cũ (ngừng hỗ trợ):**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**Cấu hình mới (khuyến nghị):**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
Để xem hướng dẫn di chuyển chi tiết, xem [docs/migration/model-list-migration.md](docs/migration/model-list-migration.md).
### Kiến Trúc Provider
PicoClaw định tuyến provider theo họ giao thức:
- Giao thức tương thích OpenAI: OpenRouter, gateway tương thích OpenAI, Groq, Zhipu, và endpoint kiểu vLLM.
- Giao thức Anthropic: Hành vi API native của Claude.
- Đường dẫn Codex/OAuth: Tuyến xác thực OAuth/token của OpenAI.
Điều này giữ runtime nhẹ trong khi làm cho backend tương thích OpenAI mới chủ yếu là thao tác cấu hình (`api_base` + `api_key`).
<details>
<summary><b>Zhipu</b></summary>
**1. Lấy API key và URL base**
* Lấy [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
**2. Cấu hình**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. Chạy**
```bash
picoclaw agent -m "Hello"
```
</details>
<details>
<summary><b>Ví dụ cấu hình đầy đủ</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 So Sánh API Key
| Service | Pricing | Use Case |
| ---------------- | ------------------------ | ------------------------------------- |
| **OpenRouter** | Free: 200K tokens/month | Multiple models (Claude, GPT-4, etc.) |
| **Volcengine CodingPlan** | ¥9.9/first month | Best for Chinese users, multiple SOTA models (Doubao, DeepSeek, etc.) |
| **Zhipu** | Free: 200K tokens/month | Suitable for Chinese users |
| **Brave Search** | $5/1000 queries | Web search functionality |
| **SearXNG** | Free (self-hosted) | Privacy-focused metasearch (70+ engines) |
| **Groq** | Free tier available | Fast inference (Llama, Mixtral) |
| **Cerebras** | Free tier available | Fast inference (Llama, Qwen, etc.) |
| **LongCat** | Free: up to 5M tokens/day | Fast inference |
| **ModelScope** | Free: 2000 requests/day | Inference (Qwen, GLM, DeepSeek, etc.) |
---
<div align="center">
<img src="assets/logo.jpg" alt="PicoClaw Meme" width="512">
</div>
+61
View File
@@ -0,0 +1,61 @@
# 🔄 Tác Vụ Bất Đồng Bộ và Spawn
> Quay lại [README](../../README.vi.md)
## Tác Vụ Nhanh (phản hồi trực tiếp)
- Báo cáo thời gian hiện tại
## Tác Vụ Dài (sử dụng spawn cho bất đồng bộ)
- Tìm kiếm web tin tức AI và tóm tắt
- Kiểm tra email và báo cáo tin nhắn quan trọng
```
**Hành vi chính:**
| Feature | Description |
| ----------------------- | --------------------------------------------------------- |
| **spawn** | Creates async subagent, doesn't block heartbeat |
| **Independent context** | Subagent has its own context, no session history |
| **message tool** | Subagent communicates with user directly via message tool |
| **Non-blocking** | After spawning, heartbeat continues to next task |
#### Cách Giao Tiếp Subagent Hoạt Động
```
Heartbeat được kích hoạt
Agent đọc HEARTBEAT.md
Cho tác vụ dài: spawn subagent
↓ ↓
Tiếp tục tác vụ tiếp theo Subagent làm việc độc lập
↓ ↓
Tất cả tác vụ hoàn thành Subagent sử dụng công cụ "message"
↓ ↓
Phản hồi HEARTBEAT_OK Người dùng nhận kết quả trực tiếp
```
Subagent có quyền truy cập công cụ (message, web_search, v.v.) và có thể giao tiếp với người dùng độc lập mà không cần qua agent chính.
**Cấu hình:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| Option | Default | Description |
| ---------- | ------- | ---------------------------------- |
| `enabled` | `true` | Enable/disable heartbeat |
| `interval` | `30` | Check interval in minutes (min: 5) |
**Biến môi trường:**
* `PICOCLAW_HEARTBEAT_ENABLED=false` để tắt
* `PICOCLAW_HEARTBEAT_INTERVAL=60` để thay đổi khoảng thời gian
+336
View File
@@ -0,0 +1,336 @@
# 🔧 Cấu Hình Công Cụ
> Quay lại [README](../../README.vi.md)
Cấu hình công cụ của PicoClaw nằm trong trường `tools` của `config.json`.
## Cấu trúc thư mục
```json
{
"tools": {
"web": {
...
},
"mcp": {
...
},
"exec": {
...
},
"cron": {
...
},
"skills": {
...
}
}
}
```
## Công cụ Web
Các công cụ web được sử dụng để tìm kiếm và tải nội dung web.
### Web Fetcher
Cài đặt chung để tải và xử lý nội dung trang web.
| Cấu hình | Kiểu | Mặc định | Mô tả |
|----------------------|--------|---------------|-----------------------------------------------------------------------------------------------|
| `enabled` | bool | true | Bật khả năng tải trang web. |
| `fetch_limit_bytes` | int | 10485760 | Kích thước tối đa của payload trang web cần tải, tính bằng byte (mặc định là 10MB). |
| `format` | string | "plaintext" | Định dạng đầu ra của nội dung đã tải. Tùy chọn: `plaintext` hoặc `markdown` (khuyến nghị). |
### Brave
| Cấu hình | Kiểu | Mặc định | Mô tả |
|----------------|--------|----------|----------------------------|
| `enabled` | bool | false | Bật tìm kiếm Brave |
| `api_key` | string | - | Khóa API Brave Search |
| `max_results` | int | 5 | Số kết quả tối đa |
### DuckDuckGo
| Cấu hình | Kiểu | Mặc định | Mô tả |
|----------------|------|----------|-------------------------------|
| `enabled` | bool | true | Bật tìm kiếm DuckDuckGo |
| `max_results` | int | 5 | Số kết quả tối đa |
### Perplexity
| Cấu hình | Kiểu | Mặc định | Mô tả |
|----------------|--------|----------|-------------------------------|
| `enabled` | bool | false | Bật tìm kiếm Perplexity |
| `api_key` | string | - | Khóa API Perplexity |
| `max_results` | int | 5 | Số kết quả tối đa |
## Công cụ Exec
Công cụ exec được sử dụng để thực thi các lệnh shell.
| Cấu hình | Kiểu | Mặc định | Mô tả |
|--------------------------|-------|----------|------------------------------------------------|
| `enable_deny_patterns` | bool | true | Bật chặn lệnh nguy hiểm mặc định |
| `custom_deny_patterns` | array | [] | Mẫu từ chối tùy chỉnh (biểu thức chính quy) |
### Chức năng
- **`enable_deny_patterns`**: Đặt thành `false` để tắt hoàn toàn các mẫu chặn lệnh nguy hiểm mặc định
- **`custom_deny_patterns`**: Thêm các mẫu regex từ chối tùy chỉnh; các lệnh khớp sẽ bị chặn
### Các mẫu lệnh bị chặn mặc định
Theo mặc định, PicoClaw chặn các lệnh nguy hiểm sau:
- Lệnh xóa: `rm -rf`, `del /f/q`, `rmdir /s`
- Thao tác đĩa: `format`, `mkfs`, `diskpart`, `dd if=`, ghi vào `/dev/sd*`
- Thao tác hệ thống: `shutdown`, `reboot`, `poweroff`
- Thay thế lệnh: `$()`, `${}`, dấu backtick
- Pipe đến shell: `| sh`, `| bash`
- Leo thang đặc quyền: `sudo`, `chmod`, `chown`
- Điều khiển tiến trình: `pkill`, `killall`, `kill -9`
- Thao tác từ xa: `curl | sh`, `wget | sh`, `ssh`
- Quản lý gói: `apt`, `yum`, `dnf`, `npm install -g`, `pip install --user`
- Container: `docker run`, `docker exec`
- Git: `git push`, `git force`
- Khác: `eval`, `source *.sh`
### Hạn chế kiến trúc đã biết
Bộ bảo vệ exec chỉ xác thực lệnh cấp cao nhất được gửi đến PicoClaw. Nó **không** kiểm tra đệ quy các tiến trình con được tạo bởi các công cụ build hoặc script sau khi lệnh đó bắt đầu chạy.
Ví dụ về các quy trình có thể bỏ qua bộ bảo vệ lệnh trực tiếp sau khi lệnh ban đầu được cho phép:
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
Điều này có nghĩa là bộ bảo vệ hữu ích để chặn các lệnh trực tiếp rõ ràng nguy hiểm, nhưng nó **không phải** là sandbox đầy đủ cho các pipeline build chưa được xem xét. Nếu mô hình mối đe dọa của bạn bao gồm mã không đáng tin cậy trong workspace, hãy sử dụng cách ly mạnh hơn như container, VM hoặc quy trình phê duyệt xung quanh các lệnh build và chạy.
### Ví dụ cấu hình
```json
{
"tools": {
"exec": {
"enable_deny_patterns": true,
"custom_deny_patterns": [
"\\brm\\s+-r\\b",
"\\bkillall\\s+python"
]
}
}
}
```
## Công cụ Cron
Công cụ cron được sử dụng để lên lịch các tác vụ định kỳ.
| Cấu hình | Kiểu | Mặc định | Mô tả |
|--------------------------|------|----------|-----------------------------------------------------|
| `exec_timeout_minutes` | int | 5 | Thời gian chờ thực thi tính bằng phút, 0 nghĩa là không giới hạn |
## Công cụ MCP
Công cụ MCP cho phép tích hợp với các máy chủ Model Context Protocol bên ngoài.
### Khám phá công cụ (tải chậm)
Khi kết nối với nhiều máy chủ MCP, việc hiển thị hàng trăm công cụ cùng lúc có thể làm cạn kiệt cửa sổ ngữ cảnh của LLM và tăng chi phí API. Tính năng **Discovery** giải quyết vấn đề này bằng cách giữ các công cụ MCP *ẩn* theo mặc định.
Thay vì tải tất cả các công cụ, LLM được cung cấp một công cụ tìm kiếm nhẹ (sử dụng khớp từ khóa BM25 hoặc Regex). Khi LLM cần một khả năng cụ thể, nó tìm kiếm trong thư viện ẩn. Các công cụ khớp sau đó được tạm thời "mở khóa" và đưa vào ngữ cảnh trong số lượt được cấu hình (`ttl`).
### Cấu hình toàn cục
| Cấu hình | Kiểu | Mặc định | Mô tả |
|-------------|--------|----------|-----------------------------------------------|
| `enabled` | bool | false | Bật tích hợp MCP toàn cục |
| `discovery` | object | `{}` | Cấu hình khám phá công cụ (xem bên dưới) |
| `servers` | object | `{}` | Ánh xạ tên máy chủ đến cấu hình máy chủ |
### Cấu hình Discovery (`discovery`)
| Cấu hình | Kiểu | Mặc định | Mô tả |
|----------------------|------|----------|-----------------------------------------------------------------------------------------------------------------------------------|
| `enabled` | bool | false | Nếu true, các công cụ MCP bị ẩn và được tải theo yêu cầu qua tìm kiếm. Nếu false, tất cả công cụ được tải |
| `ttl` | int | 5 | Số lượt hội thoại mà một công cụ đã khám phá vẫn được mở khóa |
| `max_search_results` | int | 5 | Số công cụ tối đa được trả về cho mỗi truy vấn tìm kiếm |
| `use_bm25` | bool | true | Bật công cụ tìm kiếm ngôn ngữ tự nhiên/từ khóa (`tool_search_tool_bm25`). **Cảnh báo**: tiêu tốn nhiều tài nguyên hơn tìm kiếm regex |
| `use_regex` | bool | false | Bật công cụ tìm kiếm mẫu regex (`tool_search_tool_regex`) |
> **Lưu ý:** Nếu `discovery.enabled` là `true`, bạn **phải** bật ít nhất một công cụ tìm kiếm (`use_bm25` hoặc `use_regex`),
> nếu không ứng dụng sẽ không khởi động được.
### Cấu hình từng máy chủ
| Cấu hình | Kiểu | Bắt buộc | Mô tả |
|------------|--------|----------|--------------------------------------------|
| `enabled` | bool | có | Bật máy chủ MCP này |
| `type` | string | không | Loại truyền tải: `stdio`, `sse`, `http` |
| `command` | string | stdio | Lệnh thực thi cho truyền tải stdio |
| `args` | array | không | Đối số lệnh cho truyền tải stdio |
| `env` | object | không | Biến môi trường cho tiến trình stdio |
| `env_file` | string | không | Đường dẫn đến tệp môi trường cho tiến trình stdio |
| `url` | string | sse/http | URL endpoint cho truyền tải `sse`/`http` |
| `headers` | object | không | Header HTTP cho truyền tải `sse`/`http` |
### Hành vi truyền tải
- Nếu bỏ qua `type`, truyền tải được tự động phát hiện:
- `url` được đặt → `sse`
- `command` được đặt → `stdio`
- `http``sse` đều sử dụng `url` + `headers` tùy chọn.
- `env``env_file` chỉ được áp dụng cho máy chủ `stdio`.
### Ví dụ cấu hình
#### 1) Máy chủ MCP Stdio
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"filesystem": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp"
]
}
}
}
}
}
```
#### 2) Máy chủ MCP từ xa SSE/HTTP
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"remote-mcp": {
"enabled": true,
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
}
}
```
#### 3) Thiết lập MCP quy mô lớn với khám phá công cụ được bật
*Trong ví dụ này, LLM chỉ thấy `tool_search_tool_bm25`. Nó sẽ tìm kiếm và mở khóa động các công cụ Github hoặc Postgres chỉ khi được người dùng yêu cầu.*
```json
{
"tools": {
"mcp": {
"enabled": true,
"discovery": {
"enabled": true,
"ttl": 5,
"max_search_results": 5,
"use_bm25": true,
"use_regex": false
},
"servers": {
"github": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN"
}
},
"postgres": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost/dbname"
]
},
"slack": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-slack"
],
"env": {
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
}
}
}
}
}
}
```
## Công cụ Skills
Công cụ skills cấu hình khám phá và cài đặt kỹ năng thông qua các registry như ClawHub.
### Registry
| Cấu hình | Kiểu | Mặc định | Mô tả |
|------------------------------------|--------|-----------------------|----------------------------------------------|
| `registries.clawhub.enabled` | bool | true | Bật registry ClawHub |
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | URL cơ sở ClawHub |
| `registries.clawhub.auth_token` | string | `""` | Token Bearer tùy chọn để có giới hạn tốc độ cao hơn |
| `registries.clawhub.search_path` | string | `/api/v1/search` | Đường dẫn API tìm kiếm |
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Đường dẫn API Skills |
| `registries.clawhub.download_path` | string | `/api/v1/download` | Đường dẫn API tải xuống |
### Ví dụ cấu hình
```json
{
"tools": {
"skills": {
"registries": {
"clawhub": {
"enabled": true,
"base_url": "https://clawhub.ai",
"auth_token": "",
"search_path": "/api/v1/search",
"skills_path": "/api/v1/skills",
"download_path": "/api/v1/download"
}
}
}
}
}
```
## Biến môi trường
Tất cả các tùy chọn cấu hình có thể được ghi đè qua biến môi trường với định dạng `PICOCLAW_TOOLS_<SECTION>_<KEY>`:
Ví dụ:
- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true`
- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false`
- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10`
- `PICOCLAW_TOOLS_MCP_ENABLED=true`
Lưu ý: Cấu hình kiểu map lồng nhau (ví dụ `tools.mcp.servers.<name>.*`) được cấu hình trong `config.json` thay vì qua biến môi trường.
+45
View File
@@ -0,0 +1,45 @@
# 🐛 Khắc Phục Sự Cố
> Quay lại [README](../../README.vi.md)
## "model ... not found in model_list" hoặc OpenRouter "free is not a valid model ID"
**Triệu chứng:** Bạn thấy một trong các lỗi sau:
- `Error creating provider: model "openrouter/free" not found in model_list`
- OpenRouter trả về 400: `"free is not a valid model ID"`
**Nguyên nhân:** Trường `model` trong mục `model_list` của bạn là giá trị được gửi đến API. Đối với OpenRouter, bạn phải sử dụng ID mô hình **đầy đủ**, không phải dạng viết tắt.
- **Sai:** `"model": "free"` → OpenRouter nhận được `free` và từ chối.
- **Đúng:** `"model": "openrouter/free"` → OpenRouter nhận được `openrouter/free` (định tuyến tự động tầng miễn phí).
**Cách sửa:** Trong `~/.picoclaw/config.json` (hoặc đường dẫn cấu hình của bạn):
1. **agents.defaults.model** phải khớp với một `model_name` trong `model_list` (ví dụ: `"openrouter-free"`).
2. **model** của mục đó phải là ID mô hình OpenRouter hợp lệ, ví dụ:
- `"openrouter/free"` tầng miễn phí tự động
- `"google/gemini-2.0-flash-exp:free"`
- `"meta-llama/llama-3.1-8b-instruct:free"`
Ví dụ:
```json
{
"agents": {
"defaults": {
"model": "openrouter-free"
}
},
"model_list": [
{
"model_name": "openrouter-free",
"model": "openrouter/free",
"api_key": "sk-or-v1-YOUR_OPENROUTER_KEY",
"api_base": "https://openrouter.ai/api/v1"
}
]
}
```
Lấy khóa của bạn tại [OpenRouter Keys](https://openrouter.ai/keys).
+574
View File
@@ -0,0 +1,574 @@
# 💬 聊天应用配置
> 返回 [README](../../README.zh.md)
## 💬 聊天应用集成 (Chat Apps)
PicoClaw 支持多种聊天平台,使您的 Agent 能够连接到任何地方。
> **注意**: 所有 Webhook 类渠道(LINE、WeCom 等)均挂载在同一个 Gateway HTTP 服务器上(`gateway.host`:`gateway.port`,默认 `127.0.0.1:18790`),无需为每个渠道单独配置端口。注意:飞书(Feishu)使用 WebSocket/SDK 模式,不通过该共享 HTTP webhook 服务器接收消息。
### 核心渠道
| 渠道 | 设置难度 | 特性说明 | 文档链接 |
| -------------------- | ----------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| **Telegram** | ⭐ 简单 | 推荐,支持语音转文字,长轮询无需公网 | [查看文档](../channels/telegram/README.zh.md) |
| **Discord** | ⭐ 简单 | Socket Mode,支持群组/私信,Bot 生态成熟 | [查看文档](../channels/discord/README.zh.md) |
| **WhatsApp** | ⭐ 简单 | 原生 (QR 扫码) 或 Bridge URL | [查看文档](../channels/whatsapp/README.zh.md) |
| **Slack** | ⭐ 简单 | **Socket Mode** (无需公网 IP),企业级支持 | [查看文档](../channels/slack/README.zh.md) |
| **Matrix** | ⭐⭐ 中等 | 联邦协议,支持自建 homeserver 与公开服务器 | [查看文档](../channels/matrix/README.zh.md) |
| **QQ** | ⭐⭐ 中等 | 官方机器人 API,适合国内社群 | [查看文档](../channels/qq/README.zh.md) |
| **钉钉 (DingTalk)** | ⭐⭐ 中等 | Stream 模式无需公网,企业办公首选 | [查看文档](../channels/dingtalk/README.zh.md) |
| **LINE** | ⭐⭐⭐ 较难 | 需要 HTTPS Webhook | [查看文档](../channels/line/README.zh.md) |
| **企业微信 (WeCom)** | ⭐⭐⭐ 较难 | 支持群机器人(Webhook)、自建应用(API)和智能机器人(AI Bot) | [Bot 文档](../channels/wecom/wecom_bot/README.zh.md) / [App 文档](../channels/wecom/wecom_app/README.zh.md) / [AI Bot 文档](../channels/wecom/wecom_aibot/README.zh.md) |
| **飞书 (Feishu)** | ⭐⭐⭐ 较难 | 企业级协作,功能丰富 | [查看文档](../channels/feishu/README.zh.md) |
| **IRC** | ⭐⭐ 中等 | 服务器 + TLS 配置 | - |
| **OneBot** | ⭐⭐ 中等 | 兼容 NapCat/Go-CQHTTP,社区生态丰富 | [查看文档](../channels/onebot/README.zh.md) |
| **MaixCam** | ⭐ 简单 | 专为 AI 摄像头设计的硬件集成通道 | [查看文档](../channels/maixcam/README.zh.md) |
| **Pico** | ⭐ 简单 | PicoClaw 原生协议通道 | |
---
<details>
<summary><b>Telegram</b>(推荐)</summary>
**1. 创建 Bot**
* 打开 Telegram,搜索 `@BotFather`
* 发送 `/newbot`,按提示操作
* 复制 Token
**2. 配置**
```json
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
> 通过 Telegram 上的 `@userinfobot` 获取你的 User ID。
**3. 运行**
```bash
picoclaw gateway
```
**4. Telegram 命令菜单(启动时自动注册)**
PicoClaw 使用统一的命令定义来源。启动时会自动将 Telegram 支持的命令(例如 `/start``/help``/show``/list`)注册到 Bot 命令菜单,确保菜单展示与实际行为一致。
Telegram 侧保留的是命令菜单注册能力;通用命令的实际执行统一走 Agent Loop 中的 commands executor。
如果注册因网络或 API 短暂异常失败,不会阻塞 channel 启动;系统会在后台自动重试。
</details>
<details>
<summary><b>Discord</b></summary>
**1. 创建 Bot**
* 前往 <https://discord.com/developers/applications>
* 创建应用 → Bot → 添加 Bot
* 复制 Bot Token
**2. 启用 Intents**
* 在 Bot 设置中启用 **MESSAGE CONTENT INTENT**
* (可选)启用 **SERVER MEMBERS INTENT**(如需基于成员数据的白名单)
**3. 获取 User ID**
* Discord 设置 → 高级 → 启用 **开发者模式**
* 右键点击头像 → **复制用户 ID**
**4. 配置**
```json
{
"channels": {
"discord": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allow_from": ["YOUR_USER_ID"]
}
}
}
```
**5. 邀请 Bot**
* OAuth2 → URL Generator
* Scopes: `bot`
* Bot Permissions: `Send Messages`, `Read Message History`
* 打开生成的邀请链接,将 Bot 添加到服务器
**可选:群组触发模式**
默认情况下 Bot 会回复服务器频道中的所有消息。如需仅在 @提及时回复
```json
{
"channels": {
"discord": {
"group_trigger": { "mention_only": true }
}
}
}
```
也可通过关键词前缀触发(如 `!bot`):
```json
{
"channels": {
"discord": {
"group_trigger": { "prefixes": ["!bot"] }
}
}
}
```
**6. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>WhatsApp</b>(原生 whatsmeow</summary>
PicoClaw 支持两种 WhatsApp 连接方式:
- **原生(推荐):** 进程内使用 [whatsmeow](https://github.com/tulir/whatsmeow),无需独立 Bridge。设置 `"use_native": true` 并留空 `bridge_url`。首次运行时用 WhatsApp 扫描 QR 码(关联设备)。会话存储在工作区下(如 `workspace/whatsapp/`)。原生渠道为**可选**构建,使用 `-tags whatsapp_native` 编译(如 `make build-whatsapp-native``go build -tags whatsapp_native ./cmd/...`)。
- **Bridge** 连接外部 WebSocket Bridge。设置 `bridge_url`(如 `ws://localhost:3001`),保持 `use_native` 为 false。
**配置(原生)**
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"use_native": true,
"session_store_path": "",
"allow_from": []
}
}
}
```
如果 `session_store_path` 为空,会话存储在 `<workspace>/whatsapp/`。运行 `picoclaw gateway`;首次运行时在终端扫描 QR 码(WhatsApp → 关联设备)。
</details>
<details>
<summary><b>Matrix</b></summary>
**1. 准备 Bot 账号**
* 使用你的 homeserver(如 `https://matrix.org` 或自建)
* 创建 Bot 用户并获取 access token
**2. 配置**
```json
{
"channels": {
"matrix": {
"enabled": true,
"homeserver": "https://matrix.org",
"user_id": "@your-bot:matrix.org",
"access_token": "YOUR_MATRIX_ACCESS_TOKEN",
"allow_from": []
}
}
}
```
**3. 运行**
```bash
picoclaw gateway
```
完整选项(`device_id``join_on_invite``group_trigger``placeholder``reasoning_channel_id`)请参考 [Matrix 渠道配置指南](../channels/matrix/README.md)。
</details>
<details>
<summary><b>QQ</b></summary>
**1. 创建 Bot**
- 前往 [QQ 开放平台](https://q.qq.com/#)
- 创建应用 → 获取 **AppID****AppSecret**
**2. 配置**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` 留空表示允许所有用户,或指定 QQ 号限制访问。
**3. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>Slack</b></summary>
**1. 创建 Slack App**
* 前往 [Slack API](https://api.slack.com/apps) 创建应用
* 启用 **Socket Mode**
* 获取 **Bot Token****App-Level Token**
**2. 配置**
```json
{
"channels": {
"slack": {
"enabled": true,
"bot_token": "xoxb-YOUR_BOT_TOKEN",
"app_token": "xapp-YOUR_APP_TOKEN",
"allow_from": []
}
}
}
```
**3. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>IRC</b></summary>
**1. 配置**
```json
{
"channels": {
"irc": {
"enabled": true,
"server": "irc.libera.chat:6697",
"nick": "picoclaw-bot",
"use_tls": true,
"channels_to_join": ["#your-channel"],
"allow_from": []
}
}
}
```
**2. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>钉钉 (DingTalk)</b></summary>
**1. 创建 Bot**
* 前往 [开放平台](https://open.dingtalk.com/)
* 创建内部应用
* 复制 Client ID 和 Client Secret
**2. 配置**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` 留空表示允许所有用户,或指定钉钉用户 ID 限制访问。
**3. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>LINE</b></summary>
**1. 创建 LINE Official Account**
- 前往 [LINE Developers Console](https://developers.line.biz/)
- 创建 Provider → 创建 Messaging API Channel
- 复制 **Channel Secret****Channel Access Token**
**2. 配置**
```json
{
"channels": {
"line": {
"enabled": true,
"channel_secret": "YOUR_CHANNEL_SECRET",
"channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN",
"webhook_path": "/webhook/line",
"allow_from": []
}
}
}
```
> LINE Webhook 挂载在共享 Gateway 服务器上(`gateway.host`:`gateway.port`,默认 `127.0.0.1:18790`)。
**3. 设置 Webhook URL**
LINE 要求 HTTPS Webhook。使用反向代理或隧道:
```bash
# 示例:使用 ngrokGateway 默认端口 18790
ngrok http 18790
```
然后在 LINE Developers Console 中将 Webhook URL 设置为 `https://your-domain/webhook/line` 并启用 **Use webhook**
**4. 运行**
```bash
picoclaw gateway
```
> 在群聊中,Bot 仅在被 @提及时回复。回复会引用原始消息。
</details>
<details>
<summary><b>飞书 (Feishu)</b></summary>
**1. 创建应用**
* 前往 [飞书开放平台](https://open.feishu.cn/)
* 创建企业自建应用
* 获取 **App ID****App Secret**
**2. 配置**
```json
{
"channels": {
"feishu": {
"enabled": true,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
}
}
}
```
**3. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>企业微信 (WeCom)</b></summary>
PicoClaw 支持三种企业微信集成方式:
**方式 1: 群机器人 (Bot)** — 设置简单,支持群聊
**方式 2: 自建应用 (App)** — 功能更多,支持主动推送,仅私聊
**方式 3: 智能机器人 (AI Bot)** — 官方 AI Bot,流式回复,支持群聊和私聊
详细设置请参考 [企业微信 AI Bot 配置指南](../channels/wecom/wecom_aibot/README.zh.md)。
**快速设置 — 群机器人:**
**1. 创建 Bot**
* 企业微信管理后台 → 群聊 → 添加群机器人
* 复制 Webhook URL(格式:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`
**2. 配置**
```json
{
"channels": {
"wecom": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"webhook_path": "/webhook/wecom",
"allow_from": []
}
}
}
```
> WeCom Webhook 挂载在共享 Gateway 服务器上(`gateway.host`:`gateway.port`,默认 `127.0.0.1:18790`)。
**快速设置 — 自建应用:**
**1. 创建应用**
* 企业微信管理后台 → 应用管理 → 创建应用
* 复制 **AgentId****Secret**
* 前往"我的企业"页面,复制 **CorpID**
**2. 配置接收消息**
* 在应用详情中,点击"接收消息" → "设置 API"
* 设置 URL 为 `http://your-server:18790/webhook/wecom-app`
* 生成 **Token****EncodingAESKey**
**3. 配置**
```json
{
"channels": {
"wecom_app": {
"enabled": true,
"corp_id": "wwxxxxxxxxxxxxxxxx",
"corp_secret": "YOUR_CORP_SECRET",
"agent_id": 1000002,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-app",
"allow_from": []
}
}
}
```
**4. 运行**
```bash
picoclaw gateway
```
> **注意**: WeCom Webhook 回调挂载在 Gateway 端口(默认 18790)。使用反向代理配置 HTTPS。
**快速设置 — 智能机器人 (AI Bot):**
**1. 创建 AI Bot**
* 企业微信管理后台 → 应用管理 → AI Bot
* 在 AI Bot 设置中配置回调 URL:`http://your-server:18791/webhook/wecom-aibot`
* 复制 **Token** 并点击"随机生成" **EncodingAESKey**
**2. 配置**
```json
{
"channels": {
"wecom_aibot": {
"enabled": true,
"token": "YOUR_TOKEN",
"encoding_aes_key": "YOUR_43_CHAR_ENCODING_AES_KEY",
"webhook_path": "/webhook/wecom-aibot",
"allow_from": [],
"welcome_message": "你好!有什么可以帮你的?"
}
}
}
```
**3. 运行**
```bash
picoclaw gateway
```
> **注意**: 企业微信 AI Bot 使用流式拉取协议,无回复超时问题。长任务(>30 秒)会自动切换到 `response_url` 推送投递。
</details>
<details>
<summary><b>OneBot</b></summary>
**1. 配置**
兼容 NapCat / Go-CQHTTP 等 OneBot 实现。
```json
{
"channels": {
"onebot": {
"enabled": true,
"allow_from": []
}
}
}
```
**2. 运行**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>MaixCam</b></summary>
专为 Sipeed AI 摄像头硬件设计的集成通道。
```json
{
"channels": {
"maixcam": {
"enabled": true
}
}
}
```
```bash
picoclaw gateway
```
</details>
+258
View File
@@ -0,0 +1,258 @@
# ⚙️ 配置指南
> 返回 [README](../../README.zh.md)
## ⚙️ 配置详解
配置文件路径: `~/.picoclaw/config.json`
### 环境变量
你可以使用环境变量覆盖默认路径。这对于便携安装、容器化部署或将 picoclaw 作为系统服务运行非常有用。这些变量是独立的,控制不同的路径。
| 变量 | 描述 | 默认路径 |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
| `PICOCLAW_CONFIG` | 覆盖配置文件的路径。这直接告诉 picoclaw 加载哪个 `config.json`,忽略所有其他位置。 | `~/.picoclaw/config.json` |
| `PICOCLAW_HOME` | 覆盖 picoclaw 数据根目录。这会更改 `workspace` 和其他数据目录的默认位置。 | `~/.picoclaw` |
**示例:**
```bash
# 使用特定的配置文件运行 picoclaw
# 工作区路径将从该配置文件中读取
PICOCLAW_CONFIG=/etc/picoclaw/production.json picoclaw gateway
# 在 /opt/picoclaw 中存储所有数据运行 picoclaw
# 配置将从默认的 ~/.picoclaw/config.json 加载
# 工作区将在 /opt/picoclaw/workspace 创建
PICOCLAW_HOME=/opt/picoclaw picoclaw agent
# 同时使用两者进行完全自定义设置
PICOCLAW_HOME=/srv/picoclaw PICOCLAW_CONFIG=/srv/picoclaw/main.json picoclaw gateway
```
### 工作区布局 (Workspace Layout)
PicoClaw 将数据存储在您配置的工作区中(默认:`~/.picoclaw/workspace`):
```
~/.picoclaw/workspace/
├── sessions/ # 对话会话和历史
├── memory/ # 长期记忆 (MEMORY.md)
├── state/ # 持久化状态 (最后一次频道等)
├── cron/ # 定时任务数据库
├── skills/ # 自定义技能
├── AGENT.md # Agent 行为指南
├── HEARTBEAT.md # 周期性任务提示词 (每 30 分钟检查一次)
├── IDENTITY.md # Agent 身份设定
├── SOUL.md # Agent 灵魂/性格
└── USER.md # 用户偏好
```
> **提示:** 对 `AGENT.md`、`SOUL.md`、`USER.md` 和 `memory/MEMORY.md` 的修改会通过文件修改时间(mtime)在运行时自动检测。**无需重启 gateway**,Agent 将在下一次请求时自动加载最新内容。
### 技能来源 (Skill Sources)
默认情况下,技能会按以下顺序加载:
1. `~/.picoclaw/workspace/skills`(工作区)
2. `~/.picoclaw/skills`(全局)
3. `<current-working-directory>/skills`(内置)
在高级/测试场景下,可通过以下环境变量覆盖内置技能目录:
```bash
export PICOCLAW_BUILTIN_SKILLS=/path/to/skills
```
### 统一命令执行策略
- 通用斜杠命令通过 `pkg/agent/loop.go` 中的 `commands.Executor` 统一执行。
- Channel 适配器不再在本地消费通用命令;它们只负责把入站文本转发到 bus/agent 路径。Telegram 仍会在启动时自动注册其支持的命令菜单。
- 未注册的斜杠命令(例如 `/foo`)会透传给 LLM 按普通输入处理。
- 已注册但当前 channel 不支持的命令(例如 WhatsApp 上的 `/show`)会返回明确的用户可见错误,并停止后续处理。
### 🔒 安全沙箱 (Security Sandbox)
PicoClaw 默认在沙箱环境中运行。Agent 只能访问配置的工作区内的文件和执行命令。
#### 默认配置
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"restrict_to_workspace": true
}
}
}
```
| 选项 | 默认值 | 描述 |
| ----------------------- | ----------------------- | ----------------------------- |
| `workspace` | `~/.picoclaw/workspace` | Agent 的工作目录 |
| `restrict_to_workspace` | `true` | 限制文件/命令访问在工作区内 |
#### 受保护的工具
`restrict_to_workspace: true` 时,以下工具会被沙箱化:
| 工具 | 功能 | 限制 |
| ------------- | ------------ | ------------------------------ |
| `read_file` | 读取文件 | 仅限工作区内的文件 |
| `write_file` | 写入文件 | 仅限工作区内的文件 |
| `list_dir` | 列出目录 | 仅限工作区内的目录 |
| `edit_file` | 编辑文件 | 仅限工作区内的文件 |
| `append_file` | 追加文件 | 仅限工作区内的文件 |
| `exec` | 执行命令 | 命令路径必须在工作区内 |
#### 额外的 Exec 保护
即使 `restrict_to_workspace: false``exec` 工具也会阻止以下危险命令:
* `rm -rf``del /f``rmdir /s` — 批量删除
* `format``mkfs``diskpart` — 磁盘格式化
* `dd if=` — 磁盘镜像
* 写入 `/dev/sd[a-z]` — 直接磁盘写入
* `shutdown``reboot``poweroff` — 系统关机
* Fork bomb `:(){ :|:& };:`
### 文件访问控制
| 配置键 | 类型 | 默认值 | 描述 |
|--------|------|--------|------|
| `tools.allow_read_paths` | string[] | `[]` | 允许在工作区外读取的额外路径 |
| `tools.allow_write_paths` | string[] | `[]` | 允许在工作区外写入的额外路径 |
### Exec 安全配置
| 配置键 | 类型 | 默认值 | 描述 |
|--------|------|--------|------|
| `tools.exec.allow_remote` | bool | `false` | 允许从远程渠道(Telegram/Discord 等)执行 exec 工具 |
| `tools.exec.enable_deny_patterns` | bool | `true` | 启用危险命令拦截 |
| `tools.exec.custom_deny_patterns` | string[] | `[]` | 自定义阻止的正则表达式模式 |
| `tools.exec.custom_allow_patterns` | string[] | `[]` | 自定义允许的正则表达式模式 |
> **安全提示:** Symlink 保护默认启用——所有文件路径在白名单匹配前都会通过 `filepath.EvalSymlinks` 解析,防止符号链接逃逸攻击。
#### 已知限制:构建工具的子进程
exec 安全守卫仅检查 PicoClaw 直接启动的命令行。它不会递归检查由 `make``go run``cargo``npm run` 或自定义构建脚本等开发工具产生的子进程。
这意味着顶层命令通过初始守卫检查后,仍可以编译或启动其他二进制文件。实际上,应将构建脚本、Makefile、包脚本和生成的二进制文件视为与直接 shell 命令同等级别的可执行代码进行审查。
对于高风险环境:
* 执行前审查构建脚本。
* 对编译并运行的工作流优先使用审批/手动审查。
* 如果需要比内置守卫更强的隔离,请在容器或虚拟机中运行 PicoClaw。
#### 错误示例
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (path outside working dir)}
```
```
[ERROR] tool: Tool execution failed
{tool=exec, error=Command blocked by safety guard (dangerous pattern detected)}
```
#### 禁用限制(安全风险)
如果需要 Agent 访问工作区外的路径:
**方法 1: 配置文件**
```json
{
"agents": {
"defaults": {
"restrict_to_workspace": false
}
}
}
```
**方法 2: 环境变量**
```bash
export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false
```
> ⚠️ **警告**: 禁用此限制将允许 Agent 访问系统上的任何路径。仅在受控环境中谨慎使用。
#### 安全边界一致性
`restrict_to_workspace` 设置在所有执行路径中一致应用:
| 执行路径 | 安全边界 |
| ---------------- | ---------------------------- |
| 主 Agent | `restrict_to_workspace` ✅ |
| 子 Agent / Spawn | 继承相同限制 ✅ |
| 心跳任务 | 继承相同限制 ✅ |
所有路径共享相同的工作区限制——无法通过子 Agent 或定时任务绕过安全边界。
### 心跳 / 周期性任务 (Heartbeat)
PicoClaw 可以自动执行周期性任务。在工作区创建 `HEARTBEAT.md` 文件:
```markdown
# Periodic Tasks
- Check my email for important messages
- Review my calendar for upcoming events
- Check the weather forecast
```
Agent 将每隔 30 分钟(可配置)读取此文件,并使用可用工具执行任务。
#### 使用 Spawn 的异步任务
对于耗时较长的任务(网络搜索、API 调用),使用 `spawn` 工具创建一个 **子 Agent (subagent)**
```markdown
# Periodic Tasks
## Quick Tasks (respond directly)
- Report current time
## Long Tasks (use spawn for async)
- Search the web for AI news and summarize
- Check email and report important messages
```
**关键行为:**
| 特性 | 描述 |
| ---------------- | ---------------------------------------- |
| **spawn** | 创建异步子 Agent,不阻塞主心跳进程 |
| **独立上下文** | 子 Agent 拥有独立上下文,无会话历史 |
| **message tool** | 子 Agent 通过 message 工具直接与用户通信 |
| **非阻塞** | spawn 后,心跳继续处理下一个任务 |
**配置:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| 选项 | 默认值 | 描述 |
| ---------- | ------ | ---------------------------- |
| `enabled` | `true` | 启用/禁用心跳 |
| `interval` | `30` | 检查间隔,单位分钟 (最小: 5) |
**环境变量:**
- `PICOCLAW_HEARTBEAT_ENABLED=false` 禁用
- `PICOCLAW_HEARTBEAT_INTERVAL=60` 更改间隔
+168
View File
@@ -0,0 +1,168 @@
# 🐳 Docker 与快速开始
> 返回 [README](../../README.zh.md)
## 🐳 Docker Compose
您也可以使用 Docker Compose 运行 PicoClaw,无需在本地安装任何环境。
```bash
# 1. 克隆仓库
git clone https://github.com/sipeed/picoclaw.git
cd picoclaw
# 2. 首次运行 — 自动生成 docker/data/config.json 后退出
docker compose -f docker/docker-compose.yml --profile gateway up
# 容器打印 "First-run setup complete." 后自动停止
# 3. 填写 API Key 等配置
vim docker/data/config.json # 设置 provider API key、Bot Token 等
# 4. 正式启动
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
> [!TIP]
> **Docker 用户**: 默认情况下, Gateway 监听 `127.0.0.1`,该端口不会暴露到容器外。如果需要通过端口映射访问健康检查接口,请在环境变量中设置 `PICOCLAW_GATEWAY_HOST=0.0.0.0` 或修改 `config.json`。
```bash
# 5. 查看日志
docker compose -f docker/docker-compose.yml logs -f picoclaw-gateway
# 6. 停止
docker compose -f docker/docker-compose.yml --profile gateway down
```
### Launcher 模式 (Web 控制台)
`launcher` 镜像包含所有三个二进制文件(`picoclaw``picoclaw-launcher``picoclaw-launcher-tui`),默认启动 Web 控制台,提供基于浏览器的配置和聊天界面。
```bash
docker compose -f docker/docker-compose.yml --profile launcher up -d
```
在浏览器中打开 http://localhost:18800。Launcher 会自动管理 Gateway 进程。
> [!WARNING]
> Web 控制台尚不支持身份验证。请勿将其暴露到公网。
### Agent 模式 (一次性运行)
```bash
# 提问
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent -m "2+2 等于几?"
# 交互模式
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
```
### 更新镜像
```bash
docker compose -f docker/docker-compose.yml pull
docker compose -f docker/docker-compose.yml --profile gateway up -d
```
---
## 🚀 快速开始
> [!TIP]
> 在 `~/.picoclaw/config.json` 中设置您的 API Key。获取 API Key: [火山引擎 (CodingPlan)](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) (LLM) · [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu (智谱)](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)。网络搜索是 **可选的** — 获取免费的 [Tavily API](https://tavily.com) (每月 1000 次免费查询) 或 [Brave Search API](https://brave.com/search/api) (每月 2000 次免费查询)。
**1. 初始化 (Initialize)**
```bash
picoclaw onboard
```
**2. 配置 (Configure)** (`~/.picoclaw/config.json`)
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model_name": "gpt-5.4",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_base":"https://ark.cn-beijing.volces.com/api/coding/v3"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "your-api-key",
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
}
],
"tools": {
"web": {
"enabled": true,
"fetch_limit_bytes": 10485760,
"format": "plaintext",
"brave": {
"enabled": false,
"api_key": "YOUR_BRAVE_API_KEY",
"max_results": 5
},
"tavily": {
"enabled": false,
"api_key": "YOUR_TAVILY_API_KEY",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "YOUR_PERPLEXITY_API_KEY",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://your-searxng-instance:8888",
"max_results": 5
}
}
}
}
```
> **新功能**: `model_list` 配置格式支持零代码添加 provider。详见[模型配置](providers.md#模型配置-model_list)章节。
> `request_timeout` 为可选项,单位为秒。若省略或设置为 `<= 0`PicoClaw 使用默认超时(120 秒)。
**3. 获取 API Key**
* **LLM 提供商**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
* **网络搜索** (可选):
* [Brave Search](https://brave.com/search/api) - 付费 ($5/1000 次查询,约 $5-6/月)
* [Perplexity](https://www.perplexity.ai) - AI 驱动的搜索与聊天界面
* [SearXNG](https://github.com/searxng/searxng) - 自建元搜索引擎(免费,无需 API Key)
* [Tavily](https://tavily.com) - 专为 AI Agent 优化 (1000 请求/月)
* DuckDuckGo - 内置回退(无需 API Key
> **注意**: 完整的配置模板请参考 `config.example.json`。
**4. 对话 (Chat)**
```bash
picoclaw agent -m "2+2 等于几?"
```
就是这样!您在 2 分钟内就拥有了一个可工作的 AI 助手。
---
+428
View File
@@ -0,0 +1,428 @@
# 🔌 提供商与模型配置
> 返回 [README](../../README.zh.md)
### 提供商 (Providers)
> [!NOTE]
> Groq 通过 Whisper 提供免费的语音转录。如果配置了 Groq,任意渠道的音频消息都将在 Agent 层面自动转录为文字。
| 提供商 | 用途 | 获取 API Key |
| -------------------- | ---------------------------- | -------------------------------------------------------------------- |
| `gemini` | LLM (Gemini 直连) | [aistudio.google.com](https://aistudio.google.com) |
| `zhipu` | LLM (智谱直连) | [bigmodel.cn](https://bigmodel.cn) |
| `volcengine` | LLM (火山引擎直连) | [volcengine.com](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| `openrouter` | LLM (推荐,可访问所有模型) | [openrouter.ai](https://openrouter.ai) |
| `anthropic` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
| `openai` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
| `deepseek` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
| `cerebras` | LLM (Cerebras 直连) | [cerebras.ai](https://cerebras.ai) |
| `vivgrid` | LLM (Vivgrid 直连) | [vivgrid.com](https://vivgrid.com) |
| `moonshot` | LLM (Kimi/Moonshot 直连) | [platform.moonshot.cn](https://platform.moonshot.cn) |
| `minimax` | LLM (Minimax 直连) | [platform.minimaxi.com](https://platform.minimaxi.com) |
| `avian` | LLM (Avian 直连) | [avian.io](https://avian.io) |
| `mistral` | LLM (Mistral 直连) | [console.mistral.ai](https://console.mistral.ai) |
| `longcat` | LLM (Longcat 直连) | [longcat.ai](https://longcat.ai) |
| `modelscope` | LLM (ModelScope 直连) | [modelscope.cn](https://modelscope.cn) |
### 模型配置 (model_list)
> **新功能!** PicoClaw 现在采用**以模型为中心**的配置方式。只需使用 `厂商/模型` 格式(如 `zhipu/glm-4.7`)即可添加新的 provider——**无需修改任何代码!**
该设计同时支持**多 Agent 场景**,提供灵活的 Provider 选择:
- **不同 Agent 使用不同 Provider**:每个 Agent 可以使用自己的 LLM provider
- **模型回退(Fallback)**:配置主模型和备用模型,提高可靠性
- **负载均衡**:在多个 API 端点之间分配请求
- **集中化配置**:在一个地方管理所有 provider
#### 📋 所有支持的厂商
| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key |
| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- |
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) |
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) |
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) |
| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [获取密钥](https://aistudio.google.com/api-keys) |
| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [获取密钥](https://console.groq.com) |
| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [获取密钥](https://platform.moonshot.cn) |
| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [获取密钥](https://dashscope.console.aliyun.com) |
| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [获取密钥](https://build.nvidia.com) |
| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | 本地(无需密钥) |
| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [获取密钥](https://openrouter.ai/keys) |
| **LiteLLM Proxy** | `litellm/` | `http://localhost:4000/v1` | OpenAI | 你的 LiteLLM 代理密钥 |
| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | 本地 |
| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [获取密钥](https://cerebras.ai) |
| **火山引擎(Doubao** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [获取密钥](https://www.volcengine.com/activity/codingplan?utm_campaign=PicoClaw&utm_content=PicoClaw&utm_medium=devrel&utm_source=OWO&utm_term=PicoClaw) |
| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - |
| **BytePlus** | `byteplus/` | `https://ark.ap-southeast.bytepluses.com/api/v3` | OpenAI | [获取密钥](https://www.byteplus.com) |
| **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [获取密钥](https://vivgrid.com) |
| **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [获取密钥](https://longcat.chat/platform) |
| **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [获取 Token](https://modelscope.cn/my/tokens) |
| **Antigravity** | `antigravity/` | Google Cloud | 自定义 | 仅 OAuth |
| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - |
#### 基础配置示例
```json
{
"model_list": [
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
}
],
"agents": {
"defaults": {
"model": "gpt-5.4"
}
}
}
```
#### 各厂商配置示例
**OpenAI**
```json
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
}
```
**火山引擎(Doubao**
```json
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
}
```
**智谱 AI (GLM)**
```json
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
```
**DeepSeek**
```json
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
}
```
**Anthropic (使用 OAuth)**
```json
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"auth_method": "oauth"
}
```
> 运行 `picoclaw auth login --provider anthropic` 来设置 OAuth 凭证。
**Anthropic Messages API(原生格式)**
用于直接访问 Anthropic API 或仅支持 Anthropic 原生消息格式的自定义端点:
```json
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_base": "https://api.anthropic.com"
}
```
> 使用 `anthropic-messages` 协议的场景:
> - 使用仅支持 Anthropic 原生 `/v1/messages` 端点的第三方代理(不支持 OpenAI 兼容的 `/v1/chat/completions`
> - 连接到 MiniMax、Synthetic 等需要 Anthropic 原生消息格式的服务
> - 现有的 `anthropic` 协议返回 404 错误(说明端点不支持 OpenAI 兼容格式)
>
> **注意:** `anthropic` 协议使用 OpenAI 兼容格式(`/v1/chat/completions`),而 `anthropic-messages` 使用 Anthropic 原生格式(`/v1/messages`)。请根据端点支持的格式选择。
**Ollama (本地)**
```json
{
"model_name": "llama3",
"model": "ollama/llama3"
}
```
**自定义代理/API**
```json
{
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"request_timeout": 300
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
}
```
PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/lite-gpt4` 会发送 `lite-gpt4`,而 `litellm/openai/gpt-4o` 会发送 `openai/gpt-4o`
#### 负载均衡
为同一个模型名称配置多个端点——PicoClaw 会自动在它们之间轮询:
```json
{
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
}
]
}
```
#### 从旧的 `providers` 配置迁移
旧的 `providers` 配置格式**已弃用**,但为向后兼容仍支持。
**旧配置(已弃用):**
```json
{
"providers": {
"zhipu": {
"api_key": "your-key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
},
"agents": {
"defaults": {
"provider": "zhipu",
"model": "glm-4.7"
}
}
}
```
**新配置(推荐):**
```json
{
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
}
],
"agents": {
"defaults": {
"model": "glm-4.7"
}
}
}
```
详细的迁移指南请参考 [docs/migration/model-list-migration.md](../migration/model-list-migration.md)。
### Provider 架构
PicoClaw 按协议族路由 Provider
- OpenAI 兼容协议:OpenRouter、OpenAI 兼容网关、Groq、智谱、vLLM 风格端点。
- Anthropic 协议:Claude 原生 API 行为。
- Codex/OAuth 路径:OpenAI OAuth/Token 认证路由。
这使得运行时保持轻量,同时让新的 OpenAI 兼容后端基本只需配置操作(`api_base` + `api_key`)。
<details>
<summary><b>智谱 (Zhipu) 配置示例</b></summary>
**1. 获取 API key 和 base URL**
- 获取 [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
**2. 配置**
```json
{
"agents": {
"defaults": {
"workspace": "~/.picoclaw/workspace",
"model": "glm-4.7",
"max_tokens": 8192,
"temperature": 0.7,
"max_tool_iterations": 20
}
},
"providers": {
"zhipu": {
"api_key": "Your API Key",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
}
}
}
```
**3. 运行**
```bash
picoclaw agent -m "你好"
```
</details>
<details>
<summary><b>完整配置示例</b></summary>
```json
{
"agents": {
"defaults": {
"model": "anthropic/claude-opus-4-5"
}
},
"session": {
"dm_scope": "per-channel-peer",
"backlog_limit": 20
},
"providers": {
"openrouter": {
"api_key": "sk-or-v1-xxx"
},
"groq": {
"api_key": "gsk_xxx"
}
},
"channels": {
"telegram": {
"enabled": true,
"token": "123456:ABC...",
"allow_from": ["123456789"]
},
"discord": {
"enabled": true,
"token": "",
"allow_from": [""]
},
"whatsapp": {
"enabled": false,
"bridge_url": "ws://localhost:3001",
"use_native": false,
"session_store_path": "",
"allow_from": []
},
"feishu": {
"enabled": false,
"app_id": "cli_xxx",
"app_secret": "xxx",
"encrypt_key": "",
"verification_token": "",
"allow_from": []
},
"qq": {
"enabled": false,
"app_id": "",
"app_secret": "",
"allow_from": []
}
},
"tools": {
"web": {
"brave": {
"enabled": false,
"api_key": "BSA...",
"max_results": 5
},
"duckduckgo": {
"enabled": true,
"max_results": 5
},
"perplexity": {
"enabled": false,
"api_key": "",
"max_results": 5
},
"searxng": {
"enabled": false,
"base_url": "http://localhost:8888",
"max_results": 5
}
},
"cron": {
"exec_timeout_minutes": 5
}
},
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
</details>
---
## 📝 API Key 对比
| 服务 | 价格 | 适用场景 |
| --- | --- | --- |
| **OpenRouter** | 免费: 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) |
| **火山引擎 CodingPlan** | ¥9.9/首月 | 最适合国内用户,多种 SOTA 模型(豆包、DeepSeek 等) |
| **智谱 (Zhipu)** | 免费: 200K tokens/月 | 适合中国用户 |
| **Brave Search** | $5/1000 次查询 | 网络搜索功能 |
| **SearXNG** | 免费(自建) | 隐私优先的元搜索引擎(70+ 搜索引擎) |
| **Groq** | 免费额度可用 | 极速推理 (Llama, Mixtral) |
| **Cerebras** | 免费额度可用 | 极速推理 (Llama, Qwen 等) |
| **LongCat** | 免费: 最多 5M tokens/天 | 极速推理 |
| **ModelScope (魔搭)** | 免费: 2000 次请求/天 | 推理 (Qwen, GLM, DeepSeek 等) |
+68
View File
@@ -0,0 +1,68 @@
# 🔄 异步任务与 Spawn
> 返回 [README](../../README.zh.md)
### 使用 Spawn 的异步任务
对于耗时较长的任务(网络搜索、API 调用),使用 `spawn` 工具创建一个 **子 Agent (subagent)**
```markdown
# Periodic Tasks
## Quick Tasks (respond directly)
- Report current time
## Long Tasks (use spawn for async)
- Search the web for AI news and summarize
- Check email and report important messages
```
**关键行为:**
| 特性 | 描述 |
| ---------------- | ---------------------------------------- |
| **spawn** | 创建异步子 Agent,不阻塞主心跳进程 |
| **独立上下文** | 子 Agent 拥有独立上下文,无会话历史 |
| **message tool** | 子 Agent 通过 message 工具直接与用户通信 |
| **非阻塞** | spawn 后,心跳继续处理下一个任务 |
#### 子 Agent 通信原理
```
心跳触发 (Heartbeat triggers)
Agent 读取 HEARTBEAT.md
对于长任务: spawn 子 Agent
↓ ↓
继续下一个任务 子 Agent 独立工作
↓ ↓
所有任务完成 子 Agent 使用 "message" 工具
↓ ↓
响应 HEARTBEAT_OK 用户直接收到结果
```
子 Agent 可以访问工具(message, web_search 等),并且无需通过主 Agent 即可独立与用户通信。
**配置:**
```json
{
"heartbeat": {
"enabled": true,
"interval": 30
}
}
```
| 选项 | 默认值 | 描述 |
| ---------- | ------ | ---------------------------- |
| `enabled` | `true` | 启用/禁用心跳 |
| `interval` | `30` | 检查间隔,单位分钟 (最小: 5) |
**环境变量:**
- `PICOCLAW_HEARTBEAT_ENABLED=false` 禁用
- `PICOCLAW_HEARTBEAT_INTERVAL=60` 更改间隔
+336
View File
@@ -0,0 +1,336 @@
# 🔧 工具配置
> 返回 [README](../../README.zh.md)
PicoClaw 的工具配置位于 `config.json``tools` 字段中。
## 目录结构
```json
{
"tools": {
"web": {
...
},
"mcp": {
...
},
"exec": {
...
},
"cron": {
...
},
"skills": {
...
}
}
}
```
## Web 工具
Web 工具用于网页搜索和抓取。
### Web Fetcher
用于抓取和处理网页内容的通用设置。
| 配置项 | 类型 | 默认值 | 描述 |
|---------------------|--------|---------------|----------------------------------------------------------------------------------------|
| `enabled` | bool | true | 启用网页抓取功能。 |
| `fetch_limit_bytes` | int | 10485760 | 抓取网页负载的最大大小,单位为字节(默认 10MB)。 |
| `format` | string | "plaintext" | 抓取内容的输出格式。选项:`plaintext``markdown`(推荐)。 |
### Brave
| 配置项 | 类型 | 默认值 | 描述 |
|---------------|--------|--------|--------------------|
| `enabled` | bool | false | 启用 Brave 搜索 |
| `api_key` | string | - | Brave Search API 密钥 |
| `max_results` | int | 5 | 最大结果数 |
### DuckDuckGo
| 配置项 | 类型 | 默认值 | 描述 |
|---------------|------|--------|-----------------------|
| `enabled` | bool | true | 启用 DuckDuckGo 搜索 |
| `max_results` | int | 5 | 最大结果数 |
### Perplexity
| 配置项 | 类型 | 默认值 | 描述 |
|---------------|--------|--------|-----------------------|
| `enabled` | bool | false | 启用 Perplexity 搜索 |
| `api_key` | string | - | Perplexity API 密钥 |
| `max_results` | int | 5 | 最大结果数 |
## Exec 工具
Exec 工具用于执行 shell 命令。
| 配置项 | 类型 | 默认值 | 描述 |
|------------------------|-------|--------|--------------------------------|
| `enable_deny_patterns` | bool | true | 启用默认的危险命令拦截 |
| `custom_deny_patterns` | array | [] | 自定义拒绝模式(正则表达式) |
### 功能说明
- **`enable_deny_patterns`**:设为 `false` 可完全禁用默认的危险命令拦截模式
- **`custom_deny_patterns`**:添加自定义拒绝正则模式;匹配的命令将被拦截
### 默认拦截的命令模式
默认情况下,PicoClaw 会拦截以下危险命令:
- 删除命令:`rm -rf``del /f/q``rmdir /s`
- 磁盘操作:`format``mkfs``diskpart``dd if=`、写入 `/dev/sd*`
- 系统操作:`shutdown``reboot``poweroff`
- 命令替换:`$()``${}`、反引号
- 管道到 shell`| sh``| bash`
- 权限提升:`sudo``chmod``chown`
- 进程控制:`pkill``killall``kill -9`
- 远程操作:`curl | sh``wget | sh``ssh`
- 包管理:`apt``yum``dnf``npm install -g``pip install --user`
- 容器:`docker run``docker exec`
- Git`git push``git force`
- 其他:`eval``source *.sh`
### 已知架构限制
exec 守卫仅验证发送给 PicoClaw 的顶层命令。它**不会**递归检查该命令启动后由构建工具或脚本生成的子进程。
以下工作流在初始命令被允许后可以绕过直接命令守卫:
- `make run`
- `go run ./cmd/...`
- `cargo run`
- `npm run build`
这意味着守卫对于拦截明显危险的直接命令很有用,但它**不是**未审查构建管道的完整沙箱。如果你的威胁模型包括工作区中的不受信任代码,请使用更强的隔离措施,如容器、虚拟机或围绕构建和运行命令的审批流程。
### 配置示例
```json
{
"tools": {
"exec": {
"enable_deny_patterns": true,
"custom_deny_patterns": [
"\\brm\\s+-r\\b",
"\\bkillall\\s+python"
]
}
}
}
```
## Cron 工具
Cron 工具用于调度周期性任务。
| 配置项 | 类型 | 默认值 | 描述 |
|------------------------|------|--------|-------------------------------------|
| `exec_timeout_minutes` | int | 5 | 执行超时时间(分钟),0 表示无限制 |
## MCP 工具
MCP 工具支持与外部 Model Context Protocol 服务器集成。
### 工具发现(延迟加载)
当连接多个 MCP 服务器时,同时暴露数百个工具可能会耗尽 LLM 的上下文窗口并增加 API 成本。**Discovery** 功能通过默认*隐藏* MCP 工具来解决此问题。
LLM 不会加载所有工具,而是获得一个轻量级搜索工具(使用 BM25 关键词匹配或正则表达式)。当 LLM 需要特定功能时,它会搜索隐藏的工具库。匹配的工具随后被临时"解锁"并注入上下文中,持续配置的轮数(`ttl`)。
### 全局配置
| 配置项 | 类型 | 默认值 | 描述 |
|-------------|--------|--------|--------------------------------------|
| `enabled` | bool | false | 全局启用 MCP 集成 |
| `discovery` | object | `{}` | 工具发现配置(见下文) |
| `servers` | object | `{}` | 服务器名称到服务器配置的映射 |
### Discovery 配置(`discovery`
| 配置项 | 类型 | 默认值 | 描述 |
|----------------------|------|--------|---------------------------------------------------------------------------------------------------------------|
| `enabled` | bool | false | 如果为 true,MCP 工具将被隐藏并按需通过搜索加载。如果为 false,所有工具都会被加载 |
| `ttl` | int | 5 | 已发现工具保持解锁状态的对话轮数 |
| `max_search_results` | int | 5 | 每次搜索查询返回的最大工具数 |
| `use_bm25` | bool | true | 启用自然语言/关键词搜索工具(`tool_search_tool_bm25`)。**警告**:比正则搜索消耗更多资源 |
| `use_regex` | bool | false | 启用正则模式搜索工具(`tool_search_tool_regex`) |
> **注意:** 如果 `discovery.enabled` 为 `true`,你**必须**启用至少一个搜索引擎(`use_bm25` 或 `use_regex`),
> 否则应用程序将无法启动。
### 单服务器配置
| 配置项 | 类型 | 必需 | 描述 |
|------------|--------|----------|------------------------------------|
| `enabled` | bool | 是 | 启用此 MCP 服务器 |
| `type` | string | 否 | 传输类型:`stdio``sse``http` |
| `command` | string | stdio | stdio 传输的可执行命令 |
| `args` | array | 否 | stdio 传输的命令参数 |
| `env` | object | 否 | stdio 进程的环境变量 |
| `env_file` | string | 否 | stdio 进程的环境文件路径 |
| `url` | string | sse/http | `sse`/`http` 传输的端点 URL |
| `headers` | object | 否 | `sse`/`http` 传输的 HTTP 头 |
### 传输行为
- 如果省略 `type`,传输方式将自动检测:
- 设置了 `url``sse`
- 设置了 `command``stdio`
- `http``sse` 都使用 `url` + 可选的 `headers`
- `env``env_file` 仅应用于 `stdio` 服务器。
### 配置示例
#### 1) Stdio MCP 服务器
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"filesystem": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/tmp"
]
}
}
}
}
}
```
#### 2) 远程 SSE/HTTP MCP 服务器
```json
{
"tools": {
"mcp": {
"enabled": true,
"servers": {
"remote-mcp": {
"enabled": true,
"type": "sse",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
}
}
```
#### 3) 启用工具发现的大规模 MCP 设置
*在此示例中,LLM 只会看到 `tool_search_tool_bm25`。它将仅在用户请求时动态搜索并解锁 Github 或 Postgres 工具。*
```json
{
"tools": {
"mcp": {
"enabled": true,
"discovery": {
"enabled": true,
"ttl": 5,
"max_search_results": 5,
"use_bm25": true,
"use_regex": false
},
"servers": {
"github": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN"
}
},
"postgres": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost/dbname"
]
},
"slack": {
"enabled": true,
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-slack"
],
"env": {
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
}
}
}
}
}
}
```
## Skills 工具
Skills 工具配置通过 ClawHub 等注册表进行技能发现和安装。
### 注册表
| 配置项 | 类型 | 默认值 | 描述 |
|------------------------------------|--------|----------------------|--------------------------------------|
| `registries.clawhub.enabled` | bool | true | 启用 ClawHub 注册表 |
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | ClawHub 基础 URL |
| `registries.clawhub.auth_token` | string | `""` | 可选的 Bearer 令牌,用于更高速率限制 |
| `registries.clawhub.search_path` | string | `/api/v1/search` | 搜索 API 路径 |
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Skills API 路径 |
| `registries.clawhub.download_path` | string | `/api/v1/download` | 下载 API 路径 |
### 配置示例
```json
{
"tools": {
"skills": {
"registries": {
"clawhub": {
"enabled": true,
"base_url": "https://clawhub.ai",
"auth_token": "",
"search_path": "/api/v1/search",
"skills_path": "/api/v1/skills",
"download_path": "/api/v1/download"
}
}
}
}
}
```
## 环境变量
所有配置选项都可以通过格式为 `PICOCLAW_TOOLS_<SECTION>_<KEY>` 的环境变量覆盖:
例如:
- `PICOCLAW_TOOLS_WEB_BRAVE_ENABLED=true`
- `PICOCLAW_TOOLS_EXEC_ENABLE_DENY_PATTERNS=false`
- `PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES=10`
- `PICOCLAW_TOOLS_MCP_ENABLED=true`
注意:嵌套的映射式配置(例如 `tools.mcp.servers.<name>.*`)在 `config.json` 中配置,而非通过环境变量。
+45
View File
@@ -0,0 +1,45 @@
# 🐛 疑难解答
> 返回 [README](../../README.zh.md)
## "model ... not found in model_list" 或 OpenRouter "free is not a valid model ID"
**症状:** 你看到以下任一错误:
- `Error creating provider: model "openrouter/free" not found in model_list`
- OpenRouter 返回 400`"free is not a valid model ID"`
**原因:** `model_list` 条目中的 `model` 字段是发送给 API 的内容。对于 OpenRouter,你必须使用**完整的**模型 ID,而不是简写。
- **错误:** `"model": "free"` → OpenRouter 收到 `free` 并拒绝。
- **正确:** `"model": "openrouter/free"` → OpenRouter 收到 `openrouter/free`(自动免费层路由)。
**修复方法:**`~/.picoclaw/config.json`(或你的配置路径)中:
1. **agents.defaults.model** 必须匹配 `model_list` 中的某个 `model_name`(例如 `"openrouter-free"`)。
2. 该条目的 **model** 必须是有效的 OpenRouter 模型 ID,例如:
- `"openrouter/free"` 自动免费层
- `"google/gemini-2.0-flash-exp:free"`
- `"meta-llama/llama-3.1-8b-instruct:free"`
示例片段:
```json
{
"agents": {
"defaults": {
"model": "openrouter-free"
}
},
"model_list": [
{
"model_name": "openrouter-free",
"model": "openrouter/free",
"api_key": "sk-or-v1-YOUR_OPENROUTER_KEY",
"api_base": "https://openrouter.ai/api/v1"
}
]
}
```
在 [OpenRouter Keys](https://openrouter.ai/keys) 获取你的密钥。