Skip to main content

Step Types

Multi-Agent Planning supports five step types for different operations. Each step type has specific configuration options and use cases.

Overview

Step TypeDescriptionUse Case
llm-callInvoke an LLM for inferenceText generation, analysis, reasoning
connector-callQuery an MCP connectorDatabase queries, internal APIs
conditionalBranch based on conditionsDecision logic, routing
function-callExecute a custom functionData transformation, validation
api-callCall an external HTTP APIThird-party integrations

llm-call

The llm-call step type invokes a language model for inference tasks.

Configuration

steps:
- name: analyze-sentiment
type: llm-call
agent: sentiment-analyzer # Agent name (uses agent's LLM config)
input:
text: "{{input.userMessage}}"
output:
sentiment: "{{result.sentiment}}"
confidence: "{{result.confidence}}"

Fields

FieldTypeRequiredDescription
namestringYesUnique step identifier
typestringYesMust be llm-call
agentstringYesAgent name to execute
inputobjectYesInput data for the agent
outputobjectNoOutput mapping
timeoutstringNoStep timeout (overrides agent default)
retryPolicyobjectNoRetry configuration

Example: Text Analysis

apiVersion: axonflow.io/v1
kind: AgentConfig
metadata:
name: text-analyzer
domain: generic
spec:
type: specialist
description: Analyze text for key information
capabilities:
- text_analysis
- entity_extraction
llm:
provider: openai
model: gpt-4
temperature: 0.3
promptTemplate: |
Analyze the following text and extract:
1. Main topics
2. Key entities (people, places, organizations)
3. Sentiment (positive, negative, neutral)

Text: {{input.text}}

Return as JSON:
{
"topics": [...],
"entities": [...],
"sentiment": "..."
}

Step definition:

steps:
- name: analyze-text
type: llm-call
agent: text-analyzer
input:
text: "{{input.document}}"

Example: Multi-Turn Reasoning

steps:
- name: initial-analysis
type: llm-call
agent: reasoning-agent
input:
question: "{{input.question}}"
context: "{{input.context}}"

- name: deep-analysis
type: llm-call
agent: reasoning-agent
dependsOn: [initial-analysis]
input:
question: "{{input.question}}"
previousAnalysis: "{{steps.initial-analysis.output}}"
instruction: "Build on the initial analysis and provide deeper insights"

connector-call

The connector-call step type queries MCP connectors for data operations.

Configuration

steps:
- name: fetch-user-data
type: connector-call
connector:
name: postgresql # Connector ID
operation: query # Operation type
parameters:
query: "SELECT * FROM users WHERE id = $1"
args: ["{{input.userId}}"]
output:
user: "{{result.rows[0]}}"

Fields

FieldTypeRequiredDescription
namestringYesUnique step identifier
typestringYesMust be connector-call
connectorobjectYesConnector configuration
connector.namestringYesConnector ID
connector.operationstringYesOperation to perform
connector.parametersobjectNoOperation parameters
outputobjectNoOutput mapping
timeoutstringNoStep timeout

Supported Connectors

ConnectorOperationsDescription
postgresqlquery, executePostgreSQL database
mysqlquery, executeMySQL database
mongodbfind, aggregate, insertMongoDB
redisget, set, hget, hsetRedis cache
s3get, put, listAWS S3 storage
httpget, post, put, deleteHTTP API calls

Example: Database Query

steps:
- name: get-customer-orders
type: connector-call
connector:
name: postgresql
operation: query
parameters:
query: |
SELECT o.*, c.name as customer_name
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.id = $1
ORDER BY o.created_at DESC
LIMIT 10
args: ["{{input.customerId}}"]
output:
orders: "{{result.rows}}"

Example: API Integration

steps:
- name: search-flights
type: connector-call
connector:
name: amadeus
operation: flightOffers
parameters:
origin: "{{input.origin}}"
destination: "{{input.destination}}"
departureDate: "{{input.date}}"
adults: 1
output:
flights: "{{result.data}}"

Example: Cache Lookup

steps:
- name: check-cache
type: connector-call
connector:
name: redis
operation: get
parameters:
key: "user:{{input.userId}}:preferences"
output:
cachedPreferences: "{{result.value}}"

