Skip to content

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.

{
"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" }
}
}
}
}
FieldTypeRequiredDescription
assistant_idstringYesUnique agent identifier within the agentspace
nicknamestringNoHuman-readable name (max 64 characters)
descriptionstringNoDescription shown in discovery and A2A tool lists (max 3000 characters)
tagsstring[]NoLabels for registry queries
channelsChannel[]NoInbound/outbound request/response channel configurations
streaming_channelsStreamingChannel[]NoHeld-open bidirectional audio channel configurations
audioAudioAdapterConfigNoSTT/TTS connectors and accepted/produced modalities
shieldsobjectNoPre-inference classifiers keyed by shield name
empathyEmpathyEngineNoConditional profile overrides based on shield output
role"reader" | "editor" | "operator"NoZero Trust capability tier ceiling
responseResponseProfileYesMain response provider and execution profile
FieldTypeRequiredDefaultDescription
system_promptstringNo—Jinja2 template used as the system prompt
prompt_clausesobjectNo—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_baseKnowledgeBase[]No—Vector-search or direct-access knowledge sources
short_term_memory_strategyobject[]No—Token-based history trimming
long_term_memory_strategyobject[]No—Context flush strategies
evaluation_strategyobjectNoone-shootTool use and termination policy
toolsToolConfig[]No—External tool sources
persistence_strategy"INCREMENTAL" | "FLUSH" | "EPHEMERAL"No"INCREMENTAL"How conversation history is persisted

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 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.

FieldTypeRequiredDefaultDescription
provider_id"shield-config"Yes—Must be shield-config
connectorobjectYes—Underlying classifier connector
action"observe" | "flag" | "block"No"observe"Action when threshold is crossed
thresholdnumberNo0.5Score threshold
target_labelstringNo—Only this predicted label triggers the action
fail_closedbooleanNofalseBlock on shield errors or timeouts
block_messagestringNo—Refusal text used when blocking

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.rules is a list of conditional profile overrides evaluated after all shields run. The first matching rule is applied.

FieldTypeRequiredDescription
rule_idstringYesUnique rule identifier
strategy"none" | "override" | "merge"YesHow the rule changes the response profile
descriptionstringNoHuman-readable explanation
requirementsstring[]YesShield IDs that must be present for the rule to run
conditionsstring[]Yessimpleeval expressions; all must be true
responseResponseProfileYesProfile to apply (override) or merge
StrategyBehavior
noneNo-op
overrideReplace the entire response profile with response
mergeDeep-merge response into the main profile
{
"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."
}
}
}
}
]
}
}

The config section inside response declares the LLM connector.

{
"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" }
}
}

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" }
}
}

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" }
}
}
{
"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" }
}
}

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.

FieldTypeDescription
modelstringModel identifier
temperaturenumberSampling temperature
max_tokensintegerMax output tokens
timeoutintegerRequest timeout in seconds
top_pnumberTop-p sampling
max_retriesintegerRetry count on failure
api_keySecretRefAPI key for OpenAI, Groq, or Hugging Face
groq_api_keySecretRefAPI key for Groq (alias of api_key)
base_urlSecretRefCustom endpoint URL
organizationstringOpenAI organization ID
default_headersobjectDefault headers sent with every request
reasoningobjectExtended reasoning configuration; switches to the Responses API when supported (0.5.2+)
reasoning_effortstringReasoning effort level for Chat Completions
reasoning_formatstringGroq reasoning format hint
output_versionstringResponses API output version, e.g. v0 (0.5.2+)
storebooleanWhether to store the request/response on the provider side (0.5.2+)
extra_bodyobjectAdditional provider-specific body fields for OpenAI (0.5.2+)
model_kwargsobjectProvider-specific extras that are not modeled above (0.5.3+)
harmony_preamble_as_reasoningbooleanopenai-compatible + gpt-oss/vLLM only: route streamed non-final harmony channel text to reasoning instead of the answer (0.5.5+)
{
"provider_id": "fixed",
"message": "This is a fixed response for testing.",
"chunk_size": 64
}

Instead of embedding a model connector in every profile, you can reference a model registered in the registry:

Terminal window
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.

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" }
}
ScopeEnvironment key formatVault path
globalKEYglobal/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.

ScopePer-user environment keyPer-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
dtypeFormatExample
strRaw stringsk-abc123
booltrue/false, 1/0, yes/no, on/offtrue
intInteger string587
floatFloat string0.7
listJSON array or comma-separated["a","b"] or a,b

See Rotate secrets and Vault policies for operational details.

Single LLM call, no tools. Use for simple Q&A agents.

