docs: add model config proposal
This commit is contained in:
153
docs/proposals/model-config.md
Normal file
153
docs/proposals/model-config.md
Normal file
@@ -0,0 +1,153 @@
|
||||
---
|
||||
summary: "Proposal: model config, auth profiles, and fallback behavior"
|
||||
read_when:
|
||||
- Designing model selection, auth profiles, or fallback behavior
|
||||
- Migrating model config schema
|
||||
---
|
||||
|
||||
# Model config proposal
|
||||
|
||||
Goals
|
||||
- Multi OAuth + multi API key per provider
|
||||
- Model selection via `/model` with sensible fallback
|
||||
- Global (not per-session) fallback logic
|
||||
- Keep last-known-good auth profile when switching models
|
||||
|
||||
Non-goals (v1)
|
||||
- Auto-discovery of provider capabilities beyond catalog input tags
|
||||
- Per-model auth profile order (see open questions)
|
||||
|
||||
## Proposed config shape
|
||||
|
||||
```json
|
||||
{
|
||||
"auth": {
|
||||
"profiles": {
|
||||
"anthropic:default": {
|
||||
"provider": "anthropic",
|
||||
"mode": "oauth"
|
||||
},
|
||||
"anthropic:work": {
|
||||
"provider": "anthropic",
|
||||
"mode": "api_key"
|
||||
},
|
||||
"openai:default": {
|
||||
"provider": "openai",
|
||||
"mode": "oauth"
|
||||
}
|
||||
},
|
||||
"order": {
|
||||
"anthropic": ["anthropic:default", "anthropic:work"],
|
||||
"openai": ["openai:default"]
|
||||
}
|
||||
},
|
||||
"agent": {
|
||||
"models": {
|
||||
"anthropic/claude-opus-4-5": {
|
||||
"alias": "Opus"
|
||||
},
|
||||
"openai/gpt-5.2": {
|
||||
"alias": "gpt52"
|
||||
}
|
||||
},
|
||||
"model": {
|
||||
"primary": "anthropic/claude-opus-4-5",
|
||||
"fallbacks": ["openai/gpt-5.2"]
|
||||
},
|
||||
"imageModel": {
|
||||
"primary": "openai/gpt-5.2",
|
||||
"fallbacks": ["anthropic/claude-opus-4-5"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notes
|
||||
- Canonical model keys are full `provider/model`.
|
||||
- `alias` optional; used by `/model` resolution.
|
||||
- `auth.profiles` is keyed. Default CLI login creates `provider:default`.
|
||||
- `auth.order[provider]` controls rotation order for that provider.
|
||||
|
||||
## CLI / UX
|
||||
|
||||
Login
|
||||
- `clawdbot login anthropic` → create/replace `anthropic:default`.
|
||||
- `clawdbot login anthropic --profile work` → create/replace `anthropic:work`.
|
||||
|
||||
Model selection
|
||||
- `/model Opus` → resolve alias to full id.
|
||||
- `/model anthropic/claude-opus-4-5` → explicit.
|
||||
- Optional: `/model Opus@anthropic:work` (pin auth profile for session override).
|
||||
|
||||
Model listing
|
||||
- `/model` list shows:
|
||||
- model id
|
||||
- alias
|
||||
- provider
|
||||
- auth order (from `auth.order`)
|
||||
- auth source for the current provider (env/auth.json/models.json)
|
||||
|
||||
## Fallback behavior (global)
|
||||
|
||||
Fallback list
|
||||
- Use `agent.model.fallbacks` globally.
|
||||
- No per-session fallback list; last-known-good is per-session but uses global ordering.
|
||||
|
||||
Auth profile rotation
|
||||
- If provider auth error (401/403/invalid refresh):
|
||||
- advance to next profile in `auth.order[provider]`.
|
||||
- if all fail, fall back to next model.
|
||||
|
||||
Rate limiting
|
||||
- If rate limit / quota error:
|
||||
- rotate auth profile first (same provider)
|
||||
- if still failing, fall back to next model.
|
||||
|
||||
Model not found / capability mismatch
|
||||
- immediate model fallback.
|
||||
|
||||
## Image routing
|
||||
|
||||
Rule
|
||||
- If current text model supports image input, use it.
|
||||
- Else use `agent.imageModel` (primary then fallbacks).
|
||||
|
||||
Support detection
|
||||
- From model catalog `input` tags when available (e.g. `image` in models.json).
|
||||
- If unknown: treat as text-only and use `agent.imageModel`.
|
||||
|
||||
## Migration (doctor + gateway auto-run)
|
||||
|
||||
Inputs
|
||||
- `agent.model` (string)
|
||||
- `agent.modelFallbacks` (string[])
|
||||
- `agent.imageModel` (string)
|
||||
- `agent.imageModelFallbacks` (string[])
|
||||
- `agent.allowedModels` (string[])
|
||||
- `agent.modelAliases` (record)
|
||||
|
||||
Outputs
|
||||
- `agent.models` map with keys for all referenced models
|
||||
- `agent.model.primary/fallbacks`
|
||||
- `agent.imageModel.primary/fallbacks`
|
||||
- `auth.profiles` seeded from current auth.json + env (as `provider:default`)
|
||||
- `auth.order` seeded with `["provider:default"]`
|
||||
|
||||
Auto-run
|
||||
- Gateway start detects legacy keys and runs doctor migration.
|
||||
|
||||
## Open questions
|
||||
|
||||
1) Per-provider vs per-model auth order
|
||||
- Proposed: per-provider only (`auth.order`).
|
||||
- Alternative: allow `agent.models[...].authOrder` override.
|
||||
|
||||
2) /model auth pinning
|
||||
- Do we support `/model Opus@profile`? If not, keep purely automatic rotation.
|
||||
|
||||
3) Image routing
|
||||
- If model catalog lacks input tags, should we require explicit `agent.imageModel` or probe at runtime?
|
||||
|
||||
4) Legacy compatibility
|
||||
- Keep reading old keys if migration fails, or hard-break?
|
||||
|
||||
Reference in New Issue
Block a user