Node Types
Configuration reference for every node type available in .swirls files.
Nodes are the building blocks of a graph. Each node has a type field that determines its behavior. This page documents all available node types, their fields, and examples.
For how nodes connect to each other, see Graphs. For type-safe access to node outputs, see Context.
code
Run TypeScript in an isolated sandbox.
| Field | Type | Required | Description |
|---|---|---|---|
| code | @ts { } block | No | TypeScript to execute. Access context.nodes for input. Return value becomes output. |
| schema | @json { } block | No | Output schema (JSON Schema). |
node normalize {
type: code
label: "Normalize email"
outputSchema: @json {
{ "type": "object", "required": ["email"], "properties": { "email": { "type": "string" } }, "additionalProperties": false }
}
code: @ts {
const email = context.nodes.root.input.email ?? ""
return { email: email.toLowerCase().trim() }
}
}ai
Invoke an AI model. Supports multiple kinds: text, object, image, video, and embed.
| Field | Type | Required | Description |
|---|---|---|---|
| kind | string | Yes | One of: text, object, image, video, embed. |
| model | string | Yes | Model identifier (e.g. "anthropic/claude-3.5-sonnet", "openai/dall-e-3"). |
| prompt | @ts { } block | Yes | TypeScript expression returning the prompt string. |
| temperature | number | No | Sampling temperature. |
| maxTokens | number | No | Max output tokens. |
| options | object | No | Kind-specific options (e.g. { n: 1, size: "1024x1024" } for image). |
| schema | @json { } block | No | Output schema. Required for the object kind. |
Example (object kind):
node classify {
type: ai
label: "Classify intent"
kind: object
model: "anthropic/claude-3.5-sonnet"
prompt: @ts {
return `Classify this message: ${context.nodes.root.input.message}`
}
schema: @json {
{
"type": "object",
"required": ["intent", "confidence"],
"properties": {
"intent": { "type": "string" },
"confidence": { "type": "number" }
}
}
}
}Example (image kind):
node generate_image {
type: ai
label: "Generate image"
kind: image
model: "openai/dall-e-3"
prompt: @ts {
return `A professional illustration of: ${context.nodes.root.input.topic}`
}
options: {
n: 1
size: "1024x1024"
}
}switch
Conditional routing. Returns a case name to determine which branch executes.
| Field | Type | Required | Description |
|---|---|---|---|
| cases | string array | Yes | List of case names. |
| router | @ts { } block | Yes | TypeScript expression returning one of the case names. |
Use labeled edges in the flow block: route -["case_name"]-> target.
node route {
type: switch
label: "Route by priority"
cases: ["high", "medium", "low"]
router: @ts {
const score = context.nodes.root.output.score ?? 0
if (score > 80) return "high"
if (score > 40) return "medium"
return "low"
}
}http
Make HTTP requests to external APIs.
| Field | Type | Required | Description |
|---|---|---|---|
| url | @ts { } block or string | Yes | Request URL. |
| method | string | No | HTTP method. Defaults to GET. |
| headers | object | No | Request headers. |
| body | @ts { } block | No | Request body. |
| schema | @json { } block | No | Output schema. |
node fetch_data {
type: http
label: "Fetch from API"
method: "POST"
url: @ts {
return `https://api.example.com/data/${context.nodes.root.input.id}`
}
headers: {
"Content-Type": "application/json"
"Authorization": @ts {
return `Bearer ${context.secrets.API_KEY}`
}
}
body: @ts {
return JSON.stringify({ query: context.nodes.root.input.query })
}
schema: @json {
{ "type": "object", "properties": { "results": { "type": "array" } } }
}
}Send emails with dynamic content.
| Field | Type | Required | Description |
|---|---|---|---|
| from | @ts { } block or string | Yes | Sender address. |
| to | @ts { } block or string | Yes | Recipient address. |
| subject | @ts { } block or string | Yes | Subject line. |
| text | @ts { } block or string | No | Plain text body. |
| html | @ts { } block or string | No | HTML body. |
| schema | @json { } block | No | Output schema. |
node send_email {
type: email
label: "Send notification"
from: @ts { return "[email protected]" }
to: @ts { return context.nodes.root.output.email }
subject: @ts { return "Your request has been processed" }
text: @ts {
return `Hello ${context.nodes.root.output.name}, your request is complete.`
}
}stream
Query persisted data from a graph's stream.
| Field | Type | Required | Description |
|---|---|---|---|
| stream | string | Yes | Stream name (from a graph's persistence block). |
| query | @sql { } block | No | SQL query with {{table}} placeholder. |
| schema | @json { } block | No | Output schema. |
node recent_submissions {
type: stream
label: "Recent submissions"
stream: "submissions"
outputSchema: @json {
{
"type": "object",
"required": ["results", "pageInfo"],
"properties": {
"results": { "type": "array", "items": { "type": "object" } },
"pageInfo": { "type": "object" }
},
"additionalProperties": false
}
}
query: @sql {
SELECT * FROM {{table}} ORDER BY created_at DESC LIMIT 10
}
}graph
Execute another graph as a subgraph.
| Field | Type | Required | Description |
|---|---|---|---|
| graph | string | Yes | Name of the graph to execute. |
| input | @ts { } block | Yes | TypeScript expression mapping input for the subgraph. |
node run_enrichment {
type: graph
label: "Run enrichment"
graph: "enrich_contact"
input: @ts {
return { email: context.nodes.root.input.email, name: context.nodes.root.input.name }
}
}scrape
Fetch and extract content from web pages.
| Field | Type | Required | Description |
|---|---|---|---|
| url | @ts { } block | Yes | URL to scrape. |
| selector | string | No | CSS selector to extract. |
| schema | @json { } block | No | Output schema. |
wait
Pause execution for a duration.
| Field | Type | Required | Description |
|---|---|---|---|
| duration | number | No | Seconds to wait. |
bucket
Storage operations: get, put, and delete.
| Field | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | One of: get, put, delete. |
| bucket | string | No | Bucket name. |
| key | string | No | Object key. |
| schema | @json { } block | No | Output schema. |
document
Document processing node.
| Field | Type | Required | Description |
|---|---|---|---|
| schema | @json { } block | No | Output schema. |