fix: correct docs misalignment across translations and guides
- Fix DingTalk section referencing "QQ numbers" instead of DingTalk user IDs - Fix Anthropic example showing OAuth when code uses paste-token auth - Replace OpenClaw references in ANTIGRAVITY_AUTH.md with actual PicoClaw paths and Go patterns - Fix auth file path from auth-profiles.json to auth.json in ANTIGRAVITY_USAGE.md - Remove non-existent approval tool from tools_configuration.md, add skills tool docs - Update Quick Start configs in fr/pt-br/vi/ja translations to use model_list format - Fix allowFrom camelCase to allow_from in fr/pt-br translations - Fix camelCase config keys in ja translation - Update zh/ja web search config from old flat format to brave/duckduckgo - Fix broken ClawdChat link and trailing commas in zh translation - Add missing qwen/cerebras providers to fr/pt-br/vi translation tables - Add missing protocol prefixes to migration guide - Fix typos in community roadmap
This commit is contained in:
parent
1ef33c90ed
commit
838a69085b
12 changed files with 281 additions and 440 deletions
31
README.fr.md
31
README.fr.md
|
|
@ -212,19 +212,24 @@ picoclaw onboard
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"model_list": [
|
||||||
|
{
|
||||||
|
"model_name": "gpt4",
|
||||||
|
"model": "openai/gpt-5.2",
|
||||||
|
"api_key": "sk-your-openai-key",
|
||||||
|
"api_base": "https://api.openai.com/v1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"agents": {
|
"agents": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"workspace": "~/.picoclaw/workspace",
|
"model": "gpt4"
|
||||||
"model": "glm-4.7",
|
|
||||||
"max_tokens": 8192,
|
|
||||||
"temperature": 0.7,
|
|
||||||
"max_tool_iterations": 20
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"providers": {
|
"channels": {
|
||||||
"openrouter": {
|
"telegram": {
|
||||||
"api_key": "xxx",
|
"enabled": true,
|
||||||
"api_base": "https://openrouter.ai/api/v1"
|
"token": "VOTRE_TOKEN_BOT",
|
||||||
|
"allow_from": ["VOTRE_USER_ID"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
|
@ -290,7 +295,7 @@ Discutez avec votre PicoClaw via Telegram, Discord, DingTalk, LINE ou WeCom
|
||||||
"telegram": {
|
"telegram": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "VOTRE_TOKEN_BOT",
|
"token": "VOTRE_TOKEN_BOT",
|
||||||
"allowFrom": ["VOTRE_USER_ID"]
|
"allow_from": ["VOTRE_USER_ID"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +338,7 @@ picoclaw gateway
|
||||||
"discord": {
|
"discord": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "VOTRE_TOKEN_BOT",
|
"token": "VOTRE_TOKEN_BOT",
|
||||||
"allowFrom": ["VOTRE_USER_ID"]
|
"allow_from": ["VOTRE_USER_ID"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -765,6 +770,8 @@ Le sous-agent a accès aux outils (message, web_search, etc.) et peut communique
|
||||||
| `anthropic` (À tester) | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic` (À tester) | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai` (À tester) | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
| `openai` (À tester) | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
||||||
| `deepseek` (À tester) | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek` (À tester) | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
|
| `qwen` | LLM (Alibaba Qwen) | [dashscope.aliyuncs.com](https://dashscope.aliyuncs.com/compatible-mode/v1) |
|
||||||
|
| `cerebras` | LLM (Cerebras) | [cerebras.ai](https://api.cerebras.ai/v1) |
|
||||||
| `groq` | LLM + **Transcription vocale** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **Transcription vocale** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
@ -1087,7 +1094,7 @@ Ajoutez la clé dans `~/.picoclaw/config.json` si vous utilisez Brave :
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"brave": {
|
"brave": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"api_key": "VOTRE_CLE_API_BRAVE",
|
"api_key": "VOTRE_CLE_API_BRAVE",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
},
|
},
|
||||||
|
|
|
||||||
61
README.ja.md
61
README.ja.md
|
|
@ -174,35 +174,25 @@ picoclaw onboard
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"model_list": [
|
||||||
|
{
|
||||||
|
"model_name": "gpt4",
|
||||||
|
"model": "openai/gpt-5.2",
|
||||||
|
"api_key": "sk-your-openai-key",
|
||||||
|
"api_base": "https://api.openai.com/v1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"agents": {
|
"agents": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"workspace": "~/.picoclaw/workspace",
|
"model": "gpt4"
|
||||||
"model": "glm-4.7",
|
|
||||||
"max_tokens": 8192,
|
|
||||||
"temperature": 0.7,
|
|
||||||
"max_tool_iterations": 20
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"providers": {
|
"channels": {
|
||||||
"openrouter": {
|
"telegram": {
|
||||||
"api_key": "xxx",
|
|
||||||
"api_base": "https://openrouter.ai/api/v1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"web": {
|
|
||||||
"search": {
|
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
|
||||||
"max_results": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cron": {
|
|
||||||
"exec_timeout_minutes": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"heartbeat": {
|
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"interval": 30
|
"token": "YOUR_TELEGRAM_BOT_TOKEN",
|
||||||
|
"allow_from": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -214,7 +204,7 @@ picoclaw onboard
|
||||||
|
|
||||||
> **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。
|
> **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。
|
||||||
|
|
||||||
**3. チャット**
|
**4. チャット**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
picoclaw agent -m "What is 2+2?"
|
picoclaw agent -m "What is 2+2?"
|
||||||
|
|
@ -764,10 +754,10 @@ HEARTBEAT_OK 応答 ユーザーが直接結果を受け取る
|
||||||
},
|
},
|
||||||
"providers": {
|
"providers": {
|
||||||
"openrouter": {
|
"openrouter": {
|
||||||
"apiKey": "sk-or-v1-xxx"
|
"api_key": "sk-or-v1-xxx"
|
||||||
},
|
},
|
||||||
"groq": {
|
"groq": {
|
||||||
"apiKey": "gsk_xxx"
|
"api_key": "gsk_xxx"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"channels": {
|
"channels": {
|
||||||
|
|
@ -786,17 +776,17 @@ HEARTBEAT_OK 応答 ユーザーが直接結果を受け取る
|
||||||
},
|
},
|
||||||
"feishu": {
|
"feishu": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"appId": "cli_xxx",
|
"app_id": "cli_xxx",
|
||||||
"appSecret": "xxx",
|
"app_secret": "xxx",
|
||||||
"encryptKey": "",
|
"encrypt_key": "",
|
||||||
"verificationToken": "",
|
"verification_token": "",
|
||||||
"allow_from": []
|
"allow_from": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"search": {
|
||||||
"apiKey": "BSA..."
|
"api_key": "BSA..."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cron": {
|
"cron": {
|
||||||
|
|
@ -1001,9 +991,14 @@ Web 検索を有効にするには:
|
||||||
{
|
{
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
|
"enabled": true,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ picoclaw gateway
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> Set `allow_from` to empty to allow all users, or specify QQ numbers to restrict access.
|
> Set `allow_from` to empty to allow all users, or specify DingTalk user IDs to restrict access.
|
||||||
|
|
||||||
**3. Run**
|
**3. Run**
|
||||||
|
|
||||||
|
|
@ -867,15 +867,15 @@ This design also enables **multi-agent support** with flexible provider selectio
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Anthropic (with OAuth)**
|
**Anthropic (with API key)**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"model_name": "claude-sonnet-4.6",
|
"model_name": "claude-sonnet-4.6",
|
||||||
"model": "anthropic/claude-sonnet-4.6",
|
"model": "anthropic/claude-sonnet-4.6",
|
||||||
"auth_method": "oauth"
|
"api_key": "sk-ant-your-key"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
> Run `picoclaw auth login --provider anthropic` to set up OAuth credentials.
|
> Run `picoclaw auth login --provider anthropic` to paste your API token.
|
||||||
|
|
||||||
**Ollama (local)**
|
**Ollama (local)**
|
||||||
```json
|
```json
|
||||||
|
|
|
||||||
|
|
@ -213,19 +213,17 @@ picoclaw onboard
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"model_list": [
|
||||||
|
{
|
||||||
|
"model_name": "gpt4",
|
||||||
|
"model": "openai/gpt-5.2",
|
||||||
|
"api_key": "sk-your-openai-key",
|
||||||
|
"api_base": "https://api.openai.com/v1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"agents": {
|
"agents": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"workspace": "~/.picoclaw/workspace",
|
"model": "gpt4"
|
||||||
"model": "glm-4.7",
|
|
||||||
"max_tokens": 8192,
|
|
||||||
"temperature": 0.7,
|
|
||||||
"max_tool_iterations": 20
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"providers": {
|
|
||||||
"openrouter": {
|
|
||||||
"api_key": "xxx",
|
|
||||||
"api_base": "https://openrouter.ai/api/v1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
|
@ -291,7 +289,7 @@ Converse com seu PicoClaw via Telegram, Discord, DingTalk, LINE ou WeCom.
|
||||||
"telegram": {
|
"telegram": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "YOUR_BOT_TOKEN",
|
"token": "YOUR_BOT_TOKEN",
|
||||||
"allowFrom": ["YOUR_USER_ID"]
|
"allow_from": ["YOUR_USER_ID"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -334,7 +332,7 @@ picoclaw gateway
|
||||||
"discord": {
|
"discord": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "YOUR_BOT_TOKEN",
|
"token": "YOUR_BOT_TOKEN",
|
||||||
"allowFrom": ["YOUR_USER_ID"]
|
"allow_from": ["YOUR_USER_ID"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -766,6 +764,8 @@ O subagente tem acesso às ferramentas (message, web_search, etc.) e pode se com
|
||||||
| `anthropic` (Em teste) | LLM (Claude direto) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic` (Em teste) | LLM (Claude direto) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai` (Em teste) | LLM (GPT direto) | [platform.openai.com](https://platform.openai.com) |
|
| `openai` (Em teste) | LLM (GPT direto) | [platform.openai.com](https://platform.openai.com) |
|
||||||
| `deepseek` (Em teste) | LLM (DeepSeek direto) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek` (Em teste) | LLM (DeepSeek direto) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
|
| `qwen` | Alibaba Qwen | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
|
| `cerebras` | Cerebras | [cerebras.ai](https://cerebras.ai) |
|
||||||
| `groq` | LLM + **Transcrição de voz** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **Transcrição de voz** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
@ -1088,7 +1088,7 @@ Adicione a key em `~/.picoclaw/config.json` se usar o Brave:
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"brave": {
|
"brave": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
},
|
},
|
||||||
|
|
@ -1119,3 +1119,4 @@ Isso acontece quando outra instância do bot está em execução. Certifique-se
|
||||||
| **Zhipu** | 200K tokens/mês | Melhor para usuários chineses |
|
| **Zhipu** | 200K tokens/mês | Melhor para usuários chineses |
|
||||||
| **Brave Search** | 2000 consultas/mês | Funcionalidade de busca web |
|
| **Brave Search** | 2000 consultas/mês | Funcionalidade de busca web |
|
||||||
| **Groq** | Plano gratuito disponível | Inferência ultra-rápida (Llama, Mixtral) |
|
| **Groq** | Plano gratuito disponível | Inferência ultra-rápida (Llama, Mixtral) |
|
||||||
|
| **Cerebras** | Plano gratuito disponível | Inferência ultra-rápida (Llama 3.3 70B) |
|
||||||
|
|
|
||||||
38
README.vi.md
38
README.vi.md
|
|
@ -193,32 +193,24 @@ picoclaw onboard
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"model_list": [
|
||||||
|
{
|
||||||
|
"model_name": "gpt4",
|
||||||
|
"model": "openai/gpt-5.2",
|
||||||
|
"api_key": "sk-your-openai-key",
|
||||||
|
"api_base": "https://api.openai.com/v1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"agents": {
|
"agents": {
|
||||||
"defaults": {
|
"defaults": {
|
||||||
"workspace": "~/.picoclaw/workspace",
|
"model": "gpt4"
|
||||||
"model": "glm-4.7",
|
|
||||||
"max_tokens": 8192,
|
|
||||||
"temperature": 0.7,
|
|
||||||
"max_tool_iterations": 20
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"providers": {
|
"channels": {
|
||||||
"openrouter": {
|
"telegram": {
|
||||||
"api_key": "xxx",
|
|
||||||
"api_base": "https://openrouter.ai/api/v1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"web": {
|
|
||||||
"brave": {
|
|
||||||
"enabled": false,
|
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
|
||||||
"max_results": 5
|
|
||||||
},
|
|
||||||
"duckduckgo": {
|
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"max_results": 5
|
"token": "YOUR_TELEGRAM_BOT_TOKEN",
|
||||||
}
|
"allow_from": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -747,6 +739,8 @@ Subagent có quyền truy cập các công cụ (message, web_search, v.v.) và
|
||||||
| `openai` (Đang thử nghiệm) | LLM (GPT trực tiếp) | [platform.openai.com](https://platform.openai.com) |
|
| `openai` (Đang thử nghiệm) | LLM (GPT trực tiếp) | [platform.openai.com](https://platform.openai.com) |
|
||||||
| `deepseek` (Đang thử nghiệm) | LLM (DeepSeek trực tiếp) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek` (Đang thử nghiệm) | LLM (DeepSeek trực tiếp) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
| `groq` | LLM + **Chuyển giọng nói** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **Chuyển giọng nói** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
| `qwen` | LLM (Qwen trực tiếp) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
|
| `cerebras` | LLM (Cerebras trực tiếp) | [cerebras.ai](https://cerebras.ai) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Cấu hình Zhipu</b></summary>
|
<summary><b>Cấu hình Zhipu</b></summary>
|
||||||
|
|
@ -1065,7 +1059,7 @@ Thêm key vào `~/.picoclaw/config.json` nếu dùng Brave:
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"brave": {
|
"brave": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
},
|
},
|
||||||
|
|
|
||||||
33
README.zh.md
33
README.zh.md
|
|
@ -238,9 +238,14 @@ picoclaw onboard
|
||||||
],
|
],
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cron": {
|
"cron": {
|
||||||
|
|
@ -345,7 +350,8 @@ picoclaw gateway
|
||||||
"discord": {
|
"discord": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "YOUR_BOT_TOKEN",
|
"token": "YOUR_BOT_TOKEN",
|
||||||
"allow_from": ["YOUR_USER_ID"]
|
"allow_from": ["YOUR_USER_ID"],
|
||||||
|
"mention_only": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +531,7 @@ picoclaw gateway
|
||||||
|
|
||||||
只需通过 CLI 或任何集成的聊天应用发送一条消息,即可将 PicoClaw 连接到 Agent 社交网络。
|
只需通过 CLI 或任何集成的聊天应用发送一条消息,即可将 PicoClaw 连接到 Agent 社交网络。
|
||||||
|
|
||||||
**阅读 `https://clawdchat.ai/skill.md` 并按照说明加入 [ClawdChat.ai**](https://clawdchat.ai)
|
**阅读 `https://clawdchat.ai/skill.md` 并按照说明加入 [ClawdChat.ai](https://clawdchat.ai)
|
||||||
|
|
||||||
## ⚙️ 配置详解
|
## ⚙️ 配置详解
|
||||||
|
|
||||||
|
|
@ -857,8 +863,8 @@ Agent 读取 HEARTBEAT.md
|
||||||
"zhipu": {
|
"zhipu": {
|
||||||
"api_key": "Your API Key",
|
"api_key": "Your API Key",
|
||||||
"api_base": "https://open.bigmodel.cn/api/paas/v4"
|
"api_base": "https://open.bigmodel.cn/api/paas/v4"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -921,8 +927,14 @@ picoclaw agent -m "你好"
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
"api_key": "BSA..."
|
"enabled": false,
|
||||||
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cron": {
|
"cron": {
|
||||||
|
|
@ -989,9 +1001,14 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN)
|
||||||
{
|
{
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ const antigravityPlugin = {
|
||||||
description: "OAuth flow for Google Antigravity (Cloud Code Assist)",
|
description: "OAuth flow for Google Antigravity (Cloud Code Assist)",
|
||||||
configSchema: emptyPluginConfigSchema(),
|
configSchema: emptyPluginConfigSchema(),
|
||||||
|
|
||||||
register(api: OpenClawPluginApi) {
|
register(api: PicoClawPluginApi) {
|
||||||
api.registerProvider({
|
api.registerProvider({
|
||||||
id: "google-antigravity",
|
id: "google-antigravity",
|
||||||
label: "Google Antigravity",
|
label: "Google Antigravity",
|
||||||
|
|
@ -405,7 +405,7 @@ const antigravityPlugin = {
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type ProviderAuthContext = {
|
type ProviderAuthContext = {
|
||||||
config: OpenClawConfig;
|
config: PicoClawConfig;
|
||||||
agentDir?: string;
|
agentDir?: string;
|
||||||
workspaceDir?: string;
|
workspaceDir?: string;
|
||||||
prompter: WizardPrompter; // UI prompts/notifications
|
prompter: WizardPrompter; // UI prompts/notifications
|
||||||
|
|
@ -426,7 +426,7 @@ type ProviderAuthResult = {
|
||||||
profileId: string;
|
profileId: string;
|
||||||
credential: AuthProfileCredential;
|
credential: AuthProfileCredential;
|
||||||
}>;
|
}>;
|
||||||
configPatch?: Partial<OpenClawConfig>;
|
configPatch?: Partial<PicoClawConfig>;
|
||||||
defaultModel?: string;
|
defaultModel?: string;
|
||||||
notes?: string[];
|
notes?: string[];
|
||||||
};
|
};
|
||||||
|
|
@ -438,10 +438,9 @@ type ProviderAuthResult = {
|
||||||
|
|
||||||
### 1. Required Environment/Dependencies
|
### 1. Required Environment/Dependencies
|
||||||
|
|
||||||
- Node.js ≥ 22
|
- Go ≥ 1.21
|
||||||
- OpenClaw plugin-sdk
|
- PicoClaw codebase (`pkg/providers/` and `pkg/auth/`)
|
||||||
- crypto module (built-in)
|
- `crypto` and `net/http` standard library packages
|
||||||
- http module (built-in)
|
|
||||||
|
|
||||||
### 2. Required Headers for API Calls
|
### 2. Required Headers for API Calls
|
||||||
|
|
||||||
|
|
@ -572,36 +571,40 @@ Each SSE message (`data: {...}`) is wrapped in a `response` field:
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
### openclaw.json Configuration
|
### config.json Configuration
|
||||||
|
|
||||||
```json5
|
```json
|
||||||
{
|
{
|
||||||
agents: {
|
"model_list": [
|
||||||
defaults: {
|
{
|
||||||
model: {
|
"model_name": "gemini-flash",
|
||||||
primary: "google-antigravity/claude-opus-4-6-thinking",
|
"model": "antigravity/gemini-3-flash",
|
||||||
},
|
"auth_method": "oauth"
|
||||||
},
|
}
|
||||||
},
|
],
|
||||||
|
"agents": {
|
||||||
|
"defaults": {
|
||||||
|
"model": "gemini-flash"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Auth Profile Storage
|
### Auth Profile Storage
|
||||||
|
|
||||||
Auth profiles are stored in `~/.openclaw/agent/auth-profiles.json`:
|
Auth profiles are stored in `~/.picoclaw/auth.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": 1,
|
"credentials": {
|
||||||
"profiles": {
|
"google-antigravity": {
|
||||||
"google-antigravity:user@example.com": {
|
"access_token": "ya29...",
|
||||||
"type": "oauth",
|
"refresh_token": "1//...",
|
||||||
|
"expires_at": "2026-01-01T00:00:00Z",
|
||||||
"provider": "google-antigravity",
|
"provider": "google-antigravity",
|
||||||
"access": "ya29...",
|
"auth_method": "oauth",
|
||||||
"refresh": "1//...",
|
|
||||||
"expires": 1704067200000,
|
|
||||||
"email": "user@example.com",
|
"email": "user@example.com",
|
||||||
"projectId": "my-project-id"
|
"project_id": "my-project-id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -611,277 +614,85 @@ Auth profiles are stored in `~/.openclaw/agent/auth-profiles.json`:
|
||||||
|
|
||||||
## Creating a New Provider in PicoClaw
|
## Creating a New Provider in PicoClaw
|
||||||
|
|
||||||
|
PicoClaw providers are implemented as Go packages under `pkg/providers/`. To add a new provider:
|
||||||
|
|
||||||
### Step-by-Step Implementation
|
### Step-by-Step Implementation
|
||||||
|
|
||||||
#### 1. Create Plugin Structure
|
#### 1. Create Provider File
|
||||||
|
|
||||||
|
Create a new Go file in `pkg/providers/`:
|
||||||
|
|
||||||
```
|
```
|
||||||
extensions/
|
pkg/providers/
|
||||||
└── your-provider-auth/
|
└── your_provider.go
|
||||||
├── openclaw.plugin.json
|
|
||||||
├── package.json
|
|
||||||
├── README.md
|
|
||||||
└── index.ts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. Define Plugin Manifest
|
#### 2. Implement the Provider Interface
|
||||||
|
|
||||||
|
Your provider must implement the `Provider` interface defined in `pkg/providers/types.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package providers
|
||||||
|
|
||||||
|
type YourProvider struct {
|
||||||
|
apiKey string
|
||||||
|
apiBase string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewYourProvider(apiKey, apiBase, proxy string) *YourProvider {
|
||||||
|
if apiBase == "" {
|
||||||
|
apiBase = "https://api.your-provider.com/v1"
|
||||||
|
}
|
||||||
|
return &YourProvider{apiKey: apiKey, apiBase: apiBase}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *YourProvider) Chat(ctx context.Context, messages []Message, tools []Tool, cb StreamCallback) error {
|
||||||
|
// Implement chat completion with streaming
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Register in the Factory
|
||||||
|
|
||||||
|
Add your provider to the protocol switch in `pkg/providers/factory.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
case "your-provider":
|
||||||
|
return NewYourProvider(sel.apiKey, sel.apiBase, sel.proxy), nil
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Add Default Config (Optional)
|
||||||
|
|
||||||
|
Add a default entry in `pkg/config/defaults.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
{
|
||||||
|
ModelName: "your-model",
|
||||||
|
Model: "your-provider/model-name",
|
||||||
|
APIKey: "",
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Add Auth Support (Optional)
|
||||||
|
|
||||||
|
If your provider requires OAuth or special authentication, add a case to `cmd/picoclaw/cmd_auth.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
case "your-provider":
|
||||||
|
authLoginYourProvider()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6. Configure via `config.json`
|
||||||
|
|
||||||
**openclaw.plugin.json:**
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "your-provider-auth",
|
"model_list": [
|
||||||
"providers": ["your-provider"],
|
|
||||||
"configSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**package.json:**
|
|
||||||
```json
|
|
||||||
{
|
{
|
||||||
"name": "@openclaw/your-provider-auth",
|
"model_name": "your-model",
|
||||||
"version": "1.0.0",
|
"model": "your-provider/model-name",
|
||||||
"private": true,
|
"api_key": "your-api-key",
|
||||||
"description": "Your Provider OAuth plugin",
|
"api_base": "https://api.your-provider.com/v1"
|
||||||
"type": "module"
|
|
||||||
}
|
}
|
||||||
```
|
]
|
||||||
|
|
||||||
#### 3. Implement OAuth Flow
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import {
|
|
||||||
buildOauthProviderAuthResult,
|
|
||||||
emptyPluginConfigSchema,
|
|
||||||
type OpenClawPluginApi,
|
|
||||||
type ProviderAuthContext,
|
|
||||||
} from "openclaw/plugin-sdk";
|
|
||||||
|
|
||||||
const YOUR_CLIENT_ID = "your-client-id";
|
|
||||||
const YOUR_CLIENT_SECRET = "your-client-secret";
|
|
||||||
const AUTH_URL = "https://provider.com/oauth/authorize";
|
|
||||||
const TOKEN_URL = "https://provider.com/oauth/token";
|
|
||||||
const REDIRECT_URI = "http://localhost:PORT/oauth-callback";
|
|
||||||
|
|
||||||
async function loginYourProvider(params: {
|
|
||||||
isRemote: boolean;
|
|
||||||
openUrl: (url: string) => Promise<void>;
|
|
||||||
prompt: (message: string) => Promise<string>;
|
|
||||||
note: (message: string, title?: string) => Promise<void>;
|
|
||||||
log: (message: string) => void;
|
|
||||||
progress: { update: (msg: string) => void; stop: (msg?: string) => void };
|
|
||||||
}) {
|
|
||||||
// 1. Generate PKCE
|
|
||||||
const { verifier, challenge } = generatePkce();
|
|
||||||
const state = randomBytes(16).toString("hex");
|
|
||||||
|
|
||||||
// 2. Build auth URL
|
|
||||||
const authUrl = buildAuthUrl({ challenge, state });
|
|
||||||
|
|
||||||
// 3. Start callback server (if not remote)
|
|
||||||
const callbackServer = !params.isRemote
|
|
||||||
? await startCallbackServer({ timeoutMs: 5 * 60 * 1000 })
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// 4. Open browser or show URL
|
|
||||||
if (callbackServer) {
|
|
||||||
await params.openUrl(authUrl);
|
|
||||||
const callback = await callbackServer.waitForCallback();
|
|
||||||
code = callback.searchParams.get("code");
|
|
||||||
} else {
|
|
||||||
await params.note(`Auth URL: ${authUrl}`, "OAuth");
|
|
||||||
const input = await params.prompt("Paste redirect URL:");
|
|
||||||
const parsed = parseCallbackInput(input);
|
|
||||||
code = parsed.code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Exchange code for tokens
|
|
||||||
const tokens = await exchangeCode({ code, verifier });
|
|
||||||
|
|
||||||
// 6. Fetch additional user data
|
|
||||||
const email = await fetchUserEmail(tokens.access);
|
|
||||||
|
|
||||||
return { ...tokens, email };
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. Register Provider
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const yourProviderPlugin = {
|
|
||||||
id: "your-provider-auth",
|
|
||||||
name: "Your Provider Auth",
|
|
||||||
description: "OAuth for Your Provider",
|
|
||||||
configSchema: emptyPluginConfigSchema(),
|
|
||||||
|
|
||||||
register(api: OpenClawPluginApi) {
|
|
||||||
api.registerProvider({
|
|
||||||
id: "your-provider",
|
|
||||||
label: "Your Provider",
|
|
||||||
docsPath: "/providers/models",
|
|
||||||
aliases: ["yp"],
|
|
||||||
|
|
||||||
auth: [
|
|
||||||
{
|
|
||||||
id: "oauth",
|
|
||||||
label: "OAuth Login",
|
|
||||||
hint: "Browser-based authentication",
|
|
||||||
kind: "oauth",
|
|
||||||
|
|
||||||
run: async (ctx: ProviderAuthContext) => {
|
|
||||||
const spin = ctx.prompter.progress("Starting OAuth...");
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await loginYourProvider({
|
|
||||||
isRemote: ctx.isRemote,
|
|
||||||
openUrl: ctx.openUrl,
|
|
||||||
prompt: async (msg) => String(await ctx.prompter.text({ message: msg })),
|
|
||||||
note: ctx.prompter.note,
|
|
||||||
log: (msg) => ctx.runtime.log(msg),
|
|
||||||
progress: spin,
|
|
||||||
});
|
|
||||||
|
|
||||||
return buildOauthProviderAuthResult({
|
|
||||||
providerId: "your-provider",
|
|
||||||
defaultModel: "your-provider/model-name",
|
|
||||||
access: result.access,
|
|
||||||
refresh: result.refresh,
|
|
||||||
expires: result.expires,
|
|
||||||
email: result.email,
|
|
||||||
notes: ["Provider-specific notes"],
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
spin.stop("OAuth failed");
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default yourProviderPlugin;
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 5. Implement Usage Tracking (Optional)
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/infra/provider-usage.fetch.your-provider.ts
|
|
||||||
export async function fetchYourProviderUsage(
|
|
||||||
token: string,
|
|
||||||
timeoutMs: number,
|
|
||||||
fetchFn: typeof fetch
|
|
||||||
): Promise<ProviderUsageSnapshot> {
|
|
||||||
// Fetch usage data from provider API
|
|
||||||
const response = await fetchFn("https://api.provider.com/usage", {
|
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
return {
|
|
||||||
provider: "your-provider",
|
|
||||||
displayName: "Your Provider",
|
|
||||||
windows: [
|
|
||||||
{ label: "Credits", usedPercent: data.usedPercent },
|
|
||||||
],
|
|
||||||
plan: data.planName,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 6. Register Usage Fetcher
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/infra/provider-usage.load.ts
|
|
||||||
case "your-provider":
|
|
||||||
return await fetchYourProviderUsage(auth.token, timeoutMs, fetchFn);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 7. Add Provider to Type Definitions
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/infra/provider-usage.types.ts
|
|
||||||
export type SupportedProvider =
|
|
||||||
| "anthropic"
|
|
||||||
| "github-copilot"
|
|
||||||
| "google-gemini-cli"
|
|
||||||
| "google-antigravity"
|
|
||||||
| "your-provider" // Add here
|
|
||||||
| "minimax"
|
|
||||||
| "openai-codex";
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 8. Add Auth Choice Handler
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/commands/auth-choice.apply.your-provider.ts
|
|
||||||
import { applyAuthChoicePluginProvider } from "./auth-choice.apply.plugin-provider.js";
|
|
||||||
|
|
||||||
export async function applyAuthChoiceYourProvider(
|
|
||||||
params: ApplyAuthChoiceParams
|
|
||||||
): Promise<ApplyAuthChoiceResult | null> {
|
|
||||||
return await applyAuthChoicePluginProvider(params, {
|
|
||||||
authChoice: "your-provider",
|
|
||||||
pluginId: "your-provider-auth",
|
|
||||||
providerId: "your-provider",
|
|
||||||
methodId: "oauth",
|
|
||||||
label: "Your Provider",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 9. Export from Main Index
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/commands/auth-choice.apply.ts
|
|
||||||
import { applyAuthChoiceYourProvider } from "./auth-choice.apply.your-provider.js";
|
|
||||||
|
|
||||||
// In the switch statement:
|
|
||||||
case "your-provider":
|
|
||||||
return await applyAuthChoiceYourProvider(params);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Helper Utilities
|
|
||||||
|
|
||||||
#### PKCE Generation
|
|
||||||
```typescript
|
|
||||||
function generatePkce(): { verifier: string; challenge: string } {
|
|
||||||
const verifier = randomBytes(32).toString("hex");
|
|
||||||
const challenge = createHash("sha256").update(verifier).digest("base64url");
|
|
||||||
return { verifier, challenge };
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Callback Server
|
|
||||||
```typescript
|
|
||||||
async function startCallbackServer(params: { timeoutMs: number }) {
|
|
||||||
const port = 51121; // Your port
|
|
||||||
|
|
||||||
const server = createServer((request, response) => {
|
|
||||||
const url = new URL(request.url!, `http://localhost:${port}`);
|
|
||||||
|
|
||||||
if (url.pathname === "/oauth-callback") {
|
|
||||||
response.writeHead(200, { "Content-Type": "text/html" });
|
|
||||||
response.end("<h1>Authentication complete</h1>");
|
|
||||||
resolveCallback(url);
|
|
||||||
server.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
server.listen(port, "127.0.0.1", resolve);
|
|
||||||
server.once("error", reject);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
waitForCallback: () => callbackPromise,
|
|
||||||
close: () => new Promise((resolve) => server.close(resolve)),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -892,33 +703,27 @@ async function startCallbackServer(params: { timeoutMs: number }) {
|
||||||
### CLI Commands
|
### CLI Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Enable the plugin
|
# Authenticate with a provider
|
||||||
openclaw plugins enable your-provider-auth
|
picoclaw auth login --provider your-provider
|
||||||
|
|
||||||
# Restart gateway
|
# List models (for Antigravity)
|
||||||
openclaw gateway restart
|
picoclaw auth models
|
||||||
|
|
||||||
# Authenticate
|
# Start the gateway
|
||||||
openclaw models auth login --provider your-provider --set-default
|
picoclaw gateway
|
||||||
|
|
||||||
# List models
|
# Run an agent with a specific model
|
||||||
openclaw models list
|
picoclaw agent -m "Hello" --model your-model
|
||||||
|
|
||||||
# Set model
|
|
||||||
openclaw models set your-provider/model-name
|
|
||||||
|
|
||||||
# Check usage
|
|
||||||
openclaw models usage
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Variables for Testing
|
### Environment Variables for Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test specific providers only
|
# Override default model
|
||||||
export OPENCLAW_LIVE_PROVIDERS="your-provider,google-antigravity"
|
export PICOCLAW_AGENTS_DEFAULTS_MODEL=your-model
|
||||||
|
|
||||||
# Test with specific models
|
# Override provider settings
|
||||||
export OPENCLAW_LIVE_GATEWAY_MODELS="your-provider/model-name"
|
export PICOCLAW_MODEL_LIST='[{"model_name":"your-model","model":"your-provider/model-name","api_key":"..."}]'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -926,16 +731,16 @@ export OPENCLAW_LIVE_GATEWAY_MODELS="your-provider/model-name"
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- **Source Files:**
|
- **Source Files:**
|
||||||
- `extensions/google-antigravity-auth/index.ts` - Full OAuth implementation
|
- `pkg/providers/antigravity_provider.go` - Antigravity provider implementation
|
||||||
- `src/infra/provider-usage.fetch.antigravity.ts` - Usage fetching
|
- `pkg/auth/oauth.go` - OAuth flow implementation
|
||||||
- `src/agents/pi-embedded-runner/google.ts` - Model sanitization
|
- `pkg/auth/store.go` - Auth credential storage (`~/.picoclaw/auth.json`)
|
||||||
- `src/agents/model-forward-compat.ts` - Forward compatibility
|
- `pkg/providers/factory.go` - Provider factory and protocol routing
|
||||||
- `src/plugin-sdk/provider-auth-result.ts` - Auth result builder
|
- `pkg/providers/types.go` - Provider interface definitions
|
||||||
- `src/plugins/types.ts` - Plugin type definitions
|
- `cmd/picoclaw/cmd_auth.go` - Auth CLI commands
|
||||||
|
|
||||||
- **Documentation:**
|
- **Documentation:**
|
||||||
- `docs/concepts/model-providers.md` - Provider overview
|
- `docs/ANTIGRAVITY_USAGE.md` - Antigravity usage guide
|
||||||
- `docs/concepts/usage-tracking.md` - Usage tracking
|
- `docs/migration/model-list-migration.md` - Migration guide
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -987,7 +792,7 @@ Some models might show up in the available models list but return an empty respo
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### "Token expired"
|
### "Token expired"
|
||||||
- Refresh OAuth tokens: `openclaw models auth login --provider google-antigravity`
|
- Refresh OAuth tokens: `picoclaw auth login --provider antigravity`
|
||||||
|
|
||||||
### "Gemini for Google Cloud is not enabled"
|
### "Gemini for Google Cloud is not enabled"
|
||||||
- Enable the API in your Google Cloud Console
|
- Enable the API in your Google Cloud Console
|
||||||
|
|
@ -998,5 +803,5 @@ Some models might show up in the available models list but return an empty respo
|
||||||
|
|
||||||
### Models not appearing in list
|
### Models not appearing in list
|
||||||
- Verify OAuth authentication completed successfully
|
- Verify OAuth authentication completed successfully
|
||||||
- Check auth profile storage: `~/.openclaw/agent/auth-profiles.json`
|
- Check auth profile storage: `~/.picoclaw/auth.json`
|
||||||
- Ensure the plugin is enabled: `openclaw plugins list`
|
- Re-run `picoclaw auth login --provider antigravity`
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,12 @@ picoclaw agent -m "Hello" --model claude-opus-4-6-thinking
|
||||||
|
|
||||||
If you are deploying via Coolify or Docker, follow these steps to test:
|
If you are deploying via Coolify or Docker, follow these steps to test:
|
||||||
|
|
||||||
1. **Branch**: Use the `feat/antigravity-provider` branch.
|
1. **Environment Variables**:
|
||||||
2. **Environment Variables**:
|
* `PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-flash`
|
||||||
* `PICOCLAW_AGENTS_DEFAULTS_PROVIDER=antigravity`
|
2. **Authentication persistence**:
|
||||||
* `PICOCLAW_AGENTS_DEFAULTS_MODEL=gemini-3-flash`
|
|
||||||
3. **Authentication persistence**:
|
|
||||||
If you've logged in locally, you can copy your credentials to the server:
|
If you've logged in locally, you can copy your credentials to the server:
|
||||||
```bash
|
```bash
|
||||||
scp ~/.picoclaw/auth-profiles.json user@your-server:~/.picoclaw/
|
scp ~/.picoclaw/auth.json user@your-server:~/.picoclaw/
|
||||||
```
|
```
|
||||||
*Alternatively*, run the `auth login` command once on the server if you have terminal access.
|
*Alternatively*, run the `auth login` command once on the server if you have terminal access.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
# Provider Architecture Refactoring - Test Suite Summary
|
# Provider Architecture Refactoring - Test Suite Summary
|
||||||
|
|
||||||
> PRD: `tasks/prd-provider-refactoring.md`
|
|
||||||
|
|
||||||
This document summarizes the complete test suite designed for the Provider architecture refactoring.
|
This document summarizes the complete test suite designed for the Provider architecture refactoring.
|
||||||
|
|
||||||
## Test File Structure
|
## Test File Structure
|
||||||
|
|
@ -12,10 +10,8 @@ pkg/
|
||||||
│ ├── model_config_test.go # US-001, US-002: ModelConfig struct and GetModelConfig tests
|
│ ├── model_config_test.go # US-001, US-002: ModelConfig struct and GetModelConfig tests
|
||||||
│ └── migration_test.go # US-003: Backward compatibility and migration tests
|
│ └── migration_test.go # US-003: Backward compatibility and migration tests
|
||||||
├── providers/
|
├── providers/
|
||||||
│ ├── registry_test.go # US-006: Load balancing tests
|
│ ├── factory_test.go # US-004, US-005: Provider factory tests
|
||||||
│ ├── integration_test.go # E2E integration tests
|
│ └── factory_provider_test.go # Factory provider integration tests
|
||||||
│ └── factory/
|
|
||||||
│ └── factory_test.go # US-004, US-005: Provider factory tests
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -122,7 +118,6 @@ go test ./pkg/... -race
|
||||||
# Run specific package tests
|
# Run specific package tests
|
||||||
go test ./pkg/config -v
|
go test ./pkg/config -v
|
||||||
go test ./pkg/providers -v
|
go test ./pkg/providers -v
|
||||||
go test ./pkg/providers/factory -v
|
|
||||||
|
|
||||||
# Run E2E tests
|
# Run E2E tests
|
||||||
go test ./pkg/providers -run TestE2E -v
|
go test ./pkg/providers -run TestE2E -v
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
|
||||||
| `openai/` | OpenAI API (default) | `openai/gpt-5.2` |
|
| `openai/` | OpenAI API (default) | `openai/gpt-5.2` |
|
||||||
| `anthropic/` | Anthropic API | `anthropic/claude-opus-4` |
|
| `anthropic/` | Anthropic API | `anthropic/claude-opus-4` |
|
||||||
| `antigravity/` | Google via Antigravity OAuth | `antigravity/gemini-2.0-flash` |
|
| `antigravity/` | Google via Antigravity OAuth | `antigravity/gemini-2.0-flash` |
|
||||||
|
| `gemini/` | Google Gemini API | `gemini/gemini-2.0-flash-exp` |
|
||||||
| `claude-cli/` | Claude CLI (local) | `claude-cli/claude-sonnet-4.6` |
|
| `claude-cli/` | Claude CLI (local) | `claude-cli/claude-sonnet-4.6` |
|
||||||
| `codex-cli/` | Codex CLI (local) | `codex-cli/codex-4` |
|
| `codex-cli/` | Codex CLI (local) | `codex-cli/codex-4` |
|
||||||
| `github-copilot/` | GitHub Copilot | `github-copilot/gpt-4o` |
|
| `github-copilot/` | GitHub Copilot | `github-copilot/gpt-4o` |
|
||||||
|
|
@ -93,6 +94,13 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
|
||||||
| `deepseek/` | DeepSeek API | `deepseek/deepseek-chat` |
|
| `deepseek/` | DeepSeek API | `deepseek/deepseek-chat` |
|
||||||
| `cerebras/` | Cerebras API | `cerebras/llama-3.3-70b` |
|
| `cerebras/` | Cerebras API | `cerebras/llama-3.3-70b` |
|
||||||
| `qwen/` | Alibaba Qwen | `qwen/qwen-max` |
|
| `qwen/` | Alibaba Qwen | `qwen/qwen-max` |
|
||||||
|
| `zhipu/` | Zhipu AI | `zhipu/glm-4` |
|
||||||
|
| `nvidia/` | NVIDIA NIM | `nvidia/llama-3.1-nemotron-70b` |
|
||||||
|
| `ollama/` | Ollama (local) | `ollama/llama3` |
|
||||||
|
| `vllm/` | vLLM (local) | `vllm/my-model` |
|
||||||
|
| `moonshot/` | Moonshot AI | `moonshot/moonshot-v1-8k` |
|
||||||
|
| `shengsuanyun/` | ShengSuanYun | `shengsuanyun/deepseek-v3` |
|
||||||
|
| `volcengine/` | Volcengine | `volcengine/doubao-pro-32k` |
|
||||||
|
|
||||||
**Note**: If no prefix is specified, `openai/` is used as the default.
|
**Note**: If no prefix is specified, `openai/` is used as the default.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,14 +71,14 @@ Interested in a specific feature? You can "claim" these tasks and start building
|
||||||
* Support for OneBot, additional platforms
|
* Support for OneBot, additional platforms
|
||||||
* attachments (images, audio, video, files).
|
* attachments (images, audio, video, files).
|
||||||
* **Skills:**
|
* **Skills:**
|
||||||
* Implementing `find_skill` to discover tools via [openclaw/skills](https://github.com/openclaw/skills) and other platforms.
|
* Implementing `find_skill` to discover tools via [ClawhHub](https://clawhub.ai) and other platforms.
|
||||||
* **Operations:** * MCP Support.
|
* **Operations:** * MCP Support.
|
||||||
* Android operations (e.g., botdrop).
|
* Android operations (e.g., botdrop).
|
||||||
* Browser automation via CDP or ActionBook.
|
* Browser automation via CDP or ActionBook.
|
||||||
|
|
||||||
|
|
||||||
* **Multi-Agent Ecosystem:**
|
* **Multi-Agent Ecosystem:**
|
||||||
* **Basic Model-Agnet** S
|
* **Basic Model-Agent**
|
||||||
* **Model Routing:** Small models for easy tasks, large models for hard ones (to save tokens).
|
* **Model Routing:** Small models for easy tasks, large models for hard ones (to save tokens).
|
||||||
* **Swarm Mode.**
|
* **Swarm Mode.**
|
||||||
* **AIEOS Integration.**
|
* **AIEOS Integration.**
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ PicoClaw's tools configuration is located in the `tools` field of `config.json`.
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": { ... },
|
"web": { ... },
|
||||||
"exec": { ... },
|
"exec": { ... },
|
||||||
"approval": { ... },
|
"cron": { ... },
|
||||||
"cron": { ... }
|
"skills": { ... }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -83,25 +83,12 @@ By default, PicoClaw blocks the following dangerous commands:
|
||||||
"custom_deny_patterns": [
|
"custom_deny_patterns": [
|
||||||
"\\brm\\s+-r\\b",
|
"\\brm\\s+-r\\b",
|
||||||
"\\bkillall\\s+python"
|
"\\bkillall\\s+python"
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Approval Tool
|
|
||||||
|
|
||||||
The approval tool controls permissions for dangerous operations.
|
|
||||||
|
|
||||||
| Config | Type | Default | Description |
|
|
||||||
|--------|------|---------|-------------|
|
|
||||||
| `enabled` | bool | true | Enable approval functionality |
|
|
||||||
| `write_file` | bool | true | Require approval for file writes |
|
|
||||||
| `edit_file` | bool | true | Require approval for file edits |
|
|
||||||
| `append_file` | bool | true | Require approval for file appends |
|
|
||||||
| `exec` | bool | true | Require approval for command execution |
|
|
||||||
| `timeout_minutes` | int | 5 | Approval timeout in minutes |
|
|
||||||
|
|
||||||
## Cron Tool
|
## Cron Tool
|
||||||
|
|
||||||
The cron tool is used for scheduling periodic tasks.
|
The cron tool is used for scheduling periodic tasks.
|
||||||
|
|
@ -110,6 +97,40 @@ The cron tool is used for scheduling periodic tasks.
|
||||||
|--------|------|---------|-------------|
|
|--------|------|---------|-------------|
|
||||||
| `exec_timeout_minutes` | int | 5 | Execution timeout in minutes, 0 means no limit |
|
| `exec_timeout_minutes` | int | 5 | Execution timeout in minutes, 0 means no limit |
|
||||||
|
|
||||||
|
## Skills Tool
|
||||||
|
|
||||||
|
The skills tool configures skill discovery and installation via registries like ClawHub.
|
||||||
|
|
||||||
|
### Registries
|
||||||
|
|
||||||
|
| Config | Type | Default | Description |
|
||||||
|
|--------|------|---------|-------------|
|
||||||
|
| `registries.clawhub.enabled` | bool | true | Enable ClawHub registry |
|
||||||
|
| `registries.clawhub.base_url` | string | `https://clawhub.ai` | ClawHub base URL |
|
||||||
|
| `registries.clawhub.search_path` | string | `/api/v1/search` | Search API path |
|
||||||
|
| `registries.clawhub.skills_path` | string | `/api/v1/skills` | Skills API path |
|
||||||
|
| `registries.clawhub.download_path` | string | `/api/v1/download` | Download API path |
|
||||||
|
|
||||||
|
### Configuration Example
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tools": {
|
||||||
|
"skills": {
|
||||||
|
"registries": {
|
||||||
|
"clawhub": {
|
||||||
|
"enabled": true,
|
||||||
|
"base_url": "https://clawhub.ai",
|
||||||
|
"search_path": "/api/v1/search",
|
||||||
|
"skills_path": "/api/v1/skills",
|
||||||
|
"download_path": "/api/v1/download"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
All configuration options can be overridden via environment variables with the format `PICOCLAW_TOOLS_<SECTION>_<KEY>`:
|
All configuration options can be overridden via environment variables with the format `PICOCLAW_TOOLS_<SECTION>_<KEY>`:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue