Skip to content

netclaw model

Assign LLMs to roles: Main, Fallback, and Compaction. Run netclaw model for an interactive TUI, or use subcommands to script it.

You need at least one provider configured first. If you haven’t added one, see netclaw provider.

Terminal window
netclaw model # launch TUI
netclaw model <subcommand> [options] # CLI mode

Three roles, and only Main is required:

RolePurposeWhen unset
MainPrimary model for all interactionsRequired, can’t be cleared
FallbackAutomatic failover for every role when its own model is unavailable (rate limits, network errors, provider outages), Compaction includedFalls back to Main
CompactionContext summarization with a cheaper/faster modelFalls back to Main

Role names are case-insensitive.

Compaction runs automatically when a session’s context approaches the model’s token limit.

Terminal window
netclaw model

Model Manager listing Main on lab-llama with demo-model, and Fallback and Compaction on my-ollama with qwen2:0.5b, with Max out and Thinking at their defaults and all marked Manual

All three roles are assigned here, with Main on a different provider from the other two. The Provider column stops at 40 characters, so a long type label such as OpenAI-compatible is cut with an ellipsis.

The manager lists the three roles with the provider, model, output limit (Max out) and thinking level behind each one. An unset limit shows default 32000 and an unset level shows default. Select a role to reassign it, or use the hotkeys:

KeyAction
↑ / ↓Navigate roles
EnterAssign model to selected role
DDiscover available models from a provider
PEdit the highlighted role’s output limit and thinking level
CClear the highlighted optional role (Fallback or Compaction) at once
EscBack (does nothing on the role overview)
Ctrl+QQuit from any screen

C on Main shows Cannot clear the main model role. and on an unset role Fallback role is not set.

P probes the provider for the model’s capability, then opens Model properties for the role’s definition:

  • Max output tokens: a text box. Blank means the default, 32000.
  • Thinking level: default, then off to max. Tab switches field and ↑ / ↓ picks a level. Levels the provider or model doesn’t offer are greyed with the reason beside them.
  • Enter saves and Esc cancels. A rejected value shows Not saved: <reason>.

When another role shares the definition, the panel says Also used by: <role> and the change applies to each of them. On a provider with no thinking dialect, only the output field is editable. See Output limit and thinking level.

Model properties for Main on lab-llama: Max output tokens blank with default 32000, and thinking levels where only default and off are offered

This endpoint doesn’t report thinking support, so only default and off are offered, and the ReasoningEffort dialect can’t send max at all.

Enter opens the assignment flow: pick a provider, discover its models, confirm. Discovery times out after 45 seconds and shows up to 30 results. If yours isn’t listed, pick “Enter model ID manually…” and type it in (e.g., qwen3:30b, llama3.2:latest).

Terminal window
netclaw model list
Role Provider Model ID Context Window Max out Thinking
Main lab-llama demo-model (default) default 32000 default
Fallback (not set)
Compaction (not set)

Context window shows (default) unless you’ve set an explicit --context-window value, in which case it prints it, such as 65,536 tokens. Max out shows the definition’s --max-output-tokens with thousands separators (64,000), or default 32000 when unset. Thinking shows off, low, medium, high, max or default. The table resolves roles to their provider and model. It doesn’t show definition names or modality overrides, so read the config file for those.

This reads netclaw.json and applies any NETCLAW_Models__* variables set in your shell, the way the daemon does with its own environment. When one applies, a last line names it: Note: this shell's environment (NETCLAW_Models__Roles__Main) is applied. The daemon uses its own environment. It doesn’t query the running daemon. With no models configured, it prompts you to run model set or open the TUI.

If a role points at a definition that doesn’t exist, list names the bad reference and stops:

Error: Models:Roles:Main references unknown definition 'does-not-exist'. Defined: lab-llama-demo-model. Fix the name, or run `netclaw model set main <provider> <model>`.
Fix the Models section in netclaw.json, then rerun `netclaw model list`.

Open the config, compare Roles against Definitions, and make the names agree. This usually happens after you rename a definition and forget a role. netclaw doctor flags the same thing (it won’t auto-fix it). A running daemon ignores the bad edit and keeps its previous models, and netclaw status says config on disk not applied until you fix it. A daemon that restarts with the bad file stops at startup with the same one-line message.

Terminal window
netclaw model set <role> <provider> <model-id> [options]
FlagDescriptionDefault
--context-window <tokens>Override context window size (positive integer)Provider-detected
--clear-context-windowDrop the override and go back to detection
--input-modalities <list>Comma-separated Text, Image, Audio, VideoDetected
--output-modalities <list>Same values, for outputDetected
--clear-modalitiesDrop both modality overrides
--max-output-tokens <tokens>Output limit for every call of this model (positive integer). Thinking tokens count inside it32000, clamped per call
--clear-max-output-tokensDrop the limit and go back to the default
--thinking <level>off, low, medium, high or maxModel default
--clear-thinkingDrop the level

