A prompt_toolkit extension that adds a thinking box above the prompt
Project description
thinking-prompt
A prompt_toolkit extension that adds a "thinking box" above the prompt for displaying AI thinking/processing content with real-time streaming updates.
Features
- Thinking Box: A collapsible area above the prompt that shows processing/thinking content
- Real-time Streaming: Content updates in real-time as your callback returns new content
- Fullscreen Mode: Optional fullscreen mode with chat history (disabled by default)
- Animated Separator: Configurable animated indicator showing thinking is in progress
- Rich Output: Support for markdown rendering and syntax-highlighted code blocks
- Rich/ANSI in Thinking Box: Use Rich markup for styled, in-place-updating content inside the thinking box
- Customizable Styles: Full control over colors and styling
Installation
pip install thinking-prompt
For markdown and code highlighting support:
pip install thinking-prompt[all]
Quick Start
import asyncio
from thinking_prompt import ThinkingPromptSession, AppInfo
async def main():
app_info = AppInfo(name="MyApp", version="1.0.0")
session = ThinkingPromptSession(app_info=app_info, message=">>> ")
@session.on_input
async def handle(text: str):
if not text.strip():
return
# Use context manager for clean thinking management
async with session.thinking() as content:
content.append("Processing...\n")
await asyncio.sleep(0.5)
content.append("Done!\n")
session.add_response(f"You said: {text}")
await session.run_async()
if __name__ == "__main__":
asyncio.run(main())
Key Bindings
| Key | Action |
|---|---|
| Ctrl+T | Expand/collapse thinking box (in prompt mode) |
| Ctrl+E | Toggle fullscreen mode (when enabled) |
| Ctrl+C | Cancel current operation or exit |
| Ctrl+D | Exit application |
API Reference
ThinkingPromptSession
The main class for creating a thinking-enabled prompt session.
session = ThinkingPromptSession(
message=">>> ", # Prompt message
app_info=AppInfo(...), # App metadata and configuration
max_thinking_height=15, # Max lines when collapsed
enable_status_bar=True, # Show status bar
echo_input=True, # Echo user input to console
complete_while_typing=True, # Show completions as you type
completions_menu_height=6, # Max rows in completions popup
)
Thinking API
Context Manager (recommended):
async with session.thinking() as content:
content.append("Step 1...\n")
await asyncio.sleep(0.5)
content.append("Step 2...\n")
# Automatically finishes when exiting context
Manual control:
# Start with a content callback
chunks = []
session.start_thinking(lambda: ''.join(chunks))
chunks.append("Processing...\n")
await asyncio.sleep(0.5)
# Finish and optionally echo to console
session.finish_thinking(add_to_history=True, echo_to_console=True)
Rich/ANSI Content in Thinking Box
Use append_rich() and set_line_rich() for styled content with Rich markup:
async with session.thinking(title="Processing") as ctx:
ctx.append_rich("[dim] ○ Load data[/dim]\n")
ctx.append_rich("[dim] ○ Transform[/dim]\n")
ctx.set_line_rich(0, "[bold cyan] ⟳ Load data…[/bold cyan]")
ctx.set_title("Loading")
await asyncio.sleep(1)
ctx.set_line_rich(0, "[green] ✓ Load data[/green]")
ctx.set_line_rich(1, "[bold cyan] ⟳ Transform…[/bold cyan]")
ctx.set_title("Transforming")
await asyncio.sleep(1)
ctx.set_line_rich(1, "[green] ✓ Transform[/green]")
Dynamic Titles & In-Place Updates
Use set_title() to change the thinking box title and set_line() to update lines in place:
async with session.thinking(title="Downloading") as ctx:
ctx.append("Progress: 0%\n")
for i in range(1, 101):
ctx.set_line(-1, f"Progress: {i}%")
ctx.set_title(f"Downloading {i}%")
await asyncio.sleep(0.02)
Output Methods
# Plain text response
session.add_response("Hello, world!")
# Markdown (requires rich)
session.add_response("# Title\n- Item 1\n- Item 2", markdown=True)
# Syntax-highlighted code (requires pygments)
session.add_code("def hello(): return 'world'", language="python")
# Status bar text
session.set_status("Ready") # Plain text
session.set_status("[bold]Processing[/bold]") # Rich markup
# Status messages
session.add_success("Operation completed")
session.add_warning("Rate limit approaching")
session.add_error("Connection failed")
session.add_message("system", "Connecting to server...")
Dialogs
# Yes/No confirmation
result = await session.yes_no_dialog("Confirm", "Delete this item?")
if result:
# User clicked Yes
# Message dialog
await session.message_dialog("Info", "Operation completed!")
# Choice dialog (multiple buttons)
action = await session.choice_dialog("Action", "What to do?", ["Save", "Discard", "Cancel"])
# Dropdown selection
theme = await session.dropdown_dialog("Theme", "Choose:", ["Light", "Dark", "System"])
# Custom dialog
from thinking_prompt import DialogConfig, ButtonConfig
config = DialogConfig(
title="Custom",
body="Choose an option:",
buttons=[
ButtonConfig(text="Option A", result="a"),
ButtonConfig(text="Option B", result="b"),
],
)
result = await session.show_dialog(config)
Settings Dialog
A form-based dialog for configuring multiple settings at once:
from thinking_prompt.settings_dialog import (
SettingsDialog,
DropdownItem,
InlineSelectItem,
TextItem,
CheckboxItem,
)
items = [
DropdownItem(
key="theme",
label="Theme",
description="Application color scheme",
options=["Light", "Dark", "System"],
default="System",
),
InlineSelectItem(
key="font_size",
label="Font Size",
options=["Small", "Medium", "Large"],
default="Medium",
),
TextItem(
key="username",
label="Username",
default="Guest",
),
TextItem(
key="api_key",
label="API Key",
password=True,
),
CheckboxItem(
key="notifications",
label="Enable Notifications",
description="Show desktop notifications",
default=True,
),
]
dialog = SettingsDialog(title="Settings", items=items)
result = await session.show_dialog(dialog)
if result:
# result is a dict of changed values only
for key, value in result.items():
print(f"{key}: {value}")
Control Types:
| Control | Description | Navigation |
|---|---|---|
DropdownItem |
Expandable dropdown list with ▼ indicator |
Enter to open, Up/Down to select, Enter to confirm |
InlineSelectItem |
Inline cycling with ◀/▶ indicators |
Left/Right to cycle through options |
TextItem |
Text input (optional password masking) | Enter to edit, Enter/Escape to confirm/cancel |
CheckboxItem |
Boolean toggle (true/false) |
Space/Enter/Left/Right to toggle |
Navigation: Up/Down moves between controls, Tab cycles through controls and buttons, Ctrl+S saves.
AppInfo Configuration
app_info = AppInfo(
name="MyApp",
version="1.0.0",
welcome_message="Welcome to MyApp!", # Optional custom welcome
# Key bindings
fullscreen_key="c-e", # Ctrl+E for fullscreen
expand_key="c-t", # Ctrl+T for expand/collapse
# Feature flags
fullscreen_enabled=False, # Enable fullscreen mode
echo_thinking=True, # Echo thinking to console after completion
# Thinking animation
thinking_text="Thinking", # Text in separator
thinking_animation=("⠋", "⠙", "⠹", ...), # Animation frames
thinking_animation_position="before", # "before" or "after" text
)
Examples
See the examples/ directory for complete demos:
basic.py- Simple thinking box usagedemo.py- Interactive demo with simulated AI thinkingstreaming.py- Character-by-character streamingprogress_demo.py- Progress bar with callbackdemo_progress_line.py- In-place progress updatesdemo_messages_during_thinking.py- Output messages during thinkingdemo_animated_separator.py- Different animation configurationsdialog_test.py- Dialog system demo (yes/no, message, choice, dropdown)settings_dialog_demo.py- Settings dialog with all control typesdemo_showcase.py- Feature showcase for demos and screenshotsdemo_task_progress.py- Rich-styled task progress with in-place status updatescompleter_demo.py- Slash-command autocompletion (like Claude Code)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file thinking_prompt-0.2.5.tar.gz.
File metadata
- Download URL: thinking_prompt-0.2.5.tar.gz
- Upload date:
- Size: 978.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8c1e1d09533d822582d065f2bc92435d372dd7277d385bd7a2d248ba68c063d
|
|
| MD5 |
e9b610fa8b05fbefcfedad63fa21cc0c
|
|
| BLAKE2b-256 |
efb5e09c7064b657940a478ec4a41fd86ea66073bcdfa94c9c928350a392d077
|
File details
Details for the file thinking_prompt-0.2.5-py3-none-any.whl.
File metadata
- Download URL: thinking_prompt-0.2.5-py3-none-any.whl
- Upload date:
- Size: 47.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e26ed781c222fbb7b5779becaad5ee44f8bc6f3c2007d51fce4c4d260f87091
|
|
| MD5 |
1a66741ebece5fff440b5dbe2a17ddab
|
|
| BLAKE2b-256 |
80cb40b0d7c5fb931fd453da31e001e87cfccaf48364373e3c300696159b407c
|