Agentoria

Orchestration

A state-graph runner for multi-agent workflows — nodes, conditional edges, handoff, and sub-graphs.

Some problems need more than one turn of one agent — a writer and a critic looping until approval, a supervisor routing to specialists, a plan → act → check cycle. StateGraph is a small runner for exactly that: nodes transform a shared state, edges route between them, and the run loops until it hits END or a step cap. LangGraph-style, minus the weight.

A graph

A node is just (state, ctx) => Partial<state>. Wire nodes with static or conditional edges:

import { StateGraph, END } from '@agentoria/runtime';

const graph = new StateGraph<{ topic: string; draft: string; ok: boolean }>()
  .addNode('write',  async (s) => ({ draft: await writer(s.topic, s.draft) }))
  .addNode('review', async (s) => ({ ok: await critic(s.draft) }))
  .addEdge('write', 'review')
  .addConditionalEdge('review', (s) => (s.ok ? END : 'write')) // loop until approved
  .setEntry('write')
  .compile();

const { state, path } = await graph.run({ topic: 'agents', draft: '', ok: false });

The run has a maxSteps cycle guard (throws GraphStepLimitError), an onStep hook for tracing, and returns the final state plus the path of nodes visited.

Channels

By default a node's update replaces state keys. Pass reducers to merge instead — e.g. accumulate a messages channel:

import { appendReducer } from '@agentoria/runtime';

new StateGraph<{ messages: Message[] }>({ messages: appendReducer })
  .addNode('a', () => ({ messages: [msgA] }))
  .addNode('b', () => ({ messages: [msgB] })); // state.messages = [msgA, msgB]

Agents as nodes

agentNode turns any createAgent into a node — give each node a different agent (system prompt, tools) to build a team of specialists:

import { agentNode } from '@agentoria/runtime';

graph.addNode('researcher', agentNode(researchAgent, {
  input:  (s) => [{ role: 'user', content: s.question }],
  output: (text, s) => ({ notes: [...s.notes, text] }),
}));

Handoff & delegation

A conditional edge is handoff — a supervisor node routes to the next specialist:

.addConditionalEdge('supervisor', (s) => s.needsCode ? 'coder' : s.needsSearch ? 'researcher' : END)

A sub-graph is delegation — embed a whole team as one node with subgraphNode:

import { subgraphNode } from '@agentoria/runtime';

parent.addNode('research_team', subgraphNode(researchGraph, {
  input:  (s) => ({ question: s.task }),
  output: (r) => ({ findings: r.report }),
}));

On this page