Skip to content

Nodes

Nodes are the building blocks of Moira workflows. Each node represents a step in the process with specific behavior defined by its type.

Moira supports 7 node types:

Start

Entry point for workflow execution.

End

Terminal node marking workflow completion.

Agent Directive

Agent task with directive and completion condition.

Condition

Branch execution based on structured conditions.

Expression

Compute values using arithmetic expressions.

Subgraph

Delegate to another workflow.

Telegram Notification

Send notifications via Telegram.

Entry point for workflow execution. Every workflow must have exactly one start node.

{
"id": "start",
"type": "start",
"initialData": {
"projectName": "my-project"
},
"connections": {
"default": "first-task"
}
}
PropertyRequiredDescription
idYesConvention: should be “start”
typeYesMust be "start"
initialDataNoInitial context variables
connections.defaultYesNext node ID

Terminal node marking workflow completion. No outgoing connections.

{
"id": "end",
"type": "end",
"finalOutput": ["result", "summary"]
}
PropertyRequiredDescription
idYesConvention: should be “end”
typeYesMust be "end"
finalOutputNoContext keys to include in final result

The primary node type for agent tasks. Contains a directive (what to do) and completion condition (when done).

{
"id": "analyze-requirements",
"type": "agent-directive",
"directive": "Analyze the requirements document and identify key features",
"completionCondition": "Features are listed with priorities",
"inputSchema": {
"type": "object",
"properties": {
"features": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["features"]
},
"connections": {
"success": "next-step"
}
}
PropertyRequiredDescription
directiveYesWhat the agent should do
completionConditionYesWhen the step is complete
inputSchemaNoJSON Schema for response validation
maxRetriesNoMax validation retries (default: 3)
retryMessageNoCustom retry message
connections.successYesNext node on success
connections.errorNoNext node on error
connections.maxRetriesExceededNoNext node when retries exhausted

Branch execution based on structured conditions:

{
"id": "check-result",
"type": "condition",
"condition": {
"operator": "eq",
"left": { "contextPath": "status" },
"right": "success"
},
"connections": {
"true": "success-path",
"false": "retry-step"
}
}
PropertyRequiredDescription
conditionYesStructured condition object
connections.trueYesNext node when condition is true
connections.falseYesNext node when condition is false

Conditions use a structured format (not string evaluation):

{
"operator": "and",
"conditions": [
{
"operator": "gt",
"left": { "contextPath": "score" },
"right": 80
},
{
"operator": "eq",
"left": { "contextPath": "validated" },
"right": true
}
]
}

Supported condition types:

  • equals, notEquals
  • greaterThan, lessThan, greaterThanOrEquals, lessThanOrEquals
  • and, or, not
  • exists, isEmpty

Compute values using arithmetic expressions. Useful for counters, calculations, and variable transformations:

{
"id": "increment-counter",
"type": "expression",
"expressions": ["counter = counter + 1", "result = counter * multiplier"],
"connections": {
"default": "next-step",
"error": "error-handler"
}
}
PropertyRequiredDescription
expressionsYesArray of assignment expressions
connections.defaultYesNext node after successful evaluation
connections.errorNoNext node on evaluation error

Expressions support basic arithmetic operations:

  • Arithmetic: +, -, *, /
  • Parentheses: (a + b) * c
  • Assignment: result = a + b
  • Context paths: step.index, plan.items[0].value
{
"expressions": ["total = price * quantity", "tax = total * 0.1", "final_price = total + tax"]
}

Expression nodes can fail in two cases:

  • Division by zero
  • Reference to undefined variable

When an error occurs, execution routes to the error connection if defined, otherwise the workflow fails.

Delegate execution to another workflow:

{
"id": "run-tests",
"type": "subgraph",
"graphId": "test-workflow",
"inputMapping": {
"codeDir": "projectPath"
},
"outputMapping": {
"testResults": "results"
},
"connections": {
"success": "next-step"
}
}
PropertyRequiredDescription
graphIdYesReferenced workflow ID
inputMappingYesParent context -> subgraph context
outputMappingYesSubgraph context -> parent context
connections.successYesNext node on success
connections.errorNoNext node on failure

Send automated notifications via Telegram:

{
"id": "notify-complete",
"type": "telegram-notification",
"message": "Workflow {{workflowName}} completed successfully",
"parseMode": "Markdown",
"connections": {
"default": "next-step",
"error": "notification-failed"
}
}
PropertyRequiredDescription
messageYesNotification text (supports templates)
parseModeNoMessage format: “Markdown” or “HTML”
connections.defaultYesNext node after sending
connections.errorNoNext node on API failure

Define expected response structure using JSON Schema:

{
"inputSchema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Brief summary of findings"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"priority": { "type": "number" }
}
}
}
},
"required": ["summary"]
}
}
  1. Start with start - Every workflow needs exactly one start node
  2. End with end - Use end nodes to mark completion points
  3. Clear Directives - Be specific about what the agent should do
  4. Verifiable Conditions - Completion conditions should be objectively measurable
  5. Schema Validation - Use inputSchema for structured responses
  6. Error Paths - Define error connections for graceful failure handling