Skip to main content
The TOOLS: section defines the external capabilities available to an agent. Each tool declares a typed signature (parameters and return type), an optional execution binding, and metadata that guides the LLM’s tool selection.

Tool binding types

The type: property selects how a tool is executed. The supported values are:
typePurpose
httpCall a REST (or SOAP) API endpoint. See HTTP tools.
mcpBind a tool exposed by an MCP server. See MCP tools.
sandboxRun inline JavaScript/Python in an isolated sandbox. See Code tools.
lambdaInvoke a cloud serverless function. See Lambda tools.
async_webhookFire-and-callback async HTTP. See Async webhook tools.
workflowInvoke a durable workflow on the workflow engine. See Workflow tools.
searchaiQuery a SearchAI knowledge base. See SearchAI tools.

Tool declaration syntax

A tool is declared with a function-style signature followed by indented properties:
TOOLS:
  tool_name(param1: type1, param2: type2 = default) -> ReturnType
    description: "What this tool does"
    type: http
    endpoint: "/api/path"
    method: POST

Signature format

name(parameters) -> return_type
  • name — a lowercase identifier using snake_case
  • parameters — comma-separated list of typed parameters
  • return_type — the type of data the tool returns

Parameter syntax

Each parameter follows the format name: type with an optional default value:
param_name: type
param_name: type = default_value
ComponentDescriptionExamples
nameParameter identifier (snake_case)account_id, query, limit
typeData typestring, number, boolean, date
= defaultDefault value (makes parameter optional)= 10, = "USD", = true
Parameters without a default value are required. Parameters with a default value are optional.

Parameter types

TypeDescriptionExamples
stringText value"hello"
numberNumeric value (integer or float)42, 3.14
booleanTrue or falsetrue, false
dateDate value"2026-03-01"
objectNested object (specify fields with nested parameters:)
type[]Array of the given typestring[], number[]

Object parameters

When a parameter has type object, you can define nested fields using a parameters: block under the tool:
TOOLS:
  create_order(customer: object, items: object[]) -> {order_id: string}
    description: "Create a new order"
    parameters:
      customer:
        name: string
        email: string
      items:
        product_id: string
        quantity: number

Array parameters

Array types use the [] suffix:
TOOLS:
  bulk_lookup(ids: string[]) -> {results: object[]}
    description: "Look up multiple records by ID"

Parameter enrichment and sources

The parameters: block does more than describe nested object fields — it can enrich any signature-declared parameter with a description, validation, visibility, and a value source. This lets you inject values (from system state, config, auth, an expression, or a lookup table) without the LLM having to supply them, and optionally hide them from the model.
TOOLS:
  charge_card(amount: number, customer_id: string) -> {receipt_id: string}
    description: "Charge the customer's card on file"
    type: http
    endpoint: "/api/charges"
    method: POST
    parameters:
      customer_id:
        source: system            # model | system | runtime | config | auth | expr | lookup
        value: "session.customer_id"
        hidden: true              # do not expose to the model
      amount:
        description: "Charge amount in the account currency"
        required: true
Enrichment keyTypeDescription
descriptionstringParameter description shown to the model.
requiredbooleanWhether the parameter is required.
defaultanyDefault value.
sourcestringValue source: model, system, runtime, config, auth, expr, lookup.
valuestringThe expression or reference used with expr/lookup/system/config sources.
key / tablestringLookup key and table (with source: lookup).
hiddenbooleanHide the parameter from the model (still sent to the tool).
visibilityobjectFine-grained { model, trace } visibility flags.
propertiesobjectNested object field schema (for object params).
itemsobjectItem schema (for array params).

Return type

The return type appears after the -> arrow. It can be:
FormSyntaxExample
Simple type-> type-> string
Object type-> {field: type, ...}-> {id: string, name: string}
Array type-> type[]-> Hotel[]
Nested object-> {field: {nested: type}}-> {user: {name: string, age: number}}
Optional fields-> {field?: type}-> {error?: string}
Array of objects-> {field: type}[]-> {id: string, title: string}[]
TOOLS:
  search_hotels(destination: string, checkin: date, checkout: date) -> {hotels: {id: string, name: string, price: number, rating: number}[], total: number}
    description: "Search available hotels"

