JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 41
  • Score
    100M100P100Q82668F
  • License MIT

The graph execution engine for agent swarms — production-grade orchestration with zero dependencies

Package Exports

  • @oni.bot/core
  • @oni.bot/core/agents
  • @oni.bot/core/checkpointers
  • @oni.bot/core/coordination
  • @oni.bot/core/functional
  • @oni.bot/core/guardrails
  • @oni.bot/core/harness
  • @oni.bot/core/hitl
  • @oni.bot/core/inspect
  • @oni.bot/core/messages
  • @oni.bot/core/models
  • @oni.bot/core/prebuilt
  • @oni.bot/core/store
  • @oni.bot/core/streaming
  • @oni.bot/core/swarm
  • @oni.bot/core/testing
  • @oni.bot/core/tools

Readme

@oni.bot/core

The graph execution engine for agent swarms.

Production-grade orchestration with zero dependencies.

npm version tests zero dependencies TypeScript strict MIT License


Why ONI

Most agent frameworks make the easy things easy and the hard things impossible. You can spin up a chatbot in ten lines, but the moment you need four agents coordinating with retries, circuit breakers, and human approval gates, you're writing glue code from scratch.

ONI was built for the hard things:

  • Multi-agent orchestration is a first-class primitive. Seven swarm templates ship out of the box -- hierarchical, fan-out, pipeline, peer-network, map-reduce, debate, and hierarchical-mesh. Pick one, plug in your agents, and go.
  • Zero runtime dependencies. The entire engine is self-contained TypeScript. No framework lock-in, no transitive supply-chain risk. Runs in Node, serverless functions, and edge runtimes without adaptation.
  • Production-grade from day one. Circuit breakers, node timeouts, dead letter queues, retry with exponential backoff, OpenTelemetry tracing, and checkpointing with time-travel debugging. These aren't afterthoughts -- they're wired into the execution engine.
  • Type-safe end to end. Full generics on state, channels, and node returns. TypeScript strict mode. If your graph compiles, it runs.

Quick Start

npm install @oni.bot/core
import { StateGraph, START, END, lastValue, appendList } from "@oni.bot/core";

type State = { query: string; answer: string; log: string[] };

const graph = new StateGraph<State>({
  channels: {
    query:  lastValue(() => ""),
    answer: lastValue(() => ""),
    log:    appendList(() => []),
  },
});

graph.addNode("think", async (state) => {
  return { answer: `Processed: ${state.query}`, log: ["think ran"] };
});

graph.addEdge(START, "think");
graph.addEdge("think", END);

const app = graph.compile();
const result = await app.invoke({ query: "What is ONI?" });
console.log(result.answer); // "Processed: What is ONI?"

Multi-Agent Swarm

Build coordinated agent teams with a single function call:

import { SwarmGraph } from "@oni.bot/core/swarm";
import { defineAgent } from "@oni.bot/core/agents";
import { anthropic } from "@oni.bot/core/models";

const researcher = defineAgent({
  name: "researcher",
  model: anthropic("claude-sonnet-4-6"),
  systemPrompt: "You research topics thoroughly.",
  tools: [webSearch],
});

const writer = defineAgent({
  name: "writer",
  model: anthropic("claude-sonnet-4-6"),
  systemPrompt: "You write compelling content from research notes.",
});

const swarm = SwarmGraph.hierarchical({
  supervisor: { model: anthropic("claude-sonnet-4-6"), strategy: "llm", maxRounds: 10 },
  agents: [researcher, writer],
});

const app = swarm.compile();
const result = await app.invoke({ task: "Write a technical brief on quantum error correction" });

No boilerplate routing, no manual state plumbing. The supervisor decides which agent runs next, results flow back through typed channels, and the swarm terminates when the task is complete.


Features

