refactor(config): drop INI config format and add SaveConfig format tests

This commit is contained in:
sky5454 2026-02-20 14:07:32 +08:00
parent ba5b95f008
commit 6a5e1bea6d
8 changed files with 100 additions and 158 deletions

View file

@ -160,8 +160,8 @@ docker compose --profile gateway up -d
### 🚀 クイックスタート(ネイティブ)
> [!TIP]
> `~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml`、または `~/.picoclaw/config.ini` に API キーを設定してください。
> PicoClaw は複数の設定フォーマットをサポート:**JSON**(デフォルト)、**YAML**、**TOML**、**INI** ([spf13/viper](https://github.com/spf13/viper) 経由)。
> `~/.picoclaw/config.json``~/.picoclaw/config.yaml`または `~/.picoclaw/config.toml` に API キーを設定してください。
> PicoClaw は複数の設定フォーマットをサポート:**JSON**(デフォルト)、**YAML**、**TOML** ([spf13/viper](https://github.com/spf13/viper) 経由)。
> API キーの取得先: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)
> Web 検索は **任意** です - 無料の [Brave Search API](https://brave.com/search/api) (月 2000 クエリ無料)
@ -171,13 +171,12 @@ docker compose --profile gateway up -d
picoclaw onboard
```
**2. 設定** (`~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml`、または `~/.picoclaw/config.ini`)
**2. 設定** (`~/.picoclaw/config.json``~/.picoclaw/config.yaml`または `~/.picoclaw/config.toml`)
[spf13/viper](https://github.com/spf13/viper) 経由で複数の設定フォーマットをサポート。以下のいずれかを選択:
- `config.json` - JSON フォーマット(デフォルト)
- `config.yaml` または `config.yml` - YAML フォーマット
- `config.toml` - TOML フォーマット
- `config.ini` - INI フォーマット
```json
{

View file

@ -160,7 +160,7 @@ cd picoclaw
# 2. Set your API keys
cp config/config.example.json config/config.json
vim config/config.json # Set DISCORD_BOT_TOKEN, API keys, etc. (or use config.yaml/config.toml/config.ini)
vim config/config.json # Set DISCORD_BOT_TOKEN, API keys, etc. (or use config.yaml/config.toml)
# 3. Build & Start
docker compose --profile gateway up -d
@ -192,8 +192,8 @@ docker compose --profile gateway up -d
### 🚀 Quick Start
> [!TIP]
> Set your API key in `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml`, or `~/.picoclaw/config.ini`.
> PicoClaw supports multiple configuration formats: **JSON** (default), **YAML**, **TOML**, **INI** via [spf13/viper](https://github.com/spf13/viper).
> Set your API key in `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, or `~/.picoclaw/config.toml`.
> PicoClaw supports multiple configuration formats: **JSON** (default), **YAML**, **TOML** via [spf13/viper](https://github.com/spf13/viper).
> Get API keys: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)
> Web search is **optional** - get free [Brave Search API](https://brave.com/search/api) (2000 free queries/month) or use built-in auto fallback.
@ -203,13 +203,12 @@ docker compose --profile gateway up -d
picoclaw onboard
```
# 2. Configure (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml`, or `~/.picoclaw/config.ini`)
# 2. Configure (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, or `~/.picoclaw/config.toml`)
PicoClaw supports multiple configuration formats via [spf13/viper](https://github.com/spf13/viper). Choose any one:
- `config.json` - JSON format (default, most common)
- `config.yaml` or `config.yml` - YAML format
- `config.toml` - TOML format
- `config.ini` - INI format
```json
{

View file

@ -167,7 +167,7 @@ cd picoclaw
# 2. Configure suas API keys
cp config/config.example.json config/config.json
vim config/config.json # Configure DISCORD_BOT_TOKEN, API keys, etc. (ou use config.yaml/config.yaml/config.toml/config.ini)
vim config/config.json # Configure DISCORD_BOT_TOKEN, API keys, etc. (ou use config.yaml/config.toml)
# 3. Build & Iniciar
docker compose --profile gateway up -d
@ -199,8 +199,8 @@ docker compose --profile gateway up -d
### 🚀 Início Rápido
> [!TIP]
> Configure sua API key em `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml` ou `~/.picoclaw/config.ini`.
> PicoClaw suporta múltiplos formatos de configuração: **JSON** (padrão), **YAML**, **TOML**, **INI** via [spf13/viper](https://github.com/spf13/viper).
> Configure sua API key em `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml` ou `~/.picoclaw/config.toml`.
> PicoClaw suporta múltiplos formatos de configuração: **JSON** (padrão), **YAML**, **TOML** via [spf13/viper](https://github.com/spf13/viper).
> Obtenha API keys: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)
> Busca web e **opcional** — obtenha a [Brave Search API](https://brave.com/search/api) gratuita (2000 consultas grátis/mês) ou use o fallback automático integrado.
@ -210,13 +210,12 @@ docker compose --profile gateway up -d
picoclaw onboard
```
**2. Configurar** (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml` ou `~/.picoclaw/config.ini`)
**2. Configurar** (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml` ou `~/.picoclaw/config.toml`)
PicoClaw suporta múltiplos formatos via [spf13/viper](https://github.com/spf13/viper). Escolha qualquer um:
- `config.json` - Formato JSON (padrão)
- `config.yaml` ou `config.yml` - Formato YAML
- `config.toml` - Formato TOML
- `config.ini` - Formato INI
```json
{

View file

@ -147,7 +147,7 @@ cd picoclaw
# 2. Thiết lập API key
cp config/config.example.json config/config.json
vim config/config.json # Thiết lập DISCORD_BOT_TOKEN, API keys, v.v. (hoặc dùng config.yaml/config.toml/config.ini)
vim config/config.json # Thiết lập DISCORD_BOT_TOKEN, API keys, v.v. (hoặc dùng config.yaml/config.toml)
# 3. Build & Khởi động
docker compose --profile gateway up -d
@ -180,11 +180,11 @@ docker compose --profile gateway up -d
### Cấu hình
Bạn có thể cấu hình PicoClaw bằng cách chỉnh sửa file cấu hình ở các định dạng sau: `config.json`, `config.yaml`, `config.toml`, hoặc `config.ini`. Tất cả các định dạng này đều được hỗ trợ.
Bạn có thể cấu hình PicoClaw bằng cách chỉnh sửa file cấu hình ở các định dạng sau: `config.json`, `config.yaml`, hoặc `config.toml`.
> [!TIP]
> Thiết lập API key trong `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml` hoặc `~/.picoclaw/config.ini`.
> PicoClaw hỗ trợ nhiều định dạng cấu hình: **JSON** (mặc định), **YAML**, **TOML**, **INI** via [spf13/viper](https://github.com/spf13/viper).
> Thiết lập API key trong `~/.picoclaw/config.json`, `~/.picoclaw/config.yaml` hoặc `~/.picoclaw/config.toml`.
> PicoClaw hỗ trợ nhiều định dạng cấu hình: **JSON** (mặc định), **YAML**, **TOML** via [spf13/viper](https://github.com/spf13/viper).
> Lấy API key: [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 [Brave Search API](https://brave.com/search/api) miễn phí (2000 truy vấn/tháng) hoặc dùng tính năng auto fallback tích hợp sẵn.
@ -194,13 +194,12 @@ Bạn có thể cấu hình PicoClaw bằng cách chỉnh sửa file cấu hình
picoclaw onboard
```
**2. Cấu hình** (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml`, `~/.picoclaw/config.toml` hoặc `~/.picoclaw/config.ini`)
**2. Cấu hình** (`~/.picoclaw/config.json`, `~/.picoclaw/config.yaml` hoặc `~/.picoclaw/config.toml`)
PicoClaw hỗ trợ nhiều định dạng via [spf13/viper](https://github.com/spf13/viper). Chọn bất kỳ một:
- `config.json` - Định dạng JSON (mặc định)
- `config.yaml` hoặc `config.yml` - Định dạng YAML
- `config.toml` - Định dạng TOML
- `config.ini` - Định dạng INI
```json
{

View file

@ -165,7 +165,7 @@ cd picoclaw
# 2. 设置 API Key
cp config/config.example.json config/config.json
vim config/config.json # 或使用 config.yaml/config.toml/config.ini 设置 DISCORD_BOT_TOKEN, API keys 等
vim config/config.json # 或使用 config.yaml/config.toml 设置 DISCORD_BOT_TOKEN, API keys 等
# 3. 构建并启动
docker compose --profile gateway up -d
@ -200,8 +200,8 @@ docker compose --profile gateway up -d
### 🚀 快速开始
> [!TIP]
> 在 `~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml``~/.picoclaw/config.ini` 中设置您的 API Key。
> PicoClaw 支持多种配置格式:**JSON**(默认)、**YAML**、**TOML**、**INI**,通过 [spf13/viper](https://github.com/spf13/viper) 驱动。
> 在 `~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml` 中设置您的 API Key。
> PicoClaw 支持多种配置格式:**JSON**(默认)、**YAML**、**TOML**,通过 [spf13/viper](https://github.com/spf13/viper) 驱动。
> 获取 API Key: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu (智谱)](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM)
> 网络搜索是 **可选的** - 获取免费的 [Brave Search API](https://brave.com/search/api) (每月 2000 次免费查询)
@ -212,13 +212,12 @@ picoclaw onboard
```
**2. 配置 (Configure)** (`~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml``~/.picoclaw/config.ini`)
**2. 配置 (Configure)** (`~/.picoclaw/config.json``~/.picoclaw/config.yaml``~/.picoclaw/config.toml`)
通过 [spf13/viper](https://github.com/spf13/viper) 支持多种配置格式,选择其中任意一种即可:
- `config.json` - JSON 格式(默认)
- `config.yaml``config.yml` - YAML 格式
- `config.toml` - TOML 格式
- `config.ini` - INI 格式
```json
{
@ -748,4 +747,4 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN)
| **OpenRouter** | 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) |
| **智谱 (Zhipu)** | 200K tokens/月 | 最适合中国用户 |
| **Brave Search** | 2000 次查询/月 | 网络搜索功能 |
| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) |
| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) |

View file

@ -1,129 +0,0 @@
; PicoClaw Configuration Example - INI Format
; This is an alternative to config.json for users who prefer INI format
[agents.defaults]
workspace=~/.picoclaw/workspace
restrict_to_workspace=true
model=glm-4.7
max_tokens=8192
temperature=0.7
max_tool_iterations=20
[channels.telegram]
enabled=false
token=YOUR_TELEGRAM_BOT_TOKEN
proxy=
allow_from=YOUR_USER_ID
[channels.discord]
enabled=false
token=YOUR_DISCORD_BOT_TOKEN
allow_from=
[channels.slack]
enabled=false
token=YOUR_SLACK_BOT_TOKEN
allow_from=
[channels.feishu]
enabled=false
token=YOUR_FEISHU_BOT_TOKEN
secret=YOUR_FEISHU_SECRET
allow_from=
[channels.dingtalk]
enabled=false
token=YOUR_DINGTALK_BOT_TOKEN
secret=YOUR_DINGTALK_SECRET
allow_from=
[channels.qq]
enabled=false
account=YOUR_QQ_ACCOUNT
token=YOUR_QQ_BOT_TOKEN
allow_from=
[channels.whatsapp]
enabled=false
phone_number=YOUR_PHONE_NUMBER
allow_from=
[channels.line]
enabled=false
token=YOUR_LINE_CHANNEL_ACCESS_TOKEN
secret=YOUR_LINE_CHANNEL_SECRET
allow_from=
[channels.onebot]
enabled=false
ws_url=
allow_from=
[channels.maixcam]
enabled=false
host=0.0.0.0
port=18790
allow_from=
[providers.anthropic]
enabled=false
api_key=YOUR_ANTHROPIC_API_KEY
api_base=https://api.anthropic.com
[providers.openai]
enabled=false
api_key=YOUR_OPENAI_API_KEY
api_base=https://api.openai.com/v1
[providers.openrouter]
enabled=false
api_key=YOUR_OPENROUTER_API_KEY
api_base=https://openrouter.ai/api/v1
[providers.zhipu]
enabled=false
api_key=YOUR_ZHIPU_API_KEY
api_base=https://open.bigmodel.cn/api/paas/v4
[providers.gemini]
enabled=false
api_key=YOUR_GEMINI_API_KEY
api_base=https://generativelanguage.googleapis.com/v1beta/openai/
[providers.groq]
enabled=false
api_key=YOUR_GROQ_API_KEY
api_base=https://api.groq.com/openai/v1
[providers.vllm]
enabled=false
api_key=YOUR_VLLM_API_KEY
api_base=http://localhost:8000/v1
[providers.shengsuan_yun]
enabled=false
api_key=YOUR_SHENGSUAN_YUN_API_KEY
api_base=https://api.shengsuan.cloud/v1
[gateway]
enabled=true
host=0.0.0.0
port=8080
cors_enabled=true
cors_origins=*
[tools]
enabled=true
[heartbeat]
enabled=true
interval=60
timeout=5
[devices]
enabled=true
[session]
storage=memory
; For persistent storage, set to "sqlite" and provide database_path
; database_path=~/.picoclaw/session.db

View file

@ -64,7 +64,6 @@ var configFileNames = []string{
"config.yaml",
"config.yml",
"config.toml",
"config.ini",
}
type AgentsConfig struct {
@ -534,8 +533,6 @@ func SaveConfig(path string, cfg *Config) error {
configType = "yaml"
case ".toml":
configType = "toml"
case ".ini":
configType = "ini"
case ".json", "":
configType = "json"
if ext == "" {

View file

@ -300,6 +300,85 @@ func TestSaveConfig_FilePermissions(t *testing.T) {
}
}
func TestSaveConfig_AllSupportedFormats(t *testing.T) {
tests := []struct {
name string
fileName string
expectedOut string
}{
{
name: "json",
fileName: "config.json",
expectedOut: "config.json",
},
{
name: "yaml",
fileName: "config.yaml",
expectedOut: "config.yaml",
},
{
name: "yml",
fileName: "config.yml",
expectedOut: "config.yml",
},
{
name: "toml",
fileName: "config.toml",
expectedOut: "config.toml",
},
{
name: "no_extension_defaults_to_json",
fileName: "config",
expectedOut: "config.json",
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
tmpDir := t.TempDir()
targetPath := filepath.Join(tmpDir, tc.fileName)
outPath := filepath.Join(tmpDir, tc.expectedOut)
cfg := DefaultConfig()
cfg.Agents.Defaults.Model = "unit-test-model"
cfg.Agents.Defaults.MaxTokens = 1234
cfg.Gateway.Host = "127.0.0.1"
cfg.Gateway.Port = 19090
cfg.Providers.Zhipu.APIKey = "test-zhipu-key"
if err := SaveConfig(targetPath, cfg); err != nil {
t.Fatalf("SaveConfig(%q) failed: %v", targetPath, err)
}
if _, err := os.Stat(outPath); err != nil {
t.Fatalf("expected output file %q to exist: %v", outPath, err)
}
loaded, err := LoadConfig(outPath)
if err != nil {
t.Fatalf("LoadConfig(%q) failed: %v", outPath, err)
}
if loaded.Agents.Defaults.Model != "unit-test-model" {
t.Errorf("Model = %q, want %q", loaded.Agents.Defaults.Model, "unit-test-model")
}
if loaded.Agents.Defaults.MaxTokens != 1234 {
t.Errorf("MaxTokens = %d, want %d", loaded.Agents.Defaults.MaxTokens, 1234)
}
if loaded.Gateway.Host != "127.0.0.1" {
t.Errorf("Gateway.Host = %q, want %q", loaded.Gateway.Host, "127.0.0.1")
}
if loaded.Gateway.Port != 19090 {
t.Errorf("Gateway.Port = %d, want %d", loaded.Gateway.Port, 19090)
}
if loaded.Providers.Zhipu.APIKey != "test-zhipu-key" {
t.Errorf("Providers.Zhipu.APIKey = %q, want %q", loaded.Providers.Zhipu.APIKey, "test-zhipu-key")
}
})
}
}
// TestConfig_Complete verifies all config fields are set
func TestConfig_Complete(t *testing.T) {
cfg := DefaultConfig()