buildwithnexusv0.15.1
Menu

Models & providers

Every provider below uses one of three wire protocols: Anthropic Messages, OpenAI chat completions, or Ollama's native API. Pick a provider during setup or re-run bwn init. Environment variables override stored keys. With no saved setup and no terminal, as in CI, bwn uses the first provider whose key is set, or the one named with --provider.

ProviderKindKey
Anthropic (Claude)remoteANTHROPIC_API_KEY
OpenAIremoteOPENAI_API_KEY
OpenRouterremoteOPENROUTER_API_KEY
GroqremoteGROQ_API_KEY
Hugging FaceremoteHF_TOKEN
Ollamalocal—
llama.cpp serverlocal—
LM Studiolocal—
OpenAI-compatible endpointremote or localCUSTOM_API_KEY (optional)

Switching models with /model

/model switches the model and the provider mid-session. Before it saves anything or reports success, it sends a one-token probe through the real request path to check the key, the model name, and the server. For Ollama, it checks the list of installed models instead, because a probe could spend minutes loading a large model. If the API key is missing, /model prompts you for it. If Ollama is not running, it shows the steps to install Ollama, start the server, and pull the model. If the probe fails, you keep your current model.

/model gpt-4o                        # provider inferred and validated
/model ollama/qwen2.5-coder          # checked against `ollama list` first
/model meta-llama/llama-3.3-70b      # any OpenRouter model, by org/model name
/model http://localhost:8000/v1 my-model   # any OpenAI-compatible server (vLLM, TGI, LiteLLM)

Custom endpoints work without a key, which is how vLLM runs by default. If you set CUSTOM_API_KEY, bwn refuses to send it over plain HTTP to anything but a loopback address. bwn saves a custom endpoint's key for that endpoint only, so /model to a new address asks for that address's key. CUSTOM_API_KEY from the environment goes to one custom endpoint per run, the first one bwn looks up a key for. When the run starts on a custom endpoint, that is the one.

Local models

To run with no API key and keep your code on your machine:

  1. Install Ollama from ollama.com and start it. The desktop app starts the server. If you don't use the desktop app, run ollama serve.
  2. Pull a coding model: ollama pull qwen2.5-coder.
  3. Run bwn and pick Ollama at setup, or switch an existing setup with /model ollama/qwen2.5-coder.

On the native Ollama path, bwn reads each model's context window from Ollama and sets num_ctx to match, up to 32k. This stops Ollama from truncating long prompts without warning. A num_ctx set in the model's Modelfile wins, even above 32k, up to the model's own maximum. When Ollama does not report the window, bwn uses 8,192 tokens. To use a different value, set context_tokens.

A model with a context window under 32k tokens gets a compact set of 10 tools instead of the full set, because small models make more mistakes with a long tool list. On Ollama, llama.cpp, LM Studio and any OpenAI-compatible endpoint, even a remote gateway, bwn assumes 8,192 tokens when the server does not report the window. Such a model gets the compact set. If the real window is 32k or more, set context_tokens to it to get the full set. MCP tools you add stay in the compact set.

Some small models write tool calls as text instead of native tool calls. Qwen2.5-Coder wraps them in tags such as <tool_call>, and Gemma writes a Python-style call in a tool_code fence. bwn parses those calls, so a model as small as 1.5B parameters can write files. bwn runs such a call only when it opens the reply, or ends the reply after one short lead-in line. A call inside an explanation stays text.

Timeouts and redirects

Connecting times out after 15 seconds. A streamed reply may pause for up to 300 seconds between chunks. On slower local hardware, set BWN_READ_TIMEOUT_SECS to a higher value. bwn retries a request only when it could not connect, or when the server replied with HTTP 429, 500, 502, 503, 504 or 529. It retries 3 times by default. A server that answers 503 while it loads a model gets 14 retries, about two minutes. BWN_MAX_RETRIES replaces both counts with one value from 0 to 20. bwn retries a refused connection once, whatever the setting. bwn does not retry an out-of-memory error. If a request times out or its connection drops after bwn sent it, bwn reports the error. It does not send the request again, because the server may still be working on it.

