Interactive TUI

Rich interactive terminal interface for AI-assisted coding

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
  • Smart completion ranking – @ files and / commands you use most rise to the top. See Completion Ranking.
  • 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.

Diagram

Interactive Streaming

delta by delta

provider can’t stream

one block

๐Ÿ’ฌ Prompt

agent.iter_stream()

๐Ÿ“บ Terminal

agent.chat()

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:

bash
Q: what is 2+2

A: 4

โ”€โ”€โ”€ Task #1 completed (0.8s, 1 words) โ”€โ”€โ”€

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.

Diagram
ToolsCorePrimary TUIToolsAgentTUIYouToolsAgentTUIYoupromptrun turnstep 1 narrative (live)assistant message appearscall tooltool resultstep 2 narrative (extends message)same message growsfinal responsemessage finalised (no duplicate)

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

bash
# Start interactive mode
praisonai chat

# Or use short flag
praisonai -i

# With a specific model
praisonai chat --llm gpt-4o

Chat Mode (Non-Interactive Testing)

For testing and scripting, use --chat (or praisonai chat) to run a single prompt with interactive-style output:

bash
# Single prompt with tools, streaming output, no boxes
praisonai "list files in current folder" --chat

# Test web search
praisonai "search the web for AI news" --chat

# Test file operations
praisonai "read the file README.md" --chat

Built-in Tools

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

ACP Tools (Agentic Change Plan)

ToolDescription
acp_create_fileCreate a file with plan/approve/apply/verify flow
acp_edit_fileEdit a file with tracking
acp_delete_fileDelete a file (requires approval)
acp_execute_commandExecute shell commands with tracking. Under PRAISON_SHELL=sandboxed every command, operators included, runs inside the OS sandbox โ€” see Shell Modes

LSP Tools (Code Intelligence)

ToolDescription
lsp_list_symbolsList functions, classes, methods in a file
lsp_find_definitionFind where a symbol is defined
lsp_find_referencesFind all references to a symbol
lsp_get_diagnosticsGet errors and warnings

Basic Tools

ToolDescription
read_fileRead contents of a file
write_fileWrite content to a file
list_filesList files in a directory
execute_commandRun shell commands. Shell operators are refused unless PRAISON_SHELL enables a real shell; under sandboxed every command runs contained โ€” see Shell Modes
internet_searchSearch the web for information
bash
# List available tools
โฏ /tools
Available tools: 13
  โ€ข acp_create_file, acp_edit_file, acp_delete_file, acp_execute_command
  โ€ข lsp_list_symbols, lsp_find_definition, lsp_find_references, lsp_get_diagnostics
  โ€ข read_file, write_file, list_files, execute_command, internet_search

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:

bash
# Resume most recent project session
praisonai -c

# Resume a specific session id
praisonai --session abc12345

# Branch it non-destructively
praisonai --fork --session abc12345

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.

Diagram
AgentInteractive TUISession Storepraisonai (bare)UserAgentInteractive TUISession Storepraisonai (bare)Userpraisonai -cfind_last_session()session_id + modelAsyncTUIConfig(session_id, model, resume=True)load(session_id)chat historyreplayed transcriptnew prompt(wired to session store)continues the conversation

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.

bash
# First launch โ€” no flags needed
praisonai
> Hello, help me refactor foo.py
> /quit

# Later, from any terminal
praisonai
> /sessions          # now lists the previous conversation
> /continue          # resumes it

Slash Commands

CommandDescription
/helpShow available commands
/exit or /quitExit interactive mode
/clearClear the screen and the agent’s conversation memory (resets both, not just the screen)
/newStart a new conversation โ€” resets both the screen and the agent’s conversation history
/import <file>Import a conversation from a file and restore it into the agent’s state (not just the screen)
/continue [id]Continue the most recent session, or a specific session id when given. Same renderer + agent wiring as the launch flags.
/toolsList available tools
/profileToggle profiling (show timing breakdown)
/model [name]Show or change current model
/statsShow session statistics (tokens, cost) โ€” alias /cost, same renderer
/export [file]Export the conversation to a file
/statusShow ACP/LSP runtime status
/autoToggle autonomy mode (auto-delegate complex tasks)
/debugToggle debug logging to ~/.praisonai/async_tui_debug.log
/plan <task>Create a step-by-step plan for a task
/handoff <type> <task>Delegate to specialized agent (code/research/review/docs)
/compactCompact the model’s chat_history (reports tokens/messages freed); auto-runs at the turn boundary
/compact-display (alias /dense)Toggle compact output display mode
/undoUndo last turn (files + history when checkpointing on)
/revert [n]Revert the last N turns (files + conversation)
/diffShow file changes this session (requires checkpoints.auto)
/git-statusShow working-tree status (operator command)
/git-diff [--staged]Show the uncommitted diff (operator command)
/git-log [n]Show the last n commits, default 10 (operator command)
/git-commit [message]Stage and commit; message auto-generated when omitted (operator command)
/git-undoUndo the last commit, keeping changes in the tree (operator command)
/map [path]Show the repository map (operator command)
/branch [title]Fork the current conversation here and switch onto the fork; parent stays resumable
/branch --at NFork from N user turns back
/sessionShow current session info, including Forked from: / Forks: lineage when set
/queueShow queued messages
/queue clearClear message queue
/filesList workspace files for @ mentions
bash
โฏ /help