conditional

The conditional step type branches execution based on conditions.

Configuration

steps:
- name: route-request
type: conditional
condition: "{{input.requestType}}"
branches:
- when: "support"
goto: handle-support
- when: "billing"
goto: handle-billing
- when: "technical"
goto: handle-technical
- default:
goto: handle-general

Fields

FieldTypeRequiredDescription
namestringYesUnique step identifier
typestringYesMust be conditional
conditionstringYesCondition expression
branchesarrayYesBranch definitions
branches[].whenstringYes*Value to match
branches[].ifstringYes*Boolean expression
branches[].gotostringYesTarget step name
branches[].defaultbooleanNoDefault branch flag

*Use either when (value match) or if (expression) per branch.

Example: Value Matching

steps:
- name: route-by-intent
type: conditional
condition: "{{steps.classify-intent.output.intent}}"
branches:
- when: "book_flight"
goto: flight-booking-flow
- when: "book_hotel"
goto: hotel-booking-flow
- when: "cancel_booking"
goto: cancellation-flow
- default:
goto: general-inquiry

Example: Boolean Expressions

steps:
- name: check-eligibility
type: conditional
branches:
- if: "{{input.age}} >= 18 && {{input.verified}} == true"
goto: process-application
- if: "{{input.age}} < 18"
goto: require-guardian
- default:
goto: require-verification

Example: Nested Conditions

steps:
- name: tier-routing
type: conditional
condition: "{{input.customerTier}}"
branches:
- when: "platinum"
goto: platinum-service
- when: "gold"
goto: gold-service
- default:
goto: standard-service

- name: platinum-service
type: conditional
branches:
- if: "{{input.urgency}} == 'high'"
goto: immediate-response
- default:
goto: priority-queue

function-call

The function-call step type executes custom functions for data transformation.

Configuration

steps:
- name: transform-data
type: function-call
function:
name: formatCurrency # Function name
module: utils # Optional module
input:
amount: "{{steps.calculate.output.total}}"
currency: "USD"
output:
formattedTotal: "{{result}}"

Fields

FieldTypeRequiredDescription
namestringYesUnique step identifier
typestringYesMust be function-call
functionobjectYesFunction configuration
function.namestringYesFunction name
function.modulestringNoModule containing function
inputobjectYesFunction arguments
outputobjectNoOutput mapping

Built-in Functions

FunctionDescriptionInputOutput
formatDateFormat timestamp{timestamp, format}Formatted string
formatCurrencyFormat currency{amount, currency}Formatted string
parseJsonParse JSON string{json}Object
stringifyJsonConvert to JSON{object}JSON string
calculateSumSum array values{values}Number
filterArrayFilter array{array, condition}Filtered array
mergeObjectsMerge objects{objects}Merged object

Example: Data Transformation

steps:
- name: fetch-transactions
type: connector-call
connector:
name: postgresql
operation: query
parameters:
query: "SELECT * FROM transactions WHERE user_id = $1"
args: ["{{input.userId}}"]

- name: calculate-total
type: function-call
dependsOn: [fetch-transactions]
function:
name: calculateSum
input:
values: "{{steps.fetch-transactions.output.rows}}"
field: "amount"
output:
totalAmount: "{{result}}"

- name: format-total
type: function-call
dependsOn: [calculate-total]
function:
name: formatCurrency
input:
amount: "{{steps.calculate-total.output.totalAmount}}"
currency: "{{input.currency}}"
output:
displayTotal: "{{result}}"

Example: Data Validation

steps:
- name: validate-input
type: function-call
function:
name: validateSchema
module: validation
input:
data: "{{input}}"
schema:
required: ["email", "name"]
properties:
email:
type: string
format: email
name:
type: string
minLength: 2
output:
isValid: "{{result.valid}}"
errors: "{{result.errors}}"

api-call

The api-call step type makes HTTP requests to external APIs.

Configuration

steps:
- name: send-notification
type: api-call
request:
method: POST
url: "https://api.slack.com/api/chat.postMessage"
headers:
Authorization: "Bearer {{secrets.SLACK_TOKEN}}"
Content-Type: "application/json"
body:
channel: "{{input.channel}}"
text: "{{input.message}}"
output:
messageId: "{{response.body.ts}}"

