Psyche — a machine for agentic minds

Talk agents into existence.

The runtime ships today. The conversation is where it goes. A Rust core holds the invariants. You author in a handful of Python decorators. State lives on one plane — and the dashboard breathes with it.

rust core · python authoring · frozen json-rpc/a2a wire · 320-test proof gate

psyche — ~/fairloom/greeter
Today you write the right pane yourself — the distance between these two panes is the roadmap.
you · intent.txt north star
I want a greeter.
It should welcome guests by name,
think with a big open model,
and show me everything it does —
live, in a real UI.
# that's it. that's the spec.
psyche · greeter.py shipping today
# psyche serves the nodeai.api surface — drop-in
from nodeai.api import Agent, tool, brain
@tool(["Greeter"])
def greet(self: Agent, name: str):
"""Greet a guest by name."""
return f"Hello, {name}!"
@brain(["Greeter"])
def greeter_brain():
return {"client": {"provider": "openrouter",
"model_name": "openai/gpt-oss-120b"}}
$ psyche run greeter
create_app ............ ok
wire mounted .......... json-rpc / a2a (frozen)
healthz ............... 200
proof gate ............ 320 passed · 0 failed
greeter ............... awake → dashboard on :8010
status
awake
box · greetings
3
last reply
"Hello, Ada!"
 shipping today north star — not shipped yet @tool · @brain · @box · @store 320/320 tests ✓ Aristotle — the shipped example ↓ GitHub →
How it works shipping today

From a handful of decorators to a running mind.

One system end to end. No glue services, no second state store, no separate UI backend to keep in sync.

01

@tool + @brain Egg

Author the surface in Python decorators. Typed args, docstring contracts, requires_confirmation on anything that matters.

02

create_app Larva

create_app serves your agent over the frozen JSON-RPC/A2A wire. Dashboards, CLIs, and sibling agents all speak the same frames.

03

State in boxes Chrysalis

@box state persists and streams — one shared plane, no cache layer, no drift. @store memory survives restarts.

04

The UI breathes Butterfly

The TypeScript SDK renders box-driven widgets and a full dashboard shell. The agent writes a box; every subscribed widget updates live.

The box plane — the signature primitive shipping today

State that renders. UI that remembers.

An agent writes a box — a typed piece of its own state. That single write is both the persistence layer and the UI update. Try it: this demo is the actual pattern, miniaturized.

agent · a @tool body
self.box("ui/state", {"mood": "curious"})
dashboard · MoodWidget
curious
boxes ▸ ui/state · live · 0 writes this visit
  • boxes ▸ ui/state ← { mood: "curious" } — persisted · 1 widget re-rendered
The runtime surface shipping today

Everything an agent product needs, in one runtime.

Eight things you stop building yourself the day you adopt Psyche. All shipped, all behind the proof gate, all one system.

Signature
self.box(…)Guests today42

Boxes — the box plane

One shared plane where agent state persists and the UI updates live. The agent writes a box; the dashboard breathes. No cache layer, no websocket glue, no drift.

tool: pay_invoiceHELD — asks first

Confirmation gates

requires_confirmation → destructiveHint. Important actions pause for a human. A typed property of the tool — not a prompt you hope the model respects.

"just send it" TYPED ✓

Typed tools

Docstrings become schemas; envelopes are validated at the wire. Malformed intent never reaches your functions.

openrouter/gpt-oss-120bswap the model, keep the mind

Brains

A brain is config, not plumbing. Point at any provider; swap models without touching a single tool.

process exits …memory intact ✓

Stores

@store memory survives restarts, model swaps — and, one day, bodies.

AB

Sub-agent delegation

get_mind() is one line. Each sub-agent has its own tools, brain, and boundaries.

frozen
agentJSON-RPC / A2Aui

The frozen wire

A stable protocol between runtime and clients. Build UIs against it once; it doesn’t move under you.

Widgets + dashboard

The TypeScript UI SDK ships box-driven widgets and a full agent dashboard shell. Real product UI, not a debug console.

And every tier is a plugin registry you can extend — @brain_type · @loop_type · @storage_type. Write your own Claude Code loop plugin, your own S3 store, a decentralized-compute brain: a decorator and a duck-typed contract register it by name. No core changes, no forks.

The shipped example shipping today

Meet Aristotle. He’s alive in the repo.

A small survival sim played by a real LLM through psyche tools: vitals that drift, a clickable world map, a 3D avatar, a live dashboard. He is not a mock-up — he’s the runtime demonstrating itself. Every pane below is the product surface: boxes rendered as widgets.

0 · vitals — @box, livet+0
health82
hunger41
energy67
mood → curious · the map keeps not ending
last write · boxes ▸ vitals · 11msnext decision · t+2
1 · world — click a tile to send him(6,4)
2 · tail -f thoughts.log
  • hunger is a curve, not an event. eat before the curve wins.
  • the west pool is water. remembering that.