bwn does not follow redirects, so your API key goes only to the base_url you set. A 3xx reply becomes an error that names the redirect target.

Vision

bwn sends image and video attachments only to models that accept images. Every current Claude model accepts images. For a model on Ollama, LM Studio or llama.cpp, bwn asks the server first, unless context_tokens is set. Ollama lists the model's capabilities, LM Studio reports the model type, and llama.cpp reports its modalities. When bwn does not ask, or the server says nothing, bwn decides from the model name, for example gpt-4o, o3, gemini, llava, qwen-vl, gemma3, llama3.2-vision or moondream. Set "vision": true or "vision": false in settings.json to decide for yourself. For a text-only model, bwn prints a notice instead of dropping the attachment without telling you. See Multimodal input.

Some local vision models, such as gemma3 on Ollama, have no native tool calling. When the server replies "does not support tools", bwn lists the tools in the system prompt instead and reads the calls from the model's text. The same model can then look at a screenshot and edit files. bwn prints this once per session: ⟳ gemma3:4b has no native tool calling — describing tools in the prompt instead.

bwn stores keys in ~/.buildwithnexus/.env.keys. On Linux and macOS the file has mode 0600. On Windows, bwn restricts it to your user account. Data & privacy lists what each request carries and what stays on your machine.

If your API key was rejected

An HTTP 401 or 403 from a remote provider means the key is wrong, revoked, or belongs to another account or project. Run bwn init and enter the new key for the same provider. Or set the provider's environment variable, such as ANTHROPIC_API_KEY, which overrides the stored key. A local server needs no key. A gateway behind the custom provider reads CUSTOM_API_KEY.

New in 0.15. Run /login in a session, or buildwithnexus login, to replace the stored key. bwn checks the new key with the provider before saving it. In a session, the error for a rejected key points to /login. In a headless run such as bwn run, it names buildwithnexus login or the provider's key variable. The /model picker labels that provider key rejected. See What's new in 0.15.

Reasoning depth

/effort off|low|medium|high sets the reasoning depth. You can also set it with --effort or with "reasoning_effort" in settings. The default is off. bwn maps the level to each API's own control. Claude 4.6 and later get adaptive thinking with an effort level, and earlier Claude models get a thinking budget. OpenAI reasoning models, meaning the o-series and GPT-5, get reasoning_effort. Native Ollama gets think. When an Ollama model answers that it does not support thinking, bwn sends the request again without think and leaves it off for that model for the rest of the session. bwn never sends reasoning parameters to non-reasoning or local OpenAI-compatible models.

Tokens and cost

bwn records the token usage the server reports for every reply: input, output, cache read, and cache write. /cost shows the session totals and an estimated price for known models. Local servers show $0.00 (local). Unknown models show tokens only, and bwn never makes up a price for them. /context uses the measured size of the last request when one is available, and then labels the total "measured from the last request". --max-budget-usd 2 or "max_budget_usd": 2 stops the agent before the next request once the estimated cost passes the limit. To give a price to a model the built-in table does not know, add it under "prices" in settings.json, in USD per million tokens. With a cap set, bwn sends no request to a model with no known price, because it could not count the cost. At startup it exits with code 2 and asks for a prices entry. A model on Ollama's native API, even on another machine, and any server on a loopback address are exempt, because bwn counts them as free. Anthropic requests carry prompt-cache breakpoints on the system prompt and the last message.

Native tools on local servers

With llama.cpp, LM Studio, vLLM and any OpenAI-compatible server on a loopback address, bwn sends native tool schemas on the first try. It retries once without native tools when an HTTP 400 error names tools, or when the error rejects the message roles or says the model "does not support" something, such as images. A retry after an error that names images also leaves the images out. When the 400 behind the retry names tools, the chat template or message roles, bwn sends every later request to that endpoint without native tools for the rest of the session. After any other rejection, the next request tries native tools again. If a model still answers with tool calls in tagged text, the recovery parser reads them.