Description

The description: property provides a natural-language explanation of what the tool does. The LLM uses this description to decide when and how to call the tool.
TOOLS:
  verify_account(account_id: string) -> {name: string, status: string}
    description: "Retrieve account details and verify the account is active"
Write descriptions that help the LLM understand:
  • What the tool does
  • When to call it
  • What data it returns

Hints

The hints: block provides execution metadata that the runtime uses for optimization:
TOOLS:
  get_balance(account_id: string) -> {balance: number}
    description: "Get account balance"
    hints:
      cacheable: true
      latency: fast
      timeout: 5000
HintTypeDefaultDescription
cacheablebooleannoneWhether results can be cached across calls with the same parameters
latency"fast" , "medium" , "slow"noneExpected latency category for runtime scheduling
side_effectsbooleannoneWhether the tool modifies external state
requires_authbooleannoneWhether the tool requires authenticated context
timeoutnumbernoneTool-specific timeout in milliseconds (overrides EXECUTION.tool_timeout)

HTTP tools

HTTP tools call REST API endpoints. They are the most common tool type.
TOOLS:
  search_flights(origin: string, destination: string, date: date) -> {flights: {id: string, price: number}[]}
    description: "Search available flights"
    type: http
    endpoint: "https://api.flights.com/v1/search"
    method: POST
    auth: bearer
    timeout: 10000
    retry: 3
    retry_delay: 1000

HTTP binding properties

PropertyTypeRequiredDefaultDescription
type"http"YesDeclares this as an HTTP tool
endpointstringYesURL or path for the API call. Supports path parameters: "/hotels/{hotel_id}"
method"GET" , "POST" , "PUT" , "PATCH" , "DELETE"YesHTTP method
authstringNo"none"Authentication type (see Auth)
timeoutnumberNoEXECUTION.tool_timeoutRequest timeout in milliseconds
retrynumberNononeNumber of retry attempts on failure
retry_delaynumberNononeDelay in milliseconds between retries
headersRecord<string, string>NononeCustom HTTP headers
query_paramsRecord<string, string>NononeQuery string parameters
body_type"json" , "form" , "xml" , "text"NononeRequest body encoding.
body_templatestringNononeCustom body template with interpolation. body is accepted as an alias.
request_variantsobject[]NononeConditional request variants selected by a when expression. See Request variants.
rate_limitnumberNononeMaximum requests per second
circuit_breaker{threshold, resetMs}NononeCircuit breaker configuration
protocol"rest" , "soap"No"rest"Wire protocol. Set soap for SOAP endpoints. See SOAP support.
soap_version"1.1" , "1.2"No"1.1"SOAP version (when protocol: soap).
soap_actionstringNononeSOAPAction header (1.1) or action media-type parameter (1.2).
on_soap_fault"error" , "data"NononeHow to handle <soap:Fault>error throws, data returns the fault payload.

Path parameters

Use curly braces in the endpoint to reference tool parameters:
TOOLS:
  get_hotel(hotel_id: string) -> Hotel
    type: http
    endpoint: "/hotels/{hotel_id}"
    method: GET

Headers

Custom headers are specified as key-value pairs:
TOOLS:
  get_data(query: string) -> {results: object[]}
    type: http
    endpoint: "/api/data"
    method: POST
    headers:
      X-Api-Version: "2024-01"
      Accept: "application/json"

Auth

The auth: property specifies the authentication mechanism. The runtime resolves credentials from the project’s credential store — the ABL document never contains actual secrets.
Auth typeDescription
noneNo authentication
bearerBearer token in Authorization header
api_keyAPI key (header name configurable via auth_config)
oauth2_clientOAuth 2.0 client credentials flow
oauth2_userOAuth 2.0 authorization code flow (user-scoped tokens)
samlSAML assertion-based authentication
customCustom authentication with configurable headers
saml is accepted by the parser but is not currently resolved at runtime — it is dropped during compilation. Prefer an auth profile for enterprise SSO-backed integrations.