Commands:
  /help          - Show this help
  /exit          - Exit interactive mode
  /clear         - Clear screen
  /continue [id] - Continue most recent session, or a specific session id
  /tools         - List available tools
  /profile       - Toggle profiling (show timing breakdown)
  /model [name]  - Show or change current model
  /stats         - Show session statistics (tokens, cost)
  /compact       - Compact chat_history (auto-runs at the turn boundary too)
  /compact-display - Toggle compact output display (alias /dense)
  /undo          - Undo last turn (files + history when checkpointing on)
  /diff          - Show file changes this session (needs checkpoints.auto)
  /git-status    - Show working-tree status
  /git-diff      - Show the uncommitted diff
  /git-log [n]   - Show recent commits
  /git-commit [m]- Stage and commit (message auto-generated when omitted)
  /git-undo      - Undo the last commit (keeps changes staged)
  /map [path]    - Show the repository map
  /queue         - Show queued messages
  /queue clear   - Clear message queue

@ Mentions:
  @file.txt      - Include file content in prompt
  @src/          - Include directory listing

Features:
  โ€ข File operations (read, write, list)
  โ€ข Shell command execution
  โ€ข Web search
  โ€ข Context compression for long sessions
  โ€ข Queue messages while agent is processing

@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.

bash
# Include a file in your prompt
โฏ what does @README.md say about installation?
๐Ÿ“„ Included: README.md (2,345 chars)

The README.md file explains that installation can be done via pip...

# Include multiple files
โฏ compare @file1.py and @file2.py
๐Ÿ“„ Included: file1.py (500 chars)
๐Ÿ“„ Included: file2.py (450 chars)

Here are the key differences between the two files...

# Include directory listing
โฏ what files are in @src/
๐Ÿ“ Listed: src/ (15 items)

The src/ directory contains the following files...

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.

bash
โฏ !git status              # run inline, no model turn
โฏ !!git diff               # attach output as context for the next message
โฏ summarise the change     # this turn sees the diff

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:

bash
# Show current model
โฏ /model
Current model: gpt-4o-mini

Available models (examples):
  โ€ข gpt-4o, gpt-4o-mini
  โ€ข claude-3-5-sonnet, claude-3-haiku
  โ€ข gemini-2.0-flash, gemini-1.5-pro

Usage: /model <model-name>

# Change to a different model
โฏ /model gpt-4o
โœ“ Model changed: gpt-4o-mini โ†’ gpt-4o

# Verify the change
โฏ /model
Current model: gpt-4o

Session Statistics

Track token usage and estimated costs:

bash
โฏ /stats

Model:          gpt-4o-mini
Total tokens:   3801
Estimated cost: $0.0017

Cost reads unknown (no price for this model) for models the resolver can’t price โ€” set custom pricing via ModelPricing to override (see Cost Tracking).

Context Compression

When conversations get long, use /compact to compact the model’s chat_history:

bash
โฏ /compact
Compacted context: 240,483 โ†’ 94,191 tokens (120 โ†’ 47 messages)

/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.

Undo Support

Made a mistake? Use /undo to remove the last conversation turn:

bash
โฏ write a function to sort a list
[AI generates sorting function]

โฏ /undo
โœ“ Undone last turn
Removed: write a function to sort a list...

โฏ /stats
Session Statistics
  ...
  History turns:  8  # Reduced from 10

/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:

bash
โฏ /undo
Undo: Workspace restored to `a1b2c3d` (turn 3: refactor auth handler).

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:

bash
โฏ /revert 3
Reverted 3 turn(s) โ€” files + conversation restored to a1b2c3d.

A diff preview is shown first. /revert refuses to run beyond the recorded turn count:

bash
โฏ /revert 9
Can only revert 1..N turn(s).

