v0.33.0·Open source · MIT · TypeScript

Agents that survive
production.

A self-hosted TypeScript runtime for AI agents: tools that wait for a human, workflows that outlive the process, swarms, memory and RAG — on any model, in your own infrastructure.

Read the docs
Agent-friendly docs at /llms.txt
+++ support-agent · ticket 7731 +++
const refund = tool({
  name: 'refund_order',
  description: 'Refund part or all of an order.',
  parameters: z.object({ order: z.string(), amount: z.number() }),
  requiresApproval: ({ amount }) => amount > 100,
  execute: ({ order, amount }) => payments.refund(order, amount),
});

const support = new Agent({
  name: 'support',
  model: 'anthropic/claude-sonnet-5-5',
  instructions: 'Refund orders when the customer asks.',
  tools: [refund],
});

const run = await cog.run(support, { input, threadId });

if (run.status === 'paused') {
  await cog.resume(support, threadId, {
    defaultDecision: { approved: true },
  });
}
RUN · TICKET-7731 running
Order A-1001 arrived broken, please refund all $340.
claude-sonnet-5-5208 tokens$0.0019trace · 6 spans

A run pauses before a sensitive tool and resumes when a human approves — even after a restart, with a durable checkpoint store · examples/core/14-approvals.ts

+++ Any model · any runtime · your infrastructure +++

  • Anthropic
  • OpenAI
  • Gemini
  • Ollama
  • Mistral
  • DeepSeek
  • vLLM
  • Groq
  • Together
  • AWS Bedrock
  • Azure OpenAI
  • Anthropic
  • OpenAI
  • Gemini
  • Ollama
  • Mistral
  • DeepSeek
  • vLLM
  • Groq
  • Together
  • AWS Bedrock
  • Azure OpenAI
  • TypeScript
  • Node.js
  • Bun
  • Deno
  • Cloudflare Workers
  • Next.js
  • Express
  • Fastify
  • Hono
  • Koa
  • Redis
  • PostgreSQL
  • SQLite
  • MongoDB
  • Qdrant
  • Docker
  • MCP
  • OpenTelemetry
  • Telegram
  • Discord
  • WhatsApp
  • Fly.io
  • TypeScript
  • Node.js
  • Bun
  • Deno
  • Cloudflare Workers
  • Next.js
  • Express
  • Fastify
  • Hono
  • Koa
  • Redis
  • PostgreSQL
  • SQLite
  • MongoDB
  • Qdrant
  • Docker
  • MCP
  • OpenTelemetry
  • Telegram
  • Discord
  • WhatsApp
  • Fly.io
LLM providers
11
npm packages
33
built-in tools
26
runnable examples
74

+++ Durable workflows +++

Workflows that outlive the process.

Wire agents, tools and human sign-offs into a DAG. Each finished node is checkpointed to Postgres or Redis, so a crash, a deploy or an approval that takes all afternoon picks up where it stopped — not from the top.

publish-post.ts
const checkpoints = new PostgresCheckpointStore({ client: pool });
const executor = new WorkflowExecutor(cog, checkpoints);

const draft = agentNode<Post>(writer, {
  stateMapper: (run) => ({ draft: run.output }),
});
const review = humanWorkflowNode<Post>(
  approvalNode('review', { title: 'Publish this post?' }),
  { stateMapper: (answer) => ({ approved: answer.approved }) }
);
const publish = functionNode<Post>('publish', async (post) =>
  post.approved ? cms.publish(post.draft) : null
);

const pipeline = new WorkflowBuilder<Post>('publish-post')
  .addNode('research', agentNode(researcher))
  .addNode('draft', draft, { after: ['research'] })
  .addNode('fact-check', agentNode(checker), { after: ['research'] })
  .addNode('review', review, { after: ['draft', 'fact-check'] })
  .addNode('publish', publish, { after: ['review'] })
  .build();

const durable = {
  checkpoint: true,
  checkpointStrategy: 'per-node',
  approvalStore: new PostgresApprovalStore({ client: pool }),
} as const;

await executor.execute(pipeline, { topic }, durable);

const [last] = await checkpoints.list('publish-post');
await executor.resume(pipeline, last.id, durable);
run · wf_k3Fq9ZbT2mXa
running
researchrunningagentdraftqueuedagentfact-checkqueuedagentreviewqueuedhumanpublishqueuedfn
  1. 14:02:07execute · publish-post
PostgresCheckpointStore0 checkpointsper-node

checkpointStrategy: 'per-node' — on resume, finished nodes are skipped and only the nodes that were in flight run again · @cogitator-ai/workflows

+++ Swarms +++

