Psi is an AI coding agent harness built in Clojure. Inspired by pi-mono.
AI coding agents often contain a lot of built-in tools, behaviour and assumptions, which can be hard to override. They can also be hard to extend.
Psi treats the agent as an inspectable, programmable system rather than a fixed product:
- Extensions can completely customise the agent — built-in behaviour is deliberately minimal; extensions add tools, prompts, skills, and workflows.
- Everything is introspectable — runtime state is read through an EQL graph and changed through dispatched mutations, so you can query and drive the agent live.
- Deterministic and replayable — all changes flow through an event log; statecharts enforce valid transitions.
- AI-provider agnostic — providers are pluggable.
See doc/architecture.md for how these fit together.
Psi is developed with substantial AI-agent assistance, including its own agent. Review code and documentation before relying on them.
Psi is pre-1.0 and under active development. It is usable but not yet stable: interfaces, configuration, and behaviour may change between releases without a compatibility layer. Pin a specific release for reproducible environments.
- Java 22+ (Java 25 recommended) — the TUI requires the Java FFM API
- Babashka — for the launcher
Install the latest release:
bbin install org.hugoduncan/psi --as psi --mvn/version LATESTInstall a specific release (recommended for reproducible environments):
bbin install org.hugoduncan/psi --as psi --mvn/version 0.1.2123Check the installed version:
psi --version
# psi 0.1.2123Upgrade to the latest release:
bbin uninstall psi
bbin install org.hugoduncan/psi --as psi --mvn/version LATESTRepo-local / development alternative:
bbin install . --as psiReleases are tagged vMAJOR.MINOR.PATCH on the
releases page.
See CHANGELOG.md for what changed in each release.
Each release is also published to Clojars
as org.hugoduncan/psi. For launcher resolution strategy
(PSI_LAUNCHER_POLICY) and startup details, see doc/cli.md.
Then run psi directly:
# Bare console
psi
# Terminal UI
psi --tui
# RPC mode
psi --rpc-ednFor CLI flags, launcher-only flags, environment variables, and switch behavior, see:
For keybindings, rendering behavior, and reconnect semantics, see:
Frontend contributors: see
doc/emacs-ui-development.md.
For TUI login flow, in-session commands, and runtime behavior, see:
Interactive sessions support /model for model selection, /speed for provider
throughput-tier selection, and /effort for provider reasoning-effort override.
OpenAI catalog exposure and OpenAI OAuth runtime support are distinct: bare
gpt-5.6 remains catalog-selectable for non-OAuth/API-key OpenAI use, but
OpenAI OAuth-backed bare gpt-5.6 is unsupported until an evidenced
ChatGPT/Codex alias or alternate OAuth-compatible transport is added; gpt-5.5
and the gpt-5.6-sol/gpt-5.6-terra/gpt-5.6-luna variants remain on the
OAuth/ChatGPT Codex path. Named session profiles bundle reusable
model/thinking/speed/effort settings for interactive selection
(/session-profile) and workflow steps (:session-profile). Custom providers
are configured through models.edn; the documented examples include
DeepSeek's deepseek-v4-flash over its Anthropic-compatible endpoint. See
doc/tui.md, doc/configuration.md,
doc/custom-providers.md, and
doc/workflows.md.
Config file locations, precedence (session > project-local > project-shared > user > system), settings reference, runtime scoped setters, outbound model API proxy environment variables, and custom provider setup:
By default, retryable provider failures use exponential backoff within a configurable 10-minute total-time window rather than a fixed attempt cap. See Provider auto-retry policy for configuration and disable semantics.
read bash edit write psi-tool
psi-tool is the live runtime introspection/modification tool with canonical action-based requests:
query— EQL graph readseval— in-process ψ namespace-scoped Clojure evalmutate— invoke registered runtime mutations with structured success/error reportsreload-code— explicit namespace/worktree code reload with distinct reload and graph-refresh reportingproject-repl— managed project REPL status/start/attach/stop/eval/interrupt operations with structured reportsscheduler— delayed one-shot work via explicitcreate|list|cancel, including both delayed same-session prompts and delayed fresh top-level session creationoperation— list and invoke registered deterministic operations via explicitlist|invokeworkflow— inspect and manage workflow runs, includingcancel-runto stop in-flight delegated workflows; seedoc/workflows.mdfor cancellation/removal details
For direct project-local REPL support distinct from psi's own runtime nREPL, see:
For user-facing workflow usage, workflow file location, /delegate, reload
behavior, and workflow-run retention/cleanup behavior, see:
Project workflows include:
/delegate task-lifecycle <task>runs a Munera task through design → plan → implement → review → extract knowledge. UnresolvedSCOPE_QUESTION:items halt the lifecycle before plan creation. A blocked implementation is a clean human handback: the lifecycle stops before implementation review and knowledge extraction. Resolve the recorded required human action, then freshly re-invoke the workflow; seedoc/workflows.md./delegate reduce-incidental-complexityfor function/executable-unit incidental complexity and/delegate reduce-architectural-complexityfor namespace/family/pair/community architecture targets selected by Gordian.
When a failed child makes a parent delegate attempt execution-failed, authored
retry policy may supersede that attempt and let the parent step and workflow
succeed. If retries are exhausted and the parent delegate failure becomes
terminal, psi reports a bounded, safely redacted actionable cause when one is
available and otherwise retains the generic Delegated workflow failed
fallback. The failed attempt produces no accepted result. Completed workflow runs
are retained per originating session and older runs are cleaned up automatically;
retention is configurable. See
doc/workflows.md.
Extensions customise psi by adding tools, commands, event handlers, and UI.
Built-in extensions that ship with this repo (activated via
.psi/extensions.edn):
- auto-session-name — derive a session name automatically from early conversation context for top-level user-interactive sessions only; delegated workflow, workflow-step, nested workflow, and helper sessions are excluded.
- commit-checks — run project-local checks after a local commit and feed failures back into the session.
- context-manager — registers pre-turn turn augmenters:
project-contextand automaticentity-resolution(a bash-only local-model helper that injects aResolved entitiesblock); also runs a post-turn tooling-friction analyzer (fire-and-forget: auto-creates capped, dedupedmunera/open/NNN-slug/design.mdtooling/dependency-friction tasks in the analyzed session's worktree, excluding known helper/infra sessions). Seedoc/extensions.md. - dev-http — dev-time localhost HTTP side channel (
/dev-http,dev-present) for presenting markdown/tables/Vega/Mermaid/files/hiccup and choice prompts in a browser, with choices flowing back as user input. Seedoc/dev-http.md. - edit-clj — structural Clojure/EDN editing tool that replaces whole forms
by structural equality (
edit-clj). - mementum — git-based memory protocol: memories, knowledge, and
working-memory
state.md. - metrics — accumulate persistent per-capability usage counters (
/metrics). - munera — git-native Markdown task protocol (design → plan → implement →
review) under
munera/. - ramora — prompt-contribution extension that injects the Ramora protocol (lambda-form project knowledge organization) into the system prompt.
For the extension list, configuration, and authoring details, see:
The sections below cover extending psi, runtime introspection, and internals.
For extension-facing runtime/query details (including memory durability operations and mid-conversation system-message injection), see:
This includes the preferred workflow public-data display convention for workflow-backed extensions.
For the deps-shaped extensions.edn install model, launcher-owned startup basis construction,
concise psi-owned manifest syntax, apply semantics, and introspection fields, see:
For built-in extension docs (extensions/ per-project local roots), see:
Project-local extension/config examples in this repo include:
.psi/extensions.edn.psi/commit-checks.ednbb commit-check:rama-ccbb commit-check:file-lengths— scanscomponents/,bases/, andextensions/src//test/paths; legacy oversized extension files are ratcheted to fail if they growbb commit-check:dispatch-architecture
For architecture overview, components, EQL introspection guidance, and roadmap, see:
For the session-root graph discovery surface (:psi.graph/*), canonical
discovery workflow, and graph semantics, see:
For prompt lifecycle introspection summaries and normalized prompt-turn attrs, see:
Project query/config tool details, for query/mutate/reload examples and worktree-authoritative reload targeting rules, including the recommended self-reload loop:
For scheduler kinds, session-config support, status semantics, and introspection attrs:
for the deterministic-operation list/invoke request shapes, params,
all-key + 2000-char truncation rendering, and error surfacing (both the
psi-tool action and the /operations / /operation commands)
- pi-mono — inspiration
- charm.clj — TUI framework
- Fulcrologic statecharts
- Pathom3
- nucleus