From 98a1e7b86bf7ee64f85692b40df1096e45b75325 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 26 Jan 2026 00:11:10 +0100 Subject: [PATCH] docs(coding-agent): add models.md for custom providers and models --- packages/coding-agent/docs/models.md | 166 +++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 packages/coding-agent/docs/models.md diff --git a/packages/coding-agent/docs/models.md b/packages/coding-agent/docs/models.md new file mode 100644 index 00000000..4633cba1 --- /dev/null +++ b/packages/coding-agent/docs/models.md @@ -0,0 +1,166 @@ +# 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 ` 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` |