Auth configuration

For auth types that require additional configuration, use the auth_config: block:
TOOLS:
  get_user_data(user_id: string) -> {name: string, email: string}
    type: http
    endpoint: "/api/users/{user_id}"
    method: GET
    auth: oauth2_client
    auth_config:
      token_url: "https://auth.example.com/oauth/token"
      client_id: "my-client-id"
      client_secret: "{{config.OAUTH_CLIENT_SECRET}}"
      scopes: "read:users"
TOOLS:
  call_partner_api(payload: string) -> {status: string}
    type: http
    endpoint: "https://partner.example.com/api"
    method: POST
    auth: api_key
    auth_config:
      header_name: "X-API-Key"
Auth config propertyTypeUsed withDescription
token_urlstringoauth2_client, oauth2_userOAuth token endpoint URL
client_idstringoauth2_client, oauth2_userOAuth client identifier
client_secretstringoauth2_client, oauth2_userOAuth client secret (use {{config.X}} placeholders)
scopesstringoauth2_client, oauth2_userSpace-separated OAuth scopes
header_namestringapi_keyCustom header name for the API key
providerstringoauth2_user, samlAuth provider identifier
custom_headersRecord<string, string>customCustom authentication headers

Credential placeholders

Credentials use {{config.NAME}} placeholder syntax (with isSecret: true on the config var). The runtime resolves these from the project’s config vars at execution time. For OAuth integrations, binding an auth profile is the preferred approach. Never embed actual credentials in ABL files.
auth_config:
  client_secret: "{{config.PARTNER_OAUTH_SECRET}}"
For OAuth and enterprise integrations, the preferred approach is to bind a pre-configured auth profile by name rather than declaring auth_config inline. These tool-level properties control credential resolution, transport security, just-in-time authorization, consent, and per-user vs. shared connections:
TOOLS:
  create_ticket(subject: string, body: string) -> {ticket_id: string}
    description: "Create a support ticket"
    type: http
    endpoint: "https://itsm.example.com/api/tickets"
    method: POST
    auth_profile: servicenow_oauth   # named profile resolved at runtime
    tls_profile: partner_mtls         # mTLS transport cert profile
    auth_jit: true                    # acquire credentials just-in-time
    consent: preflight                # preflight | inline
    connection: per_user              # per_user | shared
PropertyTypeDescription
auth_profilestringName of a pre-configured auth profile; resolved at runtime (no secrets in the ABL file).
tls_profilestringName of an mTLS transport-certificate profile (independent of auth_profile).
auth_jitbooleanAcquire credentials just-in-time at call time rather than up front.
consent"preflight" , "inline"When user consent is obtained — before the run (preflight) or during the conversation (inline).
connection"per_user" , "shared"Whether the integration uses per-end-user connections or a single shared connection.

Result transformation

Tool results are available in the session context after execution. You can map specific result fields to session variables using on_result: and handle errors with on_error::
TOOLS:
  get_balance(account_id: string) -> {balance: number, currency: string}
    description: "Get account balance"
    type: http
    endpoint: "/api/balance"
    method: GET
    on_result:
      set:
        current_balance: result.balance
        account_currency: result.currency
    on_error:
      set:
        balance_error: error.message
Beyond set:, both on_result: and on_error: accept an ordered do: action block that can run SET, CLEAR, LOG, RESPOND, CALL, GOTO/THEN, HANDOFF, DELEGATE, RETURN, FORMATS, and COMPLETE actions, with conditional IF:/WHEN:/ELSE: branches.

SSRF protection

The platform enforces SSRF (Server-Side Request Forgery) protection on all HTTP tool endpoints. Private IP ranges, localhost, and internal network addresses are blocked at the runtime level. Only allowlisted domains and public endpoints are permitted for HTTP tool calls.

Circuit breaker

The circuit breaker prevents cascading failures by halting requests to a failing endpoint after a threshold of consecutive errors:
TOOLS:
  unreliable_api(query: string) -> {data: string}
    type: http
    endpoint: "https://api.example.com/data"
    method: GET
    circuit_breaker:
      threshold: 5
      resetMs: 30000
