Models Select a model /model Choose from the available catalog, or provide a model identifier with /model NAME or agent-cli --model NAME. Use /session-info to verify the active choice. /effort displays or changes reasoning effort where supported. Accepted command values include none, low, medium, high, xhigh, and max; individual models may support only a subset. Changing models does not mean all providers expose identical tools. The provider determines authentication and transport; the model's dialect determines its prompts and tool interface. Reasoning effort and visible reasoning agent-cli --provider xai --effort high --show-raw-reasoning Without an explicit or resumed effort, xAI defaults to high, OpenAI, OpenRouter and Gemini to medium, and Claude Code to xhigh. /effort opens the supported-choice picker; /effort high changes the current session. Grok's dialect excludes max: an interactive request for it is rejected without changing the current effort. Startup normalizes an unsupported Grok effort to high. An endpoint can still reject a level accepted by the harness if its own model does not implement it. By default the viewport shows provider-supplied reasoning summaries. --show-raw-reasoning also includes text content supplied in reasoning items. For example, a supplied summary “Checking the tests” is visible in either mode; additional supplied reasoning text appears only with the flag. This display option neither requests disclosure of hidden reasoning nor reconstructs content absent from the response. If the provider sends no such content, there is nothing extra to display. Automatic compaction thresholds --compact-threshold N sets a positive token threshold for providers with automatic compaction. It is not a larger context window, a billing cap, or a guarantee that an oversized initial prompt can fit. Current provider behavior differs: Provider | Default and bounds | OpenAI | Current Codex metadata defaults to 244,800 tokens; the override is capped at the effective context window, currently 258,400 tokens. | xAI | 80% of the resolved context window for Grok 4.5/4.6, 85% for other model names. The override is capped at the context window and bounded below by one. | Claude Code | 80% after reserving up to 20,000 output tokens, with a further up-to-13,000-token safety margin on compaction input. SDK-reported context takes precedence over catalog/default context. An override cannot exceed the safe compaction-input limit. | Gemini / OpenRouter | The shared HTTP runtime wires manual compaction and overflow protection, not this automatic threshold. Use /compact; do not rely on the flag to schedule it. | agent-cli --provider xai --compact-threshold 100000 For a model whose resolved window exceeds 100,000 tokens, this requests compaction around that threshold instead of waiting for its percentage default. Continue the task normally; accumulated context, pending inputs and tool continuations determine when compaction is needed, not a message count. A lower threshold can compact more often and spend more on summaries. With a 200,000-token Claude window, the default calculation instead yields 144,000 tokens and the safe input ceiling is 167,000. Custom portable models need their actual context_window; increasing a catalog number does not increase the endpoint's capacity. Add a local or hosted model The model picker merges its shipped catalog with: ~/.haskell-agent/models.json The built-in add-model skill can configure this file. For example: $add-model Configure the Responses-compatible model at http://localhost:11434/v1. For manual configuration, this example assumes the server actually implements streaming POST /v1/responses and serves the specified model: { "version": 1, "connections": { "local-inference": { "api": "responses", "base_url": "http://localhost:11434/v1", "api_key_optional": true, "request_timeout_seconds": 600 } }, "models": [ { "id": "local-coder", "connection": "local-inference", "model": "qwen2.5-coder:32b", "dialect": "generic-responses", "context_window": 32768, "label": "local" } ] } Then select: agent-cli --model local-coder This does not install or start an inference server. A Chat Completions endpoint alone is not sufficient for this configuration. Authentication and context limits For an authenticated endpoint, set "api_key_env": "MY_MODEL_API_KEY" on the connection, supply that environment variable to the process, and remove "api_key_optional": true. Do not store the key itself in models.json. Set context_window to the endpoint's documented token limit. Inference can work without it, but portable-model compaction refuses to guess a limit. User model entries with an existing id replace shipped entries; new entries are appended. Built-in connection names are reserved. Custom connections are selected manually and are not used for automatic billing fallback. Supported dialects are codex, grok-build, and generic-responses. Choose a dialect the endpoint and model can actually support, not just the tool names you prefer. Catalog reference The file is a JSON object with required integer version: 1, an optional connections object (default empty), and an optional models array (default empty). Use strict JSON, not comments or trailing commas. Restart the CLI after editing the catalog; invalid entries are reported at startup. Custom Responses connection fields Field | Type and default | Meaning | api | Required string | Use responses for a custom endpoint. | base_url | Required string | HTTP or HTTPS API base URL, including its version prefix when required. | api_key_env | Optional string | Name of the environment variable holding the secret, not its value. Required unless keys are optional. | api_key_optional | Boolean; false | Permit a connection without an API key. | request_timeout_seconds | Positive integer; 600 | Request timeout in seconds. | provider belongs to built-in connection declarations, not custom Responses routing. Do not redefine reserved connections: openai, xai, openrouter, meta, gemini, claude-code, or organization-gateway. Model fields Field | Type and default | Meaning | id | Required string | Local selector used by /model and --model; nonempty with no whitespace. | connection | Required string | Existing connection name. | model | String; defaults to id | Model identifier sent to a custom endpoint. Built-in and gateway entries cannot remap it. | dialect | Required string | codex, grok-build, or generic-responses; must be compatible with the connection. | context_window | Optional positive integer | Documented context size in tokens; required for reliable portable-model compaction. | label | Optional string | Additional catalog label. | reasoning_efforts | Optional array of strings | Nonempty, unique supported efforts: none, low, medium, high, xhigh, max. | default_reasoning_effort | Optional string | Must appear in the entry's reasoning_efforts. | supports_async_tool_calls | Boolean; false | Declare support for asynchronous tool calls only when the endpoint supports them. Disabled for gateway metadata. | default | Boolean; false | Catalog default selection marker. | fallback_priority | Optional nonnegative integer | Fallback ordering metadata. Does not make custom connections eligible for automatic billing fallback. | Organization gateway aliases For each built-in provider, the merged catalog must contain exactly one default model. Replacing a shipped default with an entry that omits default: true can invalidate the catalog; marking another default without clearing the existing one also fails. This catalog fallback does not erase an explicit launch choice or a remembered project model. Asynchronous tool capability is resolved against the exact connection and wire model. If several aliases match that transport model, all must explicitly enable supports_async_tool_calls; ambiguity fails closed. Gateway aliases never inherit this capability because their name resembles a direct model. This is a transport capability declaration, not permission to run tools without approval. For a private gateway alias, add a model entry with connection set to organization-gateway; do not define that connection. The gateway's live /v1/models response remains authoritative. Metadata applies only when the same alias is advertised, cannot change the wire name, and does not add the alias to direct-provider pickers. {"version":1,"models":[{"id":"company-coder","connection":"organization-gateway","dialect":"generic-responses","context_window":131072,"label":"company"}]} Asynchronous tool protocol supports_async_tool_calls is a protocol capability declaration, not a speed setting. The Responses wire format carries an async boolean on supported tool definitions, calls and outputs. A participating endpoint must preserve those fields and call identities, stream complete asynchronous calls, and accept their later results rather than requiring every tool to finish before generation can continue. The harness can admit an asynchronous call during streaming and execute it through the tool scheduler while generation continues. Calls still need tool-level asynchronous support and normal approval. Once an async call has been observed, transport recovery must not blindly replay the response and duplicate its effects. Keep the flag false unless the exact endpoint and model implement this contract; support for ordinary function calling or parallel_tool_calls alone is insufficient. Automatic fallback eligibility and order fallback_priority is an optional nonnegative integer; smaller values rank first. Only built-in connections openai, xai, openrouter and gemini participate. Custom connections are manual-only, even if given a priority. Claude Code is excluded both as a source of automatic fallback and as a destination. A structured model-access failure first considers strictly lower-ranked models on the current provider, then the highest-ranked model for each other eligible provider. Equal-priority models retain catalog order, but are not a lower-ranked same-provider recovery. Provider-wide account/quota failures skip same-provider model changes. Providers already observed as exhausted are excluded. A bare failure does not make every model eligible: recovery requires a recognized provider-unavailable error. Review the proposed provider/model and its account before continuing. A different provider can change the recipient of conversation data and the subscription/API billing route. Priority is not a promise of access, equivalent capabilities, free usage or permission to bypass an account limit. Session title model Automatic session naming has its own model selection, independent of the coding model. Open its picker or restore automatic selection with: /title-model /title-model --auto Pin a catalog model with /title-model NAME, or choose on-device Apple Intelligence with /title-model apple-foundationmodel. The selection persists as titleModel in ~/.haskell-agent/settings.json. A pinned provider model is used only when its provider matches the current session. On supported macOS systems, automatic selection first tries Apple Intelligence through apple-session-title. The helper is found on PATH, supplied through HASKELL_AGENT_APPLE_SESSION_TITLE, or built with Xcode on first use. If unavailable or unsuccessful, naming falls back to the provider's inexpensive model. Other systems use provider selection directly. This fallback is for naming, not a switch of the coding model. The same helper also decides whether a plain follow-up steers the running fullscreen turn or waits until that turn finishes. Catalog errors and recovery Error or symptom | Action | references unknown connection | Match the model's connection exactly to a declared or shipped connection name. | requires api_key_env unless api_key_optional is true | Declare a secret variable for authenticated endpoints; use optional keys only for a server that permits them. | default_reasoning_effort must be listed in reasoning_efforts | Add the supported default to the nonempty efforts array, or remove the override. | HTTP 404 from a custom endpoint | Check the base URL and confirm support for POST /v1/responses, not only Chat Completions. | Generation works, compaction fails | Supply the server's actual positive context_window; do not guess a larger limit. | Example: check a custom model connection - Confirm your inference server is running and implements the Responses API. - Adapt the catalog example to its model name, URL, and documented context limit. - Start agent-cli --model local-coder, then inspect /session-info. - Send Reply with a short greeting. Do not use tools. before asking for repository work. Expected result: a response through the selected connection. A connection error calls for checking the server and URL; an authentication error calls for checking the environment-variable reference. Neither is fixed by changing tool approvals. Once basic generation works, try a read-only file inspection to check tool compatibility separately.