Use --context-window when a local model doesn’t report its window (discovery shows -), or to cap usage below the model’s actual maximum. Use the modality flags when detection gets a model’s capabilities wrong, such as an Ollama vision model reported as text-only.

Terminal window
netclaw model set main remote-gpu qwen3-vl:32b \
--context-window 65536 \
--input-modalities "Text, Image" \
--output-modalities "Text"

Each flag and its --clear-* partner are mutually exclusive:

Error: --context-window and --clear-context-window cannot be combined.

The same goes for --max-output-tokens with --clear-max-output-tokens and --thinking with --clear-thinking.

Modality names are case-insensitive and are stored canonicalized, so text,image lands on disk as "Text, Image". Only the four names are accepted. Anything else, including a raw integer, is rejected:

Error: invalid modalities '1'. Use a comma-separated list of: Text, Image, Audio, Video (or --clear-modalities to remove the override).

--max-output-tokens caps the reply for every call of the model, and thinking tokens count inside it. With no value, a hosted API gets 32000, capped to the model’s known maximum and clamped to its context window. Anthropic replies used to stop at 1024 tokens, so cost per call can rise on upgrade. A self-hosted server gets 32000 clamped to its context window only when the window is known, from ContextWindow or the server’s own probe. Otherwise netclaw sends no limit field.

--thinking sets one provider-neutral level, and netclaw maps it to the switch each provider has. A level the provider or model doesn’t offer is rejected, and the error lists the levels that are. netclaw never sends a nearby level instead.

Terminal window
netclaw model set main my-anthropic claude-opus-5-5 --max-output-tokens 64000 --thinking high

set validates the whole definition before it saves and leaves netclaw.json unchanged on an error:

Error: Models:Definitions:lab-llama-demo-model:MaxOutputTokens (40000) must be below the context window (32768).
Error: --max-output-tokens must be a positive integer.
Error: invalid thinking level '3'. Use off, low, medium, high, or max (or --clear-thinking).

A limit above the model’s probed maximum is rejected too (... is above the maximum output of this model (N tokens).).

An openai-compatible provider has no thinking dialect until you set one, so every level is rejected:

Error: Thinking level 'high' is not offered by provider 'lab-llama': no thinking dialect is set; set VendorOptions:ThinkingDialect on the provider to ChatTemplateKwargs, ReasoningEffort, DeepSeek, or None. Provider 'lab-llama' offers no thinking level. Set Providers:lab-llama:VendorOptions:ThinkingDialect to ChatTemplateKwargs, ReasoningEffort, DeepSeek, or None.

When set detects a llama.cpp server, it saves ReasoningEffort itself and prints Detected thinking dialect ReasoningEffort; saved Providers:<name>:VendorOptions:ThinkingDialect. For any other server, set the dialect yourself on the provider:

"lab-llama": {
"Type": "openai-compatible",
"Endpoint": "http://llm.example.internal:8080/v1",
"VendorOptions": { "ThinkingDialect": "ReasoningEffort" }
}
DialectLevels it can send
ReasoningEffortoff, low, medium, high
DeepSeekoff, low, high, max
ChatTemplateKwargsoff
Nonenone

A dialect only says which levels can be sent. The model must offer the level too. On an endpoint that doesn’t report thinking support, as most generic openai-compatible servers don’t, only off is accepted, and only with a dialect other than None:

Error: Thinking level 'high' is not offered by provider 'lab-llama': thinking support unknown for this endpoint. Provider 'lab-llama' offers off.

Hand-edited values face the same rules. Four edits fail daemon startup and the netclaw doctor Chat Client check: a Thinking level the dialect can’t send, any level other than off on an Ollama provider with VendorOptions:DisableThinking: true, a MaxOutputTokens at or above ContextWindow, and a VendorOptions:ThinkingDialect value that isn’t a valid dialect. The first two end Daemon startup will fail until this is resolved. The other two say Invalid inference configuration or The daemon will not start with this configuration and tell you to fix the Models section or the provider values. A running daemon keeps its previous models until you fix it.

set and the --clear-* flags edit the model definition, the stored facts about a given provider and model pair. Assigning a role only repoints a reference at a definition. The one exception is --thinking on a provider with no dialect, where set can also write the provider’s VendorOptions:ThinkingDialect. That’s the whole point: switch a role away from a model and back, and its overrides are still there.

Terminal window
netclaw model set main remote-gpu qwen3:30b --context-window 65536
netclaw model set main remote-gpu qwen3:8b # 30b's definition is untouched
netclaw model set main remote-gpu qwen3:30b # still 65536

