> ## Documentation Index
> Fetch the complete documentation index at: https://docs.definable.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Configuration

> Fine-tune agent behavior with AgentConfig.

`AgentConfig` is an immutable dataclass that controls every aspect of agent behavior. Pass it when creating an agent, or use the defaults.

## Basic Configuration

```python theme={null}
from definable.agent import Agent, AgentConfig
from definable.model import OpenAIChat

config = AgentConfig(
    agent_name="Support Agent",
    max_iterations=15,
    max_retries=3,
)

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    instructions="You are a customer support agent.",
    config=config,
)
```

## Configuration Reference

### Identity

<ParamField path="agent_id" type="str">
  Unique identifier for the agent. Auto-generated UUID if not set.
</ParamField>

<ParamField path="agent_name" type="str">
  Human-readable name used in logs and traces.
</ParamField>

### Execution

<ParamField path="max_iterations" type="int" default="10">
  Maximum number of model-call-then-tool-execution loops before stopping. Prevents infinite loops when the model keeps calling tools.
</ParamField>

<ParamField path="max_tokens" type="int">
  Token limit per run. Stops execution if exceeded.
</ParamField>

<ParamField path="stream_timeout_seconds" type="float" default="300.0">
  Timeout in seconds for streaming responses.
</ParamField>

### Reliability

<ParamField path="retry_transient_errors" type="bool" default="true">
  Automatically retry on transient network errors.
</ParamField>

<ParamField path="max_retries" type="int" default="3">
  Maximum number of retry attempts for transient errors.
</ParamField>

<ParamField path="validate_tool_args" type="bool" default="true">
  Validate tool arguments against their schema before execution.
</ParamField>

### State & Dependencies

<ParamField path="session_state" type="Dict[str, Any]">
  Default session state available to tools. Merged with per-run state.
</ParamField>

<ParamField path="dependencies" type="Dict[str, Any]">
  Dependencies injected into tools that declare them (e.g., database connections, API clients).
</ParamField>

### Tracing

<ParamField path="tracing" type="Tracing">
  Tracing configuration (backward compat). Prefer passing `tracing=Tracing(...)` directly to `Agent`. See [Tracing](/agents/tracing) for details.
</ParamField>

### Compression

Compression is configured directly on the `Agent` constructor (not in `AgentConfig`):

```python theme={null}
from definable.agent import Agent
from definable.agent.compression import Compression

# Defaults
agent = Agent(model="openai/gpt-4o", compression=True)

# Custom
agent = Agent(model="openai/gpt-4o", compression=Compression(tool_results_limit=5))
```

### Readers

<ParamField path="readers" type="ReadersConfig">
  File reader configuration for processing attached files. See [File Readers](/readers/overview).
</ParamField>

## Memory

Memory is configured directly on the `Agent` constructor:

```python theme={null}
from definable.agent import Agent
from definable.memory import Memory, SQLiteStore

# Ephemeral in-memory store (useful for testing)
agent = Agent(model=model, memory=True)

# Persistent store via Memory
agent = Agent(
    model=model,
    memory=Memory(
        store=SQLiteStore("./memory.db"),
    ),
)
```

See [Memory](/memory/agent-integration) for full documentation.

## Knowledge

Knowledge (RAG) is configured directly on the `Agent` constructor:

<CodeGroup>
  ```python Path shorthand (easiest) theme={null}
  from definable.agent import Agent

  # Auto-configures InMemoryVectorDB + OpenAIEmbedder + RecursiveChunker
  # Recursively loads all supported files from the directory
  agent = Agent(model=model, knowledge="./docs/")
  ```

  ```python Full configuration theme={null}
  from definable.agent import Agent
  from definable.embedder import OpenAIEmbedder
  from definable.knowledge import Knowledge
  from definable.vectordb import InMemoryVectorDB

  kb = Knowledge(
      vector_db=InMemoryVectorDB(),
      embedder=OpenAIEmbedder(),
      top_k=5,
      rerank=True,
      trigger="always",  # "always", "auto", or "never"
  )
  kb.add("Company policy: employees get 20 days PTO per year.")

  agent = Agent(model=model, knowledge=kb)
  ```
</CodeGroup>