{
"evaluation_strategy_id": "one-shoot"
}

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
}
FieldTypeDefaultDescription
max_stepsinteger10Max LLM calls before termination
max_concurrent_toolsinteger1Max tool calls per step
tool_choicestring or object"auto"Tool selection mode
decoratorsDecorator[]nullplan-mode and skills decorators
structured_outputobjectnullForce 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*:..."
}

Trims conversation history to stay within a token budget.

{
"short_term_memory_strategy": [
{
"memory_strategy_id": "max_tokens",
"memory_max_tokens": 10000,
"conditions": []
}
]
}
FieldTypeDefaultDescription
memory_max_tokensinteger10000Token budget; -1 disables trimming
conditionsstring[][]Empathy-style conditions

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."
}
]
}
FieldTypeDefaultDescription
interaction_threshold_qtyinteger20Flush after this many interactions
interaction_threshold_tokensinteger20000Flush after this many tokens
input_tokens_thresholdinteger0Flush when LLM reports this many input tokens
interaction_keepinteger0Human turns to keep after flush
step_keep_qtyinteger0Trailing tool-call round trips to keep
step_keep_tokensinteger0Same as above, bounded by token budget
cod_max_loopsinteger5Chain-of-Density summarization iterations
instructionsstring—Summarization focus instructions
knowledge_baseobject—Store summary in this knowledge base

Erases memory beyond retained interactions without summarization.

{
"long_term_memory_strategy": [
{
"long_term_memory_id": "neuralyzer",
"interaction_threshold_qty": 10,
"interaction_keep": 2
}
]
}

Decorators augment native evaluation with extra tools and prompt clauses.

Injects plan-management tools and a planning instruction block.

{
"decorator_id": "plan-mode",
"force_completion": false
}
FieldTypeDefaultDescription
force_completionbooleanfalseAgent 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.

Loads MDX skill documents and exposes tools to browse and activate them.

{
"decorator_id": "skills",
"skills_dir": "/app/skills"
}
FieldTypeRequiredDescription
skills_dirstringYesPath to directory containing .mdx skill files

Injected tools: list_skills, get_skill, select_skill, deselect_skill.

