Skip to content

Latest commit

 

History

History
198 lines (159 loc) · 8.28 KB

AGENTS.md

File metadata and controls

198 lines (159 loc) · 8.28 KB

Argon for AI agents

Give the agent a real MongoDB database that is secretly a disposable branch. Review what it did as a diff. Merge the good, undo the bad, repeat runs from the same pinned document state.

pin ──▶ sandbox (TTL) ──▶ agent writes via any driver ──▶ diff
                                                           │
                              merge (data PR) ◀────────────┴──▶ undo / discard

Four surfaces, one engine — pick by integration point:

Surface Start it For
CLI argon sandbox, argon pin, … humans, scripts, CI
MCP server argon mcp (stdio) Claude / Cursor / any MCP client
REST API + console argon console (or (cd api && go run .)) language SDKs, browsers
Wire proxy argon proxy stable per-branch connection strings

Sandboxes

Fork + checkout + TTL, one step:

argon sandbox create -p myapp --ttl 1h
# → connection string; hand it to the agent, any driver works

MCP and REST sandboxes wait for capture readiness and drain before returning URIs. Their server processes also sweep expired sandboxes every minute. With the bare CLI, keep argon watch --actor <run-label> running and explicitly schedule argon sandbox sweep. Actor labels apply to an entire branch and are persisted; use a new sandbox for a different run label. Then:

argon diff -p myapp -b <sandbox>              # review supported document changes
argon merge preview/apply …                   # adopt it — a reviewable data PR
argon undo … --actor <agent>                  # filter the branch actor label, conflict-aware
argon sandbox discard …                       # or let the managed server sweep it

Pins — reproducible evals

A pin is a named, immutable reference to a captured branch state. Its referenced history is protected from GC and resets while the pin exists:

argon pin create  -p myapp --name eval-v1 --note "golden dataset"
argon pin sandbox -p myapp --name eval-v1     # fresh sandbox per run

Pin once, fork per run: identical input state every time, no matter what happened to the branch since. Delete the pin to release its history. Pins are not independent backups, and matching input data does not make an agent's output deterministic.

MCP server

claude mcp add argon -- argon mcp

Thirteen tools: sandbox create/discard/keep · branch list · connect · diff · merge preview/apply · undo · snapshot create · pin create/list/ sandbox. The server runs a capture ingester for every sandbox it hands out — no extra process.

REST control plane

argon console serves the REST API plus a web UI locally (binds 127.0.0.1, opens your browser); (cd api && go run .) serves the API alone (default 127.0.0.1:8080, PORT/HOST to change). Control plane only — data flows through the MongoDB connection strings it returns.

POST   /api/v1/projects                                {name}
GET    /api/v1/projects
GET    /api/v1/projects/:p/branches
POST   /api/v1/projects/:p/branches                    {name, from}
GET    /api/v1/projects/:p/branches/:b
DELETE /api/v1/projects/:p/branches/:b
POST   /api/v1/projects/:p/branches/:b/checkout
POST   /api/v1/projects/:p/branches/:b/release
POST   /api/v1/projects/:p/sandboxes                   {name?, from?, ttl_minutes?, actor?}
GET    /api/v1/projects/:p/sandboxes
DELETE /api/v1/projects/:p/sandboxes/:b
POST   /api/v1/projects/:p/sandboxes/:b/extend         {ttl_minutes}
POST   /api/v1/projects/:p/sandboxes/:b/keep
GET    /api/v1/projects/:p/branches/:b/diff
POST   /api/v1/projects/:p/branches/:b/merge-preview
GET    /api/v1/merge-plans?project=:p
GET    /api/v1/merge-plans/:id
POST   /api/v1/merge-plans/:id/apply                   {strategy?}
POST   /api/v1/projects/:p/branches/:b/undo            {from_lsn, to_lsn?, actor?, dry_run?}
GET    /api/v1/projects/:p/branches/:b/entries         ?from_lsn&to_lsn&actor&collection&order&limit
GET    /api/v1/projects/:p/branches/:b/time-travel
GET    /api/v1/projects/:p/branches/:b/time-travel/query  ?lsn&collection&skip&limit
POST   /api/v1/projects/:p/branches/:b/snapshots
GET    /api/v1/projects/:p/pins
POST   /api/v1/projects/:p/pins                        {name, branch?, lsn?, note?}
DELETE /api/v1/projects/:p/pins/:name
POST   /api/v1/projects/:p/pins/:name/branches         {name}
POST   /api/v1/projects/:p/pins/:name/sandboxes        {name?, ttl_minutes?, actor?}
GET    /api/v1/meta
GET    /api/v1/status/ingesters