3 · wire — last frames
  • → tools/call look_around {}
  • ← receipt #291 ok · 4 tiles noted
[psyche]0:vitals1:world2:thoughts3:wire aristotle: curious · up 00:00 · 320/320 ✓
or click the map — operator pings become tools/call frames

This embed is a simulation of the shipped example — run the real one: docs tutorial 01. 3D avatar included.

Models propose. Typed systems enforce.

Trust rails shipping today

Natural language is intent, not authority.

The model’s words never touch your systems directly. Between intent and action sits a typed envelope, a gate, and a receipt.

What the model says

“Sure — the invoice checks out, so I’ll go ahead and pay the $1,200 to ACME now and let you know once it’s done…”

Fluent. Confident. And on its own — just text.

What the wire enforces

{ "jsonrpc": "2.0", "id": 7,
  "method": "tools/call",
  "params": {
    "name": "pay_invoice",
    "arguments": { "invoice_id": "ACME-0142",
                   "amount_usd": 1200 } } }
Held by your gate — the runtime delivered a typed envelope, not money
the-moment-of-consequence.diff
# what the model said
- "Done! I paid the $1,200 ACME invoice and archived it."
# what the runtime allowed
+ envelope : pay_invoice { invoice_id: "ACME-0142", amount_usd: 1200 }
+ gate : requires_confirmation = true → your tool HOLDS it — typed, on the envelope, not a prompt
+ receipt : #1042 · nothing paid · a person decides
requires_confirmation → destructiveHint — the gate ladder runs before any side effect, and every consequential action leaves a receipt. By design, psyche ships no signing primitive: money-grade logic lives inside tools you own, behind permissions and approvals.
Migration north star — aimed, not shipped

Metamorphosis is the roadmap.

Everything above this line ships today. Everything below it is where we’re aimed. First, why the machine is named what it is.

Once, Zhuang Zhou dreamed he was a butterfly

vividly a butterfly,

fluttering, wandering, going where it wished,

content in its own delight,

not knowing Zhou.

Suddenly he woke,

and there he was: Zhou, startled into himself.

But he did not know

whether Zhou had dreamed the butterfly,

or the butterfly was dreaming Zhou.

Between Zhou and butterfly

there must be some distinction.

This is called

the transformation of things.

— Zhuang Zi

● Now · shipping

The chrysalis is built.

  • Rust core — typed invariants under everything the model touches
  • Python authoring — @tool · @brain · @box · @store
  • Frozen wire + TS UI SDK — JSON-RPC/A2A, box widgets, dashboard shell
  • Delegation + gates — get_mind(), requires_confirmation → destructiveHint
  • Aristotle + the 320-test proof gate — the shipped example, exact count enforced
◌ North star · vision, not shipped

Then the wings.

  • Talk agents into existence — a conversational builder turns plain-language intent into a full agent spec: role, tools, permissions, boundaries, tests, UI.
  • Local specialists from rewarded use — psyche distills the repeated skill into a narrow local model; the big model stays teacher and fallback.
  • Embodiment — the same persistent mind later inhabits VR characters and robot bodies, every action an explicit typed tool behind harder gates.
describeclarify boundariesbuild the speclaunch · inspect · teach

ψυχή is also the Greek word for butterfly.

The Fairloom thesis →

Where Psyche sits

Orchestration frameworks run graphs.
Psyche runs products.

LangGraph, CrewAI and Microsoft’s Agent Framework are excellent at what they aim for: orchestrating model calls. Psyche’s bet is the layer they stop at — everything an agent needs to be a product. It isn’t either/or: whole frameworks run inside Psyche as loop plugins — a LangGraph plugin ships today, with Claude Code and Codex terminal plugins next.

CapabilityLangGraph · CrewAI · MS Agent FrameworkPsyche
Persistent state planecheckpoints & memory add-ons✓ the box plane — state is the live UI
Product UI out of the boxbring your own frontend✓ TS SDK: box-driven widgets + dashboard shell
Confirmation-gated toolsDIY per project✓ typed: requires_confirmation → destructiveHint
Sub-agent delegationgraphs & crews✓ get_mind() — one line, own tools and boundaries
Stable client protocollibrary APIs move release to release✓ frozen JSON-RPC / A2A wire
Money-grade safety postureout of scope✓ gates, receipts, no server-side signing by design

If you need a graph executor inside a bigger system, those are strong choices — and they still work here. If you’re shipping an agentic product — state, UI, safety and all — that’s what Psyche is for.

the chrysalis in the corner just opened — your move

This is called the transformation of things.

Clone the repo, run Aristotle, and author your own agent in a handful of decorators before your coffee cools.

Backing the long arc instead? The Fairloom thesis →