<Warning>
  `Agent(knowledge=True)` raises `ValueError` — unlike `memory=True`, knowledge requires explicit configuration. Use a path string or a `Knowledge` instance.
</Warning>

See [Knowledge Agent Integration](/knowledge/agent-integration) for full documentation.

## Thinking

The thinking layer is configured directly on the `Agent` constructor (not in `AgentConfig`):

```python theme={null}
from definable.agent import Agent
from definable.agent.reasoning import Thinking

# Simple enable
agent = Agent(model=model, thinking=True)

# Custom configuration
agent = Agent(
    model=model,
    thinking=Thinking(
        model=thinking_model,           # Optional separate model
        instructions="Custom prompt",    # Optional custom prompt
    ),
)
```

See [Thinking](/agents/thinking) for full documentation.

## Immutable Updates

`AgentConfig` is frozen after creation. Use `with_updates()` to create a modified copy:

```python theme={null}
base_config = AgentConfig(
    agent_name="Base Agent",
    max_iterations=10,
    max_retries=3,
)

# Create a variant with a different name and higher iteration limit
custom_config = base_config.with_updates(
    agent_name="Custom Agent",
    max_iterations=20,
)
```

The original `base_config` is unchanged. This pattern makes it safe to share configs across agents.

## Compression

Compress large tool results to save tokens:

```python theme={null}
from definable.agent import Agent
from definable.agent.compression import Compression

# Enable with defaults (compress after 3 uncompressed tool results)
agent = Agent(model="openai/gpt-4o", compression=True)

# Custom settings
agent = Agent(
    model="openai/gpt-4o",
    compression=Compression(
        tool_results_limit=3,      # Trigger compression after 3 uncompressed tool results
        token_limit=None,          # Or set a token threshold to trigger compression
        instructions="Preserve key facts and data. Remove formatting.",
    ),
)
```

<Note>
  Compression uses a separate model call to summarize tool output. This adds a small amount of latency but can significantly reduce total token usage for tools that return large results.
</Note>

## Readers Config

Configure file reader behavior for processing attached files:

```python theme={null}
from definable.agent import AgentConfig, ReadersConfig

config = AgentConfig(
    readers=ReadersConfig(
        enabled=True,
        registry=None,                     # None = auto-create with built-in readers
        max_total_content_length=None,     # Limit total injected content (None = unlimited)
        context_format="xml",              # "xml" or "markdown"
    ),
)
```

<ParamField path="readers.enabled" type="bool" default="true">
  Enable or disable file reading.
</ParamField>

<ParamField path="readers.registry" type="BaseReader">
  Custom reader instance. When `None`, a default `BaseReader` with all available built-in parsers is created.
</ParamField>

<ParamField path="readers.max_total_content_length" type="int">
  Maximum total character length of all extracted file content. When `None`, no limit is applied.
</ParamField>

<ParamField path="readers.context_format" type="str" default="xml">
  Format for injecting file content into the prompt. `"xml"` wraps content in XML tags, `"markdown"` uses code blocks.
</ParamField>

## Audio Transcription

The audio transcriber is configured directly on the `Agent` constructor. It automatically transcribes voice messages (from Telegram, Discord, or direct `arun()` calls) to text before the model sees them.

```python theme={null}
from definable.agent import Agent

# Simple enable (uses OpenAI Whisper)
agent = Agent(model=model, audio_transcriber=True)

# Custom configuration
from definable import OpenAITranscriber
agent = Agent(
    model=model,
    audio_transcriber=OpenAITranscriber(
        model="whisper-1",    # Whisper model
        language="en",        # Language hint (improves accuracy)
        api_key=None,         # Falls back to OPENAI_API_KEY env var
    ),
)
```

See [Vision & Audio](/models/vision-and-audio#voice-note-transcription) for full documentation.

### How It Works

When `audio_transcriber` is set:

1. Before the pipeline runs, `_transcribe_audio()` iterates over messages with `Audio` attachments
2. Each audio clip is transcribed via the configured backend (Whisper by default)
3. The transcript text is appended to the message's `content` field
4. The `audio` field is cleared from the message so non-audio models don't receive raw `input_audio` blocks

<Warning>
  Without `audio_transcriber`, voice messages from interfaces arrive as raw `Audio` objects. Most models (GPT-4o-mini, Claude, DeepSeek) will reject `input_audio` blocks — only `gpt-4o-audio-preview` supports them natively.
</Warning>

## Security

Security features are configured directly on the `Agent` constructor:

```python theme={null}
from definable.agent import Agent
from definable.agent.security import SecurityConfig, ToolPolicy

# Simple enable (default config)
agent = Agent(model=model, security=True)

# Full configuration
agent = Agent(
    model=model,
    security=SecurityConfig(
        tool_policy=ToolPolicy(mode="allowlist", allowed_tools={"search_web"}),
    ),
)

# Security audit
report = await agent.security_audit()
print(f"Score: {report.score}/100")
```

See [Security](/agents/security) for full documentation on tool policies, rate limiting, prompt injection detection, SSRF protection, and security audits.

## Usage Tracking

Track token usage and estimated cost across agent runs:

```python theme={null}
from definable.agent import Agent

agent = Agent(model=model, usage=True)
output = await agent.arun("Hello")

print(agent.usage_tracker.session_total)  # Cumulative tokens + cost
print(agent.usage_tracker.last_run)       # Most recent run
print(agent.usage_tracker.run_count)      # Total runs tracked
```

## Deep Research

The deep research layer is configured directly on the `Agent` constructor:

```python theme={null}
from definable.agent import Agent
from definable.agent.research import DeepResearchConfig

# Simple enable (standard depth, DuckDuckGo search)
agent = Agent(model=model, deep_research=True)

# Custom configuration
agent = Agent(
    model=model,
    deep_research=DeepResearchConfig(
        depth="deep",                    # "quick", "standard", or "deep"
        search_provider="duckduckgo",    # or "google", "serpapi"
        max_sources=30,
        max_waves=5,
        include_citations=True,
        context_format="xml",
    ),
)
```

See [Deep Research](/agents/deep-research) for full documentation.

### DeepResearchConfig Reference

<ParamField path="depth" type="str" default="standard">
  Research depth preset. `"quick"` (1 wave, 8 sources), `"standard"` (3 waves, 15 sources), `"deep"` (5 waves, 30 sources).
</ParamField>

<ParamField path="search_provider" type="str" default="duckduckgo">
  Search backend name: `"duckduckgo"`, `"google"`, or `"serpapi"`.
</ParamField>

<ParamField path="search_provider_config" type="Dict[str, Any]">
  Backend-specific config (API keys, CSE ID, etc.). Required for Google CSE and SerpAPI.
</ParamField>

<ParamField path="search_fn" type="Callable">
  Custom async search callable. Overrides `search_provider` when set.
</ParamField>

<ParamField path="compression_model" type="Model">
  Model for CKU extraction (should be cheap/fast). Defaults to the agent's model.
</ParamField>

<ParamField path="max_sources" type="int" default="15">
  Maximum number of unique sources to read across all waves.
</ParamField>

<ParamField path="max_waves" type="int" default="3">
  Maximum number of research waves.
</ParamField>

<ParamField path="parallel_searches" type="int" default="5">
  Number of concurrent search queries per wave.
</ParamField>

<ParamField path="parallel_reads" type="int" default="10">
  Number of concurrent page reads.
</ParamField>

<ParamField path="min_relevance" type="float" default="0.3">
  Minimum relevance score for CKU inclusion.
</ParamField>

<ParamField path="include_citations" type="bool" default="true">
  Whether to include source citations in the research context.
</ParamField>

<ParamField path="include_contradictions" type="bool" default="true">
  Whether to surface contradictions between sources.
</ParamField>

<ParamField path="context_format" type="str" default="xml">
  Format for the injected context: `"xml"` or `"markdown"`.
</ParamField>

<ParamField path="max_context_tokens" type="int" default="4000">
  Approximate token budget for the research context block.
</ParamField>

<ParamField path="early_termination_threshold" type="float" default="0.2">
  Stop when novelty ratio drops below this threshold between waves.
</ParamField>

<ParamField path="trigger" type="str" default="always">
  When to run research: `"always"` (every run), `"auto"` (model decides), `"tool"` (explicit tool call).
</ParamField>

<ParamField path="description" type="str">
  Description shown in the layer guide injected into the system prompt. If `None`, uses the default description.
</ParamField>