Seven ways to make agents work together. One config key.

A supervisor over workers, a jury that votes, an auction for the task, stages behind a quality gate, two agents arguing it out — and every agent on the model that suits its role.

feature-team.ts

A supervisor splits the task and hands pieces to workers with the delegate_task tool. Results flow back up to it.

agent:startlead
const team = new Swarm(cog, {
  name: 'feature-team',
  strategy: 'hierarchical',
  supervisor: lead,
  workers: [frontend, backend, devops],
  hierarchical: {
    maxDelegationDepth: 2,
    visibility: 'summary',
  },
});

const { output, agentResults } = await team.run({
  input: 'Add SSO to the admin panel',
});

Replays of what each strategy runs · the event names are the ones swarm.on() receives · examples/swarms

+++ Everything in the box +++

Every package, ready when you need it.

Memory, RAG, protocols, channels, voice, browsers, evals and more ship as focused packages on the same runtime. Add the ones you need; each comes with docs and runnable examples.

@cogitator-ai/memory

Memory & context

Every run gets a context built to a token budget: recent history, long-term facts and semantic hits, on Postgres, Redis, SQLite, MongoDB or Qdrant.

Docs
live · @cogitator-ai/memory
contextBuilder · strategy: hybrid210 / 7,200 tok
0reserve 800 for the reply
  • System prompt210
13 of 58 entries+++ assembling +++
memory.ts
const cog = new Cogitator({
  memory: {
    adapter: 'postgres',
    postgres: { connectionString: process.env.DATABASE_URL! },
    embedding: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY! },
    contextBuilder: {
      maxTokens: 8000,
      strategy: 'hybrid',
      includeFacts: true,
      includeSemanticContext: true,
    },
  },
});

await cog.run(concierge, { input: 'Book my usual hotel', threadId: 'trip-42', userId: 'alice' });

+++ Runs anywhere +++

Drop it into the stack you already run.

One adapter call turns your agents into an HTTP API with SSE streaming, memory threads, approvals and a WebSocket — on Express, Fastify, Hono, Koa, Next.js, Tetsu on Bun, Deno or Cloudflare Workers. Or keep your client: speak OpenAI's Assistants API, or hand an agent to the Vercel AI SDK as a model.

import express from 'express';
import { createServer } from 'node:http';
import { CogitatorServer } from '@cogitator-ai/express';
import { assistant, cogitator } from './agent';

const app = express();

const server = new CogitatorServer({
  app,
  cogitator,
  agents: { assistant },
  config: { basePath: '/cogitator', enableWebSocket: true },
});
await server.init();

const http = createServer(app);
await server.attachWebSocket(http);
http.listen(3000);
request → streamNode.js
POST/cogitator/agents/assistant/stream
{"input":"What is 123 * 456?"}
200 · text/event-stream

    assistant ›

    What you get
    • POST
      /cogitator/agents/:name/run
      Run an agent, JSON reply
    • POST
      /cogitator/agents/:name/stream
      Same run as an SSE stream
    • POST
      /cogitator/agents/:name/resume
      Resume a run paused for approval
    • GET
      /cogitator/threads/:id
      Memory threads · POST messages, DELETE
    • POST
      /cogitator/workflows/:name/stream
      Workflows and swarms, run or streamed
    • WS
      /cogitator/ws
      Agent runs over a socket, via attachWebSocket
    • GET
      /cogitator/docs
      Swagger UI and /openapi.json, on by default
    examples/integrations/01-express-server.tsExpress guide

    Starting from scratch? The scaffolder writes a ready-to-run project, installs it and sets up Docker Compose if you want it.

    templatesbasicmemoryswarmworkflowapi-servernextjsscaffolding guide

    +++ Agent friendly +++

    Docs your coding agent can read.

    Point Claude Code, Cursor or any agent with a shell at cogitator.app and it gets Markdown, not a rendered page: a llms.txt index, the whole docs in one file, and every page at its own URL.

    ~/shop-api · agent session
    • /llms.txt

      The index: all 114 docs pages, grouped like the sidebar, each linked to its Markdown with a one-line summary.

    • /llms-full.txt

      Every page in one Markdown file, in sidebar order — for long-context models and offline reading.

    • /docs/<page>.mdx

      Any page as Markdown: append .mdx to its URL, or request it with Accept: text/markdown.

    +++ Hand the docs to your agent +++

    Every docs page has the same actions for that page: Copy Markdown, and Open in ChatGPT, Claude or Cursor.

    Ship the agent.
    Keep the control.

    Scaffold a project with your provider, memory and Docker set up, then grow it into workflows, swarms and channels package by package.

    Quick start