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-sonnet-4-6"
:thinking-level :medium
: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 |
: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.
: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.
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 |