AGENTO
v1.1.0 · Documentation
Documentation/Guides and reference/Common recipes

Common recipes

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

You will learn: Adapt a targeted pattern with its stated prerequisites.

Choose a recipe by the behavior you need

Recipes are small composition patterns, not interchangeable complete files. Start from a working version: "2" config such as the first tool, then merge the relevant section. A block beginning with - id: is a tool entry; a block beginning with request: or behavior: is a fragment inside an existing tool.

Before copying a fragment, declare every input path it reads, every dependency it names, and every target tool it navigates to. The booking walkthrough is the complete alternative when you want a file that runs without assembly.

Understand the result before copying the pattern

A public GET has no user credential and should only expose public data. A session-authenticated GET forwards the user's token and relies on the API's authorization. A service key represents the server, so choose it only when the endpoint's privilege model matches that authority.

Adding confirmation changes a write from immediate execution to needs_confirmation. Adding a private option ID changes what the client sees, but not which internal API value is mapped. Adding a custom store or limiter changes where state is held; it must still satisfy the runtime contract.

Check a composed recipe

Compile the merged config, then invoke it with a mock response and assert the outgoing HTTP. Test the absent value and rejection path too. Do not copy a confirmation preview containing $.service_name unless service_name is declared and populated. Do not add recovery for availability unless that dependency is declared on the same tool.

The host snippets below assume existing authorized session/message/token values and your own render functions. They are wiring examples; status-aware rendering from runtime flow is still required.

This page is meant to be copied from.

Public read-only GET

- id: list-categories
  tool:
    description: List public categories.
    input_schema:
      type: object
      properties: {}
  request:
    method: GET
    url: https://api.example.com/categories

User-authenticated GET

- id: my-bookings
  tool:
    description: List the signed-in user's bookings.
    input_schema:
      type: object
      properties: {}
  request:
    method: GET
    url: https://api.example.com/bookings
    auth:
      type: session

Host:

runtime.chat({
  sessionId,
  message: "Show my bookings",
  auth: { token: accessToken },
});

Service API key

request:
  auth:
    type: api-key
    env: PARTNER_API_KEY
    header: X-API-Key

POST with confirmation

behavior:
  effect: side-effect
  confirmation:
    required: true
    preview:
      service: $.service_name
      date: $.date
request:
  method: POST
  url: https://api.example.com/bookings

Destructive action

behavior:
  effect: destructive
  confirmation:
    required: true

Use a clear preview and a host UI that visibly distinguishes destructive intent.

Direct invoke without a model

const runtime = await AgentRuntime.create({
  configPath: "./config.yml",
  presentation: "raw",
});

await runtime.invoke({
  sessionId,
  tool: "list-categories",
  arguments: {},
});

AI conversation + raw authoritative UI

const result = await runtime.chat({
  sessionId,
  message,
  presentation: "both",
});

renderNaturalLanguage(result.message);
renderStructuredCards(result.data);

Trusted tenant context

await runtime.chat({
  sessionId,
  message,
  context: {
    tenant: { id: tenantId },
  },
});
request:
  map:
    headers:
      X-Tenant-Id:
        source: session
        path: $.tenant.id

Abort a request

const controller = new AbortController();

const promise = runtime.chat({
  sessionId,
  message,
  signal: controller.signal,
});

controller.abort();

Sensitive selection ID

selection:
  items_path: $.accounts
  id_path: $.internal_id
  label_path: $.display_name
  id_sensitive: true

Stale availability recovery

behavior:
  effect: side-effect
  confirmation:
    required: true
  recovery:
    refresh_dependency: availability
    statuses: [409, 410]

Use when a confirmed write can legitimately become stale between selection and execution. The runtime refreshes the read-only dependency and asks the user again rather than silently reissuing the write.

Custom rate limiter

const runtime = await AgentRuntime.create({
  configPath: "./config.yml",
  rateLimiter: sharedLimiter,
});

Implement:

interface RateLimiter {
  consume(key: string, limit: number, windowMs: number): Promise<void>;
}

Custom retriever for thousands of tools

const runtime = await AgentRuntime.create({
  configPath: "./config.yml",
  retriever: myVectorOrDomainRetriever,
});

Return only valid tool IDs and scores; the ToolRouter still validates candidates and final tool calls.