Pass vs Map – When to Use Each Transition Type
Pass and Map are the two foundational transition types in AgetnticOS. Understanding their differences is crucial for building effective agentic processes. This guide compares them side-by-side to help you choose the right one.
Key Differences
The emit.from Semantic
This is the most critical difference: what the when condition evaluates.
Pass: when evaluates @input.data
// Input token: { "status": "active", "amount": 100 }
"emit": [
{ "to": "active", "from": "@input.data", "when": "status == 'active'" }
]
// "status" comes from the ORIGINAL token
// Token emitted unchanged: { "status": "active", "amount": 100 }
Map: when evaluates @response
// Input token: { "orderId": "123", "amount": 100 }
"action": {
"type": "map",
"template": {
"id": "${input.data.orderId}",
"status": "processed" // NEW field added by template
}
}
"emit": [
{ "to": "output", "from": "@response", "when": "status == 'processed'" }
]
// "status" comes from the TRANSFORMED result
// Token emitted: { "id": "123", "status": "processed" }
When to Use Pass
- Routing decisions – Send tokens to different places based on field values
- Filtering – Let some tokens through, block others
- Fan-out – Send same token to multiple destinations
- No transformation needed – Data is already in the right shape
// Example: Route orders by priority
{
"kind": "task",
"action": { "type": "pass" },
"emit": [
{ "to": "urgent", "from": "@input.data", "when": "priority == 'high'" },
{ "to": "normal", "from": "@input.data", "when": "priority != 'high'" },
{ "to": "audit", "from": "@input.data" } // Always emit to audit
]
}
When to Use Map
- Data transformation – Reshape token structure
- Field enrichment – Add computed or derived fields
- Data normalization – Standardize field names or formats
- Metadata injection – Add processing timestamps, source info
// Example: Transform and categorize orders
{
"kind": "map",
"action": {
"type": "map",
"template": {
"orderId": "${input.data.orderId}",
"total": "${input.data.amount}",
"category": "${input.data.amount > 1000 ? 'premium' : 'standard'}",
"processedAt": "${now()}"
}
},
"emit": [
{ "to": "premium", "from": "@response", "when": "category == 'premium'" },
{ "to": "standard", "from": "@response", "when": "category == 'standard'" }
]
}
Common Mistake: Wrong emit.from
A common error is using @input.data in Map transitions:
// WRONG - Map with @input.data
{
"kind": "map",
"action": {
"type": "map",
"template": { "status": "processed" }
},
"emit": [
{ "to": "output", "from": "@input.data", "when": "status == 'processed'" }
// ^^^^^^^^^^^^ WRONG!
// The input token doesn't have status='processed'
// The TRANSFORMED result has it
]
}
// CORRECT - Map with @response
{
"kind": "map",
"action": {
"type": "map",
"template": { "status": "processed" }
},
"emit": [
{ "to": "output", "from": "@response", "when": "status == 'processed'" }
// ^^^^^^^^^ CORRECT!
]
}
Decision Flowchart
Summary
- Pass – Routes tokens unchanged,
emit.from: @input.data - Map – Transforms tokens via template,
emit.from: @response - The
whencondition – Always evaluates whatfromresolves to - Rule of thumb – Need to change data? Use Map. Just routing? Use Pass.
Understanding this distinction is foundational to building effective AgenticOS processes.