PropertyTypeDescription
thresholdnumberNumber of consecutive failures before the circuit opens
resetMsnumberMilliseconds to wait before trying the endpoint again

SOAP support

HTTP tools can call SOAP endpoints by setting protocol: soap.
TOOLS:
  lookup_policy(policy_number: string) -> {status: string, holder: string}
    description: "Look up an insurance policy"
    type: http
    endpoint: "https://legacy.example.com/PolicyService"
    method: POST
    protocol: soap
    soap_version: "1.1"
    soap_action: "urn:PolicyService#lookupPolicy"
    on_soap_fault: error       # error | data
PropertyTypeDefaultDescription
protocol"rest" , "soap""rest"Wire protocol.
soap_version"1.1" , "1.2""1.1"SOAP envelope version.
soap_actionstringnoneSOAPAction header (1.1) or action media-type parameter (1.2).
on_soap_fault"error" , "data"noneerror raises on <soap:Fault>; data returns the fault as the result.

Request variants

For endpoints that vary by condition, request_variants selects a request shape at call time based on a when expression. Each variant can override the endpoint, method, headers, query params, and body.
TOOLS:
  submit(order: object, region: string) -> {ref: string}
    type: http
    endpoint: "https://api.example.com/us/submit"
    method: POST
    request_variants:
      - name: eu
        when: region == "EU"
        endpoint: "https://api.eu.example.com/submit"
        body_type: json
      - name: default
        default: true

MCP tools

MCP (Model Context Protocol) tools connect to external MCP servers that expose tools dynamically. The runtime handles protocol negotiation, transport, and tool discovery.
TOOLS:
  web_search(query: string) -> {results: {title: string, url: string, snippet: string}[]}
    description: "Search the web"
    type: mcp
    server: "brave-search"

MCP binding properties

PropertyTypeRequiredDefaultDescription
type"mcp"YesDeclares this as an MCP tool
serverstringYesMCP server name (resolved from runtime configuration)
server_toolstringNoTool nameTool name on the MCP server (if different from the ABL tool name)
headersRecord<string, string>NononePer-call headers, supporting {{config.X}} / {{session.X}} templates.

Server configuration

The server value is a logical name that maps to an MCP server configuration in the project’s runtime settings. Server configuration (transport type, connection URL, authentication) is managed at the project level, not in the ABL file. The platform supports these MCP transport types:
TransportDescription
stdioStandard input/output (for local MCP server processes)
httpHTTP-based transport (Streamable HTTP)
websocketWebSocket-based transport

Dynamic tool discovery

MCP servers can expose multiple tools. When you declare an MCP tool in ABL, you bind a specific tool from the server. If the tool name on the MCP server differs from the tool name in your ABL file, use server_tool: to specify the server-side name:
TOOLS:
  search(query: string) -> {results: object[]}
    description: "Search using Brave"
    type: mcp
    server: "brave-search"
    server_tool: "brave_web_search"

Code tools (sandbox)

Code tools execute user-provided JavaScript or Python code in an isolated sandbox environment with resource limits and no network access.
TOOLS:
  calculate_tax(income: number, state: string) -> {tax: number, rate: number}
    description: "Calculate state income tax"
    type: sandbox
    runtime: javascript
    timeout: 5000
    memory_mb: 128
    code: |
      const rates = { CA: 0.133, NY: 0.109, TX: 0 };
      const rate = rates[state] || 0.05;
      return { tax: income * rate, rate };

Sandbox binding properties

PropertyTypeRequiredDefaultDescription
type"sandbox"YesDeclares this as a sandbox tool
runtime"javascript" , "python"YesExecution runtime
codestringNononeInline source code (pipe block syntax for multi-line)
timeoutnumberNoPlatform defaultMaximum execution time in milliseconds
memory_mbnumberNoPlatform defaultMemory limit in megabytes

Isolation

Sandbox tools execute in a gVisor-isolated environment with the following restrictions:
  • No network access
  • No filesystem access beyond the sandbox working directory
  • Resource limits enforced (CPU, memory, execution time)
  • Each execution runs in a fresh environment

