XDG Base Directories
Run PraisonAI on servers, containers, and CI with XDG-compliant config/data/state/cache paths
On fresh installs, PraisonAI honours XDG_{CONFIG,DATA,STATE,CACHE}_HOME so config, data, state, and cache can live on different volumes. Existing single-root installs (~/.praisonai/ or PRAISONAI_HOME) keep working unchanged.
Quick Start
- Default (existing installs, unchanged)
python from praisonaiagents import Agent agent = Agent(name="assistant", instructions="Be helpful.") agent.start("Hello") # Config, data, state, cache all stay under ~/.praisonai/ โ nothing to configure. - Split classes onto different volumes
bash export XDG_CONFIG_HOME=/etc/praisonai # config.yaml, credentials export XDG_DATA_HOME=/mnt/persistent/data # sessions, memory, knowledge, plugins export XDG_STATE_HOME=/var/lib/praisonai # MRU model, logs, spill export XDG_CACHE_HOME=/tmp/praisonai-cache # tmpfs is fine praisonai run "Summarise this repo" - Explicit single root (PRAISONAI_HOME) still wins
bash export PRAISONAI_HOME=/app/data praisonai run "..." # Every class stays under /app/data โ XDG is ignored.
Which directory does what?
Each class has its own purpose, precedence, and helper.
| Class | Purpose | Precedence (fresh install) | XDG fallback default | Helper |
|---|---|---|---|---|
| config | Editable config, credentials, rules | PRAISONAI_HOME โ existing single root โ $XDG_CONFIG_HOME/praisonai | ~/.config/praisonai | get_config_dir() |
| data | Sessions, memory, knowledge, plugins | PRAISONAI_HOME โ existing single root โ $XDG_DATA_HOME/praisonai | ~/.praisonai (branded default; only overridden when XDG_DATA_HOME is explicitly set) | get_data_dir() |
| state | MRU model, logs, session spill | PRAISONAI_HOME โ existing single root โ $XDG_STATE_HOME/praisonai | ~/.local/state/praisonai | get_state_dir() |
| cache | Disposable caches, transient indexes | PRAISONAI_HOME โ existing single root โ $XDG_CACHE_HOME/praisonai | ~/.cache/praisonai | get_cache_dir() |
How It Works
The single-root decision runs once, then per-class XDG dirs apply on a fresh install.
Behaviour notes:
- Back-compat is preserved. If
~/.praisonai/(or~/.praison/) already exists, orPRAISONAI_HOMEis set, every class stays under that single root. - The single-root decision is snapshotted once per process. If PraisonAI later creates
~/.praisonai/mid-run for data, config/state/cache do not retroactively move onto it. - Relative XDG paths are ignored, per spec.
XDG_CONFIG_HOME=relative/pathfalls back to~/.config/praisonai. get_session_spill_dir()now lives under<state>/state/session_spill/โ no longer under~/.praisonai/state/.get_config_path()now returns<config>/config.yamlโ no longer<data>/config.yaml.- Split state ends. MRU model recency now writes under the canonical state home, so
~/.praisonand~/.praisonaino longer disagree.
Configuration Options
| Variable | Type | Default | Description |
|---|---|---|---|
PRAISONAI_HOME | absolute path | unset | Explicit single root. Wins over everything else; every class stays under it. |
XDG_CONFIG_HOME | absolute path | ~/.config | Where get_config_dir() resolves on fresh installs. |
XDG_DATA_HOME | absolute path | ~/.praisonai (branded default) | Where get_data_dir() resolves on fresh installs. |
XDG_STATE_HOME | absolute path | ~/.local/state | Where get_state_dir() resolves on fresh installs. |
XDG_CACHE_HOME | absolute path | ~/.cache | Where get_cache_dir() resolves on fresh installs. |
Python API
from praisonaiagents.paths import (
get_config_dir, # NEW โ editable config, credentials, rules
get_data_dir, # sessions, memory, knowledge, plugins (XDG-aware)
get_state_dir, # NEW โ MRU model, logs, spill
get_cache_dir, # disposable caches (XDG-aware)
get_all_paths, # dict now includes "config_dir" and "state_dir"
)Common Patterns
Kubernetes
Mount a ConfigMap at $XDG_CONFIG_HOME, a PVC at $XDG_DATA_HOME, and an emptyDir at $XDG_CACHE_HOME.
export XDG_CONFIG_HOME=/config # ConfigMap (read-only)
export XDG_DATA_HOME=/data # PersistentVolumeClaim
export XDG_CACHE_HOME=/cache # emptyDirsystemd service
Set the directory directives and let systemd populate the XDG vars.
[Service]
ConfigurationDirectory=praisonai
StateDirectory=praisonai
CacheDirectory=praisonaiCI runners
Point state and cache at the workspace so logs and caches don’t leak into $HOME.
export XDG_STATE_HOME="$CI_WORKSPACE/state"
export XDG_CACHE_HOME="$CI_WORKSPACE/cache"Existing install
No action needed; ~/.praisonai/ continues to hold every class.
praisonai run "Nothing to configure"Best Practices
๐๏ธ Separate volumes by class
Back up $XDG_CONFIG_HOME/praisonai (small, precious); put $XDG_CACHE_HOME/praisonai on tmpfs (disposable); size $XDG_DATA_HOME/praisonai for session/memory growth.
๐งญ Use PRAISONAI_HOME when you want one directory
It short-circuits XDG entirely and keeps every class under one root.
๐งพ Check the resolved paths
Run praisonai paths show โ the output now includes config_dir and state_dir.
๐ซ Don't use relative XDG paths
Per spec they’re ignored and the default applies.