Start
Entry point for workflow execution.
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" }}| Property | Required | Description |
|---|---|---|
id | Yes | Convention: should be “start” |
type | Yes | Must be "start" |
initialData | No | Initial context variables |
connections.default | Yes | Next node ID |
Terminal node marking workflow completion. No outgoing connections.
{ "id": "end", "type": "end", "finalOutput": ["result", "summary"]}| Property | Required | Description |
|---|---|---|
id | Yes | Convention: should be “end” |
type | Yes | Must be "end" |
finalOutput | No | Context 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" }}| Property | Required | Description |
|---|---|---|
directive | Yes | What the agent should do |
completionCondition | Yes | When the step is complete |
inputSchema | No | JSON Schema for response validation |
maxRetries | No | Max validation retries (default: 3) |
retryMessage | No | Custom retry message |
connections.success | Yes | Next node on success |
connections.error | No | Next node on error |
connections.maxRetriesExceeded | No | Next 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" }}| Property | Required | Description |
|---|---|---|
condition | Yes | Structured condition object |
connections.true | Yes | Next node when condition is true |
connections.false | Yes | Next 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, notEqualsgreaterThan, lessThan, greaterThanOrEquals, lessThanOrEqualsand, or, notexists, isEmptyCompute 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" }}| Property | Required | Description |
|---|---|---|
expressions | Yes | Array of assignment expressions |
connections.default | Yes | Next node after successful evaluation |
connections.error | No | Next node on evaluation error |
Expressions support basic arithmetic operations:
+, -, *, /(a + b) * cresult = a + bstep.index, plan.items[0].value{ "expressions": ["total = price * quantity", "tax = total * 0.1", "final_price = total + tax"]}Expression nodes can fail in two cases:
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" }}| Property | Required | Description |
|---|---|---|
graphId | Yes | Referenced workflow ID |
inputMapping | Yes | Parent context -> subgraph context |
outputMapping | Yes | Subgraph context -> parent context |
connections.success | Yes | Next node on success |
connections.error | No | Next 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" }}| Property | Required | Description |
|---|---|---|
message | Yes | Notification text (supports templates) |
parseMode | No | Message format: “Markdown” or “HTML” |
connections.default | Yes | Next node after sending |
connections.error | No | Next 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"] }}inputSchema for structured responses