Category Feature Description
Engine Pregel execution Superstep-parallel graph engine with deterministic state merging
Typed channels lastValue, appendList, mergeObject, ephemeralValue reducers
Command routing State update + routing in a single return value
Send API Dynamic fan-out to nodes with per-instance payloads
Subgraphs Nested compiled graphs with Command.PARENT state bridging
Swarm 7 templates Hierarchical, fan-out, pipeline, peer-network, map-reduce, debate, mesh
Supervisor LLM-based or rule-based routing strategies
Handoff Agent-to-agent delegation with context transfer
Coordination RequestReplyBroker, PubSub for inter-agent messaging
Models 5 LLM adapters Anthropic, OpenAI, Google, Ollama, OpenRouter
Unified interface ONIModel with chat, streaming, and tool calling
Mock model Deterministic test doubles with call history
Streaming 5 modes values, updates, debug, messages, custom
Token streaming Character-level LLM output via messages mode
Custom events Emit named events from any node via StreamWriter
Multi-mode Subscribe to multiple stream modes simultaneously
Reliability Circuit breakers Automatic failure detection with configurable thresholds
Node timeouts Per-node deadline enforcement
Dead letter queues Capture and inspect failed executions
Retry + backoff Configurable per-node retry with exponential backoff
Persistence Checkpointing Memory, SQLite, PostgreSQL backends
Time travel getHistory, getStateAt, forkFrom
Cross-thread store Namespaced KV with semantic search for agent memory
HITL Interrupts interrupt(), getUserInput(), getUserApproval()
Session management Typed resume values, multi-step approval flows
Guardrails Budget tracking Token and cost limits with automatic enforcement
Content filters PII detection, topic filtering, custom validators
Permissions Per-tool permission checks with audit logging
Audit log Structured logging of all guardrail decisions
Observability OpenTelemetry Zero-dep adapter -- bring your own tracer
Graph inspection Topology descriptors, Mermaid diagrams, cycle detection
Testing mockModel() Deterministic model stubs with call history tracking
assertGraph() Structural assertions on graph topology
createTestHarness() Pre-wired test runner with auto-checkpointing
API Styles Builder pattern StateGraph + addNode + addEdge + compile
Functional task(), entrypoint(), pipe(), branch()
Prebuilt createReactAgent(), defineAgent()

Swarm Templates

Template Pattern When to use it
SwarmGraph.hierarchical() Supervisor routes to workers General multi-agent tasks with centralized control
SwarmGraph.fanOut() Parallel execution + aggregation Independent subtasks that can run concurrently
SwarmGraph.pipeline() Sequential A -> B -> C chain Ordered processing stages (ETL, content pipelines)
SwarmGraph.peerNetwork() Dynamic peer-to-peer handoff Agents self-organize based on capabilities
SwarmGraph.mapReduce() Split -> Pool -> Reduce Distributing N items across a worker pool
SwarmGraph.debate() Judge -> Debaters -> Consensus Multi-perspective reasoning, red-teaming
SwarmGraph.hierarchicalMesh() Coordinator -> Team subgraphs Nested teams with inter-team coordination

Each template handles routing, error recovery, and termination automatically. See examples/swarm/ for runnable examples.


Architecture

@oni.bot/core v0.7.0

                           +--------------------------+
                           |      Your Application    |
                           +--------------------------+
                                       |
                  +--------------------+--------------------+
                  |                    |                    |
           defineAgent()         StateGraph           SwarmGraph
           (single agent)       (custom graph)       (7 templates)
                  |                    |                    |
                  +--------------------+--------------------+
                                       |
                           +-----------+-----------+
                           |   ONIPregelRunner     |
                           |   (execution engine)  |
                           +-----------+-----------+
                                       |
         +----------+----------+-------+-------+----------+----------+
         |          |          |               |          |          |
     Channels   Streaming  Checkpoint    Circuit     Runtime    Telemetry
     (reducers) (5 modes)  (3 backends)  Breaker    Context     (OTel)
                                         + Retry   (AsyncLocal)
                                         + DLQ

Entry points at every level of abstraction:

  • ONIModel -- Call an LLM directly
  • defineAgent() -- Single agent with tools and system prompt
  • StateGraph -- Custom graph with full control over nodes and edges
  • SwarmGraph -- Multi-agent orchestration from templates

Sub-module Imports

Tree-shakeable sub-module imports for bundle optimization:

import { StateGraph, START, END } from "@oni.bot/core";             // Core engine
import { createReactAgent }       from "@oni.bot/core/prebuilt";     // Prebuilt agents
import { SwarmGraph }             from "@oni.bot/core/swarm";        // Swarm templates
import { interrupt }              from "@oni.bot/core/hitl";         // Human-in-the-loop
import { InMemoryStore }          from "@oni.bot/core/store";        // Cross-thread store
import { messagesChannel }        from "@oni.bot/core/messages";     // Message handling
import { SqliteCheckpointer }     from "@oni.bot/core/checkpointers";// Persistence
import { entrypoint, task }       from "@oni.bot/core/functional";   // Functional API
import { buildGraphDescriptor }   from "@oni.bot/core/inspect";      // Graph inspection
import { emitToken }              from "@oni.bot/core/streaming";    // Token streaming
import { anthropic, openai }      from "@oni.bot/core/models";       // LLM adapters
import { defineAgent }            from "@oni.bot/core/agents";       // Agent builder
import { RequestReplyBroker }     from "@oni.bot/core/coordination"; // Agent messaging
import { BudgetTracker }          from "@oni.bot/core/guardrails";   // Safety controls
import { defineTool }             from "@oni.bot/core/tools";        // Tool definitions
import { mockModel }              from "@oni.bot/core/testing";      // Test utilities

