Psi resolves configuration from multiple sources with a fixed precedence order. Higher sources win:
session (runtime, not persisted)
↑
project-local — <cwd>/.psi/project.local.edn
↑
project-shared — <cwd>/.psi/project.edn
↑
user — ~/.psi/agent/config.edn
↑
system (compiled-in defaults)
Session-level overrides are held in memory for the lifetime of the session and are not written to disk unless you specify a scope when setting them.
For custom provider/model definitions loaded from models.edn rather than the
session settings files documented below, see doc/custom-providers.md.
All config files use the same EDN shape:
{:version 1
:agent-session {}}
The :agent-session map holds the settings described below.
<cwd>/.psi/project.ednPer-project defaults intended to be shared and committed when you want the whole team to use the same defaults.
{:version 1
:agent-session {:model-provider "anthropic"
:model-id "claude-opus-4-8"
:thinking-level :medium
:speed-mode :normal
:effort-override nil
:prompt-mode :lambda
:nucleus-prelude-override nil}}
<cwd>/.psi/project.local.ednPer-project local overrides intended to remain uncommitted. This is the writable
project preference layer used by persisted project-scoped updates such as
/model and /thinking.
{:version 1
:agent-session {:model-provider "openai"
:model-id "gpt-5.3-codex"
:thinking-level :high}}
Effective project config is computed by deep-merging:
project.edn ← project.local.edn
That means:
~/.psi/agent/config.ednPersonal defaults that apply across all projects. Overridden by both project layers.
{:version 1
:agent-session {:model-provider "anthropic"
:model-id "claude-sonnet-4-6"
:thinking-level :off
:prompt-mode :lambda}}
| Key | Type | Default | Description |
|---|---|---|---|
:model-provider | string | — | Provider name: "anthropic" or "openai" |
:model-id | string | — | Model id string (e.g. "claude-sonnet-4-6") |
:thinking-level | keyword | :off | Extended thinking budget — see below |
:speed-mode | keyword | — | Optional throughput-tier override — :normal or :fast |
:effort-override | keyword or nil | — | Optional provider reasoning-effort override — :low, :medium, :high, :xhigh, or nil |
:prompt-mode | keyword | :lambda | System prompt style — :lambda or :prose |
:nucleus-prelude-override | string | — | Replace the nucleus prelude block in the system prompt |
:llm-stream-idle-timeout-ms | positive integer | 600000 | Milliseconds without provider stream progress before the backend aborts the run |
Both :model-provider and :model-id must be set together; a partial entry is
ignored and the next lower source is used instead.
Psi inherits outbound proxy settings for model API HTTP traffic from the process environment. There is no parallel proxy field in session config, project config, or custom provider definitions.
Supported environment variables:
HTTPS_PROXY / https_proxy — used for https://... model API URLsHTTP_PROXY / http_proxy — used for http://... model API URLsALL_PROXY / all_proxy — fallback when the scheme-specific variable is absentPrecedence rules:
ALL_PROXYSupported proxy URI schemes in this implementation:
http://https://socks://socks5://Proxy URIs must include both host and numeric port. Invalid or unsupported proxy URIs fail explicitly when psi prepares the provider request.
NO_PROXY / no_proxy is not currently supported for model API transport in
this implementation.
Examples:
# HTTPS model APIs through an HTTP proxy
export HTTPS_PROXY=http://proxy.example:8443
psi
# HTTP model APIs through a dedicated HTTP proxy
export HTTP_PROXY=http://proxy.example:8080
psi
# Shared fallback proxy, including SOCKS5
export ALL_PROXY=socks5://proxy.example:1080
psi
These environment variables affect the shared OpenAI and Anthropic transport paths used by built-in providers and by custom providers that reuse those same transport implementations.
:thinking-level values| Value | Meaning |
|---|---|
:off | No extended thinking (default) |
:minimal | Minimal budget |
:low | Low budget |
:medium | Medium budget |
:high | High budget |
:xhigh | Maximum budget |
The level is clamped to what the selected model supports. Models that do not
support reasoning ignore levels above :off. For Anthropic adaptive-thinking
models such as Claude Opus 4.7 and Claude Opus 4.8, :xhigh is distinct from
:high and sends the provider effort value "highest"; if the provider rejects
that preview value, psi surfaces the provider error without retrying as :high.
:speed-mode values| Value | Meaning | Provider mapping |
|---|---|---|
:normal | Provider default throughput tier | no native speed parameter |
:fast | Provider alternate throughput tier | Anthropic speed: "fast" with the fast-mode beta header; OpenAI chat-completions service_tier: "flex" |
:normal and a missing value both omit native provider speed parameters.
/speed normal session clears the session override; /speed normal project and
/speed normal user persist an explicit :normal mask at that scope. Speed mode
is session-transient on cold resume; persisted project/user config applies when a
new root session is created, not when a journal is resumed.
:effort-override values| Value | Meaning |
|---|---|
| nil | No override; derive effort from :thinking-level |
:low | Force low provider effort while thinking is enabled |
:medium | Force medium provider effort while thinking is enabled |
:high | Force high provider effort while thinking is enabled |
:xhigh | Force maximum psi effort; Anthropic adaptive models send "highest", OpenAI transports cap to "high" |
The effort override is only sent when thinking is enabled. /effort none clears
the in-memory override; /effort none project and /effort none user persist an
explicit nil mask at that scope. Effort override is session-transient on cold
resume; persisted project/user config applies when a new root session is created.
:prompt-mode values| Value | Meaning |
|---|---|
:lambda | Lambda-calculus compressed system prompt (default) |
:prose | Plain prose system prompt |
Settings can be changed at runtime via EQL mutations. Each setter accepts an
optional :scope keyword controlling where the change is persisted.
:scope | Persists to |
|---|---|
:session | Memory only — lost when session ends |
:project | <cwd>/.psi/project.local.edn |
:user | ~/.psi/agent/config.edn |
psi.extension/set-model;; runtime only
{:model {:provider :anthropic :id "claude-sonnet-4-6"} :scope :session}
;; save to project-local overrides (default when :scope is omitted)
{:model {:provider :anthropic :id "claude-sonnet-4-6"} :scope :project}
;; save to user config
{:model {:provider :anthropic :id "claude-sonnet-4-6"} :scope :user}
Default scope: :project.
psi.extension/set-thinking-level (via RPC set_thinking_level){:level :medium :scope :project}
Default scope: :project.
The interactive commands are:
/speed # show current effective speed mode
/speed fast # session-local alternate throughput tier
/speed normal project # persist explicit project default/provider default
/effort # show current effort override
/effort xhigh # session-local effort override
/effort none user # persist explicit user-level clear/mask
There is currently no extension EQL mutation named psi.extension/set-speed-mode
or psi.extension/set-effort-override. Use the interactive /speed and
/effort commands for these runtime settings; their optional scope arguments
use the same :session, :project, and :user meanings as model and thinking
settings.
psi.extension/set-prompt-mode{:mode :prose :scope :user}
Default scope: :session (prompt-mode changes are session-local unless you
explicitly persist them).
When psi resolves effective configuration for a session worktree, it:
~/.psi/agent/config.edn (user config — missing file is silently ignored)<cwd>/.psi/project.edn (shared project config — missing file is silently ignored)<cwd>/.psi/project.local.edn (local project config — missing file is silently ignored)At the project layer specifically, psi deep-merges:
shared project.edn ← local project.local.edn
Malformed project config files emit warnings and are ignored best-effort:
Effective precedence is:
session runtime overrides
> project local config
> project shared config
> user config
> system defaults
For model selection, that means project-local overrides beat project-shared committed defaults.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |