8. Models and parameters

8.1 Choosing a model

Settings → Models has three pages: Providers (connections and API keys), Model settings (the model list and parameters) and Routing (which model each scenario uses, see §8.2.1). The Model settings page lists every model you can use:

  • Models the plan quota grants you (decided server-side).
  • 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.

The "Accepts image input" flag: model entries carry an "Accepts image input" checkbox — only when it's ticked does the input box allow pasting or dragging images along with a message (see §5.3.3). The built-in model table flags qwen-3.8-27b and the Landi N2.7 series; for providers you add yourself, tick it manually.

Picking an unavailable model no longer "silently downgrades the whole session": previously, choosing a model that turned out not to be usable could quietly switch the session to something else with no clear notice, affecting every subsequent message. That is now reported on the spot — one bad pick can't derail the whole session.

8.1.1 Provider protocol

The Type dropdown in Settings → Models → 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/completions for 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.

A 404 for an unknown model name is normal: the Delta endpoint answers 404 for a model it doesn't know. That means "no such model", not "the route is missing", and it no longer counts as an unusable endpoint that triggers a wholesale fallback.

Automatic slow-down from the service's own throttling hints: when the model service returns rate-limit information in its response headers (remaining quota, reset time), the client paces outbound requests adaptively to keep from hitting 429 in the first place, rather than colliding and then backing off.

8.1.2 Custom request headers (your own providers only)

The Advanced options section at the bottom of the Settings → Models → 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-version etc.), so they can override Authorization / User-Agent and 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 Host header has no effect (Go's HTTP stack requires changing req.Host, not the header). Use a reverse proxy if you need to rewrite Host.

Built-in providers (the plan-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.

Recommended sampling parameters for Landi N2.6 / N2.7: the built-in AVL-Zero Landi N2.6 / N2.7 series have been reset once to Temperature 1.0, Top-P 0.95 (each model is reset only once; same-series models fetched later come with these values already); values you change by hand afterwards are never overwritten again. Note that "Reset to defaults" in the parameter dialog gives every model the same 0.7 / 0.95.

All of these parameters are edited in the single "Model settings" drawer — the entry from the "Model settings" page and the one from the "Providers" 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 routing: choosing a model per scenario

Settings → Models → Routing decides which model each scenario uses; changes take effect on the next call:

Scenario Strategies Default Notes
Main session Global / Per session Global "Global": all sessions share one "current model". "Per session": each session remembers its own model, and a new session snapshots the current global choice as its starting point. Automatic session naming uses the main session's model
Subtasks Main session / Persona / Preferred model Main session "Persona" uses the model in the subagent definition (or the one given when delegating), falling back to the main session's model. With "Preferred model" you also choose what happens when unavailable: fall back to Main session or Persona
Routines Main session / Per task / Preferred model Main session "Per task" uses the model each task picks; only under this strategy does the task dialog show a model selector. A task without a model, or an unavailable preferred model, falls back to the main session's model
Hooks Main session / Preferred model Main session A model set on the hook entry takes precedence; an unavailable preferred model falls back to the main session's model
sec.decompile / code.ask / Memory auto-extraction Random / Lowest cost / Best quality Best quality Chooses only among enabled 澜砥 (Landi) models whose provider has an API key; if none is available, the current session's model is used
Auto-repair Off / Ask before switching / Switch automatically Ask before switching When the selected model is unavailable or the upstream fails, whether to use another provider that has the same model enabled; there is also a "Keep after switching" toggle (default off) — see §8.2.4
  • "Preferred model" candidates: only enabled, online models whose provider has a usable API key are listed. If a model you picked is later disabled, taken offline or loses its key, the button turns amber and shows "(unavailable)", and calls use the fallback.
  • How cost / quality are ranked: AVL-Zero publishes no pricing, so ranking is inferred from model names — Flash is cheapest, then Mid, then the standard tier; newer versions rank higher on quality; Preview-style variants rank below the release of the same version. When every candidate has a price configured, Lowest cost sorts by price.
  • Model given when delegating: the model argument the main agent passes when delegating a subtask only takes effect under "Persona"; under other strategies the setting decides.
  • Per-session fallback: if a session's recorded model has become unavailable (deleted / decommissioned), it falls back to the global choice — never stuck.
  • "Which model does this turn use" is decided in one place: the UI, background calls and the terminal UI (TUI) reach the same answer. Under "Per session", if the session is still on the default model picked for you when it was created, it follows changes to the current default-model setting; a model you picked explicitly is used as-is — even if it's unavailable it isn't quietly swapped, but handed to "Auto-repair" instead. Sessions in local mode only use the model you chose for them and don't follow the default model or the global choice.
  • Turns the app starts by itself follow the same rules: continuation after auto-compaction, the "Continue" nudge, todo check-ins, goal continuation, self-healing, the test gate and resuming interrupted tasks all use the model you chose for that session, never a model from another provider by mistake. The current choice under "Global" is also saved to the config.

[!warning] Where data goes: code snippets retrieved by code.ask, sample bytes sent by sec.decompile, and session content used for memory extraction go to the 澜砥 model chosen by routing (usually the built-in AVL-Zero cloud) — not necessarily the current session's model. The provider / model fields in the tool result show where it actually went. To keep data within the provider the current session uses, turn on local mode (see §13.2.2).

Session duplication and .zsession import / export carry the model field along, so handoffs across machines and people don't lose the choice. .zsession export also bundles each sub-Agent's work record — every subtask 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 → Model settings 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.2.4 "Auto-repair" when the selected model is unavailable

The selected model can become unavailable because its provider was deleted / disabled, the provider doesn't have that model, or the model was disabled or retired. The last row of Settings → Models → Routing, "Auto-repair", decides what happens then (it also decides backup switching on upstream failures — see §8.6):

Strategy Behaviour
Off Reports the error directly, no switching
Ask before switching (default) A confirmation bar, "Switch to a backup model?", appears above the input box, saying which model on which provider is unavailable and which provider (same model) could be used instead, with a warning that the backup may use your own key or send content to a different upstream; "Switch & send" sends through the backup, while "Not now" keeps the message without answering it for now — pick another model and you can continue generating
Switch automatically Doesn't ask; switches to the backup straight away and tells you it "switched to … automatically"
  • How the backup is picked: it only switches to another provider that has the same-named model enabled, not retired and with a usable API key (the first in provider order) — never to a different model.
  • Keep after switching (default off; shown when the strategy isn't "Off"): when on, the provider switched to becomes the model selection for that session (Per session) or globally (Global) until you choose another; when off, it only covers that run and the next turn uses the original selection again.
  • Where no confirmation bar can be shown: companion messaging, routines, hooks, subtasks, automatic continuation, context compaction, memory extraction, the terminal UI (TUI), resuming interrupted tasks and so on — under "Ask before switching" these don't switch and report the error directly, with a notice naming the scenario, model, reason and strategy in effect (once per scenario per model within 5 minutes); if the session already switched during this turn, these calls follow the backup. Resuming an interrupted task pre-checks first and writes nothing into the session if it can't start.
  • Local mode: "Switch automatically" is treated as "Ask before switching" — it never switches to an external service automatically, and where a confirmation bar can be shown the decision is still yours.
  • When the default model itself is unavailable this doesn't apply; it falls back to the first enabled model automatically.

8.2.5 Effort (Landi N2.7)

With the built-in AVL-Zero Landi N2.7 series (including suffixed variants such as 澜砥 N2.7-Flash), a battery-icon button appears to the right of the model name in the input area; open it to adjust how much the model thinks:

Level Description
Off No thinking; answers directly, fastest
Low Light thinking, for simple and well-defined tasks
High (default) Thorough thinking, for most coding tasks
Extra high Deeper thinking, for hard problems
Max Full thinking budget; slowest and uses the most
  • The two ends of the slider read "Faster / More effort"; dragging only previews, releasing saves; on the keyboard use {{kbd:←}} / {{kbd:→}}, {{kbd:Home}} / {{kbd:End}} to move, {{kbd:Enter}} or Space to select and {{kbd:Esc}} to close; the focus ring only appears when you operate by keyboard.
  • Saved per model: the setting applies to every session using that model, from the next message. When never set it shows "High (default)", and requests are sent as "High" too; "Reset to default" returns it to the unset state.
  • Other models (including same-named models in providers you add yourself) don't show this button.
  • Auxiliary calls never think: background calls such as context compaction, automatic session naming, memory extraction, hooks and sec.decompile / code.ask are always sent as "Off", regardless of your choice.
  • Check what was actually sent: the protocol line in the stats panel shows the "Effort: …" actually sent with that call; if the upstream rejects the parameter it is dropped and the call retried, in which case it shows "Default". The status bar shows the level you picked — when the two disagree, trust the stats panel.
  • Reasoning no longer leaks into the body: if an individual request goes out without an effort level and the model writes its reasoning, together with the closing </think> marker, into the body text, the reasoning and body are split apart automatically — during streaming it may show up in the body first, but the saved record and the history carried into the next turn are already split. Reasoning returned by some services when not streaming is also no longer lost wholesale.

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 / need to sign in again / 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.
  • When a reply stops mid-sentence (wraps up before finishing what it was saying, and doesn't carry on executing) or announces the next step without acting (ends by declaring "next I'll…" but calls no tool), a continuation is nudged automatically once — no need to ask "why did you stop?". The check looks at the reply's last sentence: ending normally with a full stop, asking you a question, handing a decision back to you, a polite sign-off or ending on a list are all left alone.
  • These output-type heals share one consecutive-attempt cap (default 3, lowered by historical success rate — see §8.5.1), reset after a clean finish; on hitting the cap you get the notice "self-repair gave up — … could not be corrected over several turns; manual intervention needed".
  • 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

When a model provider is persistently unavailable (no channel / upstream overloaded / upstream-side auth failure), what happens is decided by "Auto-repair" under Settings → Models → Routing (see §8.2.4): "Off" reports the error directly; "Switch automatically" doesn't ask and switches straight to the backup, telling you it "switched to … automatically and retried"; the default, "Ask before switching", 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.