Octov0.4.2
ReferenceBlocks

AI Blocks

Agents, routers, mapping, retry, memory management, and the MCP router.

Reference for the AI block family. For narrative guides see the AI sectionagents, routing, mapping, retry, memory, and MCP servers.

ai-agent, ai-router, ai-retry, and mcp-router are composites: their keys sit at the top level of the block, not under settings:. ai-mapping and clear-agent-memory are leaf blocks configured under settings:. The connector field on each LLM-driven block names a configured LLM provider connector (llm-anthropic, llm-openai, or llm-gemini); any provider works.

ai-agent

Lets an LLM accomplish a task by calling flow branches as tools, one or more times, in a loop. Each tool is wired to the model as a callable function: the model's arguments become the branch's message body and the branch's output body is returned as the tool result. Tool branches share the message, so variables they set accumulate across the loop.

KeyTypeRequiredDefaultDescription
connectorstringYesName of the LLM connector that drives the agent loop.
promptstringYesTask instruction; the model calls tools as needed, then stops.
guardrailstringNoDescribes when the model should fall back to the default path.
maxIterationsintNo8Cap on tool-calling turns (one model call each) before falling back to the guardrail.
memoryThreadIdexpression (string)NoConversation thread id. When set, the agent loads the thread's prior transcript before the run and saves it after. Empty disables memory.
memoryMaxTokensintNo8000Estimated-token budget for the stored transcript; compacted when exceeded.
memoryCompactionenum prune | summarizeNopruneHow memory over budget shrinks: prune drops the oldest turns; summarize folds them into a running summary (an extra model call).
toolslistYesTool branches (below). At least one required.
skillslistNoLoadable instruction resources (below).
defaultflowNoGuardrail path, run when the model refuses or hits maxIterations.

Each tools entry:

FieldTypeRequiredDescription
namestringYesTool name the model calls; must be unique and not the reserved load_skill.
descriptionstringYesTells the model what the tool does.
inputSchemastring (JSON)NoJSON Schema for the tool's arguments, written inline as a string. Defaults to {"type":"object"}.
processblock listYesChain that runs the tool: arguments arrive as the body, the output body is the tool result.

Each skills entry (see Agent skills and tools):

FieldTypeRequiredDescription
namestringYesSkill name; unique, must not collide with a tool name or load_skill.
descriptionstringYesAdvertised to the model up front, with the name.
resourcestringYesTemplate resource (its resources.templates alias) whose rendered content the implicit load_skill tool returns on demand.

Behavior notes:

  • The final assistant text becomes the message body — parsed as JSON when possible, stored as text otherwise; an empty answer leaves the last tool's body standing.
  • A tool-branch error or dropped message becomes an error result fed back to the model rather than aborting the agent.
  • On refusal or maxIterations, the default flow runs; with no default configured, the block errors so the failure reaches a recovery path.
  • With skills configured, the agent gets an implicit load_skill(name) tool; skill bodies are rendered against the current message like any template.
  • Memory is saved best-effort (a save failure logs, it does not fail the flow); wipe a thread with clear-agent-memory.
- type: ai-agent
  name: enrich-lead
  connector: claude
  maxIterations: 6
  memoryThreadId: body.threadId        # optional per-thread memory
  prompt: >
    Enrich the inbound lead. Classify the company size and decide whether it
    is a good fit. Respond with a JSON object {"tier": "...", "fit": true|false}.
  guardrail: >
    If you cannot classify the lead with confidence, take the default path.
  tools:
    - name: classify_size
      description: Classify a company's size tier from its name and domain.
      inputSchema: |
        {"type": "object", "required": ["company"],
         "properties": {"company": {"type": "string"}, "domain": {"type": "string"}}}
      process:
        - type: set-payload
          settings:
            value: '{"tier": "smb"}'
  default:
    process:
      - type: set-payload
        settings:
          value: '{"status": "needs-manual-review"}'

ai-router

Asks an LLM to pick exactly one of its named, described routes for each message. The model is given read-only inspection tools (get_body, list_variables, get_variable) plus a select_route decision tool; it may inspect for up to 5 turns before the guardrail is taken.

KeyTypeRequiredDefaultDescription
connectorstringYesName of the LLM connector that picks the route.
promptstringYesRouting instruction.
guardrailstringNoDescribes when to fall back to the default path (low confidence, ambiguity).
routeslistYesNamed branches; each entry is {name, description, process} (all required). Names must be unique.
defaultflowNoGuardrail path, run when the model is not confident or never decides. Omitted: the message passes through unchanged (mirroring switch).
- type: ai-router
  name: triage-ticket
  connector: claude
  prompt: >
    Read the support ticket in the message body and route it to the team
    best suited to handle it.
  guardrail: >
    If the ticket is ambiguous or you are not confident, take the default path.
  routes:
    - name: billing
      description: Payment failures, refunds, invoices, subscription changes.
      process:
        - type: set-payload
          settings: { value: '{"team": "billing"}' }
    - name: technical
      description: Bugs, outages, API errors, integration problems.
      process:
        - type: set-payload
          settings: { value: '{"team": "technical"}' }
  default:
    process:
      - type: set-payload
        settings: { value: '{"team": "human-triage"}' }

ai-mapping

Leaf block: reshapes the message body to a target shape described by a prompt, optional input/output examples, and an optional output JSON Schema. The model's JSON response replaces the body.

SettingTypeRequiredDefaultDescription
connectorstringYesName of the LLM connector to use.
promptstringYesInstruction describing how to reshape the body.
inputExampleJSONNoExample input payload that guides recognition. Written as an inline JSON string (block scalar) or a native YAML map.
outputExampleJSONNoExample output payload that shapes the result. Same formats.
outputSchemaJSONNoJSON Schema the result is validated against; also recorded on the message as its body schema.
maxTokensintNo0 (connector default)Response token cap for this call.

Errors: the block errors when the model's response is not valid JSON or fails outputSchema validation, so it composes with ai-retry, handle-errors, or the flow-level error path for self-healing. A malformed schema or example fails at startup.

- type: ai-mapping
  name: normalize
  settings:
    connector: claude
    prompt: >
      Map the raw contact payload to our canonical contact shape. Split the
      full name into firstName and lastName. Lowercase the email.
    outputSchema: |
      {"type": "object", "required": ["firstName", "lastName", "email"],
       "properties": {"firstName": {"type": "string"}, "lastName": {"type": "string"},
                      "email": {"type": "string"}, "phone": {"type": "string"}}}

ai-retry

Protects a process chain with an LLM-driven retry loop. When the chain fails, the model inspects the error (vars.error) and the current message, revises the body and/or variables, and the chain re-runs — up to maxAttempts revisions. When attempts are exhausted, the error chain runs (with vars.error set); with no error chain, the last error propagates.

KeyTypeRequiredDefaultDescription
connectorstringYesName of the LLM connector that revises the message between attempts.
promptstringYesInstruction for repairing the message from vars.error before a retry.
maxAttemptsintNo3How many times to revise and re-run the process chain.
processblock listYesThe protected chain, re-run after each revision.
errorblock listNoRuns when attempts are exhausted; reads vars.error.

vars.error has the shape {message, flow, block} as with handle-errors. If the model cannot produce a revision, the loop ends early and falls through to the error chain (or the error propagates).

- type: ai-retry
  name: resilient-charge
  connector: claude
  maxAttempts: 3
  prompt: >
    A step failed building the charge request. Inspect vars.error and the
    message body, correct the body, and produce a revised message to retry.
  process:
    - type: ai-mapping
      name: build-charge
      settings:
        connector: claude
        prompt: "Build a Stripe charge request from the order."
        outputSchema: |
          {"type": "object", "required": ["amount", "currency"],
           "properties": {"amount": {"type": "integer"}, "currency": {"type": "string"}}}
  error:
    - type: set-payload
      settings:
        value: '{"status": "degraded", "reason": vars.error.message}'

clear-agent-memory

Leaf block: erases an ai-agent conversation thread's stored memory by its thread id. The clear is idempotent — a missing thread is not an error — and the message passes through unchanged.

SettingTypeRequiredDefaultDescription
threadIdexpression (string)YesEvaluated to the thread id whose memory is cleared; matches the agent's memoryThreadId value.
- name: forget
  process:
    - type: clear-agent-memory
      name: wipe-thread
      settings:
        threadId: body.threadId
    - type: set-payload
      settings:
        value: '{"cleared": true}'

mcp-router

Turns a flow into a stateless MCP server. It sits behind an HTTP source: each request body is one MCP JSON-RPC request and the router's output body is the JSON-RPC response, which the source returns. It advertises tool flows as MCP tools, template resources as MCP resources and prompts, and routes tools/call to the matching flow. It calls no LLM — it is a protocol adapter.

KeyTypeRequiredDefaultDescription
serverNamestringNoblock name, then octo-mcpName reported in the MCP initialize response.
toolslistNo*Flows exposed as MCP tools; same entry shape as ai-agent tools (name, description, inputSchema, process).
resourceslistNo*Template resources advertised as MCP resources and served on resources/read (below).
promptslistNo*Template resources advertised as MCP prompts and rendered on prompts/get (below). *At least one of tools, resources, or prompts is required.

Each resources entry:

FieldTypeRequiredDefaultDescription
uristringYesStable id clients read by; unique.
namestringYesAdvertised resource name.
descriptionstringNoAdvertised description.
mimeTypestringNotext/plainAdvertised MIME type.
resourcestringYesTemplate resource whose rendered content is returned.

Each prompts entry:

FieldTypeRequiredDefaultDescription
namestringYesId clients get the prompt by; unique.
descriptionstringNoAdvertised description.
argumentslistNoAdvertised argument metadata: {name, description, required} per entry.
resourcestringYesTemplate resource rendered as the prompt message; the supplied arguments are exposed to the template as the body (body.<arg>).

Behavior notes:

  • Handled methods: initialize, ping, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get. Anything else returns a JSON-RPC method-not-found error.
  • A request with no id is a notification: acknowledged with an empty 202 body, not answered.
  • An unknown tool or a tool-flow failure is reported as an isError tool result (an application error the client sees), not a protocol error; protocol errors (bad params, unknown resource/prompt) use JSON-RPC error responses.
  • To require OAuth on the endpoint, put jwt-validate in front — see MCP auth.
- type: mcp-router
  name: weather-mcp
  serverName: weather-tools
  tools:
    - name: forecast
      description: Return a short weather forecast for a city.
      inputSchema: |
        {"type": "object", "required": ["city"],
         "properties": {"city": {"type": "string"}}}
      process:
        - type: set-payload
          settings:
            value: '{"city": body.city, "summary": "Sunny, 24C"}'
  resources:
    - uri: octo://guide
      name: guide
      description: Operator guide for the weather tools.
      mimeType: text/markdown
      resource: guide
  prompts:
    - name: assist
      description: Prime an assistant to help a user in a given city.
      arguments:
        - name: city
          description: The user's city.
          required: true
      resource: greet

On this page