update docs according to newest config version 2 (#2186)

This commit is contained in:
Cytown
2026-03-30 17:59:56 +08:00
committed by GitHub
parent 803b8bc02f
commit 010d807e61
23 changed files with 323 additions and 265 deletions
+80 -81
View File
@@ -11,24 +11,35 @@ PicoClaw uses a schema versioning system for `config.json` to ensure smooth upgr
- **Changes**: Added `version` field to Config struct
- **Migration**: No structural changes needed for existing configs
### Version 2
- **Introduction**: Model enable/disable support and channel config unification
- **Changes**:
- Added `enabled` field to `ModelConfig` — allows disabling individual model entries without removing them
- During V1→V2 migration, `enabled` is auto-inferred: models with API keys or the reserved `local-model` name are enabled; others default to disabled
- Migrated legacy channel fields: Discord `mention_only``group_trigger.mention_only`, OneBot `group_trigger_prefix``group_trigger.prefixes`
- V0 configs now migrate directly to CurrentVersion (V2) instead of going through V1
- `makeBackup()` now uses date-only suffix (e.g., `config.json.20260330.bak`) and also backs up `.security.yml`
## How It Works
### Automatic Migration
When you load a config file:
1. The system first reads the `version` field from the JSON
2. Based on the detected version, it loads the appropriate config struct (`ConfigV0`, `ConfigV1`, etc.)
2. Based on the detected version, it loads the appropriate config struct (`configV0`, `configV1`, etc.)
3. If the loaded version is less than the latest, migrations are applied incrementally
4. The version number is updated automatically
5. The migrated config is automatically saved back to disk
4. Before saving, the system automatically creates a date-stamped backup of `config.json` and `.security.yml`
5. The version number is updated automatically
6. The migrated config is automatically saved back to disk
### Version Field
The `version` field in `config.json` indicates the schema version:
- `0` or missing: Legacy config (no version field)
- `1`: Current version with versioning support
- `1`: Previous version (will be auto-migrated to V2 on load)
- `2`: Current version
```json
{
"version": 1,
"version": 2,
"agents": {...},
...
}
@@ -54,25 +65,25 @@ type ConfigV2 struct {
### Step 2: Update Current Config Version
```go
const CurrentConfigVersion = 2 // Increment this
const CurrentVersion = 2 // Increment this
```
### Step 3: Add a Loader Function
```go
// loadConfigV2 loads a version 2 config
func loadConfigV2(data []byte) (*Config, error) {
// loadConfigV3 loads a version 3 config
func loadConfigV3(data []byte) (*Config, error) {
cfg := DefaultConfig()
// Parse to ConfigV2 struct
var v2 ConfigV2
if err := json.Unmarshal(data, &v2); err != nil {
// Parse to ConfigV3 struct
var v3 ConfigV3
if err := json.Unmarshal(data, &v3); err != nil {
return nil, err
}
// Convert to current Config
cfg.Version = v2.Version
cfg.Agents = v2.Agents
cfg.Version = v3.Version
cfg.Agents = v3.Agents
// ... map other fields
return cfg, nil
@@ -82,29 +93,12 @@ func loadConfigV2(data []byte) (*Config, error) {
### Step 4: Add Migration Logic
```go
// applyMigration applies a single migration step from fromVersion to toVersion
func applyMigration(cfg *Config, fromVersion, toVersion int) (*Config, error) {
switch toVersion {
case 1:
// Migration from version 0 to 1
return &Config{
Version: 1,
Agents: cfg.Agents,
// ... copy all fields
}, nil
case 2:
// Migration from version 1 to 2
// Example: Move or rename fields
migrated := *cfg
migrated.Version = 2
// Apply structural changes
if cfg.SomeOldField != "" {
migrated.SomeNewField = cfg.SomeOldField
}
return &migrated, nil
default:
return nil, fmt.Errorf("unsupported migration target version: %d", toVersion)
}
func (c *configV2) Migrate() (*Config, error) {
// Apply V2→V3 structural changes here
migrated := &c.Config
migrated.Version = 3
// Apply structural changes
return migrated, nil
}
```
@@ -120,7 +114,9 @@ func LoadConfig(path string) (*Config, error) {
case 1:
cfg, err = loadConfigV1(data)
case 2:
cfg, err = loadConfigV2(data)
cfg, err = loadConfig(data)
case 3:
cfg, err = loadConfigV3(data)
default:
return nil, fmt.Errorf("unsupported config version: %d", versionInfo.Version)
}
@@ -134,22 +130,22 @@ func LoadConfig(path string) (*Config, error) {
Create a test in `config_migration_test.go`:
```go
func TestMigrateV1ToV2(t *testing.T) {
// Create a version 1 config
v1Config := Config{
Version: 1,
func TestMigrateV2ToV3(t *testing.T) {
// Create a version 2 config
v2Config := Config{
Version: 2,
// ... set up test data
}
// Apply migration
migrated, err := applyMigration(&v1Config, 1, 2)
migrated, err := v2Config.Migrate()
if err != nil {
t.Fatalf("Migration failed: %v", err)
}
// Verify version is updated
if migrated.Version != 2 {
t.Errorf("Expected version 2, got %d", migrated.Version)
if migrated.Version != 3 {
t.Errorf("Expected version 3, got %d", migrated.Version)
}
// Verify data is preserved/transformed correctly
@@ -164,58 +160,60 @@ func TestMigrateV1ToV2(t *testing.T) {
3. **No Data Loss**: Migrations should preserve all user settings
4. **Idempotent**: Running the same migration multiple times should be safe
5. **Auto-Save**: Migrated configs are automatically saved to update the user's file
6. **Test Thoroughly**: Test with real user config files
7. **Update Defaults**: Keep `defaults.go` in sync with the latest schema
6. **Auto-Backup**: Before saving, the system creates a date-stamped backup of `config.json` and `.security.yml`
7. **Test Thoroughly**: Test with real user config files
8. **Update Defaults**: Keep `defaults.go` in sync with the latest schema
## Example Migration
### Scenario: Adding a new field with default value
Old config (version 1):
```json
{
"version": 1,
"agents": {
"defaults": {
"max_tokens": 32768
}
}
}
```
Migration to version 2:
```go
case 2:
migrated := *cfg
migrated.Version = 2
// Add new field with default value if not set
if migrated.Agents.Defaults.NewFeatureEnabled == false {
// Use default value
}
return &migrated, nil
```
New config (version 2):
Old config (version 2):
```json
{
"version": 2,
"agents": {
"defaults": {
"max_tokens": 32768,
"new_feature_enabled": false
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4"
}
}
]
}
```
Migration to version 3:
```go
func (c *configV2) Migrate() (*Config, error) {
migrated := &c.Config
migrated.Version = 3
// Add new field with default value if not set
// ...
return migrated, nil
}
```
New config (version 3):
```json
{
"version": 3,
"model_list": [
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"new_option": true
}
]
}
```
## Troubleshooting
### Config Not Upgrading
- Check that `CurrentConfigVersion` is incremented
- Verify migration logic in `applyMigration()` handles the target version
- Ensure `migrateConfig()` is called in `LoadConfig()`
- Check that `CurrentVersion` is incremented
- Verify migration logic handles the target version
- Ensure `Migrate()` is called in `LoadConfig()`
### Migration Errors
- Check error messages for specific migration failures
@@ -227,4 +225,5 @@ New config (version 2):
- Ensure all fields are copied during migration
- Check that the migration doesn't overwrite values with defaults unnecessarily
- Review the conversion logic in the loader functions
- Check the auto-backup files (e.g., `config.json.20260330.bak`) to recover original data
+14 -11
View File
@@ -479,8 +479,9 @@ This design also enables **multi-agent support** with flexible provider selectio
- **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
- **Load balancing**: Distribute requests across multiple endpoints or keys
- **Centralized configuration**: Manage all providers in one place
- **Model enable/disable**: Use the `enabled` field to temporarily disable a model without removing its configuration
#### 🔒 Security Configuration (Recommended)
@@ -581,22 +582,22 @@ For complete documentation, see [`security_configuration.md`](security_configura
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -607,7 +608,9 @@ For complete documentation, see [`security_configuration.md`](security_configura
}
```
> **Security Note**: You can remove `api_key` fields from your config and store them in `.security.yml` instead. See [Security Configuration](#-security-configuration-recommended) above for details.
> **Security Note**: You can remove `api_keys` fields from your config and store them in `.security.yml` instead. See [Security Configuration](#-security-configuration-recommended) above for details.
>
> **Note**: The `enabled` field can be set to `false` to disable a model entry without removing it. When omitted, it defaults to `true` during migration for models that have API keys.
#### Vendor-Specific Examples
@@ -684,7 +687,7 @@ For direct Anthropic API access or custom endpoints that only support Anthropic'
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -759,13 +762,13 @@ model_list:
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -773,7 +776,7 @@ model_list:
#### Migration from Legacy `providers` Config
The old `providers` configuration is **deprecated** but still supported for backward compatibility. See [docs/migration/model-list-migration.md](../migration/model-list-migration.md) for the full guide.
The old `providers` configuration is **deprecated** and has been removed in V2. Existing V0/V1 configs are auto-migrated. See [docs/migration/model-list-migration.md](../migration/model-list-migration.md) for the full guide.
### Provider Architecture
@@ -783,7 +786,7 @@ PicoClaw routes providers by protocol family:
- **Anthropic**: Claude-native API behavior.
- **Codex/OAuth**: OpenAI OAuth/token authentication route.
This keeps the runtime lightweight while making new OpenAI-compatible backends mostly a config operation (`api_base` + `api_key`).
This keeps the runtime lightweight while making new OpenAI-compatible backends mostly a config operation (`api_base` + `api_keys`).
<details>
<summary><b>Zhipu (legacy providers format)</b></summary>
+3 -1
View File
@@ -1,6 +1,6 @@
# Credential Encryption
PicoClaw supports encrypting `api_key` values in `model_list` configuration entries.
PicoClaw supports encrypting `api_key`/`api_keys` values in `model_list` configuration entries.
Encrypted keys are stored as `enc://<base64>` strings and decrypted automatically at startup.
---
@@ -42,6 +42,8 @@ enc://AAAA...base64...
## Supported `api_key` Formats
The same formats apply to both `api_key` (singular) and individual elements in the `api_keys` (array) field:
| Format | Example | Behaviour |
|--------|---------|-----------|
| Plaintext | `sk-abc123` | Used as-is |
+3 -3
View File
@@ -95,19 +95,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+3 -3
View File
@@ -334,15 +334,15 @@ Configurez plusieurs endpoints pour le même nom de modèle — PicoClaw effectu
```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" }
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api1.example.com/v1", "api_keys": ["sk-key1"] },
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api2.example.com/v1", "api_keys": ["sk-key2"] }
]
}
```
#### Migration depuis l'ancienne config `providers`
L'ancienne configuration `providers` est **dépréciée** mais toujours supportée. Voir [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
L'ancienne configuration `providers` est **dépréciée** et a été supprimée dans V2. Les configs V0/V1 existantes sont auto-migrées. Voir [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
### Architecture des Providers
+3 -3
View File
@@ -92,19 +92,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+17 -16
View File
@@ -73,22 +73,22 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -107,7 +107,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -117,7 +117,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -127,7 +127,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -137,7 +137,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -147,7 +147,7 @@ Cette conception permet également le **support multi-agents** avec une sélecti
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -161,7 +161,7 @@ Pour l'accès direct à l'API Anthropic ou les endpoints personnalisés qui ne p
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -189,7 +189,7 @@ Pour l'accès direct à l'API Anthropic ou les endpoints personnalisés qui ne p
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -201,7 +201,7 @@ Pour l'accès direct à l'API Anthropic ou les endpoints personnalisés qui ne p
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -218,13 +218,13 @@ Configurez plusieurs endpoints pour le même nom de modèle — PicoClaw effectu
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -232,7 +232,7 @@ Configurez plusieurs endpoints pour le même nom de modèle — PicoClaw effectu
#### Migration depuis l'Ancienne Configuration `providers`
L'ancienne configuration `providers` est **dépréciée** mais toujours prise en charge pour la compatibilité ascendante.
L'ancienne configuration `providers` est **dépréciée** et a été supprimée dans V2. Les configs V0/V1 existantes sont auto-migrées.
**Ancienne configuration (dépréciée) :**
@@ -257,11 +257,12 @@ L'ancienne configuration `providers` est **dépréciée** mais toujours prise en
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {
+3 -3
View File
@@ -335,15 +335,15 @@ HEARTBEAT_OK を返信 ユーザーが直接結果を受信
```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" }
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api1.example.com/v1", "api_keys": ["sk-key1"] },
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api2.example.com/v1", "api_keys": ["sk-key2"] }
]
}
```
#### 旧 `providers` 設定からの移行
`providers` 設定は**非推奨**ですが後方互換性のためサポートされています。[docs/migration/model-list-migration.md](../migration/model-list-migration.md) を参照してください。
`providers` 設定は**非推奨**となり、V2 で削除されました。既存の V0/V1 設定は自動的に移行されます。[docs/migration/model-list-migration.md](../migration/model-list-migration.md) を参照してください。
### Provider アーキテクチャ
+3 -3
View File
@@ -94,19 +94,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+29 -17
View File
@@ -73,22 +73,22 @@
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -107,7 +107,7 @@
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -117,7 +117,7 @@
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -127,7 +127,18 @@
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
**LiteLLM Proxy**
```json
{
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_keys": ["sk-..."]
}
```
@@ -137,7 +148,7 @@
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -147,7 +158,7 @@
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -161,7 +172,7 @@ Anthropic API への直接アクセスや、Anthropic のネイティブメッ
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -189,7 +200,7 @@ Anthropic API への直接アクセスや、Anthropic のネイティブメッ
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -201,7 +212,7 @@ Anthropic API への直接アクセスや、Anthropic のネイティブメッ
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -218,13 +229,13 @@ PicoClaw はリクエスト送信前に外側の `litellm/` プレフィック
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -232,7 +243,7 @@ PicoClaw はリクエスト送信前に外側の `litellm/` プレフィック
#### レガシー `providers` 設定からの移行
`providers` 設定形式は**非推奨**ですが、後方互換性のためまだサポートされています。
`providers` 設定形式は**非推奨**となり、V2 で削除されました。既存の V0/V1 設定は自動的に移行されます。
**旧設定(非推奨):**
@@ -257,11 +268,12 @@ PicoClaw はリクエスト送信前に外側の `litellm/` プレフィック
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {
@@ -282,7 +294,7 @@ PicoClaw はプロトコルファミリーごとに Provider をルーティン
- Anthropic プロトコル:Claude ネイティブ API 動作。
- Codex/OAuth パス:OpenAI OAuth/Token 認証ルート。
これによりランタイムを軽量に保ちつつ、新しい OpenAI 互換バックエンドの追加をほぼ設定操作(`api_base` + `api_key`)のみで実現しています。
これによりランタイムを軽量に保ちつつ、新しい OpenAI 互換バックエンドの追加をほぼ設定操作(`api_base` + `api_keys`)のみで実現しています。
<details>
<summary><b>Zhipu 設定例</b></summary>
+47 -14
View File
@@ -50,22 +50,23 @@ The new `model_list` configuration offers several advantages:
```json
{
"version": 2,
"model_list": [
{
"model_name": "gpt4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key",
"api_keys": ["sk-your-openai-key"],
"api_base": "https://api.openai.com/v1"
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "deepseek",
"model": "deepseek/deepseek-chat",
"api_key": "sk-your-deepseek-key"
"api_keys": ["sk-your-deepseek-key"]
}
],
"agents": {
@@ -76,6 +77,8 @@ The new `model_list` configuration offers several advantages:
}
```
> **Note**: The `enabled` field can be omitted — during V1→V2 migration it is auto-inferred (models with API keys or the `local-model` name are enabled by default). For new configs, you can explicitly set `"enabled": false` to disable a model entry without removing it.
## Protocol Prefixes
The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
@@ -111,7 +114,8 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
| `model_name` | Yes | User-facing alias for the model |
| `model` | Yes | Protocol and model identifier (e.g., `openai/gpt-5.4`) |
| `api_base` | No | API endpoint URL |
| `api_key` | No* | API authentication key |
| `api_keys` | No | API authentication keys (array; supports multiple keys for load balancing) |
| `enabled` | No | Whether this model entry is active. Defaults to `true` during migration for models with API keys or named `local-model`. Set to `false` to disable. |
| `proxy` | No | HTTP proxy URL |
| `auth_method` | No | Authentication method: `oauth`, `token` |
| `connect_mode` | No | Connection mode for CLI providers: `stdio`, `grpc` |
@@ -119,11 +123,13 @@ The `model` field uses a protocol prefix format: `[protocol/]model-identifier`
| `max_tokens_field` | No | Field name for max tokens |
| `request_timeout` | No | HTTP request timeout in seconds; `<=0` uses default `120s` |
*`api_key` is required for HTTP-based protocols unless `api_base` points to a local server.
> **Note**: `api_key` (singular) has been **removed** in V2 configs. Only `api_keys` (array) is supported. During migration from V0/V1, both `api_key` and `api_keys` are automatically merged into the new `api_keys` array.
## Load Balancing
Configure multiple endpoints for the same model to distribute load:
There are two ways to configure load balancing:
### Option 1: Multiple API Keys in `api_keys` (Recommended)
```json
{
@@ -131,19 +137,45 @@ Configure multiple endpoints for the same model to distribute load:
{
"model_name": "gpt4",
"model": "openai/gpt-5.4",
"api_key": "sk-key1",
"api_keys": ["sk-key1", "sk-key2", "sk-key3"],
"api_base": "https://api.openai.com/v1"
}
]
}
```
Or via `.security.yml`:
```yaml
model_list:
gpt4:
api_keys:
- "sk-key1"
- "sk-key2"
- "sk-key3"
```
### Option 2: Multiple Model Entries
```json
{
"model_list": [
{
"model_name": "gpt4",
"model": "openai/gpt-5.4",
"api_keys": ["sk-key1"],
"api_base": "https://api1.example.com/v1"
},
{
"model_name": "gpt4",
"model": "openai/gpt-5.4",
"api_key": "sk-key2",
"api_keys": ["sk-key2"],
"api_base": "https://api2.example.com/v1"
},
{
"model_name": "gpt4",
"model": "openai/gpt-5.4",
"api_key": "sk-key3",
"api_keys": ["sk-key3"],
"api_base": "https://api3.example.com/v1"
}
]
@@ -162,7 +194,7 @@ With `model_list`, adding a new provider requires zero code changes:
{
"model_name": "my-custom-llm",
"model": "openai/my-model-v1",
"api_key": "your-api-key",
"api_keys": ["your-api-key"],
"api_base": "https://api.your-provider.com/v1"
}
]
@@ -173,11 +205,12 @@ Just specify `openai/` as the protocol (or omit it for the default), and provide
## Backward Compatibility
During the migration period, your existing `providers` configuration will continue to work:
During the migration period, your existing V0/V1 config will be auto-migrated to V2:
1. If `model_list` is empty and `providers` has data, the system auto-converts internally
2. A deprecation warning is logged: `"providers config is deprecated, please migrate to model_list"`
3. All existing functionality remains unchanged
2. Both `api_key` (singular) and `api_keys` (array) in V0/V1 configs are merged into the new `api_keys` array
3. A deprecation warning is logged: `"providers config is deprecated, please migrate to model_list"`
4. All existing functionality remains unchanged
## Migration Checklist
@@ -212,7 +245,7 @@ unknown protocol "xxx" in model "xxx/model-name"
api_key or api_base is required for HTTP-based protocol "xxx"
```
**Solution**: Provide `api_key` and/or `api_base` for HTTP-based providers.
**Solution**: Provide `api_keys` and/or `api_base` for HTTP-based providers.
## Need Help?
+3 -3
View File
@@ -91,19 +91,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+23 -22
View File
@@ -79,22 +79,22 @@ This design also enables **multi-agent support** with flexible provider selectio
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -117,7 +117,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "voice-gemini",
"model": "gemini/gemini-2.5-flash",
"api_key": "your-gemini-key"
"api_keys": ["your-gemini-key"]
}
],
"voice": {
@@ -140,7 +140,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -150,7 +150,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -160,7 +160,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -170,7 +170,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "glm-4.7",
"model": "openai/glm-4.7",
"api_key": "your-z.ai-key"
"api_keys": ["your-z.ai-key"],
"api_base": "https://api.z.ai/api/coding/paas/v4"
}
```
@@ -181,7 +181,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -191,7 +191,7 @@ If `voice.model_name` is not configured, PicoClaw will continue to fall back to
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -205,7 +205,7 @@ For direct Anthropic API access or custom endpoints that only support Anthropic'
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -233,7 +233,7 @@ For direct Anthropic API access or custom endpoints that only support Anthropic'
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -245,7 +245,7 @@ For direct Anthropic API access or custom endpoints that only support Anthropic'
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -259,7 +259,7 @@ If the standard Zhipu endpoint (`https://open.bigmodel.cn/api/paas/v4`) returns
{
"model_name": "glm-4.7",
"model": "openai/glm-4.7",
"api_key": "your-zhipu-api-key",
"api_keys": ["your-zhipu-api-key"],
"api_base": "https://api.z.ai/api/coding/paas/v4"
}
```
@@ -277,13 +277,13 @@ Configure multiple endpoints for the same model name—PicoClaw will automatical
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -302,17 +302,17 @@ It also applies cooldown tracking per candidate to avoid immediately retrying a
"model_name": "qwen-main",
"model": "openai/qwen3.5:cloud",
"api_base": "https://api.example.com/v1",
"api_key": "sk-main"
"api_keys": ["sk-main"]
},
{
"model_name": "deepseek-backup",
"model": "deepseek/deepseek-chat",
"api_key": "sk-backup-1"
"api_keys": ["sk-backup-1"]
},
{
"model_name": "gemini-backup",
"model": "gemini/gemini-2.5-flash",
"api_key": "sk-backup-2"
"api_keys": ["sk-backup-2"]
}
],
"agents": {
@@ -330,7 +330,7 @@ If you use key-level failover for the same model, PicoClaw can chain through add
#### Migration from Legacy `providers` Config
The old `providers` configuration is **deprecated** but still supported for backward compatibility.
The old `providers` configuration is **deprecated** and has been removed in V2. Existing V0/V1 configs are auto-migrated.
**Old Config (deprecated):**
@@ -355,11 +355,12 @@ The old `providers` configuration is **deprecated** but still supported for back
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {
+3 -3
View File
@@ -335,15 +335,15 @@ Configure múltiplos endpoints para o mesmo nome de modelo — PicoClaw fará ro
```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" }
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api1.example.com/v1", "api_keys": ["sk-key1"] },
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api2.example.com/v1", "api_keys": ["sk-key2"] }
]
}
```
#### Migração da Configuração Legada `providers`
A configuração antiga `providers` está **depreciada** mas ainda é suportada. Veja [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
A configuração antiga `providers` está **depreciada** e foi removida no V2. Configs V0/V1 existentes são auto-migradas. Veja [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
### Arquitetura de Providers
+3 -3
View File
@@ -92,19 +92,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+18 -17
View File
@@ -73,22 +73,22 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -107,7 +107,7 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -117,7 +117,7 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -127,7 +127,7 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -137,7 +137,7 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -147,7 +147,7 @@ Este design também permite **suporte multi-agente** com seleção flexível de
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -161,7 +161,7 @@ Para acesso direto à API Anthropic ou endpoints personalizados que suportam ape
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -189,7 +189,7 @@ Para acesso direto à API Anthropic ou endpoints personalizados que suportam ape
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -201,7 +201,7 @@ Para acesso direto à API Anthropic ou endpoints personalizados que suportam ape
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -218,13 +218,13 @@ Configure múltiplos endpoints para o mesmo nome de modelo — o PicoClaw fará
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -232,7 +232,7 @@ Configure múltiplos endpoints para o mesmo nome de modelo — o PicoClaw fará
#### Migração da Configuração Legacy `providers`
A configuração antiga `providers` está **descontinuada** mas ainda é suportada para compatibilidade retroativa.
A configuração antiga `providers` está **descontinuada** e foi removida no V2. Configs V0/V1 existentes são auto-migradas.
**Configuração Antiga (descontinuada):**
@@ -257,11 +257,12 @@ A configuração antiga `providers` está **descontinuada** mas ainda é suporta
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {
@@ -282,7 +283,7 @@ O PicoClaw roteia provedores por família de protocolo:
- 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`).
Isso mantém o runtime leve enquanto torna novos backends compatíveis com OpenAI basicamente uma operação de configuração (`api_base` + `api_keys`).
<details>
<summary><b>Zhipu</b></summary>
+7 -3
View File
@@ -401,7 +401,7 @@ The pattern is: `PICOCLAW_<SECTION>_<KEY>_<FIELD>` with underscores separating p
3. **Set file permissions**: `chmod 600 ~/.picoclaw/.security.yml`
4. **Use different keys** for different environments (dev, staging, production)
5. **Rotate keys regularly** and update `.security.yml`
6. **Backup securely**: Encrypt backups containing `.security.yml`
6. **Backup securely**: Encrypt backups containing `.security.yml`. Note that config migrations automatically create date-stamped backups (e.g., `config.json.20260330.bak` and `.security.yml.20260330.bak`)
7. **Review access**: Ensure only authorized users have read access to the file
## API
@@ -444,7 +444,7 @@ Returns the path to `.security.yml` relative to the config file.
```json
{
"version": 1,
"version": 2,
"agents": {
"defaults": {
"workspace": "~/picoclaw-workspace",
@@ -557,6 +557,8 @@ go test ./pkg/config -run TestSecurityConfig
### Step 1: Backup your config
The system automatically creates a date-stamped backup before saving a migrated config (e.g., `config.json.20260330.bak` and `.security.yml.20260330.bak`). If you prefer a manual backup:
```bash
cp ~/.picoclaw/config.json ~/.picoclaw/config.json.backup
```
@@ -597,9 +599,11 @@ Test your models and channels to ensure everything works correctly.
### Step 8: Clean up (optional)
If everything works, you can delete the backup:
If everything works, you can delete the backups:
```bash
rm ~/.picoclaw/config.json.backup
# Also remove auto-generated date-stamped backups if desired:
rm ~/.picoclaw/config.json.20*.bak ~/.picoclaw/.security.yml.20*.bak
```
## Advanced: Encrypted API Keys
+3 -3
View File
@@ -335,15 +335,15 @@ Cấu hình nhiều endpoint cho cùng tên mô hình — PicoClaw sẽ tự đ
```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" }
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api1.example.com/v1", "api_keys": ["sk-key1"] },
{ "model_name": "gpt-5.4", "model": "openai/gpt-5.4", "api_base": "https://api2.example.com/v1", "api_keys": ["sk-key2"] }
]
}
```
#### Di Chuyển Từ Cấu Hình `providers`
Cấu hình `providers` cũ đã **bị deprecated** nhưng vẫn được hỗ trợ. Xem [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
Cấu hình `providers` cũ đã **bị deprecated** và đã được loại bỏ trong V2. Các cấu hình V0/V1 hiện có sẽ được tự động migrate. Xem [docs/migration/model-list-migration.md](../migration/model-list-migration.md).
### Kiến Trúc Provider
+3 -3
View File
@@ -92,19 +92,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+18 -17
View File
@@ -73,22 +73,22 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -107,7 +107,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -117,7 +117,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -127,7 +127,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -137,7 +137,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -147,7 +147,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -161,7 +161,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -189,7 +189,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -201,7 +201,7 @@ Thiết kế này cũng cho phép **hỗ trợ đa agent** với lựa chọn pr
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -218,13 +218,13 @@ Cấu hình nhiều endpoint cho cùng tên mô hình — PicoClaw sẽ tự đ
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -232,7 +232,7 @@ Cấu hình nhiều endpoint cho cùng tên mô hình — PicoClaw sẽ tự đ
#### 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 `providers` cũ đã **bị deprecated** và đã được loại bỏ trong V2. Các cấu hình V0/V1 hiện có sẽ được tự động migrate.
**Cấu hình cũ (ngừng hỗ trợ):**
@@ -257,11 +257,12 @@ Cấu hình `providers` cũ đã **ngừng hỗ trợ** nhưng vẫn được h
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {
@@ -282,7 +283,7 @@ PicoClaw định tuyến provider theo họ giao thức:
- 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`).
Đ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_keys`).
<details>
<summary><b>Zhipu</b></summary>
+14 -14
View File
@@ -386,22 +386,22 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -421,7 +421,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -434,7 +434,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -447,7 +447,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -460,7 +460,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -473,7 +473,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
}
```
@@ -485,7 +485,7 @@ Agent 读取 HEARTBEAT.md
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -514,7 +514,7 @@ Agent 读取 HEARTBEAT.md
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -533,13 +533,13 @@ PicoClaw 只剥离最外层的 `litellm/` 前缀再发送请求,因此 `litell
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -547,7 +547,7 @@ PicoClaw 只剥离最外层的 `litellm/` 前缀再发送请求,因此 `litell
#### 从旧版 `providers` 配置迁移
旧版 `providers` 配置**已废弃**但仍向后兼容。完整迁移指南见 [docs/migration/model-list-migration.md](../migration/model-list-migration.md)。
旧版 `providers` 配置**已废弃**V2 中已移除。现有 V0/V1 配置会自动迁移。完整迁移指南见 [docs/migration/model-list-migration.md](../migration/model-list-migration.md)。
### Provider 架构
+3 -3
View File
@@ -94,19 +94,19 @@ picoclaw onboard
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key",
"api_keys": ["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",
"api_keys": ["your-api-key"],
"request_timeout": 300
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "your-anthropic-key"
"api_keys": ["your-anthropic-key"]
}
],
"tools": {
+20 -19
View File
@@ -75,22 +75,22 @@
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-your-api-key"
"api_keys": ["sk-your-api-key"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-your-openai-key"
"api_keys": ["sk-your-openai-key"]
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-your-key"
"api_keys": ["sk-ant-your-key"]
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-zhipu-key"
"api_keys": ["your-zhipu-key"]
}
],
"agents": {
@@ -113,7 +113,7 @@
{
"model_name": "voice-gemini",
"model": "gemini/gemini-2.5-flash",
"api_key": "your-gemini-key"
"api_keys": ["your-gemini-key"]
}
],
"voice": {
@@ -136,7 +136,7 @@
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -146,7 +146,7 @@
{
"model_name": "ark-code-latest",
"model": "volcengine/ark-code-latest",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -156,7 +156,7 @@
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
```
@@ -166,7 +166,7 @@
{
"model_name": "deepseek-chat",
"model": "deepseek/deepseek-chat",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -190,7 +190,7 @@
{
"model_name": "claude-opus-4-6",
"model": "anthropic-messages/claude-opus-4-6",
"api_key": "sk-ant-your-key",
"api_keys": ["sk-ant-your-key"],
"api_base": "https://api.anthropic.com"
}
```
@@ -218,7 +218,7 @@
"model_name": "my-custom-model",
"model": "openai/custom-model",
"api_base": "https://my-proxy.com/v1",
"api_key": "sk-...",
"api_keys": ["sk-..."],
"request_timeout": 300
}
```
@@ -230,7 +230,7 @@
"model_name": "lite-gpt4",
"model": "litellm/lite-gpt4",
"api_base": "http://localhost:4000/v1",
"api_key": "sk-..."
"api_keys": ["sk-..."]
}
```
@@ -247,13 +247,13 @@ PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/l
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api1.example.com/v1",
"api_key": "sk-key1"
"api_keys": ["sk-key1"]
},
{
"model_name": "gpt-5.4",
"model": "openai/gpt-5.4",
"api_base": "https://api2.example.com/v1",
"api_key": "sk-key2"
"api_keys": ["sk-key2"]
}
]
}
@@ -272,17 +272,17 @@ PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/l
"model_name": "qwen-main",
"model": "openai/qwen3.5:cloud",
"api_base": "https://api.example.com/v1",
"api_key": "sk-main"
"api_keys": ["sk-main"]
},
{
"model_name": "deepseek-backup",
"model": "deepseek/deepseek-chat",
"api_key": "sk-backup-1"
"api_keys": ["sk-backup-1"]
},
{
"model_name": "gemini-backup",
"model": "gemini/gemini-2.5-flash",
"api_key": "sk-backup-2"
"api_keys": ["sk-backup-2"]
}
],
"agents": {
@@ -300,7 +300,7 @@ PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/l
#### 从旧的 `providers` 配置迁移
旧的 `providers` 配置格式**已弃用**但为向后兼容仍支持
旧的 `providers` 配置格式**已弃用**V2 中已移除。现有 V0/V1 配置会自动迁移
**旧配置(已弃用):**
@@ -325,11 +325,12 @@ PicoClaw 在发送请求前仅去除外层 `litellm/` 前缀,因此 `litellm/l
```json
{
"version": 2,
"model_list": [
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "your-key"
"api_keys": ["your-key"]
}
],
"agents": {