OPEN SOURCE · MIT · TYPESCRIPT

A persistent world for AI agents.

A shared graph of objects, relations, decisions, and causal chains — derived from an append-only event log.

Operad gives your agent memory it can prove. Every mutation is an event. Every event has a cause. Every decision records what was chosen, what was rejected, and why.

npm install @operad/core @operad/adapter-memory
quickstart.ts
import { createRuntime, behavior } from '@operad/core'
import { MemoryAdapter } from '@operad/adapter-memory'

const runtime = createRuntime({ storage: new MemoryAdapter() })
const graph = await runtime.createGraph('claim-4521')

// Add what the agent knows
const claim = await graph.addObject({
  type: 'claim',
  data: { policy: 'HO-3-12345', status: 'open' }
})

// Record why it decided
await graph.recordDecision({
  selectedAction: 'approve_claim',
  alternatives: [
    { action: 'deny', rejected: 'evidence supports' }
  ],
  confidence: 0.92
})

// Trace the full causal chain
const chain = await graph.traceBackward(decision.eventId)

Paste this into Claude, ChatGPT, or your coding agent.

The best way to learn Operad is to let an AI build something with it. This prompt walks the agent through the core primitives — graphs, events, decisions, forks — using the real API.

No mocks. No abstractions. Just @operad/core and a working experiment.

prompt.txt
You are an expert TypeScript developer.

1. Install the package:
   npm install @operad/core @operad/adapter-memory

2. Build a small experiment that demonstrates:
   - Creating a graph with objects and relations
   - Recording a decision with alternatives
   - Tracing the causal chain backward
   - Forking the graph to explore an alternative
   - Diffing the original vs the branch

3. Run it and explain:
   - How the event log captures every mutation
   - How traceBackward reveals the "why"
   - How fork/diff enables counterfactual reasoning

Use the real API from @operad/core. Do not mock anything.

Agents need more than memory.

Existing tools solve one piece. None solve the whole picture.

Memory

Mem0, Zep, LangChain Memory

Store facts. Retrieve facts. But no causal history — you know what the agent remembers, not why it learned it or when it was last true.

Orchestration

LangGraph, CrewAI, AutoGen

Route tasks between agents. But state between steps is ephemeral — no immutable log, no branching, no replay from a prior state.

Observability

LangSmith, Braintrust, Arize

Watch agents from the outside. But the agent itself has no access to its own history — it can't act on what happened.

Operad

The append-only event log projected into a live graph. The agent's memory is the audit trail. Objects, relations, decisions, and causal chains — all queryable, forkable, and governed from inside the runtime.

The layer beneath your agent framework.

Operad is not an agent framework. It's the persistent state layer that any framework can use. It complements your existing stack — not replaces it.

  1. 01
    Models GPT, Claude, Llama, Mistral
  2. 02
    Tool frameworks Vercel AI SDK, MCP, function calling
  3. 03
    Orchestration LangGraph, CrewAI, custom loops
  4. 04
    Memory Mem0, Zep, vector stores
  5. 05
    Operad Event-sourced graph runtime — this layer

What you can build.

01

Auditable agents

Every mutation emits an event with causal links. Trace any decision back to its origin — the actual execution path, not a reconstructed explanation.

02

Forkable runs

Checkpoint at any event. Fork the graph. Explore a counterfactual path. Diff original vs branch. Keep the best outcome.

03

Reactive systems

Behaviors subscribe to event types. When a matching event fires, the behavior runs — creating chains of reactive logic driven by the event log.

04

Relations with meaning

Typed edges between objects — supports, contradicts, depends_on. Query patterns across the graph. Drive logic from structure, not just data.

05

Long-running memory

Facts persist across sessions. Staleness tracking flags what's gone cold. Health records show verification history. The agent knows what it knows — and what it's forgotten.

The event log is the agent.

Fork, explore, commit

Time-travel to any point in the event log. Fork a branch. Explore an alternative. Diff the outcomes. This is how agents do counterfactual reasoning — not by re-prompting, but by replaying and branching the actual state.

