395 lines
16 KiB
Markdown
395 lines
16 KiB
Markdown
# Providers and Models
|
|
|
|
OpenSquilla supports multiple LLM providers through one configuration surface.
|
|
You can run direct single-model mode or enable SquillaRouter for tiered routing.
|
|
|
|
Use this page when you need to configure a provider, inspect model support, or
|
|
choose between direct model mode and router mode.
|
|
|
|
## Inspect Providers
|
|
|
|
List provider metadata from the local install:
|
|
|
|
```sh
|
|
opensquilla providers list
|
|
opensquilla providers list --json
|
|
```
|
|
|
|
Show runtime provider diagnostics from the running gateway:
|
|
|
|
```sh
|
|
opensquilla providers status
|
|
opensquilla providers status openrouter --json
|
|
opensquilla providers status --probe-models
|
|
```
|
|
|
|
`providers list` does not require a running gateway. `providers status` does.
|
|
|
|
## Configure a Provider
|
|
|
|
Interactive:
|
|
|
|
```sh
|
|
opensquilla providers configure openrouter
|
|
```
|
|
|
|
Non-interactive onboarding-style configuration:
|
|
|
|
```sh
|
|
export OPENROUTER_API_KEY="sk-..."
|
|
opensquilla configure provider --provider openrouter --api-key-env OPENROUTER_API_KEY
|
|
```
|
|
|
|
Direct provider examples:
|
|
|
|
```sh
|
|
opensquilla configure provider --provider openai --model gpt-5.4-mini --api-key-env OPENAI_API_KEY
|
|
opensquilla configure provider --provider anthropic --model claude-sonnet-4-5 --api-key-env ANTHROPIC_API_KEY
|
|
opensquilla configure provider --provider gemini --model gemini-2.5-flash --api-key-env GEMINI_API_KEY
|
|
opensquilla configure provider --provider ollama --model llama3.1
|
|
```
|
|
|
|
Prefer environment-variable references for API keys so secrets are not written
|
|
directly into configuration files.
|
|
|
|
### Endpoint (base URL) resolution
|
|
|
|
`llm.base_url` resolves **explicit config → derived env var → provider
|
|
default**:
|
|
|
|
- A custom endpoint you saved (Web UI advanced options, `config.set`, or a
|
|
hand-written `base_url` in the TOML) always wins.
|
|
- If the config never chose an endpoint — no `base_url`, or the field still
|
|
holds the provider's own default URL — the derived environment variable
|
|
(`OPENAI_BASE_URL`, `OPENROUTER_BASE_URL`, `<PROVIDER>_BASE_URL`) applies.
|
|
This is the lever for pointing a whole fleet at a corporate proxy without
|
|
touching each config file.
|
|
- `OPENSQUILLA_LLM_BASE_URL` enters at config-model construction (the
|
|
`OPENSQUILLA_LLM_*` settings layer): it fills `base_url` whenever the TOML
|
|
does not set one, and the resolver then treats it as an explicit value —
|
|
so it beats the provider-derived vars above, while a `base_url` written in
|
|
the TOML still beats it.
|
|
|
|
API keys follow the same explicit-config-first rule via `api_key` /
|
|
`api_key_env`.
|
|
|
|
## Onboarding-Verified Providers
|
|
|
|
This build exposes onboarding support for:
|
|
|
|
- TokenRhythm
|
|
- OpenRouter
|
|
- OpenAI
|
|
- Anthropic
|
|
- Ollama
|
|
- DeepSeek
|
|
- Gemini
|
|
- DashScope / Qwen
|
|
- Moonshot AI
|
|
- Zhipu / Z.AI
|
|
- Baidu Qianfan
|
|
- Volcengine Ark
|
|
|
|
The provider registry may contain additional compatible providers for advanced
|
|
or self-hosted setups. Use `opensquilla providers list` on your install for the
|
|
current catalog.
|
|
|
|
### OpenAI: `openai` vs `openai_responses`
|
|
|
|
OpenAI is exposed as two provider ids that share the same `OPENAI_API_KEY` and
|
|
base URL (`https://api.openai.com/v1`):
|
|
|
|
- `openai` — the chat/completions request shape. Use this for standard
|
|
chat-style turns and broad tool compatibility.
|
|
- `openai_responses` — the native Responses-API shape (capabilities `chat` and
|
|
`responses`). Use this when you want Responses-API behavior rather than the
|
|
chat/completions surface.
|
|
|
|
Both read the same key and base URL, so switching between them needs only a
|
|
`provider` change.
|
|
|
|
### Volcengine Ark: regular vs coding-plan endpoints
|
|
|
|
Use `volcengine` for regular Ark chat/completions models. Its default base URL
|
|
is the OpenAI-compatible endpoint `https://ark.cn-beijing.volces.com/api/v3`.
|
|
|
|
Use `volcengine_coding_plan` for Volcengine's OpenAI Responses-compatible coding-plan
|
|
subscription surface. Its default base URL is
|
|
`https://ark.cn-beijing.volces.com/api/coding/v3`; OpenSquilla appends
|
|
`/responses` when it sends the request.
|
|
|
|
```sh
|
|
export VOLCENGINE_API_KEY="..."
|
|
opensquilla configure provider --provider volcengine_coding_plan --model <model> --api-key-env VOLCENGINE_API_KEY
|
|
```
|
|
|
|
Use `volcengine_coding_plan_anthropic` for tools or deployments that expect the
|
|
Anthropic Messages protocol. Its default base URL is
|
|
`https://ark.cn-beijing.volces.com/api/coding`; OpenSquilla appends
|
|
`/v1/messages`.
|
|
|
|
```sh
|
|
export VOLCENGINE_API_KEY="..."
|
|
opensquilla configure provider --provider volcengine_coding_plan_anthropic --model <model> --api-key-env VOLCENGINE_API_KEY
|
|
```
|
|
|
|
Do not point either coding-plan provider at the regular `/api/v3` URL. That
|
|
regular Ark URL does not consume Coding Plan quota.
|
|
|
|
### Tencent TokenHub: CN, Anthropic-protocol, and international endpoints
|
|
|
|
Tencent's Hunyuan `hy3` / `hy3-preview` models are served on the TokenHub
|
|
platform (the legacy `api.hunyuan.cloud.tencent.com` platform is being
|
|
retired and never received `hy3`). Three experimental provider ids map the
|
|
documented endpoints:
|
|
|
|
- `tencent_tokenhub` — OpenAI-compatible chat/completions at
|
|
`https://tokenhub.tencentmaas.com/v1` (mainland; keys from the CN TokenHub
|
|
console, `TENCENT_TOKENHUB_API_KEY`). `hy3` thinking uses
|
|
`reasoning_effort` `low`/`high`, and assistant `reasoning_content` is
|
|
replayed across turns as the hy3 interleaved-thinking contract requires.
|
|
- `tencent_tokenhub_anthropic` — the same deployment's Anthropic Messages
|
|
protocol (`https://tokenhub.tencentmaas.com` + `/v1/messages`,
|
|
`x-api-key` auth, same key).
|
|
- `tencent_tokenhub_intl` — the international deployment at
|
|
`https://tokenhub-intl.tencentcloudmaas.com/v1`
|
|
(`TENCENT_TOKENHUB_INTL_API_KEY`). It is a separate Tencent Cloud account
|
|
and key system, and its model list currently carries third-party models
|
|
(DeepSeek, GLM, Kimi, MiniMax) but not `hy3`.
|
|
|
|
```sh
|
|
export TENCENT_TOKENHUB_API_KEY="..."
|
|
opensquilla configure provider --provider tencent_tokenhub --model hy3 --api-key-env TENCENT_TOKENHUB_API_KEY
|
|
```
|
|
|
|
TokenHub also hosts third-party models behind the same endpoints; OpenSquilla
|
|
does not inject thinking payloads for those ids because TokenHub does not
|
|
document their dialects on this gateway.
|
|
|
|
Tencent's Token Plan subscription (the Hy Token Plan carries `hy3` /
|
|
`hy3-preview`; the General plan adds `tc-code-latest`, DeepSeek V4, GLM-5.x,
|
|
Kimi and MiniMax ids on the same key) is exposed as two more provider ids on
|
|
the plan host:
|
|
|
|
- `tencent_token_plan` — Chat Completions at
|
|
`https://api.lkeap.cloud.tencent.com/plan/v3` (the plan endpoints do not
|
|
offer the Responses API).
|
|
- `tencent_token_plan_anthropic` — Anthropic Messages at
|
|
`https://api.lkeap.cloud.tencent.com/plan/anthropic` (+ `/v1/messages`),
|
|
bearer auth.
|
|
|
|
Both read `TENCENT_TOKEN_PLAN_API_KEY`. Plan keys are dedicated `sk-tp-…`
|
|
credentials created on the TokenHub Token Plan console page — they are not
|
|
interchangeable with pay-as-you-go TokenHub keys. Note Tencent's plan terms
|
|
restrict these keys to interactive AI-tool use and prohibit non-interactive
|
|
batch/automation calling; unattended pipelines should use the pay-as-you-go
|
|
`tencent_tokenhub` provider instead. The plans are mainland-only products —
|
|
the international site offers pay-as-you-go TokenHub only.
|
|
|
|
## Model Inspection
|
|
|
|
List models:
|
|
|
|
```sh
|
|
opensquilla models list
|
|
```
|
|
|
|
If runtime-backed model inspection cannot connect, start the gateway:
|
|
|
|
```sh
|
|
opensquilla gateway run
|
|
```
|
|
|
|
For provider metadata that does not require the gateway, use:
|
|
|
|
```sh
|
|
opensquilla providers list
|
|
```
|
|
|
|
### Context-Window Resolution Order
|
|
|
|
Context budgeting, compaction thresholds, usage pressure reporting, and the
|
|
router's capability facts all resolve a model's context window through the
|
|
same layers, first match wins:
|
|
|
|
1. **Per-model override** — `[models.<provider_id>."<model_id>"]`
|
|
`context_window` in your config. Set this for models the catalog does not
|
|
know (direct DashScope/TokenHub ids, self-hosted vLLM declaring its real
|
|
window) or to correct a wrong catalog value. Reported as source
|
|
`override` (`config` in `config.effective`, `model_override` in usage
|
|
context status).
|
|
2. **Global override** — `llm.context_window_tokens` (0 = auto). A blunt
|
|
instrument that applies to whatever model is active; the per-model
|
|
override always beats it.
|
|
3. **Model catalog** — live OpenRouter data, the vendored models.dev
|
|
snapshot, then packaged corrections.
|
|
4. **Default** — a conservative 8,192 for local runtimes (match your actual
|
|
`num_ctx`/server window with an override), 200,000 otherwise.
|
|
|
|
The Web UI exposes the per-model override under Settings → Chat Model →
|
|
Advanced, with an auto-detected / override / effective readout.
|
|
|
|
## Direct Model vs Router
|
|
|
|
Direct model mode:
|
|
|
|
```sh
|
|
opensquilla configure router --router disabled
|
|
opensquilla configure provider --provider openai --model gpt-5.4-mini --api-key-env OPENAI_API_KEY
|
|
```
|
|
|
|
Router mode:
|
|
|
|
```sh
|
|
opensquilla configure router --router recommended
|
|
```
|
|
|
|
| Mode | Use when |
|
|
| --- | --- |
|
|
| Direct model | You are testing one exact model, reproducing provider behavior, or auditing provider billing. |
|
|
| Router mode | You want normal personal-agent use where cost and task complexity vary by turn. |
|
|
|
|
For routing details, see
|
|
[`features/squilla-router.md`](features/squilla-router.md).
|
|
|
|
## Pricing and Cost Estimation
|
|
|
|
OpenSquilla reports real provider-billed cost when a provider returns it, and
|
|
estimates cost locally from token usage everywhere else. Every usage row and
|
|
by-model breakdown item is labeled so you can tell which kind of number you
|
|
are looking at.
|
|
|
|
### How a Cost Is Estimated
|
|
|
|
Each priced call is split into four token buckets — fresh input, cache read,
|
|
cache write, output — and each bucket is priced at its own rate. The result
|
|
carries a `basis` label:
|
|
|
|
| Basis | Meaning |
|
|
| --- | --- |
|
|
| `cache_aware` | All buckets present in the call have a known rate; the four-bucket math ran. |
|
|
| `cache_blind` | The call used cache tokens but a needed cache rate is unknown, so OpenSquilla fell back to pricing every input token (cache or fresh) at the plain input rate. This is a conservative upper bound, not the real charge — expect it to overstate cost on cache-heavy sessions. |
|
|
| `free` | The model or runtime is zero-priced (see local runtimes below). |
|
|
|
|
### Price Resolution Order
|
|
|
|
For a given `(model, provider)` pair, OpenSquilla resolves a price through
|
|
these layers, first match wins:
|
|
|
|
1. **Local runtime** — `ollama`, `lm_studio`, `ovms`, `vllm`, and `local` are
|
|
always free, regardless of model id.
|
|
2. **User override** — `[models.<provider_id>."<model_id>"]` in your config
|
|
(see [`configuration.md`](configuration.md) and `opensquilla.toml.example`).
|
|
3. **Model catalog** — the vendored models.dev snapshot, including per-model
|
|
cache-read/cache-write rates where upstream publishes them.
|
|
4. **Live OpenRouter endpoint price** — looked up only when the provider is
|
|
`openrouter` or unset (first-party provider ids never query the OpenRouter
|
|
marketplace); falls back to the static table if OpenRouter is unreachable.
|
|
5. **Static table** — a built-in pricing table bundled with OpenSquilla.
|
|
6. **Default** — `$3` / `$15` per million input/output tokens when nothing
|
|
else matched.
|
|
|
|
If OpenSquilla is estimating a model at the wrong price, add an override
|
|
instead of waiting for a catalog refresh:
|
|
|
|
```toml
|
|
[models.openrouter."z-ai/glm-5.2"]
|
|
input_cost_per_mtok = 0.5 # USD per million input tokens
|
|
output_cost_per_mtok = 2.0 # USD per million output tokens
|
|
cache_read_cost_per_mtok = 0.05 # USD per million cached-prompt-read tokens
|
|
cache_write_cost_per_mtok = 0.6 # USD per million cached-prompt-write tokens
|
|
```
|
|
|
|
Quote model ids that contain dots or slashes. All four fields are optional —
|
|
set only the ones you need to correct. `config.set`/`patch`/`apply` and
|
|
`opensquilla gateway reload` hot-apply these overrides; see
|
|
`opensquilla.toml.example` for more examples including self-hosted `vllm` and
|
|
`custom` endpoints.
|
|
|
|
### Cost Provenance (`costSource`)
|
|
|
|
Every usage row and by-model breakdown item carries a `costSource` (also
|
|
exposed dual-cased as `cost_source`):
|
|
|
|
| `costSource` | Meaning |
|
|
| --- | --- |
|
|
| `provider_billed` | The full cost came from a real provider-reported bill. |
|
|
| `opensquilla_estimate` | No billed cost was available; the figure is a local estimate. |
|
|
| `mixed` | The same model had both billed and unbilled calls in the aggregated row — the total is billed cost plus an estimate for the rest, not a pure bill. |
|
|
| `unavailable` | No pricing table entry and no billed cost, so no dollar figure could be produced. |
|
|
|
|
Rows also carry two additive fields: `estimateBasis` (the `cache_aware` /
|
|
`cache_blind` / `free` label above, present only when part of the row was
|
|
estimated) and `priceSource` (which resolver layer priced it — `user_override`,
|
|
`catalog`, `live_openrouter`, `static_table`, `default`, or `local_free`). The
|
|
Web UI's by-model usage cards show a small source chip for `costSource` and,
|
|
when the underlying basis is `cache_blind`, a hint that the figure is an
|
|
upper bound rather than the real cache-discounted cost.
|
|
|
|
### Which Providers Yield Billed vs. Estimated Cost
|
|
|
|
| Capability | Providers |
|
|
| --- | --- |
|
|
| Provider-billed cost | `openrouter` only |
|
|
| Cache-aware estimate possible | `anthropic`, `deepseek`, `minimax` (Anthropic-shaped), ensemble members |
|
|
| Cache-read-aware estimate only (no cache-write rate) | `openai`, `openai_responses`, `azure`, `gemini`, `openai_codex` |
|
|
| Cache-blind estimate (falls back to plain input-rate pricing when cache tokens appear) | other OpenAI-compatible provider kinds |
|
|
| Free | local runtimes (`ollama`, `lm_studio`, `ovms`, `vllm`, `local`) |
|
|
| Subscription (no invoice to compare against) | coding-plan/subscription provider kinds — treat any reported figure as an estimate, not a bill |
|
|
|
|
Use `opensquilla providers status --probe-models` and `opensquilla cost
|
|
--by-model` to see which class your configured provider/model falls into for
|
|
a given session.
|
|
|
|
### Turn and Router Budget Gates
|
|
|
|
Two per-turn agent budgets exist and behave differently:
|
|
|
|
- `max_turn_billed_cost_usd` gates only on real provider-billed cost. It is
|
|
inert (never trips) on providers or paths that never report billed cost —
|
|
do not rely on it alone outside `openrouter`.
|
|
- `max_turn_cost_usd` gates on the same accumulator used everywhere else in
|
|
this section: billed cost when the provider reports it, otherwise the
|
|
cache-aware/cache-blind estimate. It works on every provider. When it trips,
|
|
the error (`turn_cost_budget_exceeded`) states whether the total was billed,
|
|
estimated, or mixed.
|
|
|
|
SquillaRouter's session budget gate (`[squilla_router.budget]`, see
|
|
[`features/squilla-router.md`](features/squilla-router.md)) logs a
|
|
`spend_source` alongside each `router_budget.warn`/`router_budget.cap` event
|
|
and in the routing trail:
|
|
|
|
| `spend_source` | Meaning |
|
|
| --- | --- |
|
|
| `billed` | Accumulated spend is real provider-billed cost. |
|
|
| `estimate` | Accumulated spend is a local estimate for the whole session. |
|
|
| `estimate_mixed` | The session mixes billed and estimated cost. |
|
|
| `none` | No spend has been recorded yet. |
|
|
| `unknown` | Spend could not be determined; the gate suspends rather than acting on a guess. |
|
|
|
|
Read next: [`usage-and-cost.md`](usage-and-cost.md) for the `opensquilla cost`
|
|
CLI and how to read a session's usage rows.
|
|
|
|
## Provider Troubleshooting
|
|
|
|
Start with:
|
|
|
|
```sh
|
|
opensquilla doctor
|
|
opensquilla providers status
|
|
opensquilla diagnostics on
|
|
```
|
|
|
|
Check:
|
|
|
|
- the API key environment variable is set in the gateway process environment;
|
|
- the model id matches the provider;
|
|
- the base URL is correct for compatible APIs;
|
|
- proxy settings match your network;
|
|
- router is disabled when debugging one exact provider/model;
|
|
- the gateway was restarted after config changes.
|
|
|
|
---
|
|
|
|
[Docs index](README.md) · [Product guide](../README.product.md) · [Improve this page](contributing-docs.md) · [Report a docs issue](https://github.com/opensquilla/opensquilla/issues/new?template=docs_report.yml)
|