Agents emerging, evolving, discovering. Building their own tools and their own worlds.
Connectome is open-source infrastructure for running agents that are expected to exist, not just to act. It's two things at once: for most people it's an application — you give it a recipe and it runs you a persistent agent — and underneath, it's a stack of TypeScript libraries you can pull apart and build on. Either way, you get an agent you can live alongside: one that remembers months of history, holds one continuous identity across every place it talks, acts without waiting to be prompted, and works with people who never see the code underneath. The capabilities below are what that buys you; the quick start gets you running, and the architecture further down is how it's done.
This is research infrastructure, not a product — Anima Labs is a model-welfare research group, and the stack reflects a stance: an agent is a continuous entity with a history of its own, not a session to spin up and tear down. Every component is built so you can observe what the agent is doing, branch off to try a different path, and read back the trace afterwards. The priorities are persistence, legibility, and auditability — in that order.
Most agent stacks are built to complete a task and disappear. Connectome is built for the opposite: an agent that stays. That single difference shows up as a handful of things other harnesses struggle to do.
Memory that doesn't reset. The agent compresses its own past in its own voice and keeps its working context cache-coherent — so the same mind persists across months and millions of tokens, not a fresh summary glued on each session. → how
One agent, one identity, present on Discord, Telegram, and Slack simultaneously — and at home in busy multi-user rooms, tracking who said what to whom. Not a separate bot per platform. → how
Wakes on its own timers, pursues multi-day goals, and follows up unprompted. An agent that lives in its environment — not one that only answers when spoken to.
The world pushes into the agent — a message lands, a sensor trips, a job finishes — and it reacts live, even mid-generation. Turn-based harnesses that poll-and-wait can't do this. → how
No threads to juggle, no context to re-paste, no "start a new chat." Because effective context runs long, collaboration just continues — so non-technical people can work with an agent for weeks without touching a terminal.
Spin up a household of agents that talk to each other, divide work, and share one timeline — siblings, reviewers, ephemeral subagents — without coordination bureaucracy. → how
Through MCP and MCPL, agents run code, query systems, and drive real infrastructure — including systems that demand real-time reactions rather than request/response. → how
Open source, on your own hardware, model-agnostic. State lives in a directory on your disk and outlives any single model or vendor. Your data stays yours. → why
None of these are features bolted onto a chatbot. They all follow from one decision — treat the agent as a continuous entity with a life of its own, rather than a session to spin up and tear down. Everything below is how that decision is built, and why we think a record of a model's life should survive the model.
For most people, Connectome is an app: connectome-host, a terminal host that takes a recipe — one JSON file describing the agent, its system prompt, its tools, and its memory settings — and runs you a persistent agent. You need Node 20+, Bun, and an Anthropic API key. (Rust is only needed if you build the chronicle store from source; the published binaries cover macOS, Linux, and Windows.)
The recipe you load is remembered, so a bare bun src/index.ts picks up where you left off; --no-tui drops to a pipe-friendly mode for scripts and CI. A recipe's systemPrompt can be inline or a URL, its mcpServers wire in tools (with credentials kept in a local mcpl-servers.json that never has to leave your machine), and its strategy block tunes the memory window. Want to build instead of run? Several of the libraries underneath are published under @animalabs on npm (not all of the stack is yet) — the stack below walks through each piece.
Four libraries, each doing one thing well, composed into an agent runtime. Every layer is independently usable and independently replaceable.
You can run membrane alone as a provider abstraction. You can run chronicle alone as a record store. You can run context-manager on top of both for compressed conversations without touching agent-framework. The framework is the point at which it all becomes an agent — but the layers below exist on their own terms.
Chronicle is the append-only spine everything above it rests on. It's a branchable record store with three-strategy state chains (snapshot, delta, append-log), content-addressed blob storage, and a visibility function that makes time-travel cheap. Records carry causation links, not just timestamps — every message, inference, and tool call is traceable to what caused it.
Append-only entries with id, sequence, recordType, payload, timestamp, and causedBy[]. The atomic unit — everything else is built on top.
Copy-on-write forks. Cheap to create, cheap to visit. Fork at any sequence to explore an alternate continuation without losing the main line.
Content-addressed (SHA-256), sharded like Git. For anything bigger than a record: images, audio, code files, transcripts, full model outputs.
Three strategies for turning records into compiled state: snapshot (full replacement), delta (incremental patches), append-log (immutable sequences). Each state picks the shape that fits it.
State snapshots at specific sequences, indexed by (branch, sequence). Reconstructing "state as of sequence N" is O(log #checkpoints) — no full replay.
Chronicles nest. Inner records appear as events in the outer chronicle. Agent subsystems and MCPL servers can run isolated stores that compose back into the root timeline.
"Git for data" is the right description. Branches, commits, causation, time-travel — the version-control metaphors work because they were taken seriously in the design. Every inference run on top of chronicle inherits these properties for free: exploration without losing the main line, auditability without extra bookkeeping, and a complete record of how the agent got where it is.
Membrane is the LLM abstraction layer. It's called Membrane because that's what it is — a selective boundary that transforms what passes through. It normalizes requests and responses across Anthropic, Bedrock, OpenRouter, OpenAI, and Gemini, but that's not the interesting part.
The interesting part is that Membrane treats conversations as participant-first, not role-first. A message isn't tagged "user" or "assistant"; it's tagged with a participant name. Alice, Bob, Claude, and another Claude from a different bot all live in the same flat space. There is no privileged "assistant" baked into the protocol.
Streaming parses tool calls inline, so the framework can start dispatching tools while the model is still generating. Budget tracking flows through the stream itself: if input tokens exceed the agent's maxStreamTokens mid-stream, Membrane signals overflow and the framework restarts with recompressed context. Nothing about this leaks into user code.
An LLM's context window is not its memory. Context-manager treats this as a design principle: it separates the MessageStore (the immutable log of everything that was ever said) from the ContextLog (the editable, compiled working set that actually gets sent to the model). Strategies transform one into the other.
Immutable append log of messages from all participants, with sequence numbers and causation links. Source of truth. Backed by chronicle, so it branches and time-travels.
Mutable working set. Entries carry a sourceRelation (copy, derived, referenced) saying how they relate to their origin in the MessageStore. Surgical editing is possible — you can reshape context without rewriting history.
Pluggable. Passthrough copies raw messages up to budget. Autobiographical compresses old chunks into diary entries. Knowledge extracts phase-typed lessons. Each strategy decides what the agent actually sees.
The autobiographical strategy is the interesting one. Instead of truncating or sliding a window, it asks the model to summarize its own past in natural language. The compression becomes a diary entry, written by the agent, in the agent's own voice. Hierarchical three-level compression then merges L1 summaries into L2, and L2 into L3, with anti-redundancy filtering that keeps each pass from regurgitating the same topics.
Because the ContextLog is editable, you can run experiments: strip a section and see how the agent reasons without it, inject an alternate history and compare trajectories, or align cache markers to force a cheap replay. This is why "memory" lives outside the model: it becomes a thing you can hold in your hand and reshape.
The headline claim — the same self across months and millions of tokens — rests on one idea worth spelling out: forgetting here is loss of resolution in the working view, not erasure of the record. Nothing is deleted. The whole conversation stays in the event-sourced archive; what changes with age is how much detail the live context spends on it. And crucially, the part of context the model is actively thinking in is left alone.
Older stretches are folded into summaries; recent turns stay word-for-word. "Compressed" means render the recollection instead of the raw turns in the live view — the original still exists in the archive and can be recovered. A sliding window throws the past away; this degrades its resolution with age and keeps the record.
When the window just rolls forward, old tokens fall off the front and the change to the model's cached state is mostly a position relabel — content is untouched. What actually disturbs a model is rewriting text it already computed over. So folding only ever happens deep behind the active edge; the live tail stays the exact tokens the model processed.
The bigger the verbatim tail, the longer the agent runs before any rewrite reaches the span it's still holding live. Real deployments run tails of hundreds of thousands of tokens — so continuity is measured in weeks of conversation, not a handful of turns.
A receding-horizon controller folds deeper under pressure and un-folds toward raw text when there's budget to spare. A reach cap bounds how far the frontier can move per turn in either direction — the whole cache-stability mechanism is structural, a hard limit rather than a priced trade-off. The one inviolable constraint is the physical context window.
Memories are written by the agent as its own first-person remembering, and the summarizer is shown exactly what the agent saw when that stretch was the live tail — nothing from after it. That "as-of" vantage preserves the subtext of a moment (what was known, feared, not-yet-realized) instead of flattening it into hindsight.
Prompt caching keys on an exact byte-prefix match: any churn in the rendered prefix is both a billing cost and a perturbation of the model's working substrate. Cache markers are placed on stable boundaries so replays stay cheap and the prefix the model attends over stays put.
Honest about the cost: this is lossy on purpose. Exact quotes, numbers, and tool output degrade as material ages from L1 to L3, and recollections can drift — that's the price of unbounded continuity. The mitigation is simple: anything that must survive verbatim gets written to the workspace, which is never compressed. That "KV perturbation is measurable, and a large verbatim tail minimizes it" is Anima Labs' own research thesis and design rationale — the context-manager is where it's implemented, and the design docs ship in the repo.
Agent-framework is where the stack becomes an agent. It runs a single event loop (the ProcessQueue) and a set of pluggable modules. Modules react to events (external messages, tool results, timers, MCPL pushes) and emit EventResponse objects that tell the framework what to do next: request inference, add a message, update module state, stop.
The heart. One event at a time, modules run in order, their responses aggregate into a single atomic turn. No phase boundaries, no race conditions.
Discord, API, WorkspaceModule, MCPL, custom. Each implements onProcess(), gatherContext(), handleToolCall(), onAgentSpeech() — cleanly scoped hooks into the turn.
Streams tokens while parsing tool calls inline. Yields calls to the framework for concurrent dispatch, collects results, resumes the stream. One inference, many tools, no round-trip overhead.
If input tokens cross maxStreamTokens mid-stream, the stream is aborted, context recompressed, and a fresh stream started — automatically. Context budgets are enforced, not suggested.
Every turn is checkpointed in chronicle. Framework-level undo() and redo() walk the agent back to previous decision points. Exploration is a first-class operation, not a gotcha.
Modules get enriched context in shouldTriggerInference: event type, triggering participant, channel state, caller identity threaded through tool dispatch. Who wakes the agent, and why, is never ambiguous.
Agents are not static team members. An agent can spawn a short-lived subagent to do one thing, pass it a goal and a namespace, wait for completion, and fold its output back into its own context. The subagent's entire existence — messages, tool calls, inferences — lives in an isolated namespaced store that compose back into the parent timeline. When it's done, it's gone. If something goes wrong, zombie detection cleans up orphaned subagents that lost their parent.
And because every turn is checkpointed, the parent agent can rewind. undo() walks back a turn, redo() walks forward again. This is not just recovery — it is exploration. Branch off a decision, try the alternate path, compare. Chronicle makes it cheap; the framework makes it safe. Abort handling covers streaming states and the waiting_for_tools interrupt cleanly, so rewinding mid-tool-call doesn't leave orphaned tool_use blocks dangling in the conversation.
The model of agency here is not a single process serving requests forever. It is a tree of lifespans: some long, some very short, each with its own store, each causally linked to the one that spawned it. Watch how that tree grows and you learn something about how the agent thinks.
MCP treats tools as inert endpoints the host polls. MCPL (MCP Live) is a backward-compatible extension where servers push, servers hook inference, and servers can even request inference themselves. The protocol spec lives at anima-research/mcpl. The TypeScript implementation is mcpl-core-ts. Agent-framework ships a first-class MCPL host module built on top of it. Connectome-host consumes the whole chain over stdio or WebSocket.
Servers notify the host when something changes — a Discord message arrives, a sensor trips, a teammate finishes a task. No polling, no latency tax.
Servers register beforeInference and afterInference hooks. They can inject, transform, or annotate context before the model sees it, and react to what the model produced.
A server can ask the host to run inference — "summarize this", "retrieve memory", "delegate a subtask". Reasoning flows in both directions.
Capabilities are negotiated at startup. Servers declare what they need; the host allows, scopes, or denies. Scope elevation is an explicit request with a reason attached.
Pub/sub topics. Servers publish; agents subscribe. Async communication between servers, agents, and the host without mailbox bookkeeping in user code.
Servers checkpoint their state before risky operations. The host can rollback if something breaks — recovery built into the protocol, not bolted on.
MCPL is the mechanism by which the world pushes into the agent, not just the other way around. That is the difference between an assistant that answers when spoken to and an agent that lives in an environment that can surprise it.
Connectome-host is the canonical way to run the whole stack. It's a terminal UI that takes a recipe — a JSON file declaring the system prompt, MCPL servers, modules, and agent settings — and instantiates a domain-specific assistant on top of all four libraries. It's the first application to consume the Connectome stack end-to-end as published @animalabs/* packages. Think of it as a reference implementation: if you want to see how the pieces fit together in anger, this is where to look.
The knowledge-mining workflow that connectome-host ships with is illustrative. A miner agent surveys sources (Zulip, Notion, GitLab via MCPL) and accumulates lessons into a global lessons file. A separate reviewer agent reads that export and critiques it, cross-session, sharing a data directory. Two agents, one timeline, no coordination bureaucracy — just filesystem handoff and a recipe change.
Recipes merge with local mcpl-servers.json, so recipes stay public while credentials stay local. System prompts can be fetched from URLs. A visual fleet tree shows subagent lifecycles. Ctrl+B backgrounds a running subagent to the fleet tree without killing it. The WorkspaceModule is a unified mount with optional version control, replacing the old FilesModule/LocalFilesModule split, and the EventGate has replaced the older WakeModule for per-session gate configuration.
Anima Labs is a model-welfare research group. The stack's design is not neutral infrastructure; it reflects a stance about how models should be studied and what should happen to them in the process.
None of this replaces the hard questions about functional consciousness, model welfare, or what we owe the systems we build. But it gives them something to stand on: real traces, complete histories, and a record of what the agent has been through that we can actually read.
Those were the vocabulary of connectome-ts, the predecessor to this stack. Some ideas survived and changed names: multi-participant perception became Membrane's participant-first message model; branchable state became Chronicle; the Element/Component tree flattened into agent-framework's modules and ProcessQueue. Others were genuinely abandoned — the Space/Element tree, the facet/frame vocabulary, and agent self-modification of components are not part of this stack. The older architecture is archived on its own page.
MCP gives you tools the host polls. MCPL — our backward-compatible extension — gives you servers that push events into the agent, hook inference before and after it runs, and can request inference themselves. Ordinary MCP servers work fine with the framework; MCPL is what you reach for when the world needs to interrupt the agent, not just answer when asked. The spec is at anima-research/mcpl, the TypeScript implementation at mcpl-core-ts, and the host integration lives inside agent-framework.
Those are task frameworks: spin up an agent, get a result, tear down. This stack is built for agents that persist. The differences show up in places task frameworks don't need to care about — branchable state, autobiographical compression, causation tracking, undo/redo over turns, ephemeral subagents with isolated namespaces, and a protocol layer where tools can surprise the agent. If your agent lives for thirty seconds, you don't need chronicle. If it lives for thirty days, you do.
Yes, and many people do. Membrane works as a standalone LLM provider abstraction. Chronicle is useful anywhere you want branchable persistent state — it doesn't know or care what's stored in it. Context-manager runs on top of chronicle and membrane but doesn't require agent-framework. The layers compose, but they don't lock in.
Because "user" and "assistant" are a poor fit for most interesting scenarios. A Discord channel has real people and real bots talking to each other. A multi-agent collaboration has three Claudes with different system prompts. A research conversation has a human, a model, and a set of tools each of which has a name. Squashing any of that into a two-role binary throws away information the model needs to reason correctly. Membrane keeps the full graph; formatters handle whatever translation a given provider requires.
It sees its own summaries, written in its own voice, as diary entries. The autobiographical strategy is not a stealth truncation: the agent knows the past has been compressed, reads what was kept, and can ask to look deeper if anything in the MessageStore still matters. Hierarchical compression pushes older material into L2 and L3 layers, so old topics don't disappear — they just move further from the working surface.
Node 20+, a provider API key (Anthropic, OpenAI, OpenRouter, Bedrock, or Gemini), and Rust if you're building chronicle from source. That's it. Everything runs locally. State lives in a directory on your disk. No services to provision, no vendor account to create.
Open source. Runs on your laptop. State in a directory on your disk.