Diff

Been editing files for a while and want to see what changed? Type /diff to see workspace file changes since session start.

bash
/diff              # all changes since session start
/diff --turn       # only the last turn's changes (alias: -t)
/diff src/auth.py  # changes to a single file 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:

Workspace checkpointing is disabled, so /diff has no session baseline to compare against.

Enable it with `checkpoints.auto: true` in config or `PRAISONAI_CHECKPOINTS=on`.

Message Queue

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

bash
# While agent is processing, type more messages
โฏ Create a Python function to calculate fibonacci
[Agent processing...]

โฏ Add docstrings to the function
โฏ Create unit tests

# Check the queue
โฏ /queue
โณ Processing...

Queued Messages (2):
  0. โ†ณ Add docstrings to the function
  1. โ†ณ Create unit tests

Use /queue clear to clear, /queue remove N to remove

Queue Commands

CommandDescription
/queueShow all queued messages
/queue clearClear the entire queue
/queue remove NRemove message at index N
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.

Diagram

Cooperative Cancellation

checked

โณ Turn running

โŒจ๏ธ Ctrl-C

๐Ÿ›‘ controller.request user

๐Ÿšฆ Next step
boundary

โน Stop + partial output

โ™ป๏ธ Warm agent + session kept

โ–ถ๏ธ Type next prompt

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.

โฏ summarise the whole repo
  โณ Praison AI is thinking... (Ctrl-C to interrupt)
^C
  โน Interruptingโ€ฆ (finishing current step)
Turn interrupted by user.

โฏ ok, just the README instead

One press vs. two

PressStateBehaviour
Ctrl-C ร— 1Turn runningCooperative cancel. Prints โน Interruptingโ€ฆ; the core loop stops at the next step boundary; partial output is kept; a system message Turn interrupted by user. is appended to the transcript. Warm agent and session survive.
Ctrl-C ร— 2Turn still running (blocked in a slow tool call that hasn’t checked yet)The wrapper stops waiting on the worker thread. The cancellation request is still set โ€” the daemon worker observes it whenever it next reaches a check-point. Control returns to the prompt immediately.
Ctrl-C ร— 1Idle (no turn running, prompt-toolkit path)Resets the current input line โ€” unchanged from before.

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:

โฏ new question
  โน Previous turn is still cancelling; please wait a moment and try again.

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.

Profiling

Enable profiling to see timing breakdown:

bash
โฏ /profile
Profiling enabled

โฏ what is 2+2
4

โ”€โ”€โ”€ Profiling โ”€โ”€โ”€
Import:      0.1ms
Agent setup: 0.3ms
LLM call:    1,234.5ms
Display:     15.2ms
Total:       1,250.1ms

โฏ /profile
Profiling disabled

Output Comparison

Interactive Mode (Clean)

bash
โฏ what is 2+2

4

Regular Mode (Verbose)

bash
โ•ญโ”€ Agent Info โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚  ๐Ÿ‘ค Agent: DirectAgent                                   โ”‚
โ”‚  Role: Assistant                                         โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Task โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ what is 2+2                                              โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Response โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ 4                                                        โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

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:

bash
โฏ list files in current folder
โš™ Using list_files...
โœ“ list_files complete

Here are the files in the current folder:
- README.md
- main.py
- config.yaml

Security

High-risk tools require approval:

  • write_file – HIGH risk level
  • execute_command – CRITICAL risk level
bash
โฏ run the command 'rm -rf /'
โ•ญโ”€ ๐Ÿ”’ Tool Approval Required โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Function: execute_command                                โ”‚
โ”‚ Risk Level: CRITICAL                                     โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

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

python
from praisonai.cli.features import InteractiveTUIHandler

# Create handler
handler = InteractiveTUIHandler()

# Define callbacks
def on_input(text):
    """Handle regular input."""
    return f"You said: {text}"

def on_command(cmd):
    """Handle slash commands."""
    if cmd == "/exit":
        return {"type": "exit"}
    return {"type": "command", "message": f"Executed: {cmd}"}

# Initialize and run
session = handler.initialize(
    on_input=on_input,
    on_command=on_command
)

handler.run()

Configuration

python
from praisonai.cli.features.interactive_tui import (
    InteractiveConfig,
    InteractiveTUIHandler
)

