Agent specification reference
An agent is fully described by a JSON configuration document stored in the registry. This page is the authoritative reference for that format.
Minimal agent
Section titled “Minimal agent”{ "assistant_id": "support-bot", "nickname": "Support Bot", "description": "Answers product support questions", "response": { "provider_id": "alquimia", "profile": { "system_prompt": "You are a helpful support assistant. Answer concisely.", "evaluation_strategy": { "evaluation_strategy_id": "one-shoot" }, "persistence_strategy": "INCREMENTAL" }, "config": { "provider_id": "openai", "params": { "model": "gpt-4o-mini", "api_key": { "$secretRef": "RESPONSE_PROVIDER_API_KEY" } } } }}Top-level fields (AssistantConfig)
Section titled “Top-level fields (AssistantConfig)”| Field | Type | Required | Description |
|---|---|---|---|
assistant_id | string | Yes | Unique agent identifier within the agentspace |
nickname | string | No | Human-readable name (max 64 characters) |
description | string | No | Description shown in discovery and A2A tool lists (max 3000 characters) |
tags | string[] | No | Labels for registry queries |
channels | Channel[] | No | Inbound/outbound request/response channel configurations |
streaming_channels | StreamingChannel[] | No | Held-open bidirectional audio channel configurations |
audio | AudioAdapterConfig | No | STT/TTS connectors and accepted/produced modalities |
shields | object | No | Pre-inference classifiers keyed by shield name |
empathy | EmpathyEngine | No | Conditional profile overrides based on shield output |
role | "reader" | "editor" | "operator" | No | Zero Trust capability tier ceiling |
response | ResponseProfile | Yes | Main response provider and execution profile |
Profile fields
Section titled “Profile fields”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
system_prompt | string | No | — | Jinja2 template used as the system prompt |
prompt_clauses | object | No | — | Named sections appended to the system prompt. Values may contain {"$paramRef": "KEY"} references to registry parameters; they are resolved before AssistantConfig validation. Referenced parameters are kept when a publish is filtered. |
knowledge_base | KnowledgeBase[] | No | — | Vector-search or direct-access knowledge sources |
short_term_memory_strategy | object[] | No | — | Token-based history trimming |
long_term_memory_strategy | object[] | No | — | Context flush strategies |
evaluation_strategy | object | No | one-shoot | Tool use and termination policy |
tools | ToolConfig[] | No | — | External tool sources |
persistence_strategy | "INCREMENTAL" | "FLUSH" | "EPHEMERAL" | No | "INCREMENTAL" | How conversation history is persisted |
Parameter references in prompt_clauses
Section titled “Parameter references in prompt_clauses”Prompt clause values can reference registry parameters with {"$paramRef": "KEY"}. The reference is resolved against the agentspace’s registered parameters before the agent spec is validated, so the final system prompt sees the parameter value as a plain string. Parameters referenced this way are automatically kept when a publish is filtered to a subset of agents.
{ "response": { "provider_id": "alquimia", "profile": { "prompt_clauses": { "support_tier": { "$paramRef": "SUPPORT_TIER" } } } }}Shields (shield-config)
Section titled “Shields (shield-config)”shields is a map of classifier names to shield-config objects. Each shield runs before the main inference call. Agent-scoped shields operate on the user request; tool- and topic-scoped shields operate on tool outputs and retrieved knowledge chunks.
shield-config schema
Section titled “shield-config schema”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
provider_id | "shield-config" | Yes | — | Must be shield-config |
connector | object | Yes | — | Underlying classifier connector |
action | "observe" | "flag" | "block" | No | "observe" | Action when threshold is crossed |
threshold | number | No | 0.5 | Score threshold |
target_label | string | No | — | Only this predicted label triggers the action |
fail_closed | boolean | No | false | Block on shield errors or timeouts |
block_message | string | No | — | Refusal text used when blocking |
Shield connector variants
Section titled “Shield connector variants”Built-in prompt-injection detector:
{ "provider_id": "shield-config", "connector": { "provider_id": "alquimia/prompt-injection-detection", "heuristic_weight": 0.3, "base_classifier_score": 0.0 }, "action": "block", "threshold": 0.5, "fail_closed": true}External Hugging Face text-classification model:
{ "provider_id": "shield-config", "connector": { "provider_id": "huggingface/text-classification", "url": "https://your-hf-endpoint.com", "token": { "$secretRef": "SHIELDS_PROVIDER_API_KEY" }, "label_map": { "LABEL_0": "safe", "LABEL_1": "toxic" } }, "action": "block", "threshold": 0.8, "target_label": "toxic", "block_message": "This request violates our safety policy."}LLM-based classifier using a registered model:
{ "provider_id": "shield-config", "connector": { "provider_id": "alquimia", "profile": { "system_prompt": "Classify user intent as one of: support, sales, enterprise.", "evaluation_strategy": { "evaluation_strategy_id": "one-shoot", "structured_output": { "method": "json_schema", "json_schema": { "type": "object", "properties": { "intent": { "type": "string" } }, "required": ["intent"] } } } }, "config": { "model_ref": "gpt-4o-mini-classifier" } }, "action": "observe"}See Shields & empathy for the conceptual model and How to configure content shields for step-by-step instructions.
Empathy engine
Section titled “Empathy engine”empathy.rules is a list of conditional profile overrides evaluated after all shields run. The first matching rule is applied.
EmpathyRule schema
Section titled “EmpathyRule schema”| Field | Type | Required | Description |
|---|---|---|---|
rule_id | string | Yes | Unique rule identifier |
strategy | "none" | "override" | "merge" | Yes | How the rule changes the response profile |
description | string | No | Human-readable explanation |
requirements | string[] | Yes | Shield IDs that must be present for the rule to run |
conditions | string[] | Yes | simpleeval expressions; all must be true |
response | ResponseProfile | Yes | Profile to apply (override) or merge |
Strategies
Section titled “Strategies”| Strategy | Behavior |
|---|---|
none | No-op |
override | Replace the entire response profile with response |
merge | Deep-merge response into the main profile |
Example
Section titled “Example”{ "empathy": { "rules": [ { "rule_id": "toxic-input", "strategy": "override", "description": "Refuse toxic requests", "requirements": ["toxicity"], "conditions": ["toxicity['label'] == 'toxic'"], "response": { "provider_id": "fixed", "message": "I'm sorry, I can't help with that." } }, { "rule_id": "formal-enterprise", "strategy": "merge", "description": "Use formal tone for enterprise intent", "requirements": ["intent-classifier"], "conditions": ["intent-classifier.get('intent') == 'enterprise'"], "response": { "provider_id": "alquimia", "profile": { "prompt_clauses": { "tone": "Use formal, professional language. Avoid contractions." } } } } ] }}Response provider (config)
Section titled “Response provider (config)”The config section inside response declares the LLM connector.
OpenAI
Section titled “OpenAI”{ "provider_id": "openai", "params": { "model": "gpt-4o", "temperature": 0.2, "max_tokens": 2048, "api_key": { "$secretRef": "RESPONSE_PROVIDER_API_KEY" }, "base_url": { "$secretRef": "RESPONSE_PROVIDER_BASE_URL" } }}OpenAI-compatible reasoning backends
Section titled “OpenAI-compatible reasoning backends”Use the openai-compatible provider for OpenAI-compatible endpoints that expose reasoning_content or other extended reasoning fields. The standard openai provider routes to langchain_openai.ChatOpenAI.
{ "provider_id": "openai-compatible", "params": { "model": "deepseek-reasoner", "temperature": 0.2, "api_key": { "$secretRef": "REASONING_PROVIDER_API_KEY" }, "base_url": { "$secretRef": "REASONING_PROVIDER_BASE_URL" } }}gpt-oss / vLLM support
Section titled “gpt-oss / vLLM support”For gpt-oss served by vLLM, set harmony_preamble_as_reasoning: true when chain-of-thought text sometimes appears glued onto the answer instead of being returned in a reasoning field. With the flag on, the connector requests return_token_ids and moves streamed content outside the final harmony channel into the reasoning field. This is streaming only.
{ "provider_id": "openai-compatible", "params": { "model": "gpt-oss-20b", "harmony_preamble_as_reasoning": true, "api_key": { "$secretRef": "REASONING_PROVIDER_API_KEY" }, "base_url": { "$secretRef": "REASONING_PROVIDER_BASE_URL" } }}As of alquimia-core 0.5.5, tool-call names that accidentally picked up harmony framing (for example, search<|channel|>commentary or functions.search) are repaired automatically to search. If the model calls a tool that does not exist, it receives an error listing the available tools instead of the call being forwarded to the client.
{ "provider_id": "groq", "params": { "model": "llama-3.3-70b-versatile", "temperature": 0.1, "groq_api_key": { "$secretRef": "RESPONSE_PROVIDER_API_KEY" } }}Hugging Face
Section titled “Hugging Face”{ "provider_id": "huggingface", "params": { "model": "meta-llama/Llama-3.1-8B-Instruct", "api_key": { "$secretRef": "RESPONSE_PROVIDER_API_KEY" }, "base_url": { "$secretRef": "RESPONSE_PROVIDER_BASE_URL" } }}Common connector parameters
Section titled “Common connector parameters”As of alquimia-core 0.5.3, connector parameters are validated against a per-provider schema when a model is registered and again when the merged configuration is instantiated. Passing a parameter that does not belong to the selected provider is rejected. Use model_kwargs for provider-specific extras that are not listed here.
| Field | Type | Description |
|---|---|---|
model | string | Model identifier |
temperature | number | Sampling temperature |
max_tokens | integer | Max output tokens |
timeout | integer | Request timeout in seconds |
top_p | number | Top-p sampling |
max_retries | integer | Retry count on failure |
api_key | SecretRef | API key for OpenAI, Groq, or Hugging Face |
groq_api_key | SecretRef | API key for Groq (alias of api_key) |
base_url | SecretRef | Custom endpoint URL |
organization | string | OpenAI organization ID |
default_headers | object | Default headers sent with every request |
reasoning | object | Extended reasoning configuration; switches to the Responses API when supported (0.5.2+) |
reasoning_effort | string | Reasoning effort level for Chat Completions |
reasoning_format | string | Groq reasoning format hint |
output_version | string | Responses API output version, e.g. v0 (0.5.2+) |
store | boolean | Whether to store the request/response on the provider side (0.5.2+) |
extra_body | object | Additional provider-specific body fields for OpenAI (0.5.2+) |
model_kwargs | object | Provider-specific extras that are not modeled above (0.5.3+) |
harmony_preamble_as_reasoning | boolean | openai-compatible + gpt-oss/vLLM only: route streamed non-final harmony channel text to reasoning instead of the answer (0.5.5+) |
Fixed response (testing)
Section titled “Fixed response (testing)”{ "provider_id": "fixed", "message": "This is a fixed response for testing.", "chunk_size": 64}Registered model reference (model_ref)
Section titled “Registered model reference (model_ref)”Instead of embedding a model connector in every profile, you can reference a model registered in the registry:
alquimia registry models add gpt-4o-mini \ --provider-id openai \ --params '{"model": "gpt-4o-mini", "temperature": 0.0, "api_key": {"$secretRef": "RESPONSE_PROVIDER_API_KEY"}}'Then use model_ref in response.config or inside a shield connector:
{ "response": { "provider_id": "alquimia", "config": { "model_ref": "gpt-4o-mini" }, "profile": { "system_prompt": "You are a helpful assistant.", "evaluation_strategy": { "evaluation_strategy_id": "one-shoot" } } }}Per-use params in the agent spec or shield override the registered model defaults.
Secrets
Section titled “Secrets”Sensitive values are never stored in the agent spec. Declare them with $secretRef and resolve them at inference time.
{ "api_key": { "$secretRef": "RESPONSE_PROVIDER_API_KEY" }}Secret scopes
Section titled “Secret scopes”| Scope | Environment key format | Vault path |
|---|---|---|
global | KEY | global/KEY |
shared | {REALM}_{KEY} | {realm}/shared/KEY |
local | {REALM}_{ASSISTANT_ID}_{KEY} | {realm}/local/{assistant_id}/KEY |
REALM is the agentspace_id.
As of alquimia-core 0.5.5, local and shared secrets support per-user overrides with a fallback to the scope default. global secrets have a single value. When a user_id is present, the resolver tries the user-specific key/path first and falls back to the scope default if no override exists.
| Scope | Per-user environment key | Per-user Vault path |
|---|---|---|
shared | {REALM}_USER_{USER_ID}_{KEY} | {realm}/shared/users/{user_id}/KEY |
local | {REALM}_{ASSISTANT_ID}_USER_{USER_ID}_{KEY} | {realm}/local/{assistant_id}/users/{user_id}/KEY |
Secret data types
Section titled “Secret data types”dtype | Format | Example |
|---|---|---|
str | Raw string | sk-abc123 |
bool | true/false, 1/0, yes/no, on/off | true |
int | Integer string | 587 |
float | Float string | 0.7 |
list | JSON array or comma-separated | ["a","b"] or a,b |
See Rotate secrets and Vault policies for operational details.
Evaluation strategies
Section titled “Evaluation strategies”one-shoot
Section titled “one-shoot”Single LLM call, no tools. Use for simple Q&A agents.
{ "evaluation_strategy_id": "one-shoot"}native
Section titled “native”Native function calling for agents that use tools.
{ "evaluation_strategy_id": "native", "max_steps": 10, "max_concurrent_tools": 1, "tool_choice": "auto", "decorators": null, "structured_output": null}| Field | Type | Default | Description |
|---|---|---|---|
max_steps | integer | 10 | Max LLM calls before termination |
max_concurrent_tools | integer | 1 | Max tool calls per step |
tool_choice | string or object | "auto" | Tool selection mode |
decorators | Decorator[] | null | plan-mode and skills decorators |
structured_output | object | null | Force structured JSON output |
Parse tool calls from unstructured text for models without native function calling.
{ "evaluation_strategy_id": "raw", "max_steps": 10, "max_concurrent_tools": 5, "parse_regex_pattern": "\\{\\s*\"name\"\\s*:..."}Memory strategies
Section titled “Memory strategies”Short-term: max_tokens
Section titled “Short-term: max_tokens”Trims conversation history to stay within a token budget.
{ "short_term_memory_strategy": [ { "memory_strategy_id": "max_tokens", "memory_max_tokens": 10000, "conditions": [] } ]}| Field | Type | Default | Description |
|---|---|---|---|
memory_max_tokens | integer | 10000 | Token budget; -1 disables trimming |
conditions | string[] | [] | Empathy-style conditions |
Long-term: summarizer
Section titled “Long-term: summarizer”Triggers a context flush when thresholds are exceeded.
{ "long_term_memory_strategy": [ { "long_term_memory_id": "summarizer", "interaction_threshold_qty": 20, "interaction_threshold_tokens": 20000, "interaction_keep": 3, "cod_max_loops": 5, "instructions": "Focus on decisions and action items." } ]}| Field | Type | Default | Description |
|---|---|---|---|
interaction_threshold_qty | integer | 20 | Flush after this many interactions |
interaction_threshold_tokens | integer | 20000 | Flush after this many tokens |
input_tokens_threshold | integer | 0 | Flush when LLM reports this many input tokens |
interaction_keep | integer | 0 | Human turns to keep after flush |
step_keep_qty | integer | 0 | Trailing tool-call round trips to keep |
step_keep_tokens | integer | 0 | Same as above, bounded by token budget |
cod_max_loops | integer | 5 | Chain-of-Density summarization iterations |
instructions | string | — | Summarization focus instructions |
knowledge_base | object | — | Store summary in this knowledge base |
Long-term: neuralyzer
Section titled “Long-term: neuralyzer”Erases memory beyond retained interactions without summarization.
{ "long_term_memory_strategy": [ { "long_term_memory_id": "neuralyzer", "interaction_threshold_qty": 10, "interaction_keep": 2 } ]}Decorators
Section titled “Decorators”Decorators augment native evaluation with extra tools and prompt clauses.
plan-mode
Section titled “plan-mode”Injects plan-management tools and a planning instruction block.
{ "decorator_id": "plan-mode", "force_completion": false}| Field | Type | Default | Description |
|---|---|---|---|
force_completion | boolean | false | Agent must resolve all tasks before answering |
Injected tools: create_plan, get_current_plan, mark_done, mark_failed, mark_blocked, mark_pending, add_task, add_note, rename_task.
skills
Section titled “skills”Loads MDX skill documents and exposes tools to browse and activate them.
{ "decorator_id": "skills", "skills_dir": "/app/skills"}| Field | Type | Required | Description |
|---|---|---|---|
skills_dir | string | Yes | Path to directory containing .mdx skill files |
Injected tools: list_skills, get_skill, select_skill, deselect_skill.
Channels
Section titled “Channels”{ "provider_id": "whatsapp", "channel_id": "whatsapp-main", "template": "{{answer}}", "middleware": [], "whatsapp_assistant_phone_number_id": { "$secretRef": "WHATSAPP_PHONE_NUMBER_ID" }, "whatsapp_verify_token": { "$secretRef": "WHATSAPP_VERIFY_TOKEN" }, "whatsapp_access_token": { "$secretRef": "WHATSAPP_ACCESS_TOKEN" }, "whatsapp_api_base_url": { "$secretRef": "WHATSAPP_API_BASE_URL" }}{ "provider_id": "email", "channel_id": "email-support", "read_mailbox": "inbox", "email_select_status": "UNSEEN", "template": "<html><body>{{ answer | markdown_to_html }}</body></html>", "middleware": [], "email_username": { "$secretRef": "EMAIL_USERNAME" }, "email_password": { "$secretRef": "EMAIL_PASSWORD" }, "email_smtp_server": { "$secretRef": "EMAIL_SMTP_SERVER" }, "email_imap_server": { "$secretRef": "EMAIL_IMAP_SERVER" }}| Field | Type | Default | Description |
|---|---|---|---|
read_mailbox | string | "inbox" | IMAP mailbox to poll |
email_select_status | string | "UNSEEN" | IMAP search criteria |
flag_on_read | string | "(\\Seen)" | Flag set when message is read |
unflag_on_error | string | "(\\Seen)" | Flag removed on processing error |
template | string | — | Jinja2 template for outbound HTML email |
{ "provider_id": "slack", "channel_id": "slack-main", "template": "{{answer}}", "middleware": [], "slack_access_token": { "$secretRef": "SLACK_ACCESS_TOKEN" }}Channel middleware
Section titled “Channel middleware”Whitelist
Section titled “Whitelist”{ "middleware": [ { "provider_id": "alquimia:whitelist", "allowed_ids": { "$secretRef": "WHITELIST_MIDDLEWARE_ALLOWED_IDS" } } ]}WHITELIST_MIDDLEWARE_ALLOWED_IDS must be a list dtype secret. Use "*" to allow all users.
Cognito OTP
Section titled “Cognito OTP”{ "middleware": [ { "provider_id": "cognito:otp", "user_pool_id": { "$secretRef": "AWS_COGNITO_USER_POOL_ID" }, "client_id": { "$secretRef": "AWS_COGNITO_CLIENT_ID" }, "client_secret": { "$secretRef": "AWS_COGNITO_CLIENT_SECRET" }, "otp_regex": "\\b(\\d{6})\\b", "otp_message": "Please send your 6-digit authentication code." } ]}Requires the AWS extra and a Redis instance.
Audio adapters
Section titled “Audio adapters”The top-level audio field declares STT/TTS connectors and the modalities the agent accepts and produces. When audio is omitted, the agent is text-only.
As of alquimia-core 0.5.2, audio connectors can also be registered as reusable models and referenced by audio_model_ref, stt_model_ref, and tts_model_ref.
AudioAdapterConfig schema
Section titled “AudioAdapterConfig schema”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
stt | SpeechToTextConnector or TritonSpeechToTextConnector | No | — | Inline speech-to-text connector; required when input_modalities contains audio and stt_model_ref is omitted |
tts | TextToSpeechConnector or TritonTextToSpeechConnector | No | — | Inline text-to-speech connector; required when output_modalities contains audio and tts_model_ref is omitted |
stt_model_ref | string | No | — | Reference to a registered STT model (0.5.2+) |
tts_model_ref | string | No | — | Reference to a registered TTS model (0.5.2+) |
audio_model_ref | string | No | — | Reference to a registered combined audio model (0.5.2+) |
input_modalities | string[] | No | ["text"] | Accepted input modalities: text, audio, or both |
output_modalities | string[] | No | ["text"] | Produced output modalities: text, audio, or both |
Registered audio model references
Section titled “Registered audio model references”Instead of embedding STT/TTS connection details in every agent, you can register reusable audio models in the agentspace and reference them from the audio field. The supported model ref types are AudioModelRef, STTModelRef, and TTSModelRef in alquimia.core.models.
alquimia registry models add stt-deepgram.json --namespace defaultalquimia registry models add tts-openai.json --namespace defaultExample STTModelRef registration:
{ "model_id": "stt-deepgram", "provider_id": "deepgram", "params": { "api_key": { "$secretRef": "STT_PROVIDER_API_KEY" }, "model": "nova-2", "language": "en-US" }}Example TTSModelRef registration:
{ "model_id": "tts-openai", "provider_id": "openai/tts", "params": { "api_key": { "$secretRef": "TTS_PROVIDER_API_KEY" }, "model": "gpt-4o-mini-tts", "voice": "alloy", "output_format": "mp3" }}Then reference them in the agent spec:
{ "audio": { "stt_model_ref": "stt-deepgram", "tts_model_ref": "tts-openai", "input_modalities": ["text", "audio"], "output_modalities": ["text", "audio"] }}Inline stt / tts connectors override the referenced registered model when both are present.
Cloud STT
Section titled “Cloud STT”{ "stt": { "provider_id": "deepgram", "api_key": { "$secretRef": "STT_PROVIDER_API_KEY" }, "model": "nova-2", "language": "en-US", "params": { "punctuate": true } }}Supported cloud provider_id values: deepgram, elevenlabs/stt, openai/transcribe.
Self-hosted STT via Triton
Section titled “Self-hosted STT via Triton”{ "stt": { "provider_id": "triton/speech-to-text", "host": "triton.example.com:8001", "model_name": "parakeet", "model_version": "1", "protocol": "grpc", "output_name": "text" }}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | Yes | — | Triton server host and port |
model_name | string | Yes | — | Model repository name |
model_version | string | Yes | — | Model version |
protocol | string | No | grpc | grpc or http |
output_name | string | No | text | Output tensor name |
Cloud TTS
Section titled “Cloud TTS”{ "tts": { "provider_id": "openai/tts", "api_key": { "$secretRef": "TTS_PROVIDER_API_KEY" }, "voice": "alloy", "model": "gpt-4o-mini-tts", "output_format": "mp3", "params": { "instructions": "Speak clearly and warmly." } }}Supported cloud provider_id values: cartesia, deepgram/aura, elevenlabs/tts, openai/tts. voice is required for elevenlabs/tts and cartesia.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
provider_id | string | Yes | — | cartesia, deepgram/aura, elevenlabs/tts, or openai/tts |
api_key | SecretRef | Yes for cloud | — | Provider API key |
voice | string | Yes for elevenlabs/tts and cartesia | — | Voice identifier |
model | string | No | Provider-specific | TTS model name |
output_format | "wav" | "mp3" | No | Provider-specific | Audio encoding format (0.5.2+) |
params | object | No | {} | Provider-specific extra parameters |
Self-hosted TTS via Triton
Section titled “Self-hosted TTS via Triton”{ "tts": { "provider_id": "triton/text-to-speech", "host": "triton.example.com:8001", "model_name": "kokoro", "model_version": "1", "protocol": "grpc", "template": "{{ text }}" }}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | Yes | — | Triton server host and port |
model_name | string | Yes | — | Model repository name |
model_version | string | Yes | — | Model version |
protocol | string | No | grpc | grpc or http |
template | string | Yes | — | Jinja2 template that renders the text payload for the model |
Streaming channels
Section titled “Streaming channels”Streaming channels keep a bidirectional audio session open for phone or WebRTC calls. They are declared in streaming_channels, separate from request/response channels.
Twilio Media Stream
Section titled “Twilio Media Stream”{ "streaming_channels": [ { "provider_id": "twilio-media-stream", "channel_id": "twilio-phone", "template": "{{answer}}", "account_sid": { "$secretRef": "TWILIO_ACCOUNT_SID" }, "auth_token": { "$secretRef": "TWILIO_AUTH_TOKEN" }, "websocket_uri": "wss://runtime.example.com/audio/twilio", "from_number": "+1234567890", "to_number": "+0987654321" } ]}| Field | Type | Required | Description |
|---|---|---|---|
provider_id | string | Yes | Must be twilio-media-stream |
channel_id | string | No | Unique identifier; auto-generated if omitted |
account_sid | SecretRef | No | Twilio account SID for inbound connection validation |
auth_token | SecretRef | No | Twilio auth token for inbound connection validation |
websocket_uri | string | No | WebSocket URI for client-side connections |
from_number | string | No | Originating phone number |
to_number | string | No | Destination phone number |
template | string | No | Jinja2 template for response text |
Browser Media Stream
Section titled “Browser Media Stream”Use this provider for browser-native or custom live audio clients that connect to the runtime’s WS /live/{assistant_id}/{channel_id} endpoint. The wire format is a simple JSON envelope carrying base64-encoded PCM s16le 16 kHz mono audio, so the client does not need to implement G.711 μ-law encoding.
{ "streaming_channels": [ { "provider_id": "browser-media-stream", "channel_id": "browser-audio", "template": "{{answer}}" } ]}| Field | Type | Required | Description |
|---|---|---|---|
provider_id | string | Yes | Must be browser-media-stream |
channel_id | string | No | Unique identifier; auto-generated if omitted |
template | string | No | Jinja2 template for response text |
The client opens wss://runtime.example.com/live/{assistant_id}/{channel_id} and sends audio as {"event": "audio", "payload": "<base64 pcm>"}. The runtime replies with the same JSON envelope. Send {"event": "stop"} to end the call gracefully.
MCP tools
Section titled “MCP tools”HTTP transport:
{ "provider_id": "mcp", "tools_id": "filesystem-tools", "human_approval": "NONE", "url": { "$secretRef": "MCP_PROVIDER_URL" }, "auth": { "$secretRef": "MCP_PROVIDER_AUTH" }, "transport": "streamable-http"}Stdio transport:
{ "provider_id": "mcp", "tools_id": "shell-tools", "human_approval": "REQUIRED", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"], "transport": "stdio"}| Field | Type | Required | Description |
|---|---|---|---|
tools_id | string | No | Unique identifier for this tool source |
human_approval | "NONE" | "REQUIRED" | No | Legacy approval gate |
url | SecretRef or string | No | MCP server URL |
auth | SecretRef or string | No | Bearer token or auth method |
command | string | No | Command to launch for stdio transport |
args | string[] | No | Arguments for stdio command |
env | object | No | Environment variables for stdio command |
headers | object | No | HTTP headers |
transport | string | No | Transport type hint |
Llama Stack tools
Section titled “Llama Stack tools”{ "provider_id": "llama-stack", "tools_id": "llama-tools", "human_approval": "NONE", "tool_group_id": "my-tool-group", "authorization": { "$secretRef": "LLAMA_STACK_PROVIDER_AUTHORIZATION" }}Requires LLAMA_STACK_BASE_URL and LLAMA_STACK_API_KEY environment variables.
A2A tools
Section titled “A2A tools”{ "provider_id": "a2a", "tools_id": "specialist-agents", "human_approval": "NONE", "selector": { "tags": ["specialist"] }, "context": null}| Field | Type | Required | Description |
|---|---|---|---|
selector | object | Yes | Registry query to find agents |
context | object | No | Extra context passed to discovered agents |
Each discovered agent is exposed as a tool named after its nickname, slugified with underscores and prefixed with ALQUIMIA_A2A_TOOLNAME_PREFIX (default agent-): a specialist with nickname QA Specialist becomes agent_qa_specialist. Use this name when classifying operations or granting tiers.
Tool registry reference (tool_ref)
Section titled “Tool registry reference (tool_ref)”Agent specs may reference a registered tool by tool_ref instead of embedding raw connection config.
{ "provider_id": "mcp", "tool_ref": "filesystem-tools", "human_approval": "NONE"}The registry must contain a matching ToolRegistration. Inline fields override registry values. For bundled connections, classify individual operations by severity, tier grants, and approval.
| Field | Type | Required | Description |
|---|---|---|---|
tool_ref | string | Yes | registered_tool_id to look up |
tier_ceiling | string[] | No | Narrows registry tier_grants for this agent (intersection) |
human_approval | "NONE" | "REQUIRED" | No | Legacy approval gate |
tier_ceiling intersects with the registry grants; it can never widen them.
| Severity | Max grantable tier | Approval |
|---|---|---|
read-only | reader, editor, operator | As configured |
mutating-recoverable | editor, operator | As configured |
destructive | operator only | Always required |
A tool name matching no classified operation is denied outright.
Human approval
Section titled “Human approval”| Value | Behavior |
|---|---|
"NONE" | Tool executes immediately unless the global authorization policy denies it |
"REQUIRED" | Emits a human-approval event before execution |
Knowledge bases
Section titled “Knowledge bases”A KnowledgeBase pairs a topic or collection with a consumption mode. It is safer to reference a registered topic by topic_id than to embed a raw collection_id, because the registry can enforce access policy and namespacing.
Common KnowledgeBase fields
Section titled “Common KnowledgeBase fields”| Field | Type | Required | Description |
|---|---|---|---|
topic_id | string | No | Reference to a TopicRegistration in the registry |
collection_id | string | No | Raw vector collection name (use only in dev/tests) |
description | string | No | Description used by the model |
search_mode | string | Yes | rag, on_demand, direct, or brain |
search_type | string | No | similarity, mmr, or similarity_score_threshold |
search_kwargs | object | No | Provider-specific search arguments |
connector | object | No | Knowledge provider connector; omitted for direct and brain |
tier_ceiling | string[] | No | Narrows the topic’s tier_grants for this agent (intersection) |
When topic_id is set, the runtime resolves agentspace_id, external_collection_id, and the topic’s access_policy from the registry. The effective collection name is {agentspace_id}__{collection_id} and an agentspace_id metadata filter is injected into every query.
Qdrant
Section titled “Qdrant”{ "collection_id": "product-docs", "description": "Product documentation and FAQs", "search_mode": "on_demand", "search_type": "similarity", "search_kwargs": { "k": 4 }, "connector": { "provider_id": "qdrant" }}{ "collection_id": "session-context", "search_mode": "rag", "search_kwargs": { "k": 4 }, "connector": { "provider_id": "redis", "ttl": 600 }}In-memory
Section titled “In-memory”{ "collection_id": "upload-context", "search_mode": "on_demand", "search_kwargs": { "k": 4 }, "connector": { "provider_id": "in_memory" }}search_mode
Section titled “search_mode”| Value | Behavior | Connector |
|---|---|---|
rag | Searched automatically before each LLM call | Required |
on_demand | Exposed as a search tool the agent calls explicitly | Required |
direct | Exposes list_files/read_file tools over a registered topic; no connector | Requires topic_id |
brain | Queries a registered Boltzmann Brain | Must be unset |
search_kwargs
Section titled “search_kwargs”| Field | Type | Default | Description |
|---|---|---|---|
k | integer | 4 | Number of results |
score_threshold | number | — | Minimum similarity score |
fetch_k | integer | — | Documents to fetch before MMR filtering |
lambda_mult | number | — | MMR diversity vs relevance |
filter | object | — | Metadata filters |
Direct file access
Section titled “Direct file access”search_mode: "direct" exposes list_files and read_file tools over a registered topic’s files. The agent can browse and read files directly instead of relying on vector search. The topic’s access_policy is enforced by the KnowledgeAuthzPolicy, so direct mode is not a bypass.
{ "topic_id": "product-docs", "search_mode": "direct", "tier_ceiling": ["reader", "editor"]}connectormust be omitted.- Files must be uploaded and associated with the topic via the runtime API or CLI.
- Use
tier_ceilingto narrow the registry’stier_grantsfor this agent.
See How to ingest files into a topic for upload and association steps.
Boltzmann brains
Section titled “Boltzmann brains”{ "search_mode": "brain", "brain_ref": "fourier-signals", "modules": ["semantic", "procedural"]}| Field | Type | Description |
|---|---|---|
brain_ref | string | brain_id of a registered brain |
modules | string[] | Memory modules to query |
See Memory & context and Tools & integrations for conceptual overviews.