mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 18:01:22 +00:00
* feat(ai): add Vercel AI Gateway routing support Add vercelGatewayRouting to OpenAICompletionsCompat, parallel to openRouterRouting. When a model targets ai-gateway.vercel.sh and has vercelGatewayRouting configured, the openai-completions provider passes providerOptions.gateway with only/order in the request body. Changes: - types.ts: VercelGatewayRouting interface + field on OpenAICompletionsCompat - openai-completions.ts: buildParams passes providerOptions.gateway, detectCompat/getCompat include the new field - model-registry.ts: VercelGatewayRoutingSchema for models.json validation - test: updated Required<OpenAICompletionsCompat> in test fixture * docs(coding-agent): add vercelGatewayRouting to custom models documentation
225 lines
5.6 KiB
Markdown
225 lines
5.6 KiB
Markdown
# Custom Models
|
|
|
|
Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.pi/agent/models.json`.
|
|
|
|
## Table of Contents
|
|
|
|
- [Basic Example](#basic-example)
|
|
- [Supported APIs](#supported-apis)
|
|
- [Provider Configuration](#provider-configuration)
|
|
- [Model Configuration](#model-configuration)
|
|
- [Overriding Built-in Providers](#overriding-built-in-providers)
|
|
- [OpenAI Compatibility](#openai-compatibility)
|
|
|
|
## Basic Example
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"ollama": {
|
|
"baseUrl": "http://localhost:11434/v1",
|
|
"api": "openai-completions",
|
|
"models": [
|
|
{
|
|
"id": "llama-3.1-8b",
|
|
"name": "Llama 3.1 8B (Local)",
|
|
"contextWindow": 128000,
|
|
"maxTokens": 32000
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The file reloads each time you open `/model`. Edit during session; no restart needed.
|
|
|
|
## Supported APIs
|
|
|
|
| API | Description |
|
|
|-----|-------------|
|
|
| `openai-completions` | OpenAI Chat Completions (most compatible) |
|
|
| `openai-responses` | OpenAI Responses API |
|
|
| `anthropic-messages` | Anthropic Messages API |
|
|
| `google-generative-ai` | Google Generative AI |
|
|
|
|
Set `api` at provider level (default for all models) or model level (override per model).
|
|
|
|
## Provider Configuration
|
|
|
|
| Field | Description |
|
|
|-------|-------------|
|
|
| `baseUrl` | API endpoint URL |
|
|
| `api` | API type (see above) |
|
|
| `apiKey` | API key (see value resolution below) |
|
|
| `headers` | Custom headers (see value resolution below) |
|
|
| `authHeader` | Set `true` to add `Authorization: Bearer <apiKey>` automatically |
|
|
| `models` | Array of model configurations |
|
|
|
|
### Value Resolution
|
|
|
|
The `apiKey` and `headers` fields support three formats:
|
|
|
|
- **Shell command:** `"!command"` executes and uses stdout
|
|
```json
|
|
"apiKey": "!security find-generic-password -ws 'anthropic'"
|
|
"apiKey": "!op read 'op://vault/item/credential'"
|
|
```
|
|
- **Environment variable:** Uses the value of the named variable
|
|
```json
|
|
"apiKey": "MY_API_KEY"
|
|
```
|
|
- **Literal value:** Used directly
|
|
```json
|
|
"apiKey": "sk-..."
|
|
```
|
|
|
|
### Custom Headers
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"custom-proxy": {
|
|
"baseUrl": "https://proxy.example.com/v1",
|
|
"apiKey": "MY_API_KEY",
|
|
"api": "anthropic-messages",
|
|
"headers": {
|
|
"x-portkey-api-key": "PORTKEY_API_KEY",
|
|
"x-secret": "!op read 'op://vault/item/secret'"
|
|
},
|
|
"models": [...]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Model Configuration
|
|
|
|
| Field | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `id` | Yes | Model identifier |
|
|
| `name` | No | Display name |
|
|
| `api` | No | Override provider's API for this model |
|
|
| `contextWindow` | No | Context window size in tokens |
|
|
| `maxTokens` | No | Maximum output tokens |
|
|
| `reasoning` | No | Supports extended thinking |
|
|
| `input` | No | Input types: `["text"]` or `["text", "image"]` |
|
|
| `cost` | No | `{"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0}` |
|
|
|
|
## Overriding Built-in Providers
|
|
|
|
Route a built-in provider through a proxy without redefining models:
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"anthropic": {
|
|
"baseUrl": "https://my-proxy.example.com/v1"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
All built-in Anthropic models remain available. Existing OAuth or API key auth continues to work.
|
|
|
|
To fully replace a built-in provider with custom models, include the `models` array:
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"anthropic": {
|
|
"baseUrl": "https://my-proxy.example.com/v1",
|
|
"apiKey": "ANTHROPIC_API_KEY",
|
|
"api": "anthropic-messages",
|
|
"models": [...]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## OpenAI Compatibility
|
|
|
|
For providers with partial OpenAI compatibility, use the `compat` field:
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"local-llm": {
|
|
"baseUrl": "http://localhost:8080/v1",
|
|
"api": "openai-completions",
|
|
"compat": {
|
|
"supportsUsageInStreaming": false,
|
|
"maxTokensField": "max_tokens"
|
|
},
|
|
"models": [...]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
| Field | Description |
|
|
|-------|-------------|
|
|
| `supportsStore` | Provider supports `store` field |
|
|
| `supportsDeveloperRole` | Use `developer` vs `system` role |
|
|
| `supportsReasoningEffort` | Support for `reasoning_effort` parameter |
|
|
| `supportsUsageInStreaming` | Supports `stream_options: { include_usage: true }` (default: `true`) |
|
|
| `maxTokensField` | Use `max_completion_tokens` or `max_tokens` |
|
|
| `openRouterRouting` | OpenRouter routing config passed to OpenRouter for model/provider selection |
|
|
| `vercelGatewayRouting` | Vercel AI Gateway routing config for provider selection (`only`, `order`) |
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"openrouter": {
|
|
"baseUrl": "https://openrouter.ai/api/v1",
|
|
"apiKey": "OPENROUTER_API_KEY",
|
|
"api": "openai-completions",
|
|
"models": [
|
|
{
|
|
"id": "openrouter/anthropic/claude-3.5-sonnet",
|
|
"name": "OpenRouter Claude 3.5 Sonnet",
|
|
"compat": {
|
|
"openRouterRouting": {
|
|
"order": ["anthropic"],
|
|
"fallbacks": ["openai"]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Vercel AI Gateway example:
|
|
|
|
```json
|
|
{
|
|
"providers": {
|
|
"vercel-ai-gateway": {
|
|
"baseUrl": "https://ai-gateway.vercel.sh/v1",
|
|
"apiKey": "AI_GATEWAY_API_KEY",
|
|
"api": "openai-completions",
|
|
"models": [
|
|
{
|
|
"id": "moonshotai/kimi-k2.5",
|
|
"name": "Kimi K2.5 (Fireworks via Vercel)",
|
|
"reasoning": true,
|
|
"input": ["text", "image"],
|
|
"cost": { "input": 0.6, "output": 3, "cacheRead": 0, "cacheWrite": 0 },
|
|
"contextWindow": 262144,
|
|
"maxTokens": 262144,
|
|
"compat": {
|
|
"vercelGatewayRouting": {
|
|
"only": ["fireworks", "novita"],
|
|
"order": ["fireworks", "novita"]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|