Clearing removes the property outright rather than writing a sentinel, so a cleared value reads as “detect this at runtime”.

If another role uses the same definition, set says so and the change applies to each of them:

Note: definition 'lab-llama-demo-model' is also used by: Fallback. The change applies to each of them.

Running set again on the model a role already uses keeps that role’s own definition. To give two roles different limits on one model, hand-edit a second definition under another name (for example sonnet-low and sonnet-high) and point the roles at them.

The role must be main, fallback or compaction. Anything else prints Error: Unknown role 'bogus'. Valid roles: main, fallback, compaction.

set accepts a context window below 4,096 tokens, but the daemon won’t. It ignores the edit, netclaw status reports config on disk not applied: ... ContextWindow (2000) is below minimum (4096), and netclaw doctor fails the Chat Client check. Set it back to 4,096 or more.

The provider must already exist in your config. If it doesn’t, the error lists your configured providers:

Error: Provider 'my-cloud' not found in configuration.
Configured providers: lab-llama

Shrinking Main’s context window prints a warning because existing sessions with longer histories may fail until compacted.

The daemon restarts itself after a valid edit to netclaw.json. After environment-variable changes, restart it yourself: netclaw daemon stop && netclaw daemon start (or docker restart netclaw in a container).

Terminal window
netclaw model discover <provider>

Discovery hits the provider’s API live, so it has to be reachable:

Discovering models from 'lab-llama' (openai-compatible) at http://llm.example.internal:8080...
Model ID Context Window Cost (in/out per 1M)
demo-model 131,072 -
1 model(s) found.

Cost shows - when the provider doesn’t report it, which is common with Ollama and OpenAI-compatible endpoints. An unknown provider prints Error: Provider '<name>' not found in configuration. and exits 1. An unreachable server prints Error: Connection failed: Connection refused (host:port) (or Name or service not known). A server with no /v1/models prints Error: The openai-compatible models API was not found at <url>/v1/models. The endpoint may end in /v1 or not, as Self-hosted providers explains.

Terminal window
netclaw model clear <role>

Clears Fallback or Compaction. Cannot clear Main:

Error: Cannot clear the main model role. Use `netclaw model set main` to change it instead.

The role assignment goes away and the definition stays. Re-assign that model later and its overrides are still there.

Terminal window
# Set main model on a remote Ollama server
netclaw model set main remote-gpu qwen3:30b --context-window 32768
# Add a smaller fallback model on the same provider
netclaw model set fallback remote-gpu qwen3:8b
# Use a cloud model for compaction
netclaw model set compaction my-anthropic claude-sonnet-4
# Raise the output limit and think harder
netclaw model set main my-anthropic claude-opus-5-5 --max-output-tokens 64000 --thinking high
# Back to the defaults for both
netclaw model set main my-anthropic claude-opus-5-5 --clear-max-output-tokens --clear-thinking
# Tell netclaw a local model can see images when detection says otherwise
netclaw model set main remote-gpu qwen3-vl:32b --input-modalities "Text, Image"
# Undo that override and let detection decide again
netclaw model set main remote-gpu qwen3-vl:32b --clear-modalities
# Drop a context-window cap you no longer need
netclaw model set main remote-gpu qwen3:30b --clear-context-window
# See what models an Ollama server has available
netclaw model discover my-ollama
# Remove the fallback assignment
netclaw model clear fallback

Assignments live in ~/.netclaw/config/netclaw.json under the Models key. Definitions hold the model facts and roles point at them by name:

{
"Models": {
"Definitions": {
"remote-gpu-qwen3-30b": {
"Provider": "remote-gpu",
"ModelId": "qwen3:30b",
"Provenance": "Manual",
"ContextWindow": 65536,
"InputModalities": "Text, Image",
"OutputModalities": "Text",
"MaxOutputTokens": 16000,
"Thinking": "Off"
},
"remote-gpu-qwen3-8b": {
"Provider": "remote-gpu",
"ModelId": "qwen3:8b",
"Provenance": "Manual"
}
},
"Roles": {
"Main": "remote-gpu-qwen3-30b",
"Fallback": "remote-gpu-qwen3-8b"
}
}
}

Thinking is stored PascalCase (Off, Low, Medium, High, Max). model set names new definitions after the provider and model (remote-gpu-qwen3-30b), but the names are yours. Hand-edit them to anything readable and point the roles at the new name. Definitions stick around after you switch a role away, which is what keeps their overrides intact.

Models configuration covers the fields in full. Older configs use an inline shape that netclaw still reads. See Migrating model configuration.

The daemon restarts itself after the config changes.

After you set your models, run netclaw status to confirm the daemon picked them up.

0 on success, 1 on invalid arguments, unknown provider, or validation failure.