npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@infomaximum/ai-orchestrator

v7.1.0

Published

LangGraph-based orchestrator for multi-agent pipelines over Claude Code CLI

Readme

@infomaximum/ai-orchestrator

LangGraph-based движок для мультиагентных пайплайнов поверх LLM-агентов. Движок не привязан к конкретному провайдеру: в комплекте идут claudeAdapter (запуск Claude Code CLI) и codexAdapter (запуск OpenAI Codex CLI), один из них нужно явно подключить в конфиге, либо реализовать свой AgentAdapter.

Что даёт пакет:

  • запуск агентов через claude -p с verdict-протоколом (маркер <verdict> в финальном ответе агента + резервный JSON-файл);
  • human-in-the-loop через interrupt() с CLI-промптом и $EDITOR для развёрнутого фидбэка;
  • persistent-сессии — после каждого запуска сохраняется чекпоинт, прерванное продолжается через imo resume;
  • параллельный запуск агентов — статический (addParallelAgents) и динамический (addDynamicFanOut + makeRetryRouter), с per-branch retry и общим прогресс-индикатором;
  • CLI: init / run / resume / sessions / graph.

Установка

npm install @infomaximum/ai-orchestrator

Требования: Node.js ≥ 18, установленный claude CLI в $PATH. Файлы агентов (.md) можно держать где удобно. Рекомендуемый вариант — рядом с файлом пайплайна, тогда путь к ним собирается через import.meta.url. Альтернатива — общая директория .claude/agents/.

Quick start

# 1. В корне своего проекта
npx imo init                          # создаст ai-orchestrator.config.mjs + дополнит .gitignore

# 2. Напиши свой пайплайн (см. docs/writing-pipelines.md) и зарегистрируй его в ai-orchestrator.config.mjs

# 3. Запусти
npx imo run my-pipeline "<описание задачи>"

Каждый запуск создаёт сессию — директорию <sessionsDir>/<id>/ с чекпоинтами, логами и артефактами агентов. Если сессия прервалась (Ctrl-C, упал агент, остановились на human-gate (ожидание подтверждения от человека) и закрыли терминал) — её можно продолжить с последнего чекпоинта: imo resume <id>. Список сессий — imo sessions.

CLI

imo init                            # ai-orchestrator.config.mjs + .gitignore + .claude/agents/imo-pipeline-writer.md
imo run <pipeline> "<описание>"     # свежий запуск пайплайна
imo resume <session-id>             # продолжить прерванную сессию
imo sessions                        # список всех сессий
imo graph <pipeline>                # ASCII-визуализация графа пайплайна
imo help                            # справка

Флаги:

  • --config <path> — путь к конфигу (по умолчанию ai-orchestrator.config.mjs в cwd).
  • imo graph: --mermaid (raw Mermaid вместо ASCII), --ascii-only (только ASCII-символы вместо Unicode), --no-color, --output <path> (записать в файл).

Конфиг

// ai-orchestrator.config.mjs
import { claudeAdapter } from "@infomaximum/ai-orchestrator/runtime";

export default {
  sessionsDir: ".ai-orchestrator/sessions",
  pipelinesDir: "configs/ai-pipelines",
  lastMigratedVersion: "6.0.0",
  adapter: claudeAdapter,  // обязательное поле: claudeAdapter или свой AgentAdapter
  pipelines: {
    "my-pipeline": () => import("./configs/ai-pipelines/my-pipeline.mjs").then((m) => m.myPipeline),
  },
};

adapterобязательное поле. Без него imo run упадёт с ошибкой loadConfig. Используй claudeAdapter из @infomaximum/ai-orchestrator/runtime или реализуй свой AgentAdapter (см. секцию 8.5 в docs/writing-pipelines.md).

В пакете встроены два адаптера: claudeAdapter (запуск claude -p) и codexAdapter (запуск codex exec). Импорт обоих — import { claudeAdapter, codexAdapter } from "@infomaximum/ai-orchestrator/runtime";. Установка CLI — на стороне пользователя: claude (см. claude.com/code) или codex (npm i -g @openai/codex / brew install --cask codex). Флаги по умолчанию подобраны под non-interactive исполнение (Claude: --dangerously-skip-permissions; Codex: --dangerously-bypass-approvals-and-sandbox + --skip-git-repo-check). Поле tools во frontmatter применимо только к claudeAdapter — в codexAdapter оно логируется warning'ом и игнорируется (у codex exec нет CLI-whitelist'а инструментов).