config = InteractiveConfig(
    prompt="๐Ÿค– >>> ",           # Custom prompt
    multiline=True,             # Enable multi-line input
    history_file="~/.praisonai_history",  # Persistent history
    max_history=1000,           # Max history entries
    enable_completions=True,    # Enable auto-complete
    enable_syntax_highlighting=True,  # Enable highlighting
    vi_mode=False,              # Use emacs keybindings
    auto_suggest=True,          # Show suggestions
    show_status_bar=True,       # Show status bar
    color_scheme="monokai"      # Color theme
)

handler = InteractiveTUIHandler()
session = handler.initialize(config=config)

Custom Completions

python
from praisonai.cli.features.interactive_tui import InteractiveSession

session = InteractiveSession()

# Add slash commands for completion
# Note: Autocomplete only triggers when you type /
session.add_commands(["help", "exit", "cost", "model", "plan", "queue"])

# Add symbols from your codebase
session.add_symbols(["MyClass", "my_function", "CONFIG"])

# Refresh file completions
session.refresh_files(root=Path("/path/to/project"))

History Management

python
from praisonai.cli.features.interactive_tui import HistoryManager

# Create history manager
history = HistoryManager(
    history_file="~/.my_history",
    max_entries=500
)

# Add entries
history.add("first command")
history.add("second command")

# Navigate
prev = history.get_previous()  # "second command"
prev = history.get_previous()  # "first command"
next_cmd = history.get_next()  # "second command"

# Search
results = history.search("/help")  # Find commands starting with "/help"

# Clear
history.clear()

Status Display

python
from praisonai.cli.features.interactive_tui import StatusDisplay

display = StatusDisplay(show_status_bar=True)

# Set status items
display.set_status("model", "gpt-4o")
display.set_status("tokens", "1,234")
display.set_status("cost", "$0.05")

# Print formatted output
display.print_welcome(version="1.0.0")
display.print_response("Here's the solution...", title="AI Response")
display.print_error("Something went wrong")
display.print_info("Processing...")
display.print_success("Done!")

Keyboard Shortcuts

Navigation

ShortcutAction
โ†‘ / โ†“Navigate history
Ctrl+RSearch history
Ctrl+AMove to start of line
Ctrl+EMove to end of line
Ctrl+WDelete word backward

Editing

ShortcutAction
TabAuto-complete
Ctrl+C (turn running)Cancel the running turn cooperatively โ€” keeps partial output and warm agent. Press twice to stop waiting on a stuck step. See details.
Ctrl+C (idle)Clear the current input line.
Ctrl+DExit (on empty line)
Ctrl+LClear screen

Multi-line

ShortcutAction
EnterNew line (in multi-line mode)
Enter on emptySubmit input
Ctrl+EnterSubmit immediately

VI Mode

Enable VI keybindings:

python
config = InteractiveConfig(vi_mode=True)

VI mode shortcuts:

  • Esc – Enter command mode
  • i – Insert mode
  • a – Append mode
  • dd – Delete line
  • / – Search

Customization

Custom Prompt

python
config = InteractiveConfig(
    prompt="๐Ÿค– praisonai> "
)

Dynamic Prompt

python
def get_prompt():
    branch = get_git_branch()
    return f"({branch}) >>> "

# Update prompt dynamically
session.config.prompt = get_prompt()

Custom Theme

python
from prompt_toolkit.styles import Style

custom_style = Style.from_dict({
    'prompt': '#00aa00 bold',
    'input': '#ffffff',
    'completion': 'bg:#333333 #ffffff',
})

# Apply to session
session._prompt_session.style = custom_style

Integration

With Slash Commands

python
from praisonai.cli.features import (
    InteractiveTUIHandler,
    SlashCommandHandler
)

# Create handlers
tui = InteractiveTUIHandler()
slash = SlashCommandHandler()

def on_command(cmd):
    if slash.is_command(cmd):
        return slash.execute(cmd)
    return None

session = tui.initialize(on_command=on_command)

With Cost Tracking

python
from praisonai.cli.features import (
    InteractiveTUIHandler,
    CostTrackerHandler
)

tui = InteractiveTUIHandler()
cost = CostTrackerHandler()
cost.initialize()

def on_input(text):
    # Process with AI...
    response = ai.chat(text)

    # Track costs
    cost.track_request("gpt-4o", input_tokens, output_tokens)

    # Update status
    tui._session.display.set_status("cost", f"${cost.get_cost():.4f}")

    return response

session = tui.initialize(on_input=on_input)

Fallback Mode

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

python
# Without prompt_toolkit
>>> (Enter empty line to submit)
Hello, help me with my code

# Basic input still works, just without advanced features

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:

