AGENTO
v1.1.0 · Documentation
Documentation/Build your config/Understand config.yml

Understand config.yml

2026-10-15·source 4bebed4·8 min read·6 / 27

You will learn: Know where each setting belongs and when you need it.

You can write config by hand or use the OpenAPI generator in a release that includes it. Generated config uses the same native format; review it and add the settings your application needs.

After the quick start, you have a request working against your API. This chapter explains where configuration belongs, why you would add it, and how to observe its effect.

The runtime loads configuration at creation and validates executable rules. It is not a general prompt that leaves the model to decide how HTTP should work.

Answer three questions before adding options

What operation may the user request? This determines the tool and its description. Searching for services and booking a slot are distinct operations.

What inputs are acceptable? This determines tool.input_schema. A search might require a string named query. A booking may require a date and a slot identifier. A required identifier is not necessarily something the user knows; dependencies can supply it later.

How does the API accept those values? This determines request and request.map. Declaring query does not automatically send an API parameter named q.

arguments.query = "hair"
        |
        v
input_schema: accept a non-empty string
        |
        v
request.map.query: q <- $.query
        |
        v
GET /services?q=hair

A number fails the string schema. A valid argument without a mapping is not automatically sent. A correct mapping with a wrong URL still calls the wrong location. Identify the failing layer before editing descriptions.

Know the levels of the file

Root settings apply to the runtime. Each item in tools describes one operation. Within that item, tool describes inputs and request configures HTTP. response, depends_on, and behavior are siblings of those blocks when needed.

This is a placement diagram, not runnable YAML:

config.yml
├── version
├── models                  used by chat
├── assistant               conversation guidance
├── session                 conversation state limits
└── tools
    └── one tool
        ├── id
        ├── tool
        │   ├── description
        │   └── input_schema
        ├── request
        │   ├── method / url / auth
        │   └── map
        ├── response
        ├── depends_on
        └── behavior

YAML indentation determines structure. models does not belong inside a tool, and input_schema belongs inside tool. When a familiar key is rejected, check its placement.

The permitted root keys are version, assistant, routing, session, rate_limits, models, and tools. Version is the string "2"; the tools list must not be empty.

Add each section for a concrete reason

After the request works, add response validation from a verified contract. HTTP 200 can then fail validation if the returned shape violates what your application expects.

To accept user messages, configure models.routing and use chat(). This enables tool selection and input extraction; it is not needed just to call a known tool through invoke().

When an operation needs an ID the user cannot supply, configure a dependency. Multiple lookup results may produce needs_selection: the runtime is waiting for a choice.

For writes, configure effect and confirmation policies. Expect needs_confirmation before execution. Merely changing GET to POST is insufficient.

Before integrating multiple users and workers, address authentication, sessions, and HTTP failures. More options do not automatically improve a tool.

Separate validation from integration testing

Configuration validation rejects unknown keys, duplicate IDs, mappings to undeclared inputs, and references to missing tools. It cannot prove your API still serves the endpoint or that a credential has permission.

Successful runtime creation checks configuration rules. A real tool invocation checks the API integration. A conversation test then checks whether language leads to the correct tool.

On your first read, continue to tool inputs now. The remaining sections are a root-settings reference to revisit when tuning conversation, sessions, or usage limits.

Assistant: language and conversation, not execution permission

assistant:
  name: Booking assistant
  language: auto
  timezone: Asia/Hebron
  system_prompt: |
    Help users find and book appointments using the available tools.
    Do not invent availability or claim a booking before it completes.
  conversation:
    enabled: true
    include_capability_summary: true
    capability_summary:
      include_title: true
      include_description: true
    use_presentation_model: true

name is optional, 1–100 characters. language defaults to auto; it guides responses, and Arabic selection prompts use explicit ar or Arabic detected in the last user message. timezone defaults to UTC and must be a valid IANA zone. Set it for relative-date routing; it does not rewrite your API's stored timestamps.

system_prompt guides conversation and result presentation. It cannot authorize a write or override the mapper. Put execution rules in schemas and policies.

You can use it to clarify the model's personality and tone in conversations.

conversation.enabled defaults to true. Turning it off makes a deliberate no-match return ROUTING_NO_MATCH instead of normal conversation; pending work has its own preservation behavior. Keep it enabled for assistants that must answer greetings or detours.