lastMigratedVersion — опциональное поле, фиксирует версию движка, под которую актуализированы пайплайны. Используется при обновлении пакета (см. ниже). imo init подставляет туда текущую версию движка автоматически.

Миграции при обновлении

Каждая версия пакета содержит файл docs/migrations/v<X.Y.Z>.md (внутри npm-tarball'а). В нём — структурированные записи о breaking-changes, deprecations и новых возможностях с примерами before/after и инструкцией по миграции.

Чтобы обновить существующие пайплайны:

  1. Укажи в ai-orchestrator.config.mjs поле lastMigratedVersion с версией, на которой ты сейчас.
  2. Открой Claude Code в проекте и попроси: «обнови мои пайплайны под текущую версию @infomaximum/ai-orchestrator».
  3. Агент pipeline-writer (его системный промпт — node_modules/@infomaximum/ai-orchestrator/agents/pipeline-writer.md) сам прочитает миграции, найдёт затронутые места и предложит правки. После твоего подтверждения он обновит lastMigratedVersion.

Если поля lastMigratedVersion нет — агент один раз спросит «обновляем под текущую или работаем как есть?». Ответ «как есть» отключает миграции до тех пор, пока поле не появится в конфиге.

Контракт агента

Каждый узел-агент в твоём пайплайне зовёт callAgent(...) — это запускает агента через адаптер провайдера (берётся из OrchestratorConfig.adapter или явно из callAgent.adapter) с system-prompt из .md-файла, путь к которому ты передаёшь в agentPath (обязательно абсолютный — собирай через import.meta.url). Дефолта нет — без adapter в конфиге imo run упадёт сразу с ошибкой loadConfig.

См. секцию 8.5 в docs/writing-pipelines.md для деталей про адаптеры провайдеров.

Агент сообщает вердикт двумя маркерами в финальном ответе:

<verdict>ok</verdict>
<summary>одна строка про результат</summary>

Маркер <verdict> обязателен, <summary> — желателен. Маркер ловится из stream-json события result (это финальный текст агента, его модель выдаёт всегда). Если маркеров <verdict> несколько — побеждает последний.

Резервный канал — записать тот же вердикт в <sessionDir>/verdict-<stateName>.json:

{ "verdict": "ok", "summary": "одна строка про результат" }

Файл нужен только если по какой-то причине маркер в ответе не появился. callAgent сначала ищет маркер, потом — лезет в файл. verdict обязан быть одним из validVerdicts, которые ты передал в callAgent. Несоответствие в маркере — отказ без fallback на файл (агент явно выдал «не тот» вердикт). Несоответствие в файле и нет маркера — узел упадёт с ошибкой, сессия пометится failed. Это весь интерфейс между движком и агентом. Что агент делает внутри (читает и правит файлы, запускает тесты, что-то ещё) — движку неважно.

Что лежит в директории сессии

<sessionsDir>/<id>/ после прогона:

meta.json                                     # id, pipeline, args, status, startedAt, updatedAt
verdict-<stateName>.json                      # резервный канал вердикта (если агент не дал маркер в финальном ответе)
logs/<stateName>-<round>.log                  # события адаптера (для отладки упавшего агента)
logs/<stateName>-<round>.codex-system.md      # [только codexAdapter] system-prompt, переданный в codex exec
logs/<stateName>-<round>.codex-final.txt      # [только codexAdapter] финальный ответ модели (--output-last-message)
checkpoints/<id>/_default/...                 # JSON-чекпоинты LangGraph (для imo resume)
<артефакты от агентов>                        # plan.md, diagnosis.md и что ещё пишет твой агент

Когда что-то упало — смотри сначала в logs/<state>-<round>.log (события адаптера — там видно, был ли маркер <verdict> в финальном ответе). При использовании codexAdapter дополнительно проверь logs/<state>-<round>.codex-final.txt — там чистый финальный ответ модели. Файл verdict-<state>.json появляется только в fallback-ситуации.

Создание своего пайплайна

Важно: пайплайны пишутся на JavaScript с расширением .mjs и обязательной директивой // @ts-check в первой строке + JSDoc-типизацией. TypeScript не используется — файлы загружаются напрямую через import() без шага сборки. Расширение .mjs гарантирует ESM-режим независимо от "type" в package.json потребителя. См. полное руководство ниже.

Полное руководство — docs/writing-pipelines.md. Содержит:

  • ментальную модель и контракты,
  • 4 типа узлов с примерами (agent / human-gate / routing / shell),
  • conditional edges, verdict-протокол, идемпотентность для resume,
  • полный рабочий шаблон пайплайна (≈80 строк, копируется и адаптируется),
  • best practices, антипаттерны, чек-лист перед пушем,
  • шпаргалка по JSDoc-типизации (typedef, @type, @param, inline cast).

После npm install @infomaximum/ai-orchestrator файл доступен по пути node_modules/@infomaximum/ai-orchestrator/docs/writing-pipelines.md — передай его LLM-агенту, и тот сможет писать пайплайны без обращения к исходникам.

Также imo init создаёт агента imo-pipeline-writer в .claude/agents/ — Claude Code может его вызвать командой типа «напиши пайплайн который делает X», агент сам прочитает руководство и сгенерирует .mjs-файл.

Параллельные агенты

Если несколько агентов могут работать одновременно, движок предоставляет две публичные builder-функции из @infomaximum/ai-orchestrator/runtime:

  • addParallelAgents — статический fan-out: ветки и их агенты известны на этапе pipeline.build(). Подходит для «запусти ревьюера, тестировщика и линтера параллельно».
  • addDynamicFanOut + makeRetryRouter — динамический fan-out: количество и состав веток выясняется в runtime по результату узла-исследователя. Подходит для «найди все библиотеки в проекте и проанализируй каждую».

Обе записывают сбой ветки в BranchResult.error — падение одной ветки не отменяет выполнение остальных. Прогресс рендерится через общий tracker, а повтор конкретной ветки делается через conditional edge от merge-узла.

Подробности, ограничения LangGraph 1.x, полные примеры и подводные камни — в docs/writing-pipelines.md секции 4.5 и 4.6.

Минимальный пример

// configs/ai-pipelines/my-pipeline.mjs
// @ts-check
import path from "node:path";
import { fileURLToPath } from "node:url";
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
import { callAgent } from "@infomaximum/ai-orchestrator/runtime";

const here = path.dirname(fileURLToPath(import.meta.url));

const State = Annotation.Root({
  args: Annotation({ reducer: (_, b) => b, default: () => "" }),
  sessionDir: Annotation({ reducer: (_, b) => b, default: () => "" }),
  rounds: Annotation({
    reducer: (a, b) => ({ ...(a ?? {}), ...(b ?? {}) }),
    default: () => /** @type {Record<string, number>} */ ({}),
  }),
  lastFeedback: Annotation({ reducer: (_, b) => b, default: () => "" }),
});

/** @typedef {typeof State.State} StateType */

/** @type {import("@infomaximum/ai-orchestrator").PipelineDefinition<StateType>} */
export const myPipeline = {
  id: "my-pipeline",
  build: (deps) => {
    return new StateGraph(State)
      .addNode(
        "step1",
        /** @param {StateType} state */
        async (state) => {
          const round = (state.rounds.step1 ?? 0) + 1;
          await callAgent({
            agentPath: path.join(here, "agents/implementer.md"),
            prompt: `... ${state.args} ...`,
            sessionDir: state.sessionDir,
            stateName: "step1",
            round,
            validVerdicts: ["ok"],
            adapter: deps.adapter,  // передавай adapter из deps для поддержки глобальной подмены
          });
          return { rounds: { step1: round } };
        }
      )
      .addEdge(START, "step1")
      .addEdge("step1", END)
      .compile({ checkpointer: deps.checkpointer });
  },
};

Локаль для $EDITOR (важно для UTF-8)

Human-gate с requiresFeedback открывает $EDITOR (по умолчанию nano/vi). Если LANG/LC_ALL не UTF-8 — кириллица в редакторе будет отображаться некорректно. Поправь:

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

или в Dockerfile:

RUN apt-get install -y locales && \
    sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen && \
    locale-gen en_US.UTF-8 && \
    update-locale LANG=en_US.UTF-8
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8

Лицензия

MIT