agent execution

One request. Many steps. One durable run.

Psych turns an agent request into work a Worker can execute, pause, recover, and inspect. Your application keeps control of where it runs and what it can reach.

the path a request takes

Two processes, one database.

The handler returns as soon as the Run is admitted. The Worker does the slow part in its own process, and the two share a Store and nothing else.

Three ports meet in one record logThe Psych mark drawn as a diagram. Its three prongs are labelled tools, model and store, the ports a consumer supplies. They stand on the shaft, labelled the record log, and everything read back out of a Run is a fold over that log.toolsmodelstorethe record logcode · http · mcp · a2aModelClientStorereport · status · answer · stream

one log per run

Three ports in. One log out.

You supply a model client, tools and a store. Psych folds what they do into one append-only log per Run, and everything you read back is derived from it.

The report, the live stream, the status a screen shows and the step a crashed workflow resumes from are all computed from that log. Nothing is stored twice, so no two reads disagree.

inside the package

What is yours, and what is Psych’s.

What to implement, and what to import. Dependencies point inward, and an import linter enforces it.

yours

your app

Routes, auth, cron, queue consumers. Turn a request into a Scope and call dispatch().

psych

psych_runtime

The whole public surface. Every type you can hold is exported here, and a test fails when one is not.

psych

runtime/

Worker, supervisor, Attempt, lease, agent loop, workflow engine, suspend, interrupts, subagents.

psych

tools/ model/

Per-turn resolution, access narrowing, the four tool executors, the model client, pricing, one egress seam.

psych

core/

Spec models, Version hashing, Record types, the pure reducer. No IO, no clock, no randomness.

yours

your infra

Store, BlobStore, Sandbox, Telemetry, SecretResolver, Policy. Ports, with adapters in the box.

the boundary

Left to your application, on purpose.

You already have each of these. A library that brought its own would argue with yours.

Not in PsychWhat it does instead
An HTTP server or any transportFunctions you call from your own routes.
Auth, users, orgs, rolesA Scope on every call and a Policy port you implement.
A database of its ownA Store port, four adapters, one contract suite.
A scheduler or timerYou call dispatch(). A Run waiting on a clock suspends as external.
A UIstatus() returns a serialisable RunStatus a screen can draw.
Prompt management, evalsInstructions and skills live in the Spec you version.
A vector store or retrievalNothing. You have one, and it belongs behind a tool.
Budgets and model routingMetering yes, enforcement no. Fallback models yes, a router no.