16 entry points. Import only what you use.


Production Features

Circuit Breakers

const app = graph.compile({
  circuitBreaker: { threshold: 5, resetAfter: 30_000 },
});

After 5 consecutive failures, the circuit opens and fast-fails all requests. After 30 seconds, it transitions to half-open and lets one request through to test recovery.

Node Timeouts

graph.addNode("llm_call", handler, { timeout: 10_000 }); // 10s deadline

Nodes that exceed their timeout are killed and routed through the error recovery path.

Retry with Backoff

graph.addNode("flaky_api", handler, {
  retry: { maxAttempts: 3, backoff: "exponential", initialDelay: 1000 },
});

Dead Letter Queue

const dlq = new DeadLetterQueue();
const app = graph.compile({ dlq });

// Later: inspect failures
const failures = dlq.list();

OpenTelemetry Tracing

import { ONITracer } from "@oni.bot/core";
import { trace } from "@opentelemetry/api";

const tracer = new ONITracer(trace.getTracer("my-app"));
const app = graph.compile({ tracer });

Zero-dep adapter that wraps any OpenTelemetry-compatible tracer. Emits spans for graph execution, node runs, tool calls, model invocations, and checkpoint operations.

Checkpointing + Time Travel

import { SqliteCheckpointer } from "@oni.bot/core/checkpointers";

const checkpointer = new SqliteCheckpointer("./state.db");
const app = graph.compile({ checkpointer });

// Resume from any point
const history = await app.getHistory("thread-1");
const forked = await app.forkFrom("thread-1", history[2].checkpoint);

Three built-in backends: MemoryCheckpointer (dev), SqliteCheckpointer (single-node), PostgresCheckpointer (distributed). Or implement ONICheckpointer for your own.


Human-in-the-Loop

import { interrupt, getUserApproval } from "@oni.bot/core/hitl";

graph.addNode("review", async (state) => {
  const approved = await getUserApproval("Publish this draft?", {
    payload: state.draft,
  });
  if (!approved) return { status: "rejected" };
  return { status: "published" };
});

Execution pauses, the interrupt is surfaced to your application, and the graph resumes exactly where it left off when the user responds.


Streaming

// Single mode
for await (const event of app.stream(input, { streamMode: "updates" })) {
  console.log(event.node, event.data);
}

// Multiple modes simultaneously
for await (const event of app.stream(input, { streamMode: ["values", "messages"] })) {
  if (event.mode === "messages") {
    process.stdout.write(event.data.chunk); // Token-by-token LLM output
  }
}

// Custom events from inside a node
import { getStreamWriter } from "@oni.bot/core";

graph.addNode("agent", async (state) => {
  const writer = getStreamWriter();
  writer.emit("progress", { step: 1, message: "Searching..." });
  // ...
});

Functional API

For simpler use cases, skip the builder pattern entirely:

import { entrypoint, task } from "@oni.bot/core/functional";
import { lastValue } from "@oni.bot/core";

const summarize = task("summarize", async (text: string) => {
  return await llm.chat({ messages: [{ role: "user", content: `Summarize: ${text}` }] });
});

const app = entrypoint(
  { channels: { query: lastValue(() => ""), answer: lastValue(() => "") } },
  async (state) => ({ answer: await summarize(state.query) }),
);

const result = await app.invoke({ query: "Explain quantum computing" });

Testing

import { mockModel, assertGraph, createTestHarness } from "@oni.bot/core/testing";

// Deterministic model responses
const model = mockModel([
  { role: "assistant", content: "Hello!" },
  { role: "assistant", content: "Goodbye!", toolCalls: [{ id: "1", name: "search", args: {} }] },
]);

// Structural graph assertions
assertGraph(graph, {
  hasNode: ["agent", "tools"],
  hasEdge: [["__start__", "agent"]],
  nodeCount: 2,
});

// Pre-wired test harness
const harness = createTestHarness(graph);
const result = await harness.invoke({ query: "test" });
const events = await harness.collectStream({ query: "test" }, "updates");

Documentation

Resource Description
Developer Guide Progressive tutorial from zero to advanced -- 19 sections covering every feature
API Reference Complete reference for all 130+ public exports
Examples 30+ runnable example files covering every feature

Optional Peer Dependencies

The core engine has zero runtime dependencies. Optional packages unlock additional backends:

npm install better-sqlite3   # SqliteCheckpointer
npm install pg               # PostgresCheckpointer

Contributing

Contributions are welcome. Please open an issue to discuss significant changes before submitting a PR.

git clone https://github.com/oni-bot/core.git
cd core
npm install
npm test

License

MIT -- ONI Platform