Skip to main content

Configuration

16.1 Environment Variables

GAIA has no GAIA_LOG_LEVEL environment variable. Log levels are set programmatically through gaia.logger (set_level(name, level)); the default is INFO.
~/.gaia/gaia.log is size-capped and shared safely by every GAIA process. Two variables tune the cap: Both must be whole numbers of at least 1; any other value stops GAIA at startup with an error naming the variable.

Local context window

Overrides below 32,768 tokens emit a warning because agent prompts may be truncated. The requested value is still honored; increase or unset it if replies are empty. Set GAIA_CTX_SIZE to a positive integer token count to override the requested context window for CLI startup, agent construction, installer verification and subsequent local-model reloads. For example:
Without an override, each model gets its own window. GPU/CPU models default to 65,536 tokens, and unknown local models use the same default. Registered models keep their own default, and a registered model that declares its native maximum and its KV-cache cost per token is sized to this machine’s memory: the largest 8,192-token step whose KV cache fits beside the weights, the embedder (on shared memory) and 10% headroom, up to that maximum and never below its default. NPU (FLM) models are capped at 32,768 tokens with a warning; default_device = npu does not cap a GPU model. Invalid nonempty values fail with an actionable error; unset or blank values use the default. That window is then checked against the memory free right now, for a model GAIA knows the size of on a Lemonade on this machine. When other apps leave too little, the window shrinks in 8,192-token steps, keeping 1 GB free and room for the embedder, to no less than 32,768 tokens, and a warning names the free memory. The choice holds until the process restarts, so a loaded model is not reloaded as free memory moves. A load that would not fit even then is refused with how much memory it needs; see Not enough free memory. GAIA_CTX_SIZE is never shrunk, but its load is still refused when it would run the machine out of memory.

Reasoning effort

Set GAIA_REASONING_EFFORT to low, medium or high to choose where a model that grades its reasoning (gpt-oss) starts each request. Unset, it starts at medium. The agent can still change it for the rest of a request with set_reasoning_effort, and a request that passes chat_template_kwargs.reasoning_effort itself wins over both: chat titles, memory upkeep, document summaries and gaia llm pass low. Any other value fails the request with an error naming the variable. Models with an on/off thinking switch ignore it.

Per-request time budget

A long document arrives as one large prefill, and the bigger the context window the longer that takes. GAIA derives the budget from the window rather than keeping a separate number that can drift from it: 32,768 tokens gets 1,024 seconds, 65,536 gets 2,048, and everything is capped at 3,600 so a wedged request still ends. GAIA_CTX_SIZE moves it too. The same value is used at both ends — the private Lemonade instance’s global_timeout and GAIA’s own client read timeout — so the server cannot be allowed more time than the client will wait. Set GAIA_LEMONADE_REQUEST_BUDGET to a positive integer number of seconds to override it on a machine slower than that assumption:
Invalid nonempty values fail with an actionable error rather than falling back to the derived number; unset or blank values use it. This applies to the embedded Lemonade instance GAIA owns — a system-wide install keeps its own settings. Larger windows require model support and more KV-cache memory. The override is a requested window, not proof of the backend’s effective capacity. A model already loaded with a sufficient window is reused; lowering the value takes effect on the next load rather than forcing eviction. SDK ctx_size_override remains a separate instance-scoped exact pin and takes precedence over this environment variable. Installer verification uses the profile being installed, even before it is saved. This setting does not change overflow recovery; it controls requested load capacity.

Retrying a flaky model endpoint

Hosted OpenAI-compatible endpoints, the proxies in front of them, and a busy local server occasionally drop a request: a reset connection, a 502/503/504, a 429, a 500 from a failed upstream hop. GAIA retries those, and only those. Each request is retried with exponential backoff and full jitter, honouring Retry-After up to the longest-wait cap below. Retried: connection errors and timeouts, 408, 429, 502, 503, 504, and 500 unless its body says the request itself was rejected — including a cloud model’s 429 or 502 that Lemonade reports inside a stream that had already opened, and a cloud connection that dropped or hit Lemonade’s time limit with no status code at all. Never retried: 400 (including content-filter rejections), 401, 403, 404, 413, 422, a TLS certificate failure, and context-window overflow. A cloud time limit is retried only within the request’s deadline, never again at the agent-step level. A stream is retried here only before its first token, so one request never repeats output. Each retry shows a status line such as “The model service is busy — retrying in 8s (2/4)”. A stalled stream is one that stops sending data. A hosted model gets the idle limit above from the moment it accepts the request; a local model gets the whole request budget (GAIA_LEMONADE_REQUEST_BUDGET) for its first token, because prefilling a long prompt legitimately sends nothing for minutes, and the idle limit after that. Any byte, a keep-alive included, resets the clock. A stall before the first token of a hosted model is retried once; the time it spent does not count against GAIA_LLM_RETRY_DEADLINE. A stall after the first token, or a local model that used its whole prefill budget, ends the request with a message saying so. Stop ends a stalled stream at once. A hosted model answering without streaming sends its reply all at once, so it gets the reply limit above (300 s, or 1 s per 40 requested tokens if longer) and the same single retry; a local model keeps its request budget. A busy Lemonade — one another app shares, which is loading a model — is waited for, not treated as down. A server that accepts the connection but does not answer a status check within 5 s is reported as busy: GAIA never starts or restarts it, and the first request prints that it is waiting. A request that fails while Lemonade reports a model load in progress waits for that load instead of backing off, and is retried once it ends, within its attempts. That time does not count against GAIA_LLM_RETRY_DEADLINE; GAIA_LLM_LOAD_WAIT bounds it, and the error names that setting when it runs out. A cloud model’s request never waits on a local load. An agent step whose request still fails after that is not the end of the run. The agent waits, then asks again with its conversation and tool history intact; the wait doubles each time. Only the model call is repeated: tools that already ran are not run again. If a reply was cut off part-way, the partial text stays on screen and the new reply follows it; only the new reply becomes the answer. If the model stays unreachable, the turn ends with a one-line answer that says where it stopped and which tool calls are kept, the run is reported as failed, and saying “continue” once the service is back picks the task up from there.
Invalid nonempty values fail with an actionable error; unset or blank values use the defaults. Stop cancels any retry wait, within half a second: the client’s backoff as well as the agent’s wait between step attempts, and the wait on a busy Lemonade, even while a check of the server is still waiting for its answer.

16.2 Configuration in Code