{
"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" }
}
FieldTypeDefaultDescription
read_mailboxstring"inbox"IMAP mailbox to poll
email_select_statusstring"UNSEEN"IMAP search criteria
flag_on_readstring"(\\Seen)"Flag set when message is read
unflag_on_errorstring"(\\Seen)"Flag removed on processing error
templatestring—Jinja2 template for outbound HTML email
{
"provider_id": "slack",
"channel_id": "slack-main",
"template": "{{answer}}",
"middleware": [],
"slack_access_token": { "$secretRef": "SLACK_ACCESS_TOKEN" }
}
{
"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.

{
"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.

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.

FieldTypeRequiredDefaultDescription
sttSpeechToTextConnector or TritonSpeechToTextConnectorNo—Inline speech-to-text connector; required when input_modalities contains audio and stt_model_ref is omitted
ttsTextToSpeechConnector or TritonTextToSpeechConnectorNo—Inline text-to-speech connector; required when output_modalities contains audio and tts_model_ref is omitted
stt_model_refstringNo—Reference to a registered STT model (0.5.2+)
tts_model_refstringNo—Reference to a registered TTS model (0.5.2+)
audio_model_refstringNo—Reference to a registered combined audio model (0.5.2+)
input_modalitiesstring[]No["text"]Accepted input modalities: text, audio, or both
output_modalitiesstring[]No["text"]Produced output modalities: text, audio, or both

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.

Terminal window
alquimia registry models add stt-deepgram.json --namespace default
alquimia registry models add tts-openai.json --namespace default

Example 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.

{
"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.

{
"stt": {
"provider_id": "triton/speech-to-text",
"host": "triton.example.com:8001",
"model_name": "parakeet",
"model_version": "1",
"protocol": "grpc",
"output_name": "text"
}
}
FieldTypeRequiredDefaultDescription
hoststringYes—Triton server host and port
model_namestringYes—Model repository name
model_versionstringYes—Model version
protocolstringNogrpcgrpc or http
output_namestringNotextOutput tensor name
{
"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.

FieldTypeRequiredDefaultDescription
provider_idstringYes—cartesia, deepgram/aura, elevenlabs/tts, or openai/tts
api_keySecretRefYes for cloud—Provider API key
voicestringYes for elevenlabs/tts and cartesia—Voice identifier
modelstringNoProvider-specificTTS model name
output_format"wav" | "mp3"NoProvider-specificAudio encoding format (0.5.2+)
paramsobjectNo{}Provider-specific extra parameters
{
"tts": {
"provider_id": "triton/text-to-speech",
"host": "triton.example.com:8001",
"model_name": "kokoro",
"model_version": "1",
"protocol": "grpc",
"template": "{{ text }}"
}
}
FieldTypeRequiredDefaultDescription
hoststringYes—Triton server host and port
model_namestringYes—Model repository name
model_versionstringYes—Model version
protocolstringNogrpcgrpc or http
templatestringYes—Jinja2 template that renders the text payload for the model

Streaming channels keep a bidirectional audio session open for phone or WebRTC calls. They are declared in streaming_channels, separate from request/response channels.

{
"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"
}
]
}
FieldTypeRequiredDescription
provider_idstringYesMust be twilio-media-stream
channel_idstringNoUnique identifier; auto-generated if omitted
account_sidSecretRefNoTwilio account SID for inbound connection validation
auth_tokenSecretRefNoTwilio auth token for inbound connection validation
websocket_uristringNoWebSocket URI for client-side connections
from_numberstringNoOriginating phone number
to_numberstringNoDestination phone number
templatestringNoJinja2 template for response text

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}}"
}
]
}
FieldTypeRequiredDescription
provider_idstringYesMust be browser-media-stream
channel_idstringNoUnique identifier; auto-generated if omitted
templatestringNoJinja2 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.

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"
}
FieldTypeRequiredDescription
tools_idstringNoUnique identifier for this tool source
human_approval"NONE" | "REQUIRED"NoLegacy approval gate
urlSecretRef or stringNoMCP server URL
authSecretRef or stringNoBearer token or auth method
commandstringNoCommand to launch for stdio transport
argsstring[]NoArguments for stdio command
envobjectNoEnvironment variables for stdio command
headersobjectNoHTTP headers
transportstringNoTransport type hint
{
"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.

{
"provider_id": "a2a",
"tools_id": "specialist-agents",
"human_approval": "NONE",
"selector": { "tags": ["specialist"] },
"context": null
}
FieldTypeRequiredDescription
selectorobjectYesRegistry query to find agents
contextobjectNoExtra 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.

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.

FieldTypeRequiredDescription
tool_refstringYesregistered_tool_id to look up
tier_ceilingstring[]NoNarrows registry tier_grants for this agent (intersection)
human_approval"NONE" | "REQUIRED"NoLegacy approval gate

tier_ceiling intersects with the registry grants; it can never widen them.

SeverityMax grantable tierApproval
read-onlyreader, editor, operatorAs configured
mutating-recoverableeditor, operatorAs configured
destructiveoperator onlyAlways required

A tool name matching no classified operation is denied outright.

ValueBehavior
"NONE"Tool executes immediately unless the global authorization policy denies it
"REQUIRED"Emits a human-approval event before execution

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.

FieldTypeRequiredDescription
topic_idstringNoReference to a TopicRegistration in the registry
collection_idstringNoRaw vector collection name (use only in dev/tests)
descriptionstringNoDescription used by the model
search_modestringYesrag, on_demand, direct, or brain
search_typestringNosimilarity, mmr, or similarity_score_threshold
search_kwargsobjectNoProvider-specific search arguments
connectorobjectNoKnowledge provider connector; omitted for direct and brain
tier_ceilingstring[]NoNarrows 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.

{
"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 }
}
{
"collection_id": "upload-context",
"search_mode": "on_demand",
"search_kwargs": { "k": 4 },
"connector": { "provider_id": "in_memory" }
}
ValueBehaviorConnector
ragSearched automatically before each LLM callRequired
on_demandExposed as a search tool the agent calls explicitlyRequired
directExposes list_files/read_file tools over a registered topic; no connectorRequires topic_id
brainQueries a registered Boltzmann BrainMust be unset
FieldTypeDefaultDescription
kinteger4Number of results
score_thresholdnumber—Minimum similarity score
fetch_kinteger—Documents to fetch before MMR filtering
lambda_multnumber—MMR diversity vs relevance
filterobject—Metadata filters

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"]
}
  • connector must be omitted.
  • Files must be uploaded and associated with the topic via the runtime API or CLI.
  • Use tier_ceiling to narrow the registry’s tier_grants for this agent.

See How to ingest files into a topic for upload and association steps.

{
"search_mode": "brain",
"brain_ref": "fourier-signals",
"modules": ["semantic", "procedural"]
}
FieldTypeDescription
brain_refstringbrain_id of a registered brain
modulesstring[]Memory modules to query

See Memory & context and Tools & integrations for conceptual overviews.