Fields

FieldTypeRequiredDescription
namestringYesUnique step identifier
typestringYesMust be api-call
requestobjectYesHTTP request configuration
request.methodstringYesHTTP method (GET, POST, PUT, DELETE)
request.urlstringYesRequest URL
request.headersobjectNoRequest headers
request.bodyobjectNoRequest body
request.queryobjectNoQuery parameters
timeoutstringNoRequest timeout
retryPolicyobjectNoRetry configuration
outputobjectNoOutput mapping

Example: REST API Call

steps:
- name: create-ticket
type: api-call
request:
method: POST
url: "https://api.zendesk.com/api/v2/tickets"
headers:
Authorization: "Basic {{secrets.ZENDESK_AUTH}}"
Content-Type: "application/json"
body:
ticket:
subject: "{{input.subject}}"
description: "{{input.description}}"
priority: "{{input.priority}}"
requester:
email: "{{input.userEmail}}"
output:
ticketId: "{{response.body.ticket.id}}"
ticketUrl: "{{response.body.ticket.url}}"

Example: Webhook Notification

steps:
- name: notify-completion
type: api-call
request:
method: POST
url: "{{input.webhookUrl}}"
headers:
Content-Type: "application/json"
X-Signature: "{{secrets.WEBHOOK_SECRET}}"
body:
event: "plan_completed"
planId: "{{context.planId}}"
status: "success"
result: "{{steps.final-step.output}}"
completedAt: "{{context.timestamp}}"

Example: API with Authentication

steps:
- name: get-oauth-token
type: api-call
request:
method: POST
url: "https://oauth.example.com/token"
headers:
Content-Type: "application/x-www-form-urlencoded"
body:
grant_type: "client_credentials"
client_id: "{{secrets.CLIENT_ID}}"
client_secret: "{{secrets.CLIENT_SECRET}}"
output:
accessToken: "{{response.body.access_token}}"

- name: call-protected-api
type: api-call
dependsOn: [get-oauth-token]
request:
method: GET
url: "https://api.example.com/protected/resource"
headers:
Authorization: "Bearer {{steps.get-oauth-token.output.accessToken}}"
output:
data: "{{response.body}}"

Step Dependencies

Control execution order with dependsOn:

steps:
- name: step-a
type: llm-call
agent: analyzer

- name: step-b
type: llm-call
agent: summarizer
dependsOn: [step-a] # Runs after step-a

- name: step-c
type: connector-call
connector: { ... }
dependsOn: [step-a, step-b] # Runs after both step-a and step-b

Parallel Execution

Group steps for parallel execution with parallelGroup:

steps:
- name: search-flights
type: connector-call
parallelGroup: search # These run in parallel
connector: { ... }

- name: search-hotels
type: connector-call
parallelGroup: search # These run in parallel
connector: { ... }

- name: search-cars
type: connector-call
parallelGroup: search # These run in parallel
connector: { ... }

- name: combine-results
type: llm-call
dependsOn: [search-flights, search-hotels, search-cars]
agent: trip-planner

Error Handling

Configure error handling per step:

steps:
- name: risky-operation
type: api-call
request: { ... }
retryPolicy:
maxRetries: 3
initialDelay: 1s
backoffMultiplier: 2.0
onError:
action: continue # continue, fail, goto
goto: fallback-step # Target step if action is goto
output:
error: "{{error.message}}"

Error Actions

ActionDescription
failStop plan execution (default)
continueContinue to next step
gotoJump to specified step

Template Variables Reference

VariableDescriptionExample
{{input.key}}Input data{{input.userId}}
{{steps.name.output}}Step output{{steps.analyze.output}}
{{steps.name.output.key}}Specific output field{{steps.analyze.output.score}}
{{context.planId}}Plan IDplan_abc123
{{context.timestamp}}Current timestamp2025-12-18T10:30:00Z
{{context.requestId}}Request IDreq_xyz789
{{secrets.KEY}}Secret value{{secrets.API_KEY}}
{{result}}Current step resultUsed in output mapping
{{response.body}}API response bodyFor api-call steps
{{error.message}}Error messageIn onError handlers

Next Steps