# Models and agents

> Configure model connections with providers and wire methods, define agents that select them, and choose which agent runs.

Raw separates two things in `config.json`:

- **Models** (`models`) describe how to reach an upstream model.
- **Agents** (`agents`) choose one model and define how a run behaves.

Several agents can share one model. Changing an agent never changes the model connection, and changing a model affects every agent that uses it.

## Configure a model

Each entry under `models` is a connection. The key is a local alias that agents use.

| Field                      | Required  | Purpose                                                                                                    |
| -------------------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| `provider`                 | Yes       | The service or deployment, such as `ollama`, `deepseek`, `openai` or a custom gateway name.                |
| `method`                   | Yes       | The wire API. See the table below. Raw never infers it from the provider or model name.                    |
| `model_id`                 | Yes       | The exact model ID sent to the service.                                                                    |
| `base_url`                 | Sometimes | The endpoint. Required for a custom service, and for any pair other than the official provider and method. |
| `api_key` or `api_key_env` | No        | A literal key, or the name of an environment variable that holds the key. You cannot set both.             |
| `context_window_tokens`    | No        | The model’s context size, a positive integer. Used for context percentages and automatic compaction.       |
| `max_output_tokens`        | No        | A positive integer. Must be smaller than `context_window_tokens` when both are set.                        |
| `vision`                   | No        | `true` if the model accepts images. Defaults to `false`.                                                   |

### Wire methods

The `method` field selects the API that Raw calls.

| Method                    | Typical service                                           | Output cap field                                                    |
| ------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------- |
| `openai-chat-completions` | OpenAI, DeepSeek, OpenRouter, Ollama, compatible gateways | `max_completion_tokens` for OpenAI, `max_tokens` for other services |
| `openai-responses`        | OpenAI                                                    | `max_output_tokens`                                                 |
| `anthropic-messages`      | Anthropic or a compatible gateway                         | `max_tokens`                                                        |
| `google-generate-content` | Gemini or a compatible gateway                            | `maxOutputTokens`                                                   |

Official endpoint defaults apply only when the provider and method form the matching pair. For anything else, set `base_url` explicitly, so Raw never sends a credential to the default endpoint of a different service.

### Credentials

Raw reads credentials for the selected model only. These environment variables are used by default for known services:

- `OPENAI_API_KEY`
- `ANTHROPIC_API_KEY`
- `GEMINI_API_KEY` or `GOOGLE_API_KEY`
- `OPENROUTER_API_KEY`

A local Ollama endpoint needs no key. A custom service needs an explicit `base_url`, and a key source if the endpoint requires authentication. Prefer `api_key_env` over a literal `api_key`, so the key stays out of the file.

`raw config list` shows model and access settings without printing keys.

### Example: a local model and a hosted model

```json
{
  "default_agent": "raw",
  "models": {
    "local": {
      "provider": "ollama",
      "method": "openai-chat-completions",
      "model_id": "YOUR_INSTALLED_MODEL",
      "base_url": "http://127.0.0.1:11434/v1"
    },
    "flash": {
      "provider": "deepseek",
      "method": "openai-chat-completions",
      "model_id": "deepseek-flash",
      "base_url": "https://api.deepseek.com",
      "api_key_env": "DEEPSEEK_API_KEY",
      "context_window_tokens": 1048576
    }
  },
  "agents": {
    "raw": {
      "model": "local",
      "tools": { "use": ["builtin/read_file", "builtin/write_file", "builtin/bash"] }
    },
    "deepseek": {
      "model": "flash",
      "tools": { "use": ["builtin/read_file", "builtin/write_file", "builtin/bash"] },
      "request": { "thinking": "enabled", "reasoning_effort": "high", "max_output_tokens": 4096 },
      "compact": { "trigger_tokens": 800000, "keep_recent_turns": 2, "max_output_tokens": 512 }
    }
  }
}
```

## Configure an agent

Each entry under `agents` names exactly one model alias in its `model` field.

| Field                | Default       | Purpose                                                                                                                                            |
| -------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`              | Required      | The model alias from `models`.                                                                                                                     |
| `tools.use`          | Required      | Exact tool IDs, in the order the model sees them. An empty array gives the agent no tools.                                                         |
| `tools.rules`        | None          | Ordered allow, ask and deny rules. See [Permissions](https://raw.tlelabs.com/docs/guides/permissions/).                                            |
| `skills.use`         | `[]`          | Skills the agent may load. Requires `builtin/list_skills` and `builtin/load_skill` in `tools.use`.                                                 |
| `hooks.use`          | `[]`          | Hooks to run, in order.                                                                                                                            |
| `vars`               | None          | Exact names of root variables the agent may read.                                                                                                  |
| `system_prompt`      | Raw’s default | Literal prompt text. Cannot be combined with `system_prompt_file`.                                                                                 |
| `system_prompt_file` | None          | Path to a UTF-8 Markdown file, relative to the config file or absolute.                                                                            |
| `request`            | None          | Provider-specific request options. See [Request options](#request-options).                                                                        |
| `cache`              | None          | Prompt-cache settings where the provider supports them. See [Context and compaction](https://raw.tlelabs.com/docs/guides/context-and-compaction/). |
| `compact`            | Manual        | Compaction settings. See [Context and compaction](https://raw.tlelabs.com/docs/guides/context-and-compaction/).                                    |
| `max_steps`          | 10000         | Maximum model requests in one run.                                                                                                                 |
| `max_output_bytes`   | 8192          | Model-facing cap on each tool result, in bytes.                                                                                                    |
| `request_timeout_ms` | 120000        | Deadline for one model request or MCP call.                                                                                                        |

Tool IDs use these forms: `builtin/read_file`, `local/my_tool`, `agent/project_note` and `mcp/search/web_search`. The [Core concepts](https://raw.tlelabs.com/docs/start/concepts/) page describes each source.

### Choose the agent that runs

Raw picks the agent in this order:

1. `--agent NAME` on the command line.
2. The `RAW_AGENT` environment variable.
3. `default_agent` in the config file.

Raw has no `--provider`, `--model` or `--base-url` flags. The agent selection fixes the model, endpoint and credentials for a session.

```sh
raw --agent deepseek "Fix the failing tests"
```

### Limits and prompt precedence

Numeric limits resolve in this order, highest first: a command-line flag (`--max-steps`, `--max-output-bytes`, `--request-timeout-ms`), the matching `RAW_*` environment variable, the agent field, and then the built-in default.

The system prompt resolves in this order: `--system-prompt`, then `RAW_SYSTEM_PROMPT`, then the agent’s `system_prompt` or `system_prompt_file`, then Raw’s default prompt.

### Use a different config file

`--config PATH` replaces the default config file for one command. An explicit path that does not exist is an error.

```sh
raw --config ./team/raw.json --agent project "Summarize the open issues"
```

> **Older settings are not accepted:**
>
> Raw is pre-release and its config schema is strict. Unknown or duplicate fields fail validation. The old `profiles`, `default_profile`, `--profile` and `RAW_PROFILE` names are not supported. The environment variables `RAW_PROVIDER`, `RAW_MODEL` and `RAW_BASE_URL` cause an error when they are set, even when empty. Rewrite older configs to the `models` and `agents` shape shown on this page.

## Request options

The `request` object passes provider-specific settings. It is validated strictly and cannot override the model ID, tools, endpoint or credentials. Each option is accepted only for the provider it names. Raw does not translate options between services, and a provider’s error for an unsupported combination is returned to you.

| Method                                          | Options                                                                         |
| ----------------------------------------------- | ------------------------------------------------------------------------------- |
| `openai-chat-completions` (provider `openai`)   | `service_tier`, `reasoning_effort`                                              |
| `openai-chat-completions` (provider `deepseek`) | `thinking` (`enabled` or `disabled`), `reasoning_effort` (`low`, `high`, `max`) |
| `openai-responses` (provider `openai`)          | `service_tier`, `reasoning_effort`, `reasoning_mode` (`standard` or `pro`)      |
| `anthropic-messages` (provider `anthropic`)     | `thinking`, `effort`, `service_tier`                                            |
| `google-generate-content` (provider `google`)   | `thinking_level` or `thinking_budget`, not both                                 |

All methods accept `max_output_tokens`, a positive integer. For Anthropic, a manual `thinking` budget must be at least 1024 and smaller than the output cap. Raise `compact.max_output_tokens` above that budget as well if you enable manual thinking.

> **Note:**
>
> GPT-6 Astra tool use requires the `openai-responses` method.

## Add image support

To let an agent view images, mark the model as vision-capable and select the tool explicitly. Raw never adds the tool for you.

1. Set `vision` to `true` on the model entry.

   ```json
   {
     "models": {
       "local": {
         "provider": "ollama",
         "method": "openai-chat-completions",
         "model_id": "YOUR_VISION_MODEL",
         "base_url": "http://127.0.0.1:11434/v1",
         "vision": true
       }
     }
   }
   ```

2. Add `builtin/view_image` to the agent’s `tools.use`.

3. Name the image path in your task, for example `raw "Explain screenshot.png"`.

A text-only model can still work with images through an MCP tool that returns a text description.

## Check your setup

```sh
raw config list
```

The output lists each agent with its model alias, upstream model ID, provider, method, sanitized endpoint, selected tools, tool rules and compaction trigger.