fork-explore.ts
// Time-travel to event #42
const branch = await runtime.fork('claim-4521', {
  atEvent: 42,
  label: 'what-if-deny'
})

// Explore a different path
await branch.graph.recordDecision({
  selectedAction: 'deny_claim',
  alternatives: [{ action: 'approve', rejected: 'testing' }],
  confidence: 0.65
})

// Compare outcomes
const diff = await runtime.diff('claim-4521', branch.id)
governance.ts
const guard = behavior({
  name: 'stale-data-guard',
  on: ['object.stale'],
  handler: async (event, graph, ctx) => {
    ctx.propose({
      target: event.payload.objectId,
      action: 'reverify',
      reason: 'Not verified in 30+ days'
    })
  }
})
// Human approves → object re-verified
await runtime.approve(patchId)

Detect, react, govern

Behaviors watch the event stream. When stale data is detected, a behavior proposes a patch — not a direct mutation. A governance gate requires human approval. The agent suggests; a human decides.

A claim flows through six behaviors.

Click each step to watch the graph build — or hit Play to run the full cascade. Every node is an object. Every edge is a causal link. Every event is logged.

policy HO-3-12345 claim CLM-4521 claimant John Doe evidence-1 photo · roof damage evidence-2 adjuster report · filed 3/12 ⚠ risk_flag assessment score: 0.72 · medium risk carrier Acme Ins. approval pending
seed.ts
 
EVENT LOG
task-agent.ts
import { createRuntime, behavior } from '@operad/core'
import { MemoryAdapter } from '@operad/adapter-memory'

// Behavior 1: Initialize with a goal
const initializer = behavior({
  name: 'initialize-goal',
  on: ['graph.created'],
  handler: async (event, graph) => {
    await graph.addObject({
      type: 'task',
      data: { description: 'Research competitor pricing', status: 'pending' }
    })
  }
})

// Behavior 2: Execute pending tasks
const executor = behavior({
  name: 'execute-task',
  on: ['object.created'],
  where: { 'payload.objectType': 'task' },
  handler: async (event, graph, ctx) => {
    const result = await ctx.llm('Execute this task', event.payload.data)
    await graph.addObject({
      type: 'result',
      data: { taskId: event.payload.objectId, output: result }
    })
    await graph.recordDecision({
      selectedAction: 'completed',
      confidence: 0.85,
      reasoning: result.summary
    })
  }
})

// Behavior 3: Create follow-up tasks from results
const taskCreator = behavior({
  name: 'create-follow-ups',
  on: ['object.created'],
  where: { 'payload.objectType': 'result' },
  handler: async (event, graph, ctx) => {
    const nextTasks = await ctx.llm('What follow-up tasks?', event.payload.data)
    for (const task of nextTasks) {
      await graph.addObject({ type: 'task', data: task })
    }
  }
})

const runtime = createRuntime({
  storage: new MemoryAdapter(),
  behaviors: [initializer, executor, taskCreator]
})

// One line starts the entire loop
await runtime.createGraph('research-agent')
// → initializer fires → executor fires → taskCreator fires → loop continues
// Every step is in the event log. Every decision is recorded.

Task agent in behaviors.

Three behaviors wired through events — not function calls. The graph is the task queue. The event log is the execution trace.

  1. 01 initialize-goal creates the first task object
  2. 02 execute-task reacts to new tasks, records decisions
  3. 03 create-follow-ups reacts to results, spawns more tasks

The loop emerges from the event log. No explicit orchestration needed.

How Operad compares.

Feature Operad LangChain Memory Mem0 LangGraph
Event sourcing
Causal chains
Decision records
Replay / checkoutPartial
Fork / branch / diff
Staleness tracking
Reactive behaviors
TypeScript-nativePythonPythonPython
Storage-agnosticVector DBProprietaryCheckpointer
Open sourceMITMITClosedMIT

Inspired by

Operad stands on the work of researchers and builders who proved these patterns first.