Sandbox-creating endpoints start a supervised ingester; errors return {"error": "..."} with a meaningful status. Optional switches, all off by default: ARGON_API_TOKEN (Bearer auth on every /api endpoint except /meta), ARGON_READ_ONLY=1, ARGON_CORS_ORIGINS, and ARGON_DEMO_MODE=1 — a restricted anonymous hosted playground with no native URIs/checkout: one ephemeral seeded project per visitor, requests scoped to it, writes rate-limited, everything reclaimed after ARGON_DEMO_TTL_MINUTES (default 60).

Python — argon-agents

Install SDK v0.2.0 from PyPI, with [langgraph] for the checkpointer:

python3 -m pip install 'argon-agents[langgraph]==0.2.0'

Start argon console --no-browser in another terminal. It listens on port 1818; use port 8080 instead if you started the standalone API with go run ..

from argon_agents import ArgonClient, ArgonCheckpointSaver

argon = ArgonClient("http://127.0.0.1:1818")
argon.get_or_create_project("myapp")

# LangGraph: the official MongoDB checkpointer on a sandboxed branch
saver = ArgonCheckpointSaver.from_sandbox(argon, "myapp", ttl_minutes=60)
# Compile and run your graph with checkpointer=saver.
# Optional: forked_saver = saver.fork(argon) branches its checkpoint history.
plan = argon.merge_preview("myapp", saver.sandbox.branch)
print(plan)           # inspect document changes and conflicts
# After reviewing this exact plan:
# argon.merge_apply(plan["id"])
# Or reject the run: saver.discard()

# Mem0: sandboxed agent memory
from argon_agents import sandboxed_mem0_config
config, sandbox = sandboxed_mem0_config(argon, "myapp")

# Reproducible evals
argon.create_pin("myapp", "eval-v1")
run = argon.sandbox_from_pin("myapp", "eval-v1")

LangGraph's checkpoint ids rewind steps within a thread; Argon adds fork/merge/undo/audit across the whole store. The saver.merge(), sandbox.merge() and argon.merge() convenience methods preview and apply immediately, without an approval pause. Use separate preview and apply calls for reviewed changes. The running API manages capture and TTL sweeps; materializing a sandbox copies data into a physical MongoDB database. Mem0 semantic vector retrieval also requires Atlas Search or a compatible MongoDB Search deployment and separately provisioned search indexes.

Wire proxy

Checked-out branches get machine-named physical databases. argon proxy serves stable, human-readable URIs instead:

mongodb://proxy-host:27018/<project>~<branch>?directConnection=true

The proxy rewrites each command's $db to the branch's physical database; mongod still evaluates every query. Constraints: directConnection=true required, compression negotiated away, authSource=admin with auth, unresolvable aliases return a clean command error. Capture stays asynchronous — run argon watch (or use API/MCP sandboxes) behind it.

Complete business-data example

examples/pinned_agents.py runs two deterministic agent proposals against one pin, writes through PyMongo, checks isolation, reviews both diffs, merges the approved discount and discards the rejected proposal. Start argon console --no-browser, install pymongo, then run:

python3 examples/pinned_agents.py --api http://127.0.0.1:1818

Set ARGON_API_TOKEN in the example's environment when the local server uses a bearer token. This requires your own engine; the hosted demo does not provide database credentials. Native MongoDB credentials remain deployment credentials, not a security boundary between mutually untrusted agents. Provision restricted MongoDB users/deployments for those workloads.

Prepare every new collection before updates with argon collections prepare or the MongoDB driver's changeStreamPreAndPostImages: {enabled:true} option. A newly materialized collection is already prepared by checkout.