Engine configuration
Each agent's agents/<slug>/config/engine.toml configures its inference providers. It is required and must define exactly one default provider for that agent using isGlobalDefault = true. Agents do not inherit providers from a runtime-root config/engine.toml.
The file maps provider names to provider tables.
toml
[default]
apiBase = "https://api.openai.com/v1"
apiKey = "not-needed"
defaultModel = "gpt-5.6"
isGlobalDefault = true
kind = "openai"Provider fields
| Field | Required | Default | Description |
|---|---|---|---|
apiBase | Yes | — | Absolute provider API base URL. |
apiKey | No | ["not-needed"] | One API key, or an array of keys for rotation. |
defaultModel | Yes | — | Default model name. |
isGlobalDefault | No | false | Marks exactly one provider as the global default. |
kind | No | "openai" | Provider kind: openai, anthropic, or openai-codex. |
authId | No | "default" | OAuth credential id used by openai-codex. |
availableModels | No | "analyze" | Explicit model list, or "analyze" to resolve the provider's models on demand; a list replaces analysis for that provider. |
customHeaders | No | {} | Extra request headers sent with provider requests. |
maxGenerationRetries | No | 2 | Separate retry limits for provider failures and undelivered-output recovery, each counted across a turn. |
useFilesApi | No | false | Files API mode; false or "kimi". |
useJpegForImages | No | false | Send images as JPEG. |
useToolChoiceAuto | No | false | Prefer automatic tool choice. |
History pruning uses the model's token budget, not a sliding turn cap. The runtime uses an explicit per-model contextWindow first, then provider metadata, then a fixed 128000-token fallback when neither supplies a window. Budget pruning drops history near the token limit rather than shifting the visible prefix on every turn, preserving provider prompt caching between pruning events. Set contextWindow explicitly for models with smaller windows when their provider does not publish usable metadata. The removed maxTurns setting is migrated automatically; see upgrade instructions.
Provider context-window metadata set to 0 is treated as unspecified, as with ArliAI's Fastest routing alias, without discarding metadata for other models. OpenAI-compatible discovery checks context_length, then top_provider.context_length, then max_input_tokens, using the first positive value. If all are absent, null, or zero, configure contextWindow explicitly or the runtime uses its fixed fallback.
When availableModels = "analyze", the /model override subcommand analyzes the provider's model list on demand, so models published after the runtime started are selectable without a restart. Autocomplete reuses a successful analysis for 30 seconds and renews that window on every keystroke, so one lookup covers an operator typing a model name.
When a header value contains $session, the runtime replaces it on generation requests with the lower-case hexadecimal SHA-256 hash of the current session ID. The same hash is sent as the provider prompt cache key, so configured headers and provider-side cache partitioning share one opaque session identifier instead of the internal ID. The placeholder is also resolved for OpenAI-compatible file uploads and Codex requests.
Per-model overrides
A [<provider>.models.<model>] table overrides context and reasoning settings for one model.
toml
[default.models.gpt-5.6]
contextWindow = 128000
contextBudget = 0.8
contextHardBudget = 0.95
reasoning = "medium"
reasoningBudget = 8192
supportsVision = true
supportsVideo = false
systemOnlyAtStart = true
maxImagesPerRequest = 10
repeatedToolCallThreshold = 3
toolFailThreshold = 3| Field | Default | Description |
|---|---|---|
contextWindow | — | Context window size in tokens; uses provider metadata when absent, then a 128000-token fallback. |
contextBudget | 0.6 | Soft context budget as a fraction of the window. |
contextHardBudget | 0.85 | Hard context budget as a fraction of the window. |
reasoning | true | Reasoning toggle or mode: true, false, or xhigh, high, medium, low, minimal, none. |
reasoningBudget | 16384 | Reasoning token budget. |
supportsVision | true | Whether the model accepts images. |
supportsVideo | false | Whether the model accepts video. |
systemOnlyAtStart | true | Send system messages after the initial system prompt as user messages. |
maxImagesPerRequest | — | Maximum images per request. |
repeatedToolCallThreshold | 3 | Consecutive identical successful calls, with unchanged input and result, allowed before the turn fails. |
toolFailThreshold | 3 | Consecutive failures per tool before disabling it for the rest of the turn; respond and no-response are exempt. |
systemOnlyAtStart leaves the initial system prompt unchanged and converts later system injections, including OpenAI-compatible tool-use reminders, to the user role without changing their content or stored session history. Set it to false to preserve the provider's previous behavior: OpenAI-compatible and Codex requests keep later system roles, while Anthropic omits system messages from conversation history because its API only accepts a separate initial system prompt.
A repeated-call limit applies to every turn, including heartbeats. A tripped limit never produces HEARTBEAT_OK; the scheduler records the turn as failed and continues with the next scheduled heartbeat.
The runtime captures the date, context usage, and any near-limit warning once at the start of each turn. This metadata is labeled as a turn-start snapshot, not a live reading. Tool continuations and generation retries retain the original snapshot before that turn's tool activity instead of appending a fresh user-context message after each tool result. The snapshot is request-local and is not saved in session history; the next turn captures a new one. Context pruning still runs before each inference request.
Provider kinds
openai— OpenAI-compatible chat completions API.anthropic— Anthropic messages API.openai-codex— OpenAI Codex via ChatGPT OAuth credentials managed by thecodexcommand.
Codex models
An openai-codex provider talks to the ChatGPT Codex backend, so apiBase must be https://chatgpt.com/backend-api; the runtime appends codex/responses for generation and codex/models for the model list.
toml
[codex]
kind = "openai-codex"
apiBase = "https://chatgpt.com/backend-api"
authId = "default"
defaultModel = "gpt-5.6-terra"
isGlobalDefault = trueThe runtime asks that backend for the account's model list, so models it publishes after the runtime started are selectable without a restart. The query reuses its result for five minutes, sends the provider's customHeaders, and falls back to a catalog snapshot bundled with the build when it fails, logging a warning instead of failing the command. Only models the backend publishes as visible appear in the list and in autocomplete; a hidden model stays selectable by naming it in availableModels or in a [codex.models.<model>] table.
A configured model name reaches the backend unchanged apart from a stripped vendor/ prefix and normalized case and separators, so the runtime never substitutes a different model for the one you chose. Reasoning follows the levels the backend advertises for that model: an explicit reasoning mode is used when the model advertises it, false and minimal use the model's least advertised level, and an unset mode uses the model's advertised default. The reasoning picklist stops at xhigh, so max, which the backend accepts for some models, is not selectable in configuration. Context windows resolve from the same catalog, so contextWindow is optional when the backend reports one.
Codex image input is automatically downscaled when its 32-pixel patch count would exceed the backend's 30,000-patch per-image limit. The resized image is sent as WebP, or JPEG when useJpegForImages = true.
OpenAI-compatible request headers
The openai provider sends these attribution headers with chat-completions requests:
| Header | Value |
|---|---|
HTTP-Referer | https://github.com/CutieZone/CireilClaw |
X-OpenRouter-Categories | personal-agent,cli-agent |
X-OpenRouter-Title | CireilClaw |
These headers support OpenRouter application attribution and are sent for every openai provider because the route supports OpenAI-compatible APIs.
Use customHeaders for additional provider-specific request headers.
Reload
The runtime watches engine.toml and applies changes live to subsequent turns.