session command manages conversation sessions, allowing you to save, resume, and organize multi-turn interactions.
Every sub-command (list, resume, show, delete, export, share, unshare) and every --continue / --session <id> flag resolves the same session by the same id through a single resolver.
Quick Start

Commands
Start a Session
List Sessions
identity: tag showing which resolver was used (see Project Sessions → How It Works).
Sessions that have not yet accumulated any usage show - in the Tokens and Cost columns.
Updated columns (praisonaiagents 1.6.85+): The table now shows
ID | Name | Status | Events | Tokens | Cost | Parent | Updated. Tokens are formatted with thousands separators (e.g. 12,345); Cost is formatted as $0.0140. Sessions with no recorded usage show - for both. The Parent column shows an 8-character parent id prefix for a forked session, or - for a root session.--json to get machine-readable output with usage data per session:
session list (no --project, no --all) merges the current project’s session store with the global default store — every session --continue/resume could see, in one list, deduped by session id (freshest updated_at wins when the same id lives in both stores). Use --all to include every project’s sessions, or --project <id> to restrict to one project’s store only. Cross-store merge landed with the fix for PraisonAI #2655.What shows up
Without--all or --project, the default listing surfaces:
- Sessions created by
praisonai run(project store) ✅ - Sessions created by
chat,code, gateway, TUI, API, or a bareAgent(memory={"session_id": "..."})(global default store) ✅ new - Sub-agent / forked child sessions still appear here (with their parent shown in the Parent column), but
--continueskips them in favour of the last root session.
--project <id> stays project-scoped only; --all widens to every project.
Token / Cost columns
TheTokens and Cost columns show cumulative totals across all runs for each session. Totals are persisted in session-store metadata under usage and updated automatically by praisonai run / direct prompts whenever --session is set or a default project session is active. A - is rendered when no usage has been recorded yet.
JSON output (--json):
Rename a Session
session rename gives a session a human-readable title so session list reads like a menu of tasks instead of an agent name or message snippet. The title is display-only metadata — the session id never changes. See Session Rename for the full feature page.
Clear a previously set title by passing an empty string:
Failed to rename session: <id> and also exits 1.
JSON output — pass the global --json flag for a machine-readable result instead of the human-readable line:
session list displays a title using this order (_session_title()):
- The explicit stored title, if set
- The agent name
- A message snippet
Any id that
resolve_session accepts is renameable — including legacy-only sessions listed in session list but not yet migrated to the canonical store. The canonical store stores the title in metadata["title"]; the legacy fallback (SessionManager.rename) persists it in metadata["name"]. Both paths persist so any id you can list, resume, show, delete, or export can also be renamed. Renaming is currently CLI-only — there is no /rename bot chat command. Titles set here surface in session list and every resolver-backed sub-command. See Bot Commands for the chat-side command set.Fork a Session
session fork copies a saved session into a new child session, keeping both timelines resumable. It mirrors praisonai run --fork but works on any saved session without entering the REPL. See Session Forking for the full feature page, including the interactive /branch command.
An unknown id exits 1 with the same remediation text as the other session commands:
--at-message is rejected up front (no silent slice wrap):
--json flag for a machine-readable result:
from_message_index and title are null when not passed.
Resume a Session
session resume restores chat history, model, and agent name from a previous session.
History is preserved by default via compact retention — older turns are summarised and archived rather than dropped. See Session Persistence — Retention Policies.
Usage: line shows cumulative tokens and cost accumulated across all previous prompts in this session. If no usage has been recorded yet, the line is omitted.
Resume and continue with a prompt
praisonai run --session <id> path. The resume panel is suppressed when a prompt is provided — the run pipeline emits the only top-level output.
Show transcript only (legacy view)
--transcript to inspect a session without restoring state. The panel title shows “Session Transcript”.
Cross-store lookup
session resume finds a session whether it was created via praisonai run --continue (project store) or via the gateway/TUI (global store). See Storage Backends.
When you pass a continuation prompt, the resume panel is suppressed — the run pipeline emits the only top-level output. To inspect a session without continuing, use
--transcript or omit the prompt.Cost & Token Tracking
PraisonAI accumulates input/output/cached tokens and dollar cost on every session run, so you can see exactly what a conversation has spent.Quick Start
1
Run with a session
2
Check cumulative usage
3
Continue — totals keep accumulating
What gets persisted
Each session stores ausage object in its metadata:
The persisted
total_tokens and cost fields are exactly what praisonai usage aggregates across sessions by day, model, or project.
Footer format
After each prompt run with an active session, the CLI prints:"{input:,} in / {output:,} out · ${cost:.4f}" — locale-formatted integers, 4-decimal cost. The footer is suppressed in --json mode but usage is still persisted.
Resume behaviour
Totals are rehydrated on--continue / --session <id> and keep accumulating — they do not reset. The resume panel shows a usage summary line:
How it works
Reading usage programmatically
Notes
Best-effort — never breaks a run
Best-effort — never breaks a run
Any failure (pricing lookup, persistence error, missing collector) leaves the session untouched. Usage accounting never breaks a run.
Multi-model aware
Multi-model aware
When a run uses more than one model, each model’s tokens are priced individually with
get_pricing(model_name).Cached tokens tracked separately
Cached tokens tracked separately
Provider-reported cached reads are accumulated in
cached_tokens but excluded from cost — the provider already discounts them.Show Session Details
session show resolves against the same stores as list / resume, so any id you can list or resume is also showable.
session show now resolves through the same shared session resolver as list / resume, so its output includes the persisted agent, model, created / updated times, and message count for the resolved session.
Identity invariant (praisonai #3133): any id shown by
praisonai session list — or resumable via praisonai run --continue — can be inspected with session show, exported with session export, and deleted with session delete using the same id. There is no hidden second store: show / delete / export now route through the same DefaultSessionStore (project-scoped + global) that list / resume use, so id → session is unambiguous. praisonai/PraisonAI#3201 made this an invariant by construction: both the list-path and the show/delete/export-path now delegate to a single canonical_cli_stores() helper, and a regression test asserts they enumerate identical store instances.Show a Read-Only Recap
Render a “where were we” block instead of raw session details. Non-destructive — never modifies the session or triggers compaction.Session Recap panel:
--json flag for structured output:
/recap bot chat command — same read-only recap, surfaced from the terminal.
Hand off a Session (Continuation Prompt)
Assemble a self-contained continuation prompt from durable state — recap describes where we were; handoff is a prompt a fresh context can act on.Session Handoff panel:
--json flag for structured output:
Export a Session
session export resolves the id through the same shared resolver, so an id from session list always exports the same session — with a legacy-store fallback for legacy-only ids.
Delete a Session
Delete targets the single canonical store that owns the id — a project-scopedsession delete never removes an unrelated same-id session that lives only in the global store.
--yes / -y:
Legacy
SessionManager sessions created before 2026-07-17 are also swept on delete, so a duplicate legacy record can’t resurface a session you already deleted.Export a Session
session export writes a resolved session as markdown (default) or JSON.
--output is set, the CLI writes the file and prints:
The interactive
/export slash command uses this same renderer — when a session id resolves, the REPL’s /export [file] is byte-for-byte identical to praisonai session export <id>. It falls back to the in-memory transcript when no session is persisted yet, so /export works without --session.
Legacy-only sessions fall back to the
SessionManager exporter automatically — and legacy sessions also honour --sanitise now, so a raw transcript is never leaked through the fallback (see Sanitise before sharing).
Sanitise before sharing
praisonai session export <id> --sanitise (alias --sanitize) redacts secrets, absolute file paths, the working directory, and file contents embedded in tool I/O — replacing them with stable [redacted:<category>:<n>] placeholders — so a session is safe to paste into a bug report, share with a teammate, or attach to an audit trail. The default export (no flag) is byte-for-byte unchanged; sanitisation is strictly opt-in.
[redacted:<category>:<n>], where the same source value maps to the same placeholder within one export — so the reader still follows which value recurs where, without ever seeing it.
[redacted:path:1] three times, not :1, :2, :3.
Redaction levels.
An unknown value is rejected up front (exit 1):
The redactor is a small, self-contained helper (
praisonai_code/cli/state/redact.py, stdlib only — no new dependencies). It reuses praisonaiagents.secrets when available, so any value registered via the process-wide secret registry is masked first, even if it does not match a built-in token shape.Legacy
SessionManager sessions (created before 2026-07-17) also honour --sanitise — they used to return a raw verbatim transcript ignoring the flag, a secret-leak gap closed by praisonai/PraisonAI#3434.To hand a redacted transcript straight to someone, use
session share instead — it runs this same redactor, wraps the result in a self-contained HTML file, and returns a file:// link, so there’s no manual export --sanitise > out.md plus attach step.Share a Session
session share publishes a redacted, read-only HTML transcript to ~/.praisonai/shares/ and returns a file:// link — no external service or dependency.
share resolves session_id through the same shared resolver as list / resume / show / export (project store first, then global default store, then a best-effort legacy SessionManager fallback for pre-2026-07-17 ids), then calls export_session(session_id, format="md", redact=True, redact_level=<level>). Sharing is always redacted — there is intentionally no --no-redact escape hatch. The redacted Markdown is wrapped in a single self-contained HTML file (inline CSS, no external assets), with the transcript inserted via html.escape inside a <pre> block so no session text can be interpreted as markup.
Expected Output:
--json for a machine-readable link and on-disk path:
.html file lands under the canonical data home alongside sessions/, so shares never split across a second home root:
sha256(id)[:16] — a stable per-session path. Re-sharing the same id overwrites the same file, and the write is atomic: the HTML is written to a sibling temp file, then os.replace() swaps it in, so a failed or interrupted write never truncates a previously published transcript. On an OSError the temp file is cleaned up and the command exits non-zero.
The shared file is a plain
file:// link on the local filesystem. It is not uploaded to any server — only people who can read ~/.praisonai/shares/ (or receive the file itself) can open it. To share externally, attach or upload the file separately.The
.html filename is sha256(id)[:16], not the session id — so ids containing /, .., or shell metacharacters are safe on every filesystem.Unshare a Session
session unshare revokes a previously published transcript by deleting the shared HTML file.
unshare resolves the shared path deterministically via the same sha256(id)[:16] mapping — no session lookup — so it works even if the underlying session has since been deleted. A missing file is a clean no-op, not an error, so the command is idempotent and safe to script. A real OSError (permission denied, disk error) exits 1 with an actionable message.
Expected Output (a file was removed):
revoked: false means nothing was there to revoke — not that the operation failed.
unshare on a session that was never shared is a clean no-op, not an error. Safe to script.Related
- Sanitise before sharing — the underlying redactor is shared;
share=export --sanitise+ HTML wrap + atomic publish. Samestandardvsstricttable. - List sessions — how to find the id to share.
- Upstream: PraisonAI issue #3590, commits
9c27592+cdd41eb.
Import a Session
session import reads a previously-exported JSON file and prints the resulting id.
Only JSON files are accepted. The imported id is printed and can then be resumed with
praisonai --continue or praisonai session resume.Help
Token and Cost Tracking
Every session accumulates cumulative token usage and cost across all prompts, visible insession list and the resume panel.
After each run, a single-line footer is printed:
·). The footer reflects cumulative totals since session start, not just the last prompt. It is silently suppressed in JSON mode (--json / --output json) — there is no --no-usage flag.
When you resume a session, the cumulative totals are rehydrated so subsequent prompts keep accumulating:
Working with praisonai run
The same project-scoped store powers --continue and --session on praisonai run. As of PR #1963, every surface restores history from and saves to this store:
As of the fix for issue #2700, the actions-mode row is fully honoured for
--auto-save, --session, --continue, and --fork. If you hit a TypeError about auto_save on an older praisonai-code build, upgrade and retry — see the run.mdx troubleshooting section.
As of PR #2277, --session <id> and --continue now persist model and agent_name into session metadata so a later session resume reproduces the same configuration deterministically. For advanced programmatic use, the rehydrate_session helper in praisonai.cli.session returns a RehydratedSession with session_id, chat_history, model, agent_name, metadata, and found fields — see the SDK reference for details.
Using Sessions with Prompts
Continue a Conversation
Session with Other Features
Use Cases
Project-Based Conversations
Learning Sessions
Code Review Sessions
Auto-Save Sessions
Automatically save sessions after each agent run using the--auto-save flag:
Python API
History in Context
Load conversation history from previous sessions into the current context:Python API
Workflow Checkpoints
Save and resume workflow execution at any step:Checkpoint Storage
Project-Scoped Sessions
Sessions are automatically scoped to your current project. PraisonAI detects your project by finding the git repository root, or uses the current working directory as a fallback. Project identification:- Project ID: First 8 characters of SHA256 hash of project root path
- Git detection: Uses
git rev-parse --show-toplevelwith 5-second timeout - Fallback: Current working directory if not in a git repository
Session Storage
Sessions are stored in a project-scoped layout when using the default behavior:--all flag:
Storage Backend Options
Store sessions in different backends for production deployments:When
--storage-path is omitted, --storage-backend file writes to ~/.praisonai/sessions/ and --storage-backend sqlite writes to ~/.praisonai/sessions.db (both under the canonical ~/.praisonai/ data home). Prior releases anchored these defaults under ~/.praison/ — any existing sessions there are still readable via the same code paths, but new sessions land under the canonical root. See praisonai/PraisonAI#3203.Concurrent Sessions
Multiplepraisonai processes can safely share the same session — the CLI store reloads, merges, and writes under an exclusive lock so no messages are lost when the TUI, --interactive mode, and praisonai "…" --session all touch the same file.
Merge Strategy
When two writers race, the session store merges their changes:Lost-Update Prevention
praisonai session show and praisonai session resume always reflect the latest on-disk state — the in-process cache is invalidated automatically when another process writes (mtime-based check).
This concurrent-save safety was added in PR #1854. For the equivalent feature in the SDK-level store, see Multi-Process Safety.
This applies to the default file-backed session store. The
sqlite / redis:// backends in the Storage Backend Options table above handle concurrency via the database itself; the CLI does not add its own merge layer there.How Session IDs Resolve
Everysession sub-command and every --continue / --session <id> flag resolves the same session by the same id through a single session_resolver.
Session Identity
show, delete, and export now read the same project-scoped + global DefaultSessionStore that list, resume, and --continue already use — so any id you can list or resume is also showable, deletable, and exportable by the same id.
Delete targets the single store that owns the id and honours that store’s confirmation — an I/O failure exits non-zero instead of reporting a fake success. The legacy store is always swept so a shadow record can’t resurface a deleted session.
Cross-Platform Support
Thepraisonai session commands work on Windows, macOS, and Linux — file locking is automatic and platform-appropriate.
On Windows, sessions are stored under
%USERPROFILE%\.praisonai\sessions\{session_id}.json following the OS convention via Path.home(). (Legacy pre-canonical installs may still read from %USERPROFILE%\.praison\sessions\ as a fallback — see Storage Paths.) The same directory is shared by praisonai code, praisonai run, and the gateway/TUI, so a session written by one surface is readable by the others. Cross-platform locking was added in PR #1837. Concurrent multi-process writes (e.g. TUI + praisonai --interactive sharing the same session directory) are preserved without message loss as of PR #1885 and PR #1892. For the SDK-level session store with the same cross-platform guarantees, see Session Persistence.
Example usage across platforms:
Best Practices
Naming
Use descriptive names like
project-auth-featureOrganization
Create separate sessions for different projects
Cleanup
Delete old sessions to free up storage
Context
Start new sessions when changing topics significantly
Related
Run Command
Session flags and usage footer for
praisonai runSession Persistence
SDK-level session management
Session Forking
Fork mid-session with
/branch or session forkCost Tracking
Per-session persistence and
/cost slash commandProject Sessions
Persisted usage shape and project scoping
Usage
Aggregate token and cost reporting across all sessions

