Alibaba Model Studio static-API-key providers. Each plan is registered as its own extension:
:alibaba-coding-plan -> Coding Plan subscription
(https://coding-intl.dashscope.aliyuncs.com/v1).
Env var: ALIBABA_CODING_PLAN_API_KEY.
:alibaba-token-plan -> Token Plan prepaid token bundle
(https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1).
Env var: ALIBABA_TOKEN_PLAN_API_KEY.
Both endpoints speak the OpenAI-compatible chat wire (/chat/completions,
SSE streaming with stream_options.include_usage, native tool_calls,
reasoning_content for thinking models), so svar's default
:openai-compatible-chat api-style drives them unchanged.
The plans are SEPARATE credentials: a Token Plan key is rejected by the
Coding Plan endpoint and vice versa (HTTP 401 InvalidApiKey). Hence one
provider id, one env var and one auth-file slice per plan - never a shared
ALIBABA_API_KEY fallback that would silently authenticate as the wrong
plan.
The provider ids match their models.dev slugs, which is what lets svar
resolve pricing, context windows and capabilities for the catalog models
listed in each preset; svar's KNOWN_PROVIDERS has no Alibaba entry, so
the preset here owns :base-url (svar accepts an unknown provider id
whenever a base URL is supplied).
Auth lifecycle:
vis-agent providers auth alibaba-coding-plan (or
vis-agent providers auth alibaba-token-plan) takes the API key once
and persists it under ~/.vis/alibaba-auth.json, as canonical
snake_case JSON - top-level plan tag, then api_key / saved_at
(never kebab, never keyword keys).:api-key wins so status/limits match the
key used for model calls; the env vars override the auth file when
present so CI / scripted setups stay home-directory-free.vis-agent providers status alibaba-coding-plan reports the source
(config / env / file) without exposing the full key.vis-agent providers logout alibaba-coding-plan clears the persisted
key for that plan only; the other plan stays intact.Alibaba Model Studio static-API-key providers. Each plan is registered as its own extension:
:alibaba-coding-plan -> Coding Plan subscription
(https://coding-intl.dashscope.aliyuncs.com/v1).
Env var: `ALIBABA_CODING_PLAN_API_KEY`.
:alibaba-token-plan -> Token Plan prepaid token bundle
(https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1).
Env var: `ALIBABA_TOKEN_PLAN_API_KEY`.
Both endpoints speak the OpenAI-compatible chat wire (`/chat/completions`,
SSE streaming with `stream_options.include_usage`, native `tool_calls`,
`reasoning_content` for thinking models), so svar's default
`:openai-compatible-chat` api-style drives them unchanged.
The plans are SEPARATE credentials: a Token Plan key is rejected by the
Coding Plan endpoint and vice versa (HTTP 401 `InvalidApiKey`). Hence one
provider id, one env var and one auth-file slice per plan - never a shared
`ALIBABA_API_KEY` fallback that would silently authenticate as the wrong
plan.
The provider ids match their models.dev slugs, which is what lets svar
resolve pricing, context windows and capabilities for the catalog models
listed in each preset; svar's `KNOWN_PROVIDERS` has no Alibaba entry, so
the preset here owns `:base-url` (svar accepts an unknown provider id
whenever a base URL is supplied).
Auth lifecycle:
1. `vis-agent providers auth alibaba-coding-plan` (or
`vis-agent providers auth alibaba-token-plan`) takes the API key once
and persists it under `~/.vis/alibaba-auth.json`, as canonical
snake_case JSON - top-level plan tag, then `api_key` / `saved_at`
(never kebab, never keyword keys).
2. Subsequent runs read the configured provider key, env var, or
persisted key. A TUI/config `:api-key` wins so status/limits match the
key used for model calls; the env vars override the auth file when
present so CI / scripted setups stay home-directory-free.
3. `vis-agent providers status alibaba-coding-plan` reports the source
(config / env / file) without exposing the full key.
4. `vis-agent providers logout alibaba-coding-plan` clears the persisted
key for that plan only; the other plan stays intact.Anthropic providers.
Providers:
:anthropic - normal Anthropic API key provider. API key lives in Vis config.:anthropic-coding-plan - Claude subscription OAuth provider. OAuth
credentials live in ~/.vis/anthropic-auth.json.Runtime calls hand the OAuth access token to svar; svar handles only the Anthropic Messages API wire differences for subscription tokens.
Anthropic providers. Providers: - `:anthropic` - normal Anthropic API key provider. API key lives in Vis config. - `:anthropic-coding-plan` - Claude subscription OAuth provider. OAuth credentials live in `~/.vis/anthropic-auth.json`. Runtime calls hand the OAuth access token to svar; svar handles only the Anthropic Messages API wire differences for subscription tokens.
GitHub Copilot OAuth provider - device flow authentication + token lifecycle.
Auth flow:
ghu_...)api.github.com/copilot_internal/v2/tokenToken detection priority (same as Copilot CLI):
~/.vis/github-copilot-auth.jsonCOPILOT_GITHUB_TOKEN env varGH_TOKEN env varGITHUB_TOKEN env varcopilot-cli service) - if security CLI availableWorks with both Individual and Business/Enterprise plans.
Enterprise users can pass :enterprise-domain for GHE.
GitHub Copilot OAuth provider - device flow authentication + token lifecycle. Auth flow: 1. Device flow -> user visits github.com/login/device, enters code 2. Poll until authorized -> receive OAuth token (`ghu_...`) 3. Exchange OAuth token for short-lived Copilot API token via `api.github.com/copilot_internal/v2/token` 4. Auto-refresh the API token before expiry Token detection priority (same as Copilot CLI): 1. Persisted OAuth token in `~/.vis/github-copilot-auth.json` 2. `COPILOT_GITHUB_TOKEN` env var 3. `GH_TOKEN` env var 4. `GITHUB_TOKEN` env var 5. macOS Keychain (`copilot-cli` service) - if `security` CLI available Works with both Individual and Business/Enterprise plans. Enterprise users can pass `:enterprise-domain` for GHE.
LM Studio local provider preset extension.
LM Studio local provider preset extension.
Mistral.ai provider preset extension. API keys are configured by channels.
Mistral.ai provider preset extension. API keys are configured by channels.
Ollama local provider preset extension.
Ollama local provider preset extension.
OpenAI provider preset extension. API keys are configured by channels.
OpenAI provider preset extension. API keys are configured by channels.
OpenAI Codex (ChatGPT OAuth) provider.
Headless clients use Codex's official device authorization flow, so the browser can be on a phone or desktop while the gateway stays behind NAT. The interactive CLI also retains the registered loopback PKCE flow. Neither path rewrites a provider-registered redirect URI.
Tokens are persisted at ~/.vis/openai-codex-auth.json. The access
token is a JWT; Codex requests require the embedded ChatGPT account
id, so this namespace validates/extracts it during login/refresh.
The dynamic quota report lives here too (dynamic-limits!): it fetches
https://chatgpt.com/backend-api/wham/usage, selects the regular Codex
bucket (or the nested Codex Spark bucket) and exposes the 5h and 7d
percentage windows as normalized Vis limit rows.
OpenAI Codex (ChatGPT OAuth) provider. Headless clients use Codex's official device authorization flow, so the browser can be on a phone or desktop while the gateway stays behind NAT. The interactive CLI also retains the registered loopback PKCE flow. Neither path rewrites a provider-registered redirect URI. Tokens are persisted at `~/.vis/openai-codex-auth.json`. The access token is a JWT; Codex requests require the embedded ChatGPT account id, so this namespace validates/extracts it during login/refresh. The dynamic quota report lives here too (`dynamic-limits!`): it fetches `https://chatgpt.com/backend-api/wham/usage`, selects the regular Codex bucket (or the nested Codex Spark bucket) and exposes the 5h and 7d percentage windows as normalized Vis limit rows.
OpenCode Go (https://opencode.ai/go) static-API-key provider.
OpenCode Go is a flat-rate ($10/month) subscription gateway serving a curated
set of open-source coding models from ONE endpoint
(https://opencode.ai/zen/go/v1) over TWO wire dialects. Vis surfaces them
as a SINGLE first-class provider — :opencode-go — that routes each model to
the correct wire automatically:
OpenAI chat wire (/chat/completions, svar default): GLM, Kimi, DeepSeek, MiMo, Hy3.
Anthropic Messages wire (/messages, per-model :api-style :anthropic):
MiniMax, Qwen.
svar reads (or (:api-style model-map) (:api-style provider)) at request
build time, so a per-model :api-style override on the Anthropic models
inside :default-models is all that is needed — one provider, one key, one
endpoint, two wires.
Authentication is the shared static-API-key shape, owned by
com.blockether.vis.internal.provider.key-store and declared by BOOK below:
lookup order, status, logout, the token envelope and the interactive
vis-agent providers auth opencode-go flow all come from there.
What stays here is what only OpenCode Go knows: which model rides which wire,
and the live /usage quota report (dynamic-limits! below).
OpenCode Go (https://opencode.ai/go) static-API-key provider.
OpenCode Go is a flat-rate ($10/month) subscription gateway serving a curated
set of open-source coding models from ONE endpoint
(`https://opencode.ai/zen/go/v1`) over TWO wire dialects. Vis surfaces them
as a SINGLE first-class provider — `:opencode-go` — that routes each model to
the correct wire automatically:
OpenAI chat wire (/chat/completions, svar default):
GLM, Kimi, DeepSeek, MiMo, Hy3.
Anthropic Messages wire (/messages, per-model `:api-style :anthropic`):
MiniMax, Qwen.
svar reads `(or (:api-style model-map) (:api-style provider))` at request
build time, so a per-model `:api-style` override on the Anthropic models
inside `:default-models` is all that is needed — one provider, one key, one
endpoint, two wires.
Authentication is the shared static-API-key shape, owned by
`com.blockether.vis.internal.provider.key-store` and declared by `BOOK` below:
lookup order, status, logout, the token envelope and the interactive
`vis-agent providers auth opencode-go` flow all come from there.
What stays here is what only OpenCode Go knows: which model rides which wire,
and the live `/usage` quota report (`dynamic-limits!` below).OpenRouter static-API-key provider (https://openrouter.ai/api/v1).
OpenRouter is a multi-provider gateway speaking the OpenAI chat wire, so no
:api-style override is needed - svar's default OpenAI transport handles it.
Model names are vendor/model slugs (anthropic/claude-sonnet-4.5,
openai/gpt-5.1, ...).
Authentication is the shared static-API-key shape, owned by
com.blockether.vis.internal.provider.key-store and declared by BOOK below:
lookup order, status, logout, the token envelope and the interactive
vis-agent providers auth openrouter flow all come from there.
What stays here is what only OpenRouter knows: the starter catalog, the live
model enrichment, and the credit report from GET /api/v1/key - the credits
this key has consumed and, for capped keys, its limit.
OpenRouter static-API-key provider (https://openrouter.ai/api/v1). OpenRouter is a multi-provider gateway speaking the OpenAI chat wire, so no `:api-style` override is needed - svar's default OpenAI transport handles it. Model names are `vendor/model` slugs (`anthropic/claude-sonnet-4.5`, `openai/gpt-5.1`, ...). Authentication is the shared static-API-key shape, owned by `com.blockether.vis.internal.provider.key-store` and declared by `BOOK` below: lookup order, status, logout, the token envelope and the interactive `vis-agent providers auth openrouter` flow all come from there. What stays here is what only OpenRouter knows: the starter catalog, the live model enrichment, and the credit report from `GET /api/v1/key` - the credits this key has consumed and, for capped keys, its limit.
Z.ai (ZhipuAI) static-API-key provider helpers. Each plan is registered as its own extension:
:zai-coding-plan -> coding-plan subscription
(https://api.z.ai/api/coding/paas/v4).
Env var: ZAI_CODING_API_KEY.
:zai -> pay-as-you-go / Pass gateway
(https://api.z.ai/api/paas/v4).
Env var: ZAI_API_KEY.
Both endpoints serve the same GLM model family (glm-5.3-flash,
glm-5.3, glm-5-turbo, glm-5.1, ...) with effort-based reasoning
on GLM-5.3 models and binary thinking on older models (handled by svar). They
share helper code, but the runtime extension registry sees one
extension entry per provider id.
Auth lifecycle:
vis-agent providers auth zai-coding (or vis-agent providers auth zai) prompts for the API
key once and persists it under ~/.vis/zai-auth.json,
as canonical snake_case JSON - top-level plan tag, then
api_key / saved_at (never kebab, never keyword keys).:api-key wins so status/limits
match the key used for model calls; env vars
(ZAI_CODING_API_KEY, ZAI_API_KEY) override the auth file when
present so CI / scripted setups stay home-directory-free.vis-agent providers status zai-coding reports the source
(config / env / file) without exposing the full key.vis-agent providers logout zai-coding clears the persisted key for
that plan only; the other plan stays intact.Z.ai (ZhipuAI) static-API-key provider helpers. Each plan is registered as its own extension:
:zai-coding-plan -> coding-plan subscription
(https://api.z.ai/api/coding/paas/v4).
Env var: `ZAI_CODING_API_KEY`.
:zai -> pay-as-you-go / `Pass` gateway
(https://api.z.ai/api/paas/v4).
Env var: `ZAI_API_KEY`.
Both endpoints serve the same GLM model family (`glm-5.3-flash`,
`glm-5.3`, `glm-5-turbo`, `glm-5.1`, ...) with effort-based reasoning
on GLM-5.3 models and binary thinking on older models (handled by svar). They
share helper code, but the runtime extension registry sees one
extension entry per provider id.
Auth lifecycle:
1. `vis-agent providers auth zai-coding` (or `vis-agent providers auth zai`) prompts for the API
key once and persists it under `~/.vis/zai-auth.json`,
as canonical snake_case JSON - top-level plan tag, then
`api_key` / `saved_at` (never kebab, never keyword keys).
2. Subsequent runs read the configured provider key, env var, or
persisted key. A TUI/config `:api-key` wins so status/limits
match the key used for model calls; env vars
(`ZAI_CODING_API_KEY`, `ZAI_API_KEY`) override the auth file when
present so CI / scripted setups stay home-directory-free.
3. `vis-agent providers status zai-coding` reports the source
(config / env / file) without exposing the full key.
4. `vis-agent providers logout zai-coding` clears the persisted key for
that plan only; the other plan stays intact.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |