Agent Configuration Reference
Agent configuration lives in agent_setups.json (local development and self-hosted) or in your tenant's chat_bot_setups (managed deployments). Both use the same structure.
For managed deployments, see Managing Agents in the Platform.
Basic Structure
[
{
"agent_identifier": "my-agent",
"agent_name": "agent",
"llm_client_configuration": { ... },
"agent_configuration": { ... }
}
]
agent_identifier- the identifier used in API calls and the platform UIagent_name- use"agent"for the built-in composable agent (recommended for all new configurations).llm_client_configuration- which model to usellm_configuration_name- alternative tollm_client_configuration: reference a named LLM configuration shared across agentsagent_configuration- SDK runtime settings plus provider configuration for the built-in agenttracing_configuration- optional; where the agent's traces go, see Tracing Configuration
LLM Configuration
Credentials are configured by name: openai_api_key_ref, anthropic_api_key_ref and the other _ref fields take the name of a stored secret. See Secrets.
Named LLM configurations
Instead of an inline llm_client_configuration, an agent can reference a shared configuration by name:
{ "agent_identifier": "rag", "agent_name": "agent", "llm_configuration_name": "default" }
Names resolve against llm_configurations.json, next to agent_setups.json:
[
{
"name": "default",
"vendor": "openai",
"vendor_configuration": { "openai": { "openai_api_key_ref": "default-openai-api-key" } },
"model_configuration": { "name": "gpt-5.2", "type": "chat", "temperature": 0.0 }
}
]
Several agents can point at one entry, so a model or key change happens in one place. When both are present, an inline llm_client_configuration wins over llm_configuration_name; an unknown name logs a warning and leaves the agent without an LLM. Manage entries with za agents model add <name> and za agents model list. This mirrors how managed deployments reference the tenant's llm_configurations from chat_bot_setups.
Allowed LLM configurations
An agent may list additional named configurations that requests and tools can select:
{
"agent_identifier": "rag",
"agent_name": "agent",
"llm_configuration_name": "default",
"allowed_llm_configuration_names": ["fast", "vision"]
}
The default plus the allowed names are the menu a caller can select from per request, through the model policy (llm_selection_configuration in bot_params); a requested name outside the menu falls back to the default, and every chat model consumer in the request (the agent's client and the tools that call a chat model) follows the selection. Names travel everywhere; configurations and credentials stay in the store. In managed deployments the same field lives on the tenant's chat_bot_setups entries.
agent_setups.json (committed to version control):
{
"llm_client_configuration": {
"vendor": "openai",
"vendor_configuration": {},
"model_configuration": {
"name": "gpt-5.2",
"type": "chat",
"temperature": 0.0,
"reasoning_effort": "medium",
"json_output": false,
"seed": null,
"parallel_tool_calls": null
}
}
}
vendor
Which LLM provider to use. Determines which key under vendor_configuration must be populated with credentials.
| Value | Description |
|---|---|
openai | OpenAI API (GPT-4.1, o3, etc.) |
anthropic | Anthropic API (Claude) |
azure_openai | Azure OpenAI / Azure AI Services |
azure_anthropic | Azure-hosted Anthropic models |
bedrock | Amazon Bedrock (Converse API) |
ollama | Local Ollama instance |
model_configuration
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Model name (e.g. "gpt-4.1-mini", "claude-sonnet-4-20250514", "o3") |
type | string | yes | "chat" for chat models, "prompt" for completion models, "prompt_with_logits" for completion models that also return token log probabilities (openai and azure_openai only), "responses" for the OpenAI Responses API (see below), "image" for image generation models, "realtime_transcription" for the realtime transcription endpoint |
temperature | float | for chat/prompt/prompt_with_logits | Sampling temperature (0.0 = deterministic). Optional for "responses" and "image" models; not allowed for "realtime_transcription" models |
max_tokens | integer | no | Maximum tokens in the response |
reasoning_effort | string | no | Constrains effort for reasoning models: "low", "medium", "high" |
verbosity | string | no | Constrains the verbosity of the model's response (models that support it) |
json_output | boolean | no | Force JSON output format (default: false) |
seed | integer | no | Seed for deterministic outputs (provider support varies) |
parallel_tool_calls | boolean | no | Allow the model to call multiple tools in parallel |
prompt_cache | boolean | no | Use Anthropic prompt caching (default: true). Ignored for non-Anthropic models |
tool_choice_none_handling | string | no | Set to "omit_tools" to omit tools and tool_choice from the request when tool_choice is none - for OpenAI-compatible servers (e.g. vLLM) that otherwise leak tool-call markup into the answer. Only for openai and azure_openai chat models |
image_settings | object | no | Rendering options of "image" models, see Image models |
tool_search_methods | list | no | The tool search methods the model supports: server, client, emulated. server and client need an openai or azure_openai responses model or an anthropic or azure_anthropic chat model. Unset: emulated only, for chat and responses models |
Responses API models
Set "type": "responses" to call OpenAI or Azure OpenAI through the Responses API instead of Chat Completions. This is the native surface for reasoning models: the SDK requests encrypted reasoning content, replays it across tool-call turns, and carries the model's reasoning summaries on the response messages.
- Supported only for
vendor: "openai"andvendor: "azure_openai". temperatureis optional (reasoning models reject it).- For Azure, use
vendor: "azure_openai"; configuring Azure through theopenaivendor withopenai_api_type: "azure"is rejected for responses models.
The vendor configuration references the credential by name:
{
"llm_client_configuration": {
"vendor": "openai",
"vendor_configuration": {
"openai": { "openai_api_key_ref": "openai-api-key" }
}
}
}
Supported vendors: openai, anthropic, ollama, bedrock, azure_openai, azure_anthropic. For Azure OpenAI:
{
"llm_client_configuration": {
"vendor": "azure_openai",
"vendor_configuration": {
"azure_openai": {
"endpoint": "https://your-resource.openai.azure.com/",
"api_version": "2024-02-01",
"auth_type": "api_key",
"api_key": { "api_key_ref": "azure-api-key" }
}
},
"model_configuration": {
"name": "gpt-4.1-mini",
"type": "chat"
}
}
}
Image models
Set "type": "image" for an image generation model. Agents reach it only through the image generation tools, which name it through the agent's image_llm_selection_configuration block.
- Supported only for
vendor: "openai"andvendor: "azure_openai", with gpt-image-2.5 (flareorsunburst): the tool relies on its free aspect ratios and quality levels. temperatureis optional.- Rendering options live in
image_settings; every field is optional and an unset field leaves the vendor default in place.
| Field | Type | Description |
|---|---|---|
quality | string | Rendering quality in OpenAI's levels: "low", "medium", "high", "xhigh", "max", "auto" |
output_format | string | "jpeg", "png" or "webp". A transparent background switches jpeg to png |
output_compression | integer | 0-100 compression, sent with jpeg/webp output |
moderation | string | Provider safety strictness: "auto" or "low" |
{
"name": "gpt-image-2.5",
"vendor": "openai",
"vendor_configuration": {
"openai": { "openai_api_key_ref": "openai-api-key" }
},
"model_configuration": {
"name": "gpt-image-2.5-flare",
"type": "image",
"image_settings": {
"quality": "medium",
"output_format": "jpeg"
}
}
}
SDK Runtime Configuration
Some SDK behavior is configured through dependency factories rather than through llm_client_configuration. These settings live in agent_configuration because they control the agent runtime, not the model request sent to the LLM provider.
{
"agent_identifier": "my-agent",
"agent_name": "agent",
"agent_configuration": {
"max_nesting_level": 8
}
}
| Field | Type | Default | Description |
|---|---|---|---|
max_nesting_level | integer | 20 | Maximum number of recursive LLM/tool-execution turns allowed by ZAVChatCompletionClient before the SDK forces a final tool-less answer. Agent code can still override this for one call by passing max_nesting_level to client.complete(). |
image_llm_selection_configuration | object | none | { "llm_configuration_name": "<name>" }, the LLM configuration of type image that the image generation tools generate with; same shape as the model policy. See Image models. |
Tracing Configuration
tracing_configuration sits next to agent_configuration and records every turn as a trace whose id is the turn's message_id. vendor picks the backend; vendor_configuration holds the block of the same name.
{
"agent_identifier": "my-agent",
"agent_name": "agent",
"tracing_configuration": {
"vendor": "file",
"vendor_configuration": { "file": { "directory": "traces" } }
}
}
vendor | Where traces go |
|---|---|
langfuse | A Langfuse project: vendor_configuration.langfuse takes host, public_key and secret_key_ref (a secret name), plus optional release and sample_rate. Needs the langfuse extra |
capture | An in-process trace store, no settings. za agents test run uses it for agents without a tracing configuration |
file | One JSON file per trace, rewritten on every span update so an interrupted run still leaves its last state |
vendor_configuration.file field | Type | Default | Description |
|---|---|---|---|
directory | string | required | Where trace files are written; relative paths resolve against the working directory |
file_name | string | "timestamp_and_trace_id" | "timestamp_and_trace_id" writes <start time>_<trace id>.trace.json, so each run leaves its own file; "trace_id" writes <trace id>.trace.json, so a rerun replaces the earlier file |
Built-in Agent Provider Configuration
The agent_configuration block controls which providers are active and how they behave. All fields are optional — omit a provider's config block to disable it.
Tools
Which tool sources are available to the agent:
{
"tools_provider_configuration": {
"enabled": true,
"include_sources": ["index_tools", "document_tools", "tag_tools", "web_tools"],
"exclude_sources": [],
"include_tools": null,
"exclude_tools": ["dangerous_tool_name"]
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch for tool provider |
include_sources | list | null | Only activate these tool sources |
exclude_sources | list | null | Permanently disable these tool sources |
include_tools | list | null | Only expose these specific tools (by name) |
exclude_tools | list | null | Hide these specific tools (by name) |
Available tool sources: index_tools, document_tools, tag_tools, web_tools, user_document_tools, note_tools, image_tools, sql_database_tools, dataframe_tools, plot_tools, image_generation_tools, platform_docs, sub_agent.
→ See Configuring Tools for index_tools_source_configuration, DataFrame tools, and platform docs.
Skills
{
"skills_provider_configuration": {
"enabled": true,
"injection_mode": "both",
"prompt_format": "text",
"writable_source": null
},
"disk_skills_source_configuration": {
"skills_directories": ["skills/"]
},
"tag_note_skills_source_configuration": {
"tag_ids": ["your-tag-id"]
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch |
injection_mode | string | "both" | "prompt" (system message), "tools" (as callable tools), or "both" |
prompt_format | string | "text" | "text" or "xml" for how skills appear in the prompt |
writable_source | string | null | Which source can be written to for skill persistence |
→ See Using Agent Skills.
Memory
{
"memory_provider_configuration": {
"enabled": false,
"inject_context": true,
"provide_tools": true,
"memory_context_strategy": "full",
"writable_source": "tag_notes",
"read_instructions": null,
"write_instructions": null
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Master switch (disabled by default) |
inject_context | boolean | true | Inject memory contents into conversation context |
provide_tools | boolean | true | Expose memory read/write as tools |
memory_context_strategy | string | "full" | Which memories to inject: "full" for all, "recent" for the latest recent_memory_context_strategy_configuration.size (default 10) |
writable_source | string | null | Which store to write to (e.g. "tag_notes", "searchable_memory_notes"); null uses the first enabled store |
read_instructions | string | null | Custom instructions for the memory read tool |
write_instructions | string | null | Custom instructions for the memory write tool |
→ See Configuring Memory.
Context
{
"context_provider_configuration": {
"enabled": true,
"injection_mode": "conversation",
"content_format": "xml",
"max_item_content_length": null,
"document_context_source_configuration": {
"metadata_fields": ["title", "source", "abstract"]
},
"tag_context_source_configuration": { "enabled": true },
"user_document_context_source_configuration": { "enabled": true },
"user_workspace_context_source_configuration": { "enabled": true }
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master switch |
injection_mode | string | "conversation" | "prompt" (system message), "conversation" (as messages), or "both" |
content_format | string | "xml" | "json" or "xml" — how context items are formatted |
max_item_content_length | integer | null | Truncate individual context items to this character length |
Available context sources: documents, filters, tags, user_documents, user_workspace, images, custom, scheduled_task.
→ See Configuring Context.
Sub-Agent Delegation
{
"agent_delegation_provider_configuration": {
"enabled": true
},
"in_memory_delegable_agents_source_configuration": {
"enabled": true,
"agents": [
{
"agent_identifier": "specialist-agent",
"description": "Specialized in X. Use for Y tasks."
}
]
}
}
→ See Configuring Delegation.
Sub-Agent Limits
Bounds the agents started with the task and delegate tools:
{
"sub_agent_limits_configuration": {
"max_depth": 1,
"max_sub_agents": 8
}
}
| Field | Type | Default | Description |
|---|---|---|---|
max_depth | integer | 1 | An agent this many levels below the root gets no task or delegate tool. At 1, agents started by either tool get neither |
max_sub_agents | integer | 8 | Agents the whole turn may start with task and delegate together, counted across every depth. Once the turn has started this many, the agent's further calls are refused with a message telling it to finish the work itself. At 0, the agent gets neither tool |
- Each agent applies the limits in its own setup, counting its depth from the root and the agents the turn has started so far. A delegated agent whose setup sets
max_depth: 2can start agents even when the agent that delegated to it cannot. - Raising
max_depthdoes not multiply the budget: with the defaultmax_sub_agents, a turn starts at most 8 agents at any depth. - Sub-agents declared in an agent's code count as one level below it, like agents started with
taskordelegate. - Only the agent setup sets these limits:
bot_params, from a request or a delegable agent, cannot change them or the depth.
Context Window Management
{
"context_window_configuration": {
"enabled": false,
"max_context_tokens": 120000,
"preview_tokens": 200
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable automatic context compaction |
max_context_tokens | integer | 120000 | Start compacting when conversation exceeds this token budget |
preview_tokens | integer | 200 | Keep this many tokens as a preview when compacting old messages |
System Prompt
Text added to the system prompt right after system_prompt from agent_configuration, before the other providers' sections. The sources' text is joined in the order include_sources names them. The provider is off by default. Like system_prompt, these blocks come from the agent setup only: a request's bot_params cannot fill them.
{
"system_prompt_provider_configuration": {
"enabled": true,
"include_sources": ["in_memory_system_prompt", "disk_system_prompt"]
},
"in_memory_system_prompt_source_configuration": {
"enabled": true,
"text": "You are a specialist the main agent delegates to."
},
"disk_system_prompt_source_configuration": {
"enabled": true,
"files": ["prompts/specialist.md"]
}
}
Available system prompt sources: in_memory_system_prompt (text in the configuration), disk_system_prompt (files joined in order; a file it cannot read is logged and skipped).
Write your own as a SystemPromptSource (zav.agents_sdk.adapters.system_prompt), for example to read the prompt from an external system, with za agents capabilities system-prompt-sources add <name>:
source_name: the nameinclude_sourcesorders it by.enabled: set from its<source_name>_system_prompt_source_configurationblock.async def to_prompt(self): returns its text; an empty text adds nothing.
Instructions
{
"instructions_provider_configuration": {
"enabled": true,
"include_sources": ["datetime", "user_instructions"]
},
"datetime_instruction_source_configuration": { "timezone": "Europe/Amsterdam" },
"user_instruction_source_configuration": { "enabled": true, "instructions": "..." }
}
Available instruction sources: datetime, user_instructions.
→ See Configuring Instructions.
Message Processing
{
"message_processing_provider_configuration": {
"enabled": true,
"include_sources": ["citation_processor"]
}
}
Runs post-processing steps on the agent's response (e.g. inserting citations).
→ See Configuring Message Processing.
User Instructions
Free-text behavioral guidance added to the system prompt:
{
"user_instructions": "Always check for recent publications (last 6 months) before answering. Prefer primary sources over reviews."
}
Onboarding
Drives a guided new-user onboarding flow. The onboarding tool source provides the update_onboarding_status progress tool and injects the step-by-step onboarding guidance into the system prompt. Only bots using the built-in composable agent ("agent_name": "agent") can run it.
{
"onboarding_tools_source_configuration": {
"enabled": true,
"instructions": "Address the user in Dutch. Refer to collections as 'dossiers'.",
"steps": [
{
"title": "Role",
"content": "Ask the user's role in a warm, conversational way and save it.",
"status_label": "Getting started"
},
{
"title": "Create a tag",
"content": "Walk the user through creating their first tag.",
"status_label": "Create a tag"
}
]
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Whether onboarding is active. Intended to be switched on per conversation via runtime bot_params (see below), not in the agent configuration. |
steps | list | built-in defaults | Ordered onboarding steps. The total step count (used by the progress bar) is derived from this list. |
instructions | string | null | Cross-cutting behavioral guidance inserted before the steps (e.g. language or terminology overrides). |
Each step has a title, content (the behavioral instructions the agent follows for that step), and an optional status_label (the short action phrase shown in the progress bar, e.g. "Create a tag" — falls back to title when unset).
Enabling onboarding. There are two ways to turn it on:
-
Per conversation, via
bot_params(default). The chat UI starts an onboarding conversation by passingbot_paramson the chat request:{ "bot_params": { "onboarding_tools_source_configuration": { "enabled": true } } }Runtime
bot_paramsare deep-merged under the bot's agent configuration, and agent-configuration values take precedence on conflicts. So definesteps/instructionsin the bot's agent configuration and leaveenabledunset there — this lets the runtime flipenabled: truefor onboarding conversations only, while normal conversations with the same bot stay unaffected. -
A dedicated onboarding bot. Set
"enabled": truedirectly in the bot's agent configuration so every conversation with that bot runs onboarding. Because agent-configuration values win overbot_params, an explicitenabledhere forces onboarding on (or, withfalse, off) for all conversations regardless of runtime params. Pointchat_page.onboarding_bot_identifierat this bot to have the platform launch it for new users.
Notifications
The notification_tools source gives the agent a notify_user tool, which sends the user who made the request a short notification with a title and a message, for example when long work has finished. If the setup lists include_sources under tools_provider_configuration, add "notification_tools" to it.
{
"notification_tools_source_configuration": {
"enabled": true,
"channel": "email",
"max_notifications_per_turn": 1
}
}
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Whether the agent gets the notify_user tool |
channel | string | "email" | "email": an email to the user's account address, with a link back to the chat. "file": a markdown file per notification in file_notification_channel_configuration.directory (default notifications), available only when the agent runs locally with the za agents CLI |
max_notifications_per_turn | integer | 1 | Further notify_user calls in the same turn fail |
can_subagents_notify | boolean | false | Whether this agent keeps notify_user when another agent starts it, with task, delegate or a tool of its own. Each such agent then has its own max_notifications_per_turn |
notification_instructions | string | built-in | Tells the agent when to notify. By default it notifies only when the user asks for a notification |
- By default only the agent the user talks to gets
notify_user, somax_notifications_per_turnholds for the whole turn. A sub-agent's own setup decides withcan_subagents_notify; agents a tool starts as copies of the agent run its setup. - The email goes only to the requesting user, never to an address the agent chooses, and is not sent when the user has turned off Enable research reports emails in their profile settings. The tool then tells the agent why nothing was sent.
- The email carries the title and message as plain text: the agent's formatting, code blocks, images and link targets are removed, and link text stays.
Source Filtering (All Providers)
Every provider supports include_sources and exclude_sources for fine-grained control over which sources are active. This is a cross-cutting pattern - it works the same way for tools, skills, context, instructions, and message processing.
{
"tools_provider_configuration": {
"include_sources": ["index_tools", "document_tools"],
"exclude_sources": ["web_tools"]
}
}
The filtering follows a valve-chain:
- Exclude - if a source name is in
exclude_sources, it is always off (hard veto) - Include - if
include_sourcesis defined and the source name is listed, it is on (overrides the source's ownenabledflag) - Default - if neither list applies, the source's own
enabledfield determines whether it's active
This lets you precisely control which sources are active without modifying their individual configurations. For example, you can disable a source for one agent while keeping it enabled for another, using the same shared configuration.
Policies
Policies are top-level keys that affect multiple lifecycle phases simultaneously. They are not nested under any provider.
Citations
{
"citation_configuration": {
"strategy": "inline_url"
}
}
| Strategy | Description |
|---|---|
inline_url | LLM cites as [[N]](source_url "text") — best for web UIs |
short_id | LLM cites as [[short_id]] — 8 hex chars of doc hash |
deferred | LLM doesn't cite inline; post-processing inserts citations |
sup_numeric | Superscript numeric citations |
→ See Configuring Policies.
Full Example
agent_setups.json:
[
{
"agent_identifier": "research-agent",
"agent_name": "agent",
"llm_client_configuration": {
"vendor": "openai",
"vendor_configuration": {},
"model_configuration": {
"name": "gpt-5.2",
"type": "chat",
"temperature": 0.0,
"reasoning_effort": "medium"
}
},
"agent_configuration": {
"tools_provider_configuration": {
"include_sources": ["index_tools", "document_tools", "tag_tools", "web_tools", "dataframe_tools"]
},
"index_tools_source_configuration": {
"description": "R&D papers from ArXiv and top ML conferences, 2000–2026",
"known_filters": [
{ "field_path": "source", "description": "Publication venue" },
{ "field_path": "year", "description": "Publication year" }
],
"sort_field_mapping": { "date": "date", "citations": "citations" }
},
"citation_configuration": {
"strategy": "inline_url"
},
"skills_provider_configuration": {
"injection_mode": "both"
},
"disk_skills_source_configuration": {
"skills_directories": ["skills/"]
},
"memory_provider_configuration": {
"enabled": true,
"writable_source": "tag_notes",
"inject_context": true,
"provide_tools": true
},
"context_provider_configuration": {
"injection_mode": "conversation",
"content_format": "xml",
"tag_context_source_configuration": { "enabled": true },
"user_document_context_source_configuration": { "enabled": true },
"user_workspace_context_source_configuration": { "enabled": true }
},
"instructions_provider_configuration": {
"include_sources": ["datetime"]
},
"datetime_instruction_source_configuration": { "timezone": "Europe/Amsterdam" },
"onboarding_tools_source_configuration": { "enabled": true },
"context_window_configuration": {
"enabled": true,
"max_context_tokens": 120000
},
"user_instructions": "Focus on peer-reviewed research. Cite your sources."
}
}
]
Custom Agent Classes (Advanced)
If you need to build a custom agent class rather than configure the built-in one, the agent_configuration keys are matched to your agent class __init__ parameters - see Custom Agent Development.