The loop is solved. What happens after the fork is not.
A plugin for the Claude Agent SDK that versions an agent's evolution — diff it, merge it, refuse to ship it when the eval fails.
The Agent SDK runs the loop, ships the tools, manages context, and enforces
permissions. It also branches: fork gives you a second session starting from a
copy of the first.
Nothing brings the two back together. There is no merge, no diff between two sessions, nothing that refuses to promote an agent whose eval regressed, and the transcript is plain JSONL that anyone can edit. Sessions persist the conversation — the skills, subagents, model and goal that produced it are not versioned alongside it.
That gap is this repository.
| Agent SDK | This plugin | |
|---|---|---|
| Branch a session | fork |
— |
| Compare two branches | — | avcs_diff |
| Rejoin them | — | avcs_merge, with a --reconcile seam for goal and trace |
| Refuse to ship a regression | — | avcs_freeze, which fails unless the eval passes |
| Prove a transcript wasn't edited | — | Ed25519-signed commits |
| Keep the trace past compaction | summarised away | archived by the PreCompact hook |
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions(
plugins=[{"type": "local", "path": "/path/to/evolving-agents/plugin"}],
)Full details in plugin/README.md. The MCP server has zero
runtime dependencies — standard library only, with a test that fails if that
ever stops being true.
plugin/ |
The Agent SDK plugin: MCP server + three hooks |
packages/agentvcs/ |
The version control itself — 214 tests, no dependencies |
packages/memory/ |
Structured recall above the SDK's flat .claude/ memory files. Works; measures no better than naive matching — see PLAN.md |
demos/robot/ |
A 2D robot that evolves its own skills, versioned with agentvcs |
legacy/eat/ |
The Evolving Agents Toolkit, 2025. Kept readable; see below |
It was the Evolving Agents Toolkit: 18,680 lines across twelve subsystems — a component library, an agent bus, smart memory, an evolution loop, and a governance layer called Firmware. Backed by MongoDB Atlas.
It had three test functions.
That number is the story. EAT was not a product that failed; it was an architecture written down and never pinned to anything that could contradict it.
Most of it is now deleted, because the SDK does it better —
docs/WHAT-WAS-DELETED.md lists the 10,165 lines and
what replaced each one. Firmware asked a model to "never use dangerous
imports" in a string; a PreToolUse hook returning permissionDecision: "deny"
stops the call whatever the model decided. We do not ship our own version of a
problem that is already solved.
What survives in legacy/eat/ is the ancestry of what ships today. Read
evolution/ if you read one thing: 337 lines that closed the loop between an
agent changing and that change being kept, with nothing to verify the change was
an improvement. avcs_freeze is the same idea with the missing half added.
Claims here are measured, including the ones that came back flat.
- The dual-embedding resolver does not help. EAT indexed every component
twice — once for what it is, once for what it is for. Rebuilt and measured:
80% acc@1 either way, no difference. The second axis is genuinely distinct
(
cosine = 0.753); it just buys nothing on a modern encoder. - This organisation's "byte-identical wire format" claim was wrong. Two of
three opcode regexes matched;
HALThad diverged in a way that changes what parses. Found by writing the test instead of repeating the sentence.
pip install git+https://github.com/EvolvingAgentsLabs/evolving-agents no longer
installs an evolving_agents package — this is a monorepo now. Install what you
want directly:
pip install ./packages/agentvcsThe 2025 package sits at legacy/eat/ with its original setup.py, unchanged.
By Matias Molinas and Ismael Faro · Apache 2.0