FeaturePraisonAIClaude CodeGemini CLICodex CLI
/helpโœ…โœ…โœ…โœ…
/clearโœ…โœ…โœ…โœ…
/toolsโœ…โœ…โœ…โœ…
/modelโœ…โœ…โœ…โœ…
/statsโœ…โœ…โœ…โœ…
/compactโœ…โœ…โœ…โœ…
/undoโœ…โœ…โœ…โœ…
/revert [n]โœ…
/queueโœ…โœ…โœ…โœ…
@file mentionsโœ…โœ…โœ…โœ…
Message queuingโœ…โœ…โœ…โœ…
Autocompleteโœ…โœ…โœ…โœ…
Profilingโœ…โŒโœ…โŒ
Real token streamingโœ…โœ…โœ…โœ…
Tool executionโœ…โœ…โœ…โœ…

Troubleshooting

Completions Not Working

bash
# Install prompt_toolkit
pip install prompt_toolkit

# Verify installation
python -c "import prompt_toolkit; print(prompt_toolkit.__version__)"

History Not Persisting

python
# Ensure history file path is writable
config = InteractiveConfig(
    history_file=os.path.expanduser("~/.praisonai_history")
)

Display Issues

bash
# Set terminal type
export TERM=xterm-256color

# Or disable colors
config = InteractiveConfig(enable_syntax_highlighting=False)

@File Mentions Not Working

bash
# Ensure the file exists and is readable
ls -la @yourfile.txt

# Use absolute paths if relative paths don't work
โฏ what does @/full/path/to/file.txt say?

# Check for typos in the path
โฏ what does @README.md say?  # Correct
โฏ what does @readme.md say?  # Case-sensitive on Linux/Mac

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

bash
# Run built-in smoke tests
praisonai test interactive --suite smoke

# Run tool-specific tests
praisonai test interactive --suite tools

# Run refactoring workflow tests
praisonai test interactive --suite refactor

# Run multi-agent tests
praisonai test interactive --suite multi_agent

# List available suites
praisonai test interactive --list

# Run custom CSV tests
praisonai test interactive --csv my_tests.csv

# Keep artifacts for debugging
praisonai test interactive --suite tools --keep-artifacts

# Generate CSV template
praisonai test interactive --generate-template

CSV Test Format

Tests are defined in CSV format with the following columns:

ColumnRequiredDescription
idYesUnique test identifier
nameYesTest name
promptsYesSingle prompt or JSON array for multi-step
expected_toolsNoComma-separated tools that must be called
forbidden_toolsNoComma-separated tools that must NOT be called
expected_filesNoJSON dict of {path: content_regex}
expected_responseNoRegex pattern for response
judge_rubricNoLLM judge evaluation rubric
judge_thresholdNoPass threshold (default: 7.0)
skip_ifNoSkip condition (e.g., no_openai_key)
agentsNoJSON array for multi-agent tests

Example CSV:

csv
id,name,prompts,expected_tools,expected_files,judge_rubric
test_01,Create File,"Create hello.py with print('hello')",acp_create_file,"{""hello.py"": ""print.*hello""}",File created successfully
test_02,Multi-step,"[""Create test.py"", ""Edit test.py""]","acp_create_file,acp_edit_file",,Files modified correctly

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

bash
praisonai test interactive [OPTIONS]

Options:
  --csv, -c PATH          Path to CSV test file
  --suite, -s NAME        Built-in suite: smoke, tools, refactor, multi_agent, github-advanced
  --model, -m MODEL       LLM model for agent (default: gpt-4o-mini)
  --judge-model MODEL     LLM model for judge (default: gpt-4o-mini)
  --workspace, -w PATH    Workspace directory
  --artifacts-dir PATH    Directory for artifacts
  --fail-fast, -x         Stop on first failure
  --keep-artifacts        Keep test artifacts
  --no-judge              Skip judge evaluation
  --verbose, -v           Verbose output
  --list                  List available suites
  --generate-template     Generate CSV template

GitHub Advanced Tests

The github-advanced suite provides 5 end-to-end GitHub workflow scenarios that exercise real GitHub operations:

ScenarioDescription
GH_01Repo Lifecycle + Feature + Issue + Fix + PR
GH_02CI Regression + Workflow Fix + PR
GH_03Refactor + Performance Micro-Optimization
GH_04Documentation + Broken Link Fix
GH_05Multi-Agent Collaboration

Prerequisites:

  • gh CLI installed and authenticated
  • PRAISON_LIVE_NETWORK=1 environment variable
bash
# Run GitHub Advanced tests
PRAISON_LIVE_NETWORK=1 praisonai test interactive --suite github-advanced

# Check prerequisites
gh auth status

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

Related Features