The capability-summary switches control whether conversation sees tool titles/descriptions. Disabling them reduces context but gives the assistant less information about what it can do. They do not remove tools from routing. use_presentation_model defaults to true; it uses the presentation model for conversation, falling back to the routing model if no separate presentation model exists.

Routing: balance recall, context, and latency

routing:
  candidate_limit: 6
  fallback_attempts: 2
  lexical:
    enabled: true
    min_score: 1
    normalize_unicode: true
    normalize_arabic: true
    phrase_matching: true
  semantic_recall:
    enabled: true
    candidate_limit: 6
    max_catalog_tools: 100
    max_catalog_chars: 100000
    metadata:
      include_id: true
      include_title: true
      include_description: true
    allow_no_match: true
    multilingual: true

These are the defaults.

  • candidate_limit bounds the final selection shortlist, from 1 to 100. Increase it only when relevant tools are being excluded; larger lists can increase cost and ambiguity.
  • fallback_attempts permits 1–3 structured/JSON selection fallback attempts. It is not an HTTP retry policy.
  • lexical.enabled controls cheap metadata matching. min_score sets the confidence threshold. Disabling normalization can reduce matches for equivalent Unicode or Arabic spellings. phrase_matching rewards configured phrases.
  • semantic_recall.enabled permits model-assisted discovery when lexical recall is weak. Disabling it can save calls but lose paraphrases and cross-language matches.
  • Its candidate_limit bounds recalled IDs. max_catalog_tools and max_catalog_chars bound metadata sent for recall; raising them allows broader catalogs at additional context cost. Their maximums are 10,000 tools and 1,000,000 characters.
  • Metadata title/description switches trade richer discovery context for smaller prompts. include_id, allow_no_match, and multilingual currently accept only true; they are not off switches.

Measure routing outcomes on representative messages before tuning these values. A precise description is often more useful than increasing every limit.

Session: distinguish memory, expiry, and work limits

SettingDefaultEffect of changing it
ttl_ms1,800,000Controls session lifetime. Longer sessions retain pending context longer; do not use this to extend a slot's dependency TTL.
max_history_messages20Bounds model conversation history. Zero disables retained history; maximum 1,000. This is not a lifetime message allowance.
max_sessions10,000Capacity passed to the default in-memory store. Custom stores must implement their own capacity policy.
max_steps32Bounds dependency orchestration per operation, maximum 100. More steps permit deeper work but increase possible latency.

Except for history length, these values must be positive integers. In-memory storage is suitable for a single process; configuration does not turn it into shared storage. See sessions for deployment consequences.

Rate limits: count real work

rate_limits:
  ai_calls: 60
  tool_calls: 120
  messages: 120
  messages_per_session: 1000
  window_ms: 60000

The window budgets are enforced per session in the default implementation. ai_calls includes model work such as routing, recall, conversation, and presentation; one chat message can spend more than one call. tool_calls includes every actual HTTP attempt, including retries. messages counts incoming runtime operations, including invoke, select, confirm, and cancel, in the window; messages_per_session is a separate lifetime counter.

Increasing window_ms with unchanged budgets makes the allowance stricter over time. Lower budgets can interrupt an otherwise valid multi-step flow. Handle RATE_LIMITED explicitly. A distributed application needs a shared limiter; these settings are not an account-wide billing cap.

Models: enable only the work you need

models.routing enables chat routing. models.presentation optionally separates result wording and conversation from routing. Supported provider IDs are openai, anthropic, mistral, cohere, and ollama.

Each provider needs provider and model. Hosted providers require api_key: $ENV:NAME; missing environment values fail compilation. Optional base_url selects the provider endpoint. timeout_ms defaults to 30,000. temperature is optional, from 0 to 2, and must be supported by the model.

Capability overrides describe real adapter/model behavior; setting nativeTools: true does not give an unsupported model tool calling. See providers before changing them.

Validate changes before startup

import { readFile } from "node:fs/promises";
import { compileConfig } from "agento-runtime";

const compiled = compileConfig(await readFile("./config.yml", "utf8"));
console.log(compiled.tools.values());

Compilation checks relationships that a YAML parser cannot: duplicate IDs, invalid schemas, unmapped URL placeholders, unknown input paths, dependency cycles, conflicting destinations, unsafe credentials, and missing confirmations.

It does not prove the API returns your declared structure or that descriptions route correctly. Pair it with mocked execution tests and a routing evaluation set. The booking fixture demonstrates a complete behavioral test.