8. Models and parameters
8.1 Choosing a model
Settings → Models lists every model you can use:
- Models the shared quota grants you (decided by your organisation).
- Models you've added yourself (OpenAI / Anthropic / Aliyun Tongyi / Volcengine / your own LLM service, etc.).
Each workspace picks its default model; you can also swap per-conversation.
8.1.1 Provider protocol
The Type dropdown in Settings → Providers offers three protocols:
| Type | When to use |
|---|---|
| AVL Delta compatible | What the built-in AVL-Zero defaults to. Sends only the per-turn delta to the server; the stable history isn't re-sent. Combined with the prefix-cache work, this saves bandwidth and tokens and speeds responses |
| OpenAI (compatible) | OpenAI's official API, Aliyun Tongyi, Volcengine, Kimi, Moonshot, DeepSeek, self-hosted OpenAI-compatible proxies, etc. |
| Anthropic | Claude official endpoint, Anthropic-compatible proxies — uses x-api-key + anthropic-version headers; supports tool calls, streaming, extended thinking, retries |
The "Refresh from API" button dispatches by protocol and pulls the model list.
Delta endpoint auto-fallback: if the server doesn't yet offer the Delta API (404 / 405 / 501), the session transparently falls back to standard
chat/completionsfor that round; the conversation isn't interrupted. Real authentication errors (401 / 403) are still reported as such and not silently downgraded.The stats panel shows which protocol each call took (OpenAI Chat / Anthropic Messages / AVL Delta) and the client version. Delta auto-fallback also shows up in the meta. Every model request carries client version, protocol identifier and a browser-like User-Agent for easier gateway-side logging.
8.1.2 Custom request headers (your own providers only)
The Advanced options section at the bottom of the Settings → Providers edit panel expands a Custom Headers editor — available only on providers you added yourself (not built-in ones). Add as many key / value rows as you need; each one is attached to every outbound request to that provider. Useful for proxies and gateways that require extra auth headers, gateway identifiers or special version headers.
- Scope: applies on all four request paths — OpenAI, Anthropic, and AVL Delta (streaming + non-streaming).
- Order and override: custom headers are applied after the built-in headers (auth /
User-Agent/anthropic-versionetc.), so they can overrideAuthorization/User-Agentand other defaults. Avoid same-name keys if you don't want to override. - Injection-safe: empty keys are skipped; any entry whose key or value contains CR/LF is rejected to block header-injection attacks.
- Known limit: a custom
Hostheader has no effect (Go's HTTP stack requires changingreq.Host, not the header). Use a reverse proxy if you need to rewrite Host.
Built-in providers (the shared-quota AVL-Zero etc.) don't expose this entry — only providers you add yourself are editable.
8.2 Parameters
Per model:
- Temperature: 0–1, controls randomness.
- Top-P: 0–1, nucleus sampling.
- Max output tokens: per-reply cap; no hard limit — values above the model's nominal limit are allowed, the upstream API enforces its real limit.
- Stream: streaming render (recommended on).
These are saved per workspace and per mode.
All of these parameters are edited in the single "Parameter configuration" drawer — the entry from the "Models" page and the one from the "Model provider" dialog open the same panel. Converging on a single edit surface is deliberate: previously the two edit surfaces each kept their own copy and overwrote each other, so a parameter you had just tuned could be silently wiped; now concurrent edits from both entries are checked with optimistic locking, and a conflict raises a prompt in place instead of overwriting in silence.
8.2.1 Model scope: global / per-session
The Settings → Models tab has a segmented control at the top for the current-model scope:
| Scope | Behaviour |
|---|---|
| Global (default) | All sessions share one "current model"; upgrade is zero-impact |
| Per-session | Each session remembers its own model; switching to a session swaps back to that session's last model. New sessions snapshot the current global choice as a starting point and can diverge after |
Under "Per-session", if a session's recorded model has become unavailable (deleted / decommissioned), it auto-falls back to the global choice — never stuck.
Session duplication and
.zsessionimport / export carry the model field along, so handoffs across machines and people don't lose the choice..zsessionexport also bundles each sub-Agent's work record — every sub-task dispatched in this conversation is reconstructible when opened on another machine or shared with a colleague, so debugging / post-mortem is more complete.Import / rebuild is more robust: fixed "importing a session into a new workspace shows nothing, while a blank workspace falsely reports 'already exists'" (root cause: a misdirected write target plus reusing the original session ID causing a same-ID cross-workspace conflict) — import / rebuild now complete normally.
8.2.2 Unselected models default to collapsed
Settings → Models shows only the enabled models per provider group by default, instead of being drowned in a long list of unused entries; the bottom of each group has an "Expand N unselected models" button to see everything (and collapse again).
- Expanded state is per-provider and only remembered for the current settings session.
- Search automatically bypasses the fold: search hits show unselected models too.
- Toggling models doesn't make rows jump.
8.2.3 Slashes in model IDs are preserved
Model IDs like openrouter/free, openai/gpt-4o, anthropic/claude-3.5-sonnet — the vendor/model convention used by OpenRouter / Cloudflare / etc. — use the slash as the official separator on the upstream side. AVL Code now preserves it as-is: both manual add and refresh paths keep the slash.
If you previously hit a "model not found" error for such IDs, refresh the model list once to recover (the bad entry is replaced with the correct ID).
8.3 Multi-provider fallback
With multiple providers connected, AVL Code can run priority and fallback: if the primary provider fails or rate-limits, switch to the secondary automatically.
8.4 Context length and compaction
Different models have different context windows. AVL Code automatically triggers history compaction (Chapter 17) as you approach the limit, so conversations can go on indefinitely.
8.5 Self-repair loop: switch approach automatically on errors
When the AI hits an error it automatically switches strategy and keeps healing by error type rather than banging on the same wall. This is always on, no configuration needed; the result-type internal messages the healing injects into the conversation (auto_self_heal) are not shown in the chat, so you still see clean, normal output. An upstream error is first triaged by origin (request / gateway / upstream provider) and category (auth / rate-limit / quota / balance / no-channel / overloaded / server error / context overflow / content filtered, etc.), then mapped to a repair strategy:
| Repair strategy | When | What happens |
|---|---|---|
| Compact & retry (transient_compact) | Context overflow | Compress the context, then re-spawn (default up to 2×) |
| Switch provider (transient_fallback) | No channel / upstream overloaded / upstream auth failed | Suspend and offer a backup provider; resume on confirm (default up to 3×, see §8.6) |
| Backoff retry (backoff) | Rate-limit / timeout / network jitter | Retry on a backoff schedule (default up to 3×) |
| Hand back to you (terminal) | Insufficient balance / re-login needed / model missing | Surface a clear message and stop — no blind retry |
Even a server 5xx / 4xx with no error detail falls back to the right heal path by status code. Beyond upstream errors, the AI's own output is healed too:
- A length-truncated reply auto-continues from the cut-off point (no restart), default up to 3×.
- Reasoning that loops (repeating the same thinking) is interrupted with a prompt to conclude or take the next action.
- A reply blocked by the content filter is healed by rephrasing.
- A non-compliant tool name rejected by the upstream is auto-corrected and retried (several upstream phrasings — including prose-style errors — are recognised).
- When the same check / test keeps failing or a todo makes no progress for too long, it escalates the prompt to change approach (e.g. consider reverting and starting over) instead of repeating — and stops, handing back to you, once the cap is reached.
Network-jitter handling: on a transient disconnect / temporary offline, it waits for the network to recover and then retries, and that "waiting for the network" does not consume the retry budget — stepping into an elevator or a Wi-Fi blip won't burn through your retries. Connection-level transients (connection reset, a name that won't resolve for a moment, an interrupted handshake) are correctly identified as network problems rather than lumped into a generic "model error", so you don't waste time checking upstream config.
Self-healing also learns from history (see §8.5.1): the success/failure of each heal kind is recorded and used to adjust how many attempts are allowed next time — kinds that almost never recover get fewer tries before handing back, while still-recoverable ones aren't given up too easily.
8.5.1 Heal attempts adjust to history
Self-repair consults past heal outcomes (persisted to self-heal-stats.json in the config directory) and adjusts the allowed attempts per heal kind: with too few samples (< 5) it uses the default cap; a smoothed historical success rate < 20% drops it to 1, 20–50% to −1, ≥ 50% keeps the default. Every kind keeps at least 1 attempt; history can only lower the cap, never raise it above the default.
8.6 Provider auto-failover (with confirmation)
When a model provider is persistently unavailable (no channel / upstream overloaded / upstream-side auth failure), AVL Code neither silently switches nor stalls — it suspends the turn and pops a switch-confirmation bar above the input box:
- It only switches to another enabled provider that serves the same model (the first one, in config order, that actually holds that model — never a downgrade to a different model).
- The bar reads like "Switch to a backup model? Preferred provider {A} is unavailable. Retry this turn with {B} (model {M})?", and warns "⚠ The backup may use your own API key (your cost) or send content to a different upstream."
- Click "Switch & retry" to resume seamlessly on the new provider, or "Not now" to skip the switch.