JavaScript runtime

JavaScript code tools have access to standard JavaScript built-ins. The code should return a value matching the declared return type.
TOOLS:
  format_currency(amount: number, currency: string) -> {formatted: string}
    type: sandbox
    runtime: javascript
    code: |
      const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: currency
      });
      return { formatted: formatter.format(amount) };

Python runtime

Python code tools use a sandboxed Python interpreter. The code should return a dictionary matching the declared return type.
TOOLS:
  analyze_text(text: string) -> {word_count: number, sentences: number}
    type: sandbox
    runtime: python
    code: |
      import re
      words = len(text.split())
      sentences = len(re.split(r'[.!?]+', text))
      return {"word_count": words, "sentences": sentences}

Lambda tools

Lambda tools invoke cloud serverless functions. The function name is a logical identifier resolved to an actual endpoint (ARN, URL) at runtime through the project’s function registry.
TOOLS:
  process_document(document_url: string, format: string) -> {text: string, pages: number}
    description: "Extract text from a document"
    type: lambda
    function: "document-processor"
    runtime: "nodejs20"
    timeout: 30000

Lambda binding properties

PropertyTypeRequiredDefaultDescription
type"lambda"YesDeclares this as a lambda tool
functionstringYesLogical function name (resolved at runtime)
runtimestringNononeRuntime hint (for example. "nodejs20", "python3.12")
timeoutnumberNoPlatform defaultOverride timeout for this function in milliseconds

Async webhook tools

Async webhook tools send an HTTP request with a callback URL injected into the payload. The external system processes the request asynchronously and posts the result back to the callback URL when complete.
TOOLS:
  generate_report(report_type: string, date_range: string) -> {report_url: string, status: string}
    description: "Generate a financial report (processed asynchronously)"
    type: async_webhook
    endpoint: "https://reports.internal/api/generate"
    method: POST
    callback_url_field: "callbackUrl"
    timeout_seconds: 3600

Async webhook binding properties

PropertyTypeRequiredDefaultDescription
type"async_webhook"YesDeclares this as an async webhook tool
endpointstringYesURL to send the initial request
method"POST" , "PUT" , "PATCH"YesHTTP method
headersRecord<string, string>NononeCustom HTTP headers
callback_url_fieldstringNo"callbackUrl"Dot-path in the request body where the callback URL is injected
timeout_secondsnumberNo3600Timeout in seconds for the async callback response

Workflow tools

Workflow tools invoke a durable workflow on the workflow engine. Use these for long-running, stateful orchestrations (waits, polling, human approval, multi-hour processes) that should not run inside the stateless agent runtime.
TOOLS:
  start_onboarding(customer_id: string, plan: string) -> {run_id: string, status: string}
    description: "Kick off the customer onboarding workflow"
    type: workflow
    workflow_id: "customer-onboarding"
    mode: async
    timeout_ms: 60000
    param_mapping:
      customerId: customer_id
      selectedPlan: plan

Workflow binding properties

PropertyTypeRequiredDefaultDescription
type"workflow"YesDeclares this as a workflow tool.
workflow_idstringYesLogical workflow identifier. Version routing comes from the deployment manifest.
mode"sync" , "async"No"sync"sync waits for completion; async starts the run and returns a handle.
timeout_msnumberNononeMaximum time to wait. Supports {{config.X}} interpolation.
param_mappingRecord<string,string>NononeMaps workflow input fields to tool parameters (workflow key → tool parameter).
The workflow must exist in the same tenant/project; this is validated at compile time. Legacy workflow_version / trigger_id fields are no longer used and are silently ignored.

SearchAI tools

SearchAI tools query a SearchAI knowledge base (KB) index, letting an agent ground its answers in indexed content.
TOOLS:
  search_policies(query: string) -> {results: object[]}
    description: "Search the HR policy knowledge base"
    type: searchai
    index_id: "hr-policies-v2"
    kb_name: "HR Policies"
    search_instructions: "Prefer the most recent policy version when duplicates exist."

