The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
Agent harness for apps, models, and guarded writes
Reins turns your app’s existing functions or ORM models into capabilities an LLM can use. It decides which operations to call, keeps reads and writes separated, and routes writes through approval, audit, and policy checks before anything changes.
Builders who want to expose an existing app or database to an agent without wrapping it in a new graph framework.
You can let an agent answer questions and carry out tasks on your app while keeping writes gated and traceable.
What it does
Typed capabilities from your code
Decorate functions or point Reins at SQLAlchemy or Django models, and it builds callable capabilities from their names, types, and docstrings.
Read-only and write-capable modes
`ask()` stays read-only, while `run()` can write only after policy and approval checks pass.
Approval gate and audit trail
Writes can pause for human approval, and every denied, approved, or executed write is recorded in a structured audit log.
Row-level scoping with identity
Pass a principal into the agent so capability code can keep each user scoped to their own rows.
Code-mode execution
For bigger tasks, Reins writes a short program that runs in a sandbox and calls your capabilities directly.
Progressive discovery at scale
It can search capabilities on demand so large apps do not need to stuff every tool into the model context.
Cross-language packages and conformance suite
The repo includes Python, Go, and TypeScript packages that share the same contract and conformance tests.
Zero-code database CLI
You can inspect, ask, or chat with a database directly from the terminal without writing model code first.
How to get it
- 1Reins requires Python 3.11+.
pip install reins # core (first PyPI release coming soon) pip install "reins[anthropic]" # with the Anthropic backend pip install "reins[openai]" # with OpenAI / Gemini / Groq / Z.ai / Ollama / vLLM pip install "reins[sqlalchemy]" # with Agent.from_orm(...) for SQLAlchemy pip install "reins[django]" # with Agent.from_orm(...) for Django
- 2Until the first published release, install from source
git clone https://github.com/shamspias/reins pip install -e "reins/packages/python[anthropic,openai]" export ANTHROPIC_API_KEY=sk-... # or any provider key from the table below
README
Reins
A lightweight agent harness you bolt onto your app so an LLM can operate it — safely and cheaply.
Point Reins at functions you already have — or your ORM models — and hand it a goal in plain language. It works out which of your operations to call and in what order, runs them through your own code (never raw SQL by default), and returns the result, with near-zero token overhead and safe-by-default writes. There is no graph to draw: you expose your app, and the agent operates it.
The wedge: Reins gives the model your verbs, not your tables. Intent-named functions like
refund_ordercarry the meaning that raw schemas and OpenAPI specs strip away — which is exactly where text-to-SQL and auto-generated tool layers lose their reliability.
See it all at once
git clone https://github.com/shamspias/reins && cd reins
make setup && make demo
make demo runs the flagship example (examples/fastapi_sqlalchemy/) — no API
key needed. It auto-exposes a shop's SQLAlchemy models, answers a read question,
scopes orders per logged-in user, pauses a write at an approval prompt, and prints
the audit trail. examples/fastapi_sqlalchemy/app.py is the same agent as a real
FastAPI server with the <reins-chat> widget.
No code at all: point it at a database
Already have a database? Operate it from your terminal — no models, no Python:
pip install "reins[sqlalchemy]"
export ANTHROPIC_API_KEY=sk-... # or any provider key
reins inspect sqlite:///shop.db # see what Reins can do (no key needed)
reins ask sqlite:///shop.db "how many orders shipped last week?"
reins chat sqlite:///shop.db # an interactive, read-only Q&A session
reins chat and ask are read-only — they answer questions but never change
your data. reins inspect reflects your tables and prints the exact capability
surface (with read/write classification) so you can see what an agent could do
before you ever run one.
The adoption ladder
Start at the top rung and stop wherever you have what you need — each is a strict superset of the one above, and nothing lower ever requires the levels below it.
| Level | You have… | You write… |
|---|---|---|
| 0 — Try it | a database | nothing — make demo, or reins chat <db-url> |
| 1 — Your ORM | SQLAlchemy / Django models | Agent.from_orm(db, models=[...]) |
| 2 — Your functions | functions or a module | @capability / Agent.from_module(mod) |
| 3 — Writes, safely | something to change | can_write=True, approve=, principal= (RLS) |
| 4 — Production | users and traffic | a provider, DockerSandbox(), endpoint(...), budgets |
Full copy-paste walkthrough: QUICKSTART.md. Swapping in your own model, policy, approval gate, sandbox, or audit sink: EXTENDING.md.
Example
from reins import Agent, capability
@capability
def find_orders(status: str) -> list[dict]:
"""Find orders by their current status."""
return store.orders(status=status) # your existing code
@capability
def refund_order(order_id: int) -> dict:
"""Refund a customer's order by its public order number."""
return payments.refund(order_id) # your existing code
agent = Agent(capabilities=[find_orders, refund_order])
# ask() is read-only: it can never call a write capability.
result = agent.ask("how many orders are stuck in processing?")
print(result.output.text)
# run() may write: writes are gated before they execute.
agent.run("refund order 8842")
The model is auto-detected from your environment (set any of ANTHROPIC_API_KEY,
OPENAI_API_KEY, GEMINI_API_KEY, GROQ_API_KEY, ZAI_API_KEY), or named
explicitly: Agent(model="openai:gpt-4o"), Agent(model="ollama:llama3.1"), or just
Agent(model="claude-opus-4-8").
Already have an ORM? Skip the decorating.
Point Reins at your SQLAlchemy or Django models and it generates the capabilities for you — intent-named verbs, not raw tables — with zero hand-written code:
from reins import Agent
# SQLAlchemy: pass your Session / sessionmaker / Engine
agent = Agent.from_orm(db, models=[User, Order]) # reads only, safe
agent.ask("how many orders are still open for acme@corp.com?")
# Django: no db argument — the connection is global
agent = Agent.from_orm(models=[User, Order], can_write=True) # writes opt-in, gated
agent.run("refund order 8842 and email the customer")
Reins introspects each model into find_orders / get_user_by_email /
create_user / … (lookups prefer a unique natural key like email over
internal ids), builds a searchable schema index, trims every response so raw
tables never flood the context, and runs it all through your ORM —
inheriting your constraints and validation. The same from_orm works
identically for SQLAlchemy and Django.
Why Reins
- Your verbs, not your tables. The model sees intent-named operations with real descriptions and types — not opaque columns or hand-written JSON schemas.
- Safe by default.
ask()is read-only and can never write; writes are opt-in and gated. Beginners cannot cause damage, and the boundary is enforced in code, not in a prompt the model can reason around. - You hold the reins. Reins runs your functions, so it inherits your existing validation, authorization, and business rules. No raw SQL against your database.
- Tiny and transparent. The core is a small, readable loop you own — no hidden
graph, no framework internals to reverse-engineer when you hit a ceiling. And
agent.explain()shows exactly what it did: the code it wrote, every call, each result. - Any model. Anthropic, OpenAI, Gemini, Groq, Z.ai (GLM), and local servers (Ollama, vLLM) ship in the box; anything OpenAI-compatible works too.
How it works
- Register. Decorate the functions you want to expose. Reins reads their type hints and docstrings to derive a schema and classify each as read or write.
- Discover. The agent is shown your intent-named operations and the goal.
- Plan. It decides which operations to call, and in what order, to reach the goal.
- Govern. Reads run freely; writes pass through policy, approval, and audit before anything touches your data.
- Return. Only results cross back to the model, and every decision and call is traceable.
Installation
Reins requires Python 3.11+.
pip install reins # core (first PyPI release coming soon)
pip install "reins[anthropic]" # with the Anthropic backend
pip install "reins[openai]" # with OpenAI / Gemini / Groq / Z.ai / Ollama / vLLM
pip install "reins[sqlalchemy]" # with Agent.from_orm(...) for SQLAlchemy
pip install "reins[django]" # with Agent.from_orm(...) for Django
Until the first published release, install from source:
git clone https://github.com/shamspias/reins
pip install -e "reins/packages/python[anthropic,openai]"
export ANTHROPIC_API_KEY=sk-... # or any provider key from the table below
Bring any model
One line picks the provider — everything else stays identical:
Agent(model="anthropic:claude-opus-4-8") # or just "claude-opus-4-8"
Agent(model="openai:gpt-5.1") # or just "gpt-5.1"
Agent(model="gemini:gemini-2.5-flash")
Agent(model="groq:llama-3.3-70b-versatile")
Agent(model="zai:glm-4.6") # Z.ai / GLM ("glm:..." works too)
Agent(model="ollama:llama3.1") # local, no API key needed
Agent(model="vllm:Qwen/Qwen2.5-72B") # your own vLLM server
| Provider | Env var for the key | Notes |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY | native adapter |
| OpenAI | OPENAI_API_KEY | OPENAI_BASE_URL points it at any compatible proxy |
| Google Gemini | GEMINI_API_KEY | via Gemini's OpenAI-compatible endpoint |
| Groq | GROQ_API_KEY | |
| Z.ai (GLM) | ZAI_API_KEY | |
| Ollama | — (none) | local; OLLAMA_BASE_URL overrides http://localhost:11434/v1 |
| vLLM | VLLM_API_KEY (optional) | VLLM_BASE_URL overrides http://localhost:8000/v1 |
With no model= at all, Reins auto-detects from the environment in that table's
order. Every resolution failure tells you exactly what to set next.
The two verbs
Reins has exactly two entry points, and they are the safety model:
ask(goal)— the agent may only read. It never writes, never blocks, and never prompts. Use it for dashboards, search, analytics, and "what is…".run(goal)— the agent may read and write. Writes are detected automatically and gated for approval. Use it for "do something": create, update, refund, send.
Read/write classification is automatic and errs toward "write" when a name is ambiguous, so a wrong guess only ever adds a needless approval — it can never let a write slip through as a read. Override it explicitly when you know better:
@capability(reads=True)
def export_report(month: str) -> bytes: ...
@capability(destructive=True, confirm=True)
def deactivate_user(user_id: int) -> None: ...
Approvals: the human gate
When run() reaches a write that needs approval, it pauses and shows you exactly
what it wants to do before anything executes:
⚠ Reins wants to run a DESTRUCTIVE WRITE: refund_order(order_id=8842)
Approve? [y]es / [n]o / [s]how
[s]how reveals the unabridged calls and arguments as JSON. The gate fails
closed: denying, running headless (no terminal), or an approval handler that
crashes all mean the write does not run — and the attempt is recorded.
The terminal prompt is just the default. Plug in your own gate — any
request -> bool callable or an object with an approve method:
agent = Agent(
capabilities=[find_orders, refund_order],
approve=lambda request: request.bulk_count is None, # e.g. auto-deny bulk writes
)
Anything touching more than one row needs an explicit confirm at every
autonomy level — even for agents trusted to write freely (confirm_bulk=True
by default).
Identity, row-level security, and the audit trail
Tell the agent who it's acting for, and every capability knows it — your existing per-user logic keeps working, and one user's agent can never see another's rows:
from reins import Agent, Context, capability
@capability(reads=True, scope="user")
def list_my_orders(ctx: Context) -> list[dict]:
"""List the calling user's orders."""
return store.orders(user=ctx.principal) # scoped to the caller — RLS
agent = Agent(capabilities=[list_my_orders], principal="user:alice")
agent.ask("what did I order last week?") # ctx.principal == "user:alice"
agent.ask("…", principal="user:bob") # per-call override (e.g. per request)
A scope-annotated capability refuses to run if no principal is set — fail
closed, with a message telling you what to pass. And every write attempt — refused,
denied, approved, or executed — lands in a structured, PII-redacted audit trail:
for r in agent.audit.records:
print(r.timestamp, r.principal, r.decision, r.capability, r.arguments)
# 2026-07-03 … user:alice approved update_password {'user_id': 7, 'password': '[redacted]'}
# 2026-07-03 … user:alice executed update_password {'user_id': 7, 'password': '[redacted]'}
Plug in your own sink with Agent(audit=...) — if a write can't be audited, it
doesn't run.
Code-mode: perfect work, near-zero tokens
For anything beyond a trivial call, the agent doesn't ping-pong data through the model — it writes a short program that runs in a sandbox, calls your capabilities as plain functions, and prints back only the answer:
# what the model writes (and you can inspect):
overdue = find_orders(status="overdue")
print(f"{len(overdue)} overdue orders, {sum(r['total'] for r in overdue)} owed")
A thousand rows flow from your function into the sandbox, get aggregated there, and a single line returns to the model. Crucially, the sandbox isolates computation, never authority: every call a program makes passes the same policy → approval → audit → row-level-security chain as a direct call — a gated write pauses at your terminal even mid-program.
The default sandbox is a whitelisted-import subprocess (great for development; honestly labeled: not a hard security boundary). For production:
from reins import Agent, DockerSandbox
agent = Agent(capabilities=[...], sandbox=DockerSandbox()) # no network, read-only
agent = Agent(capabilities=[...], mode="simple") # or: no programs at all
Drop it into your web app
Add a chat endpoint to the app your users already log in to — and let their existing session decide what each of them can see:
from reins import Agent, endpoint
agent = Agent.from_orm(db, models=[Order, Invoice])
# a WSGI app: POST /ask runs read-only; identity comes from the live session
app.wsgi_app = endpoint( # Flask; FastAPI via WSGIMiddleware
agent,
identity=lambda req: req.cookies.get("user_id"), # your auth, reused
)
endpoint() is read-only by default (no write route exists at all). The
identity you pass flows straight into row-level security, so one user's chat can
never surface another's rows — no second auth system. There are native
reins.web.flask_blueprint(agent) and reins.web.fastapi_router(agent) too.
Drop the chat box on any page — one self-contained element, no build step:
from reins import chat_widget
page_html += chat_widget("/ask") # renders <reins-chat>, POSTs with your cookies
Scale without paying for it
Registered 10 capabilities or 10,000? The model's base context is byte-identical:
above a small threshold, Reins shows the model one search_capabilities tool instead
of every schema — it discovers just the operations it needs, which then become
directly callable. Attach a schema index and your data model works the same way:
from reins import Agent, SchemaIndex, TableInfo
agent = Agent(
capabilities=every_operation_in_your_app, # hundreds? fine.
schema=SchemaIndex(tables=(
TableInfo("orders", "Customer orders.", ("id", "status", "total")),
TableInfo("refunds", "Issued refunds.", ("id", "order_id", "amount")),
)),
)
agent.ask("how many refunds this week?")
# model: search_capabilities("refunds") → finds find_refunds → calls it. ~700 chars
# of base context — the same whether you registered 20 operations or 20,000.
Agent.from_orm(...) builds both the capabilities and this schema index from your
models automatically, so scale is free out of the box.
Never a black box
Ask what the agent just did and get a straight answer — the operations it found, the code it wrote, every call and its result, each approval decision:
agent.run("cancel order ORD-2")
print(agent.explain())
# ── reins trace ──
# outcome: executed · turns: 2
# ⚠ approval: update_order: approved (approval_required)
# • call: update_order(ref='ORD-2', status='cancelled')
# answer: Order ORD-2 has been cancelled.
reins ask <db-url> "…" --trace prints the same. Arguments are PII-redacted in
the trace, just like the audit log.
Reins vs. graph frameworks
| Aspect | Graph frameworks (LangChain / LangGraph) | Reins |
|---|---|---|
| Mental model | You draw a graph of nodes and edges | You expose functions; the agent finds the path |
| Control flow | Predefined by you | Decided by the model, within your guardrails |
| Adding it to an app | Wrap logic in framework primitives | Decorate functions you already have |
| CRUD on a database | Often raw SQL tools, or custom nodes | Calls your typed methods, inheriting your auth |
| Debuggability | Debug the framework's internals | Debug your own small loop and your own functions |
| Languages | Python-first | Python, Go, and TypeScript — one shared conformance suite |
Status
Reins is at its first Python alpha (0.1.0a1). Everything below works today:
typed capabilities derived from your functions or ORM, the ask() / run() safety
boundary, deterministic write policy with the autonomy ladder, the human approval
gate with previews and bulk confirm, a structured audit trail, identity propagation
with row-level scoping, code-mode in a sandbox, on-demand discovery, budgets, the
zero-code CLI, instant web integration, and seven model providers behind one
interface — all under a coverage-gated, mypy --strict build. APIs may change
before 1.0.
Roadmap
- Typed capabilities from your functions — schema and read/write classification
- The agent loop with
ask()/run()and a strict read-only boundary - Deterministic write policy and the autonomy ladder
- Human approval gate — previews,
[y]/[n]/[s]how, pluggableapprove=, bulk confirm - Structured audit log, identity propagation, and row-level scoping
- Any model: Anthropic, OpenAI, Gemini, Groq, Z.ai/GLM, Ollama, vLLM
- On-demand capability & schema discovery — constant context at any scale
- Code-mode execution — sandboxed programs, data never transits the model
- Budgets (turns/tokens/cost/time) and history compaction that keeps the goal
- Record / replay —
RecordingModel/ReplayModelcapture a run and re-run it offline, deterministically - SQLAlchemy and Django auto-exposure —
Agent.from_orm(...), zero capabilities - Zero-code CLI —
reins chat/ask/inspect <db-url>andfrom_module - Instant web integration —
reins.endpoint,<reins-chat>, session-identity → RLS - A flagship end-to-end example (FastAPI + SQLAlchemy, gated writes) —
make demo - Go package (
packages/go) — same verbs, passes the shared conformance suite; capabilities + classification + linter, theAsk/Runloop, full safety (policy/approval/audit/RLS), progressive disclosure, an OpenAI-compatible adapter for all providers above, GORMFromORM, and areins inspect|ask|chat <db-url>CLI. Remaining: a native Go code-mode sandbox. - TypeScript package (
packages/js) — same verbs, passes the shared conformance suite; the core types +Model/FakeModel, capabilities + classification + linter, the asyncask/runloop, full safety (policy/approval/audit/RLS), dual progressive disclosure, an OpenAI-compatible adapter for all providers above,fromDrizzle(auto-expose Drizzle models via the optionalreins/ormsubpath), areins inspect|ask|chat <db-url>CLI (zero-dep SQLite reflection vianode:sqlite), and code-mode (aWorkerSandboxdev tier — bridged calls gated like direct ones). Remaining:<reins-chat>.
Development
make setup # create a local venv, install the package and dev tools, set up pre-commit
make check # the gate: ruff + mypy --strict + tests + conformance
The Python package lives in packages/python. See CONTRIBUTING.md for
the workflow and conventions.
Go
The Go package (packages/go, module github.com/shamspias/reins/packages/go) mirrors
the Python verbs and passes the same conformance suite. The zero-code CLI works the same
way — point it at a SQLite database and it reflects the schema into intent-level
capabilities (no models to write):
go install github.com/shamspias/reins/packages/go/cmd/reins@latest
reins inspect ./app.db # list the capabilities Reins would expose (no key needed)
reins ask ./app.db "how many active customers?" # read-only answer
reins chat ./app.db --model groq:llama-3.3-70b-versatile
ask and chat are read-only (writes aren't even generated); inspect --write reveals
the gated create/update/delete. The model is resolved from --model (provider:model) or the
environment — the same seven providers as Python. In code:
model, _ := reins.ResolveModel("openai:gpt-4o") // or reins.DefaultModel() from env
// The input schema is reflected from RefundArgs; access is classified from the name.
refund := reins.Define[RefundArgs]("refund_order", "Refund an order by its id.",
func(ctx reins.Context, args map[string]any) (any, error) {
return refundOrder(args["order_id"])
})
agent, _ := reins.NewAgent(model, reins.WithCapabilities(refund))
res, _ := agent.Ask("how much did order 8842 cost?") // Ask never writes; Run gates writes
fmt.Println(res.Output.Text)
Run make go-check for the Go gate (gofmt + vet + tests). A native Go code-mode sandbox is
the one remaining piece.
Documentation
- QUICKSTART.md — the adoption ladder, rung by rung, all runnable.
- EXTENDING.md — swap in your own model, policy, approval gate, sandbox, or audit sink.
examples/fastapi_sqlalchemy/— a complete app (make demo, and a real FastAPI server).- SECURITY.md — the threat model and a production deployment checklist.
License
Files in the repo
- .github
- examples
- packages
- spec
- .gitignore
- .pre-commit-config.yaml
- CONTRIBUTING.md
- EXTENDING.md
- LICENSE
- Makefile
- QUICKSTART.md
- README.md
- SECURITY.md
Discussion (0)
Ask about usage, or say what you built with itSign in to join the discussion.
No comments yet. Be the first to say what this is good for.
More harnesses
from vibe coding to agentic engineering - practice makes claude perfect
🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
Practical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.
Git. Ship. Done - Core

The most RAM efficient harness