Skip to main content

Interactive TUI

PraisonAI CLI provides a rich interactive terminal user interface (TUI) for seamless AI-assisted coding sessions. Inspired by Gemini CLI, Codex CLI, and Claude Code, it offers real token streaming, built-in tools, and a clean terminal experience.

Overview

The Interactive TUI provides:
  • Real token streaming - Model deltas rendered as they arrive, real time-to-first-token
  • Built-in tools - File operations, shell commands, web search
  • Slash commands - /help, /model, /stats, /compact, /undo, /queue, /git-status, /map, and more
  • @file mentions - Include file content with @file.txt syntax
  • Shell escape - !cmd runs a shell command inline (gated by PRAISONAI_ALLOW_SHELL); !!cmd also attaches the output as context for the next prompt. See Shell Escape.
  • Message queuing - Queue messages while agent is processing
  • Model switching - Change models on-the-fly with /model
  • Token tracking - Monitor usage and costs with /stats
  • Context compression - Compact chat_history with /compact (auto-runs at the turn boundary)
  • Undo/revert - roll files + conversation back with /undo (last turn) and /revert [n] (last n turns) — on by default
  • Queue management - View and manage queued messages with /queue
  • Profiling - Measure response times with /profile
  • Tool status indicators - See when tools are being used
  • Clean UX - No cluttered panels, just streaming text

Streaming

The interactive CLI consumes real token streaming from agent.iter_stream() — every chunk you see is a live model delta, rendered as it arrives, giving you real time-to-first-token instead of a finished string replayed word-by-word.
If a provider does not support streaming, the CLI transparently falls back to a single non-streamed agent.chat() response — the answer still arrives, just as one block. No configuration required.
For interactive coding, prefer a provider whose OpenAI-compatible endpoint streams (openai, anthropic, gemini, most LiteLLM providers) — you will see real time-to-first-token. See Streaming for the SDK-level API and provider coverage.

Verbose Mode Order

In verbose mode the Q: / A: header prints on the first streamed delta, the body streams in live, and the completion line renders only after the streamed body finishes:
The completion line never appears before the answer, and no leading word-replay precedes the streamed body.

Multi-step (tool-using) turns

When a turn uses tools, each LLM step in the loop streams its narrative into the same live assistant message as it completes — you see the model’s reasoning between tool calls appear immediately, instead of waiting for the whole turn to finish.
The primary TUI consumes the existing llm_content display callback that the core (praisonaiagents/llm/llm.py) emits per LLM step — no new API surface, no configuration.
The live message becomes the finalised turn — no duplicate assistant message is appended, so /undo, /revert, and conversation history behave exactly as before. Read-only review turns keep their single-summary behaviour (spinner-only during work) and do not stream intermediate narrative.

Quick Start

Chat Mode (Non-Interactive Testing)

For testing and scripting, use --chat (or praisonai chat) to run a single prompt with interactive-style output:
--chat is different from praisonai chat which starts a web-based Chainlit UI. The praisonai chat flag is an alias for backward compatibility.

Built-in Tools

Interactive mode comes with 13 built-in tools across 3 groups:

ACP Tools (Agentic Change Plan)

LSP Tools (Code Intelligence)

Basic Tools

Launching with a resumed session

As of PR #4912, you can jump straight back into the interactive TUI with a prior session already restored — no need to launch cold and type /continue:
On launch, the TUI:
  1. Resolves the target session id via the same ProjectSessionStore / find_last_session / session_exists_anywhere path that run --continue / run --session uses.
  2. Restores the recorded session model so the resumed launch continues on the original provider, not the current default.
  3. Replays the prior transcript into scrollback using the same renderer as the in-TUI /continue command.
  4. Wires the primary agent to the resumed session’s store — a follow-up prompt is answered with the restored conversation context, not just after redisplaying it.
If any of this fails, the launch degrades to a fresh session rather than aborting. The no-flag path (praisonai) is byte-identical to previous versions.

Automatic session persistence

