Перейти к содержимому

Узлы

Узлы — это строительные блоки воркфлоу Moira. Каждый узел представляет шаг в процессе со специфическим поведением, определяемым его типом.

Moira поддерживает 7 типов узлов:

Start

Точка входа для выполнения воркфлоу.

End

Терминальный узел, отмечающий завершение воркфлоу.

Agent Directive

Задача агента с директивой и условием завершения.

Condition

Ветвление выполнения на основе структурированных условий.

Expression

Вычисление значений с помощью арифметических выражений.

Subgraph

Делегирование другому воркфлоу.

Telegram Notification

Отправка уведомлений через Telegram.

Точка входа для выполнения воркфлоу. Каждый воркфлоу должен иметь ровно один start node.

{
"id": "start",
"type": "start",
"initialData": {
"projectName": "my-project"
},
"connections": {
"default": "first-task"
}
}
СвойствоОбязательноОписание
idДаСоглашение: должен быть “start”
typeДаДолжен быть "start"
initialDataНетНачальные переменные контекста
connections.defaultДаID следующего узла

Терминальный узел, отмечающий завершение воркфлоу. Нет исходящих соединений.

{
"id": "end",
"type": "end",
"finalOutput": ["result", "summary"]
}
СвойствоОбязательноОписание
idДаСоглашение: должен быть “end”
typeДаДолжен быть "end"
finalOutputНетКлючи контекста для включения в финальный результат

Основной тип узла для задач агента. Содержит директиву (что делать) и условие завершения (когда готово).

{
"id": "analyze-requirements",
"type": "agent-directive",
"directive": "Проанализируй документ требований и определи ключевые фичи",
"completionCondition": "Фичи перечислены с приоритетами",
"inputSchema": {
"type": "object",
"properties": {
"features": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["features"]
},
"connections": {
"success": "next-step"
}
}
СвойствоОбязательноОписание
directiveДаЧто агент должен сделать
completionConditionДаКогда шаг завершен
inputSchemaНетJSON Schema для валидации ответа
connections.successДаСледующий узел при успехе

Ветвление выполнения на основе структурированных условий:

{
"id": "check-result",
"type": "condition",
"condition": {
"operator": "eq",
"left": { "contextPath": "status" },
"right": "success"
},
"connections": {
"true": "success-path",
"false": "retry-step"
}
}
СвойствоОбязательноОписание
conditionДаОбъект структурированного условия
connections.trueДаСледующий узел когда условие true
connections.falseДаСледующий узел когда условие false

Условия используют структурированный формат (не строковую оценку):

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

Поддерживаемые операторы:

  • eq, neq — равно, не равно
  • gt, lt, gte, lte — операторы сравнения
  • and, or, not — логические операторы
  • exists, isEmpty — проверки существования

Вычисление значений с помощью арифметических выражений. Полезно для счётчиков, расчётов и трансформации переменных:

{
"id": "increment-counter",
"type": "expression",
"expressions": ["counter = counter + 1", "result = counter * multiplier"],
"connections": {
"default": "next-step",
"error": "error-handler"
}
}
СвойствоОбязательноОписание
expressionsДаМассив выражений присваивания
connections.defaultДаСледующий узел после успешного вычисления
connections.errorНетСледующий узел при ошибке вычисления

Выражения поддерживают базовые арифметические операции:

  • Арифметика: +, -, *, /
  • Скобки: (a + b) * c
  • Присваивание: result = a + b
  • Пути в контексте: step.index, plan.items[0].value
{
"expressions": ["total = price * quantity", "tax = total * 0.1", "final_price = total + tax"]
}

Expression node может завершиться с ошибкой в двух случаях:

  • Деление на ноль
  • Обращение к неопределённой переменной

При ошибке выполнение переходит к connection error если он определён, иначе воркфлоу завершается с ошибкой.

Делегирование выполнения другому воркфлоу:

{
"id": "run-tests",
"type": "subgraph",
"graphId": "test-workflow",
"inputMapping": {
"codeDir": "projectPath"
},
"outputMapping": {
"testResults": "results"
},
"connections": {
"success": "next-step"
}
}
СвойствоОбязательноОписание
graphIdДаID ссылаемого воркфлоу
inputMappingДаРодительский контекст -> контекст подграфа
outputMappingДаКонтекст подграфа -> родительский контекст
connections.successДаСледующий узел при успехе

Отправка автоматических уведомлений через Telegram:

{
"id": "notify-complete",
"type": "telegram-notification",
"message": "Воркфлоу {{workflowName}} успешно завершен",
"parseMode": "Markdown",
"connections": {
"default": "next-step",
"error": "notification-failed"
}
}
СвойствоОбязательноОписание
messageДаТекст уведомления (поддерживает шаблоны)
parseModeНетФормат сообщения: “Markdown” или “HTML”
connections.defaultДаСледующий узел после отправки
connections.errorНетСледующий узел при ошибке API

Определение ожидаемой структуры ответа с использованием JSON Schema:

{
"inputSchema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Краткое резюме находок"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"priority": { "type": "number" }
}
}
}
},
"required": ["summary"]
}
}
  1. Начинайте со start — Каждый воркфлоу должен иметь ровно один start узел
  2. Заканчивайте end — Используйте end узлы для отметки точек завершения
  3. Четкие директивы — Будьте конкретны в том, что агент должен сделать
  4. Проверяемые условия — Условия завершения должны быть объективно измеримы
  5. Валидация схемы — Используйте inputSchema для структурированных ответов
  6. Пути ошибок — Определяйте error соединения для graceful failure handling