SearchAI binding properties

PropertyTypeRequiredDefaultDescription
type"searchai"YesDeclares this as a SearchAI tool.
index_idstringYesSearchAI KB index to query.
kb_namestringNoDisplay name for the knowledge base.
search_instructionsstringNoExtra instructions injected into the search/classification prompt.
SearchAI tools are tenant-scoped; the tenant binding is applied by the platform. Do not hardcode a tenant_id in shared/exported definitions.

Tool file imports

Tool definitions can be organized into reusable .tools.abl files and imported into agent documents. This allows sharing tool definitions across multiple agents.

Tool file format

A .tools.abl file starts with a TOOLS: section that can include shared defaults:
TOOLS:
  base_url: "https://api.hotels.com/v1"
  auth: bearer
  timeout: 5000
  retry: 3

  search_hotels(destination: string, checkin: date, checkout: date) -> Hotel[]
    type: http
    endpoint: "/search"
    method: POST
    description: "Search available hotels"

  get_hotel(hotel_id: string) -> Hotel
    type: http
    endpoint: "/hotels/{hotel_id}"
    method: GET
    description: "Get hotel details by ID"

Shared defaults

The following defaults can be set at the top of a .tools.abl file and apply to all tools in the file:
DefaultTypeDescription
base_urlstringBase URL prepended to all relative endpoint paths
authstringDefault auth type for all tools
timeoutnumberDefault timeout in milliseconds
retrynumberDefault retry count
retry_delaynumberDefault retry delay in milliseconds
rate_limitnumberDefault rate limit (requests per second)
headersRecord<string, string>Default headers applied to all tools

Import syntax

Import tools from a .tools.abl file into an agent using the file: directive within the TOOLS: section:
TOOLS:
  file: "./tools/hotels-api.tools.abl" [search_hotels, get_hotel]
The import specifies:
  1. The path to the .tools.abl file (relative to the agent file)
  2. An optional list of specific tool names to import (in brackets). If omitted, all tools from the file are imported.
Project bundle import can also synthesize tool stubs from inline agent TOOLS: signatures during apply. That keeps imported agents compileable even when the bundle didn’t include companion .tools.abl files, and the next export writes those synthesized stubs back out as tools/<name>.tools.abl.

Example

Given the file tools/hotels-api.tools.abl:
TOOLS:
  base_url: "https://api.hotels.com/v1"
  auth: bearer

  search_hotels(destination: string, checkin: date, checkout: date) -> Hotel[]
    type: http
    endpoint: "/search"
    method: POST
    description: "Search available hotels"

  get_hotel(hotel_id: string) -> Hotel
    type: http
    endpoint: "/hotels/{hotel_id}"
    method: GET
    description: "Get hotel details by ID"

  get_hotel_reviews(hotel_id: string, limit: number = 10) -> Review[]
    type: http
    endpoint: "/hotels/{hotel_id}/reviews"
    method: GET
    description: "Get reviews for a hotel"
An agent file can import selected tools:
AGENT: Hotel_Search

TOOLS:
  file: "./tools/hotels-api.tools.abl" [search_hotels, get_hotel]

  # Additional agent-specific tools
  check_availability(hotel_id: string, dates: string) -> {available: boolean}
    description: "Check real-time availability"
    type: http
    endpoint: "/api/availability"
    method: POST

Tool features

Confirmation

The confirmation: block configures whether the agent should ask the user for confirmation before executing a tool. This is particularly important for tools with side effects (for example. executing a payment, deleting a record).
TOOLS:
  execute_payment(amount: number, recipient: string) -> {confirmation_id: string}
    description: "Execute a payment"
    type: http
    endpoint: "/api/payments"
    method: POST
    confirmation:
      require: always
      immutable_params: [recipient]
PropertyTypeDefaultDescription
require"always" , "never" , "when_side_effects"noneWhen to require user confirmation
immutable_paramsstring[]noneParameters that cannot be changed after confirmation
consent_required_in"conversation" , "explicit_prompt"noneWhere consent must be obtained.
consent_scopestring[]noneConsent scopes required before executing.
consent_actionstringnoneNamed consent action to trigger.
consent_fallback"explicit_prompt" , "block"noneWhat to do if consent is not granted.

State authority and provided fields

The effect property declares a tool’s authority over session state, and provides lists the fields the tool is authoritative to supply. These help the runtime reason about which values a tool is allowed to write.
TOOLS:
  set_shipping_address(address: object) -> {saved: boolean}
    description: "Persist the customer's shipping address"
    type: http
    endpoint: "/api/shipping-address"
    method: PUT
    effect: state_write          # read_only | state_write | side_effect
    provides: [shipping_address, shipping_zone]
PropertyTypeValuesDescription
effectstringread_only, state_write, side_effectThe tool’s authority over external/session state.
providesstring[]Fields this tool is authoritative to provide.

Result compaction

The per-tool compaction: block controls how this tool’s results are compacted in conversation history (independent of the agent-wide EXECUTION.compaction policy).
TOOLS:
  search_catalog(query: string) -> {items: object[]}
    type: http
    endpoint: "/api/catalog/search"
    method: GET
    compaction:
      essential_fields: [items.id, items.name, items.price]
      max_description_length: 500
      summary_timeout_ms: 3000
PropertyTypeDescription
essential_fieldsstring[]Fields to preserve verbatim when compacting this tool’s result.
max_description_lengthnumberMaximum characters kept for descriptive fields.
summary_timeout_msnumberTimeout for LLM summarization of this tool’s result.

Input/output transforms (process)

The process: block defines pure input (before) and output (after) transform stages that run around the tool call — remapping parameters, enforcing preconditions, and reshaping results.
TOOLS:
  quote_fx(amount: number, from: string, to: string) -> {converted: number}
    type: http
    endpoint: "/api/fx/quote"
    method: POST
    process:
      before:
        params:
          amount_cents: "amount * 100"
        require: [amount > 0]
        on_fail: reask("Please provide a positive amount.")
      after:
        result:
          converted: "result.amount_cents / 100"
        on_fail: warn("Could not normalize the quote.")
before supports params (computed parameter map), require (precondition expressions), on_fail (one of block("msg"), reask("msg"), warn("msg"), use_original, fallback("msg")), and use (a named transform). after supports result (output remapping) and on_fail.

Caching hints

Use the cacheable hint to indicate that a tool’s results can be cached:
TOOLS:
  get_exchange_rate(from: string, to: string) -> {rate: number}
    description: "Get current exchange rate"
    type: http
    endpoint: "/api/fx/rate"
    method: GET
    hints:
      cacheable: true
      latency: fast
When cacheable: true, the runtime may cache results for identical parameter combinations. When cacheable: false, results are never cached (use this for tools that return time-sensitive data).

PII access

The pii_access: property declares what level of personally identifiable information (PII) a tool can access:
TOOLS:
  verify_identity(ssn_last4: string, dob: string) -> {verified: boolean}
    description: "Verify customer identity"
    type: http
    endpoint: "/api/identity/verify"
    method: POST
    pii_access: user
ValueDescription
toolsTool can access PII data from other tool results
userTool can access user-provided PII
logsPII from this tool may appear in logs
llmPII from this tool is sent to the LLM

Context access

The context_access: block declares which session context variables a tool reads from and writes to. This enables the runtime to automatically inject context into HTTP requests and apply result values back to session state:
TOOLS:
  update_profile(name: string) -> {updated: boolean}
    description: "Update user profile"
    type: http
    endpoint: "/api/profile"
    method: PUT
    context_access:
      read: [user.id, user.email]
      write: [user.name, user.updated_at]

Store result

The store_result: property controls whether the raw tool result blob is stored in the session context. Defaults to true.
TOOLS:
  log_event(event: string) -> {logged: boolean}
    description: "Log an audit event"
    type: http
    endpoint: "/api/audit"
    method: POST
    store_result: false
  • Language overview — file structure and syntax
  • Agent declarationtool_timeout and model settings in EXECUTION
  • GATHER — information collection (often used alongside tools)
  • FLOWCALL action for invoking tools within flow steps