As of PR #4943, every interactive conversation is auto-saved from the first turn — no --auto-save flag required. Each completed turn is written to the UnifiedSessionStore, so /sessions lists it and /continue can resume it, even on a fresh install where you have never passed a save flag before. A first-ever session can now become a session to resume. This applies to both interactive paths: the rich prompt_toolkit TUI and the plain-terminal fallback (used when prompt_toolkit is unavailable). Previously the default interactive path never wrote to the store, so /sessions always answered No saved sessions found. and /continue had nothing to continue.
The --auto-save flag is still relevant for non-interactive praisonai "<prompt>" runs. The interactive TUI persists by default and ignores the flag.

Slash Commands

As of PR #4943, /clear, /new, /import, and /continue all round-trip through the agent, not just the screen. They share the same persist + rebuild path, so after any of them the model’s conversation memory matches what you see. Previously /clear / /new cleared only the transcript while the agent kept the pre-clear context, and /import printed Imported N messages but answered as if none had been loaded.

@File Mentions

Include file content directly in your prompts using @ syntax, inspired by Gemini CLI and Claude Code. @file and @dir mentions submit through the same expansion path as the legacy REPL — the file’s contents are inlined before the prompt reaches the model on every surface.
  • Files larger than 50KB are automatically truncated
  • Hidden files and common ignore patterns (node_modules, pycache) are filtered from directory listings
  • Paths can be relative or absolute
  • Use ~ for home directory (e.g., @~/Documents/file.txt)

Shell Escape

Run a shell command inline with the ! prefix — no model turn is spent. !!cmd also attaches the output as context for your next prompt.
Gated by PRAISONAI_ALLOW_SHELL (default off). See Shell Escape for configuration, safety limits, and failure behaviour.

Model Switching

Change models on-the-fly without restarting:

Session Statistics

Track token usage and estimated costs:
Use /stats regularly to monitor your token usage and avoid unexpected costs.
/stats and /cost are the same output in the async TUI — one renderer, two names. Both are also available in the legacy REPL and praisonai chat, so the command works whichever surface you’re on.

Context Compression

When conversations get long, use /compact to compact the model’s chat_history:
/compact:
  • Compacts the model’s own chat_history, not just the transcript pane.
  • Reports the tokens and messages it freed.
  • Runs automatically at the turn boundary when the session nears its context budget, so a long turn no longer waits for the provider to reject the request.
/compact used to be a display toggle. That behaviour moved to /compact-display (alias /dense). See Compaction.

Undo Support

Made a mistake? Use /undo to remove the last conversation turn:
/undo rolls the workspace and the conversation back to the previous turn boundary. Checkpointing is on by default in the async TUI — opt out with checkpoints.auto: false or PRAISONAI_CHECKPOINTS=off. The TUI captures a session-start baseline on launch and a pre-turn checkpoint before every submission, so /undo unwinds one turn at a time:
If checkpointing is off, /undo prints an enable hint; if no turns are recorded yet it prints Undo: No checkpoints yet — nothing to undo. See Checkpoints for config-precedence details.

Revert N turns

Use /revert [n] to roll files + conversation back by more than one turn at a time:
A diff preview is shown first. /revert refuses to run beyond the recorded turn count:

Diff

Been editing files for a while and want to see what changed? Type /diff to see workspace file changes since session start.
/diff uses the session-start baseline captured on launch, so it includes edits from earlier turns. It requires auto-checkpointing. When checkpointing is off it prints, verbatim:

Message Queue

Queue messages while the AI agent is processing. Type new prompts and they’ll be executed in order as each task completes.

Queue Commands

Messages are processed in FIFO order (First In, First Out). The agent automatically processes the next queued message when the current task completes.

Message Queue

See the full Message Queue documentation for programmatic usage and API reference.

Interrupting a Turn

Press Ctrl-C while the agent is thinking and the current turn stops at the next step boundary — the partial output is kept, the warm agent stays loaded, and the session is intact. Type the next prompt immediately.

What happens

Each turn runs in a worker thread wired to an InterruptController — the same cooperative-cancellation primitive the core chat loop already checks at every step boundary. Ctrl-C requests the interrupt on the main thread; the worker observes it at the next check and returns.

One press vs. two

While a cancel is in flight

If you press Ctrl-C twice and try to start a new turn before the previous one has observed the cancel, the CLI refuses cleanly rather than double-booking the shared controller:
This is deliberate — silently starting a new turn would either un-cancel the abandoned worker (and let it resume against the warm session) or race two turns against the same agent. Wait a moment and retry.
Between turns, a stale Ctrl-C you pressed while nothing was running does not kill the next turn — the interrupt is cleared at the start of every fresh turn. You only cancel what is actually running.
Cooperative means the loop stops at the next boundary — it does not kill the current step. A single long-running blocking call (a slow HTTP request, a long shell command) finishes before the interrupt is observed. That is why a second Ctrl-C is available: it stops waiting on the wrapper side and returns you to the prompt.
Cancelling a turn does not cost you the session. Re-run praisonai chat in the same directory, or use praisonai session resume <id>, and the transcript up to (and including) the partial output is restored.

Profiling

Enable profiling to see timing breakdown:

Output Comparison

Interactive Mode (Clean)

Regular Mode (Verbose)

Features

Streaming Responses

Responses stream token-by-token as real model deltas from agent.iter_stream(), similar to Gemini CLI and Claude Code. When a provider cannot stream, the CLI falls back to a single agent.chat() call and prints the completed answer as one block. Tool-using turns also stream each LLM step’s narrative live into one assistant message — see Multi-step (tool-using) turns and the Streaming section above.

Tool Status Indicators

When tools are used, you’ll see status indicators:

Security

High-risk tools require approval:
  • write_file - HIGH risk level
  • execute_command - CRITICAL risk level
Rejecting a tool call takes an optional one-line reason that flows back to the agent as the tool’s result. See Reject with a Reason.

Python API

Basic Usage

Configuration

Custom Completions

History Management

Status Display

Keyboard Shortcuts

Editing

Multi-line

VI Mode

Enable VI keybindings:
VI mode shortcuts:
  • Esc - Enter command mode
  • i - Insert mode
  • a - Append mode
  • dd - Delete line
  • / - Search

Customization

Custom Prompt

Dynamic Prompt

Custom Theme

Integration

With Slash Commands

With Cost Tracking

Fallback Mode

If prompt_toolkit is not available, a simple fallback is used:

Best Practices

  1. Use @file mentions - Include relevant files directly in prompts for context
  2. Monitor with /stats - Check token usage regularly to avoid surprises
  3. Use /compact - Compress history when conversations get long
  4. Switch models - Use /model gpt-4o-mini for simple tasks, /model gpt-4o for complex ones
  5. Enable profiling - Use /profile to identify slow operations
  6. Use completions - Press Tab often for faster input
  7. Learn shortcuts - Ctrl+R for history search is powerful

Feature Comparison

PraisonAI Interactive Mode compared to other AI CLI tools:

Troubleshooting

Completions Not Working

History Not Persisting

Display Issues

@File Mentions Not Working

Testing Interactive Mode

PraisonAI provides a CSV-driven test runner for testing interactive mode functionality. This is useful for:
  • Validating tool execution (ACP/LSP tools)
  • Testing multi-step workflows
  • Automated regression testing
  • CI/CD integration

Running Interactive Tests

CSV Test Format

Tests are defined in CSV format with the following columns: Example CSV:

Test Artifacts

When running with --keep-artifacts, each test generates:
  • transcript.txt - Full conversation
  • tool_trace.jsonl - Structured tool call trace
  • result.json - Test result with assertions
  • workspace/ - Snapshot of workspace files
  • judge_result.json - LLM judge evaluation (if rubric provided)

CLI Options

GitHub Advanced Tests

The github-advanced suite provides 5 end-to-end GitHub workflow scenarios that exercise real GitHub operations: Prerequisites:
  • gh CLI installed and authenticated
  • PRAISON_LIVE_NETWORK=1 environment variable
Artifacts Generated:
  • RUNBOOK.md - Step-by-step execution log
  • gh_repo_view.json - Repository state
  • gh_issue_list.json - Issues created
  • gh_pr_list.json - Pull requests created
  • transcript.txt - Full conversation
  • tool_trace.jsonl - Tool call trace
  • verifications.json - Verification results