diff --git a/README.md b/README.md
index 3a7ac89..b19a4d6 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,13 @@ A command-line interface (CLI) chat application for interacting with AI language
## 🌟 Features
-- **Model Flexibility**: Choose from hundreds of OpenRouter-supported models (e.g., GPT-4, Claude, Gemini) with substring-based search and selection [github.com](https://github.com/owengretzinger/gitreadme) for template-inspired ease.
-- **File Attachments**: Attach images (JPEG, PNG) or plain text files directly to messages using `@path` syntax, with automatic Base64 encoding for models that support modalities.
-- **Streaming Responses**: Enable real-time streaming for faster, live responses; toggle on/off via config commands (inspired by streaming in modern chat apps).
-- **Persistent Configuration**: Securely store API keys, base URLs, and settings in a local SQLite database for reuse across sessions.
-- **Rich UI in CLI**: Enhanced console output with Rich library panels, tables, and progress indicators for a polished terminal experience.
+- **Model Flexibility**: Choose from hundreds of OpenRouter-supported models (e.g., GPT-4, Claude, Gemini) with substring-based search and selection—inspired by dynamic model retrieval in advanced CLIs [github.com](https://github.com/oop7/OrChat) for seamless user experience.
+- **File Attachments**: Attach images (JPEG, PNG) or plain text files directly to messages using `@path` syntax, with automatic Base64 encoding for models that support modalities [github.com](https://github.com/rdhillbb/openRchat), enhancing multimodal interactions like in OrChat's smart picker.
+- **Streaming Responses**: Enable real-time streaming for faster, live responses; toggle on/off via config commands (inspired by streaming in modern chat apps), with Ctrl+C cancellation support similar to advanced TUIs.
+- **Persistent Configuration**: Securely store API keys, base URLs, and settings in a local SQLite database for reuse across sessions, leveraging cross-session persistence like in OrChat's conversation management [github.com](https://github.com/oop7/OrChat).
+- **Rich UI in CLI**: Enhanced console output with Rich library panels, tables, and progress indicators for a polished terminal experience, drawing from Ink-based interfaces in React TUIs [github.com](https://github.com/rdhillbb/openRchat).
+- **Arrow Key History Navigation**: Scroll through previous user inputs using up/down arrow keys for quick recall and editing, akin to command history in shells and CLIs like those using prompt_toolkit [prompt-toolkit.readthedocs.io](https://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html), for efficient iterative chatting.
+- **Screen Clearing**: Instantly clear the terminal screen with the `/clear` command, maintaining session state while providing a fresh interface—similar to `/cls` or `/clear-screen` in advanced chat apps [github.com](https://github.com/oop7/OrChat), preventing visual clutter.
- **Clipboard Integration**: Copy AI responses to the clipboard with a single prompt.
- **Help Command**: Built-in `/help` with examples for all commands, making the app self-documenting and user-friendly [github.com](https://github.com/Piyush64-bit/ReadMe-Generator).
- **Error Handling**: Graceful prompts for missing configs, file issues, and model incompatibilities.
@@ -24,7 +26,8 @@ A command-line interface (CLI) chat application for interacting with AI language
- **Python**: 3.9 or higher
- **OpenRouter API Key**: Free tier available at [openrouter.ai](https://openrouter.ai). Models like GPT-4 may require a paid plan.
-- **Dependencies**: Listed in `requirements.txt` (generate automatically with tools like `pipreqs` if needed).
+- **Additional Dependencies**: Requires `prompt_toolkit` for interactive input features like arrow key history and multi-line support (install via `pip install prompt_toolkit`) [prompt-toolkit.readthedocs.io](https://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html).
+- **Base Dependencies**: Listed in `requirements.txt` (generate automatically with tools like `pipreqs` if needed).
- **Internet Connection**: For API calls to OpenRouter.
## 🚀 Installation
@@ -39,10 +42,10 @@ A command-line interface (CLI) chat application for interacting with AI language
Use `pip` for simplicity or `uv` for faster management:
```bash
# Using pip
- pip install typer rich openrouter pyperclip requests
+ pip install typer rich openrouter pyperclip requests prompt_toolkit
# Using uv
- uv add typer rich openrouter pyperclip requests
+ uv add typer rich openrouter pyperclip requests prompt_toolkit
# Using pip and requirements.txt (recommended)
pip3 install -r requirements.txt
@@ -72,14 +75,16 @@ python oai_chat.py chat
| Command | Description | Example |
|---------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------|
-| `/help` | Display a table with examples for all commands and features. | `/help` |
+| `/help` | Display a table with examples for all commands and features, including new ones like `/clear`. | `/help` |
| `/model [search]` | Select or switch models; optional search for substring matching. | `/model gpt` (Filters to GPT models)
`/model` (Shows all models) |
| `/config api` | Update OpenRouter API key and reinitialize the client. | `/config api`
Enter key: sk-...
[Output: API key updated!] |
| `/config url` | Change the base URL for custom OpenRouter endpoints. | `/config url`
Enter URL: https://custom.openrouter.ai/api/v1 |
| `/config stream on/off` | Toggle response streaming (default: on for real-time chat). | `/config stream off` (For full responses at once)
`/config stream on`|
| `/config` | View current configurations. | `/config` (Displays table: API Key, Base URL, Streaming, Database path)|
+| `/clear` | Clear the terminal screen for a clean interface, preserving chat state. | `/clear`
[Output: Screen cleared. Ready for your next input!] |
| `exit`, `quit`, `bye` | Exit the app cleanly. | `exit` |
| Chatting with Files | Attach files using `@path` (e.g., images for vision models, text for context). | `Explain this @~/demo.png`
(Attaches image if model supports it) |
+| Arrow Key Navigation | Use ↑/↓ arrow keys to scroll through and edit previous user inputs. | While at "You>" prompt, press ↑ for last message, ↓ for next. |
### Example Session
@@ -87,31 +92,38 @@ python oai_chat.py chat
Welcome to OAI! Type your message, '/model [search]' to select/change model, '/config api/url/stream' to configure, '/help' for examples, or 'exit'/'quit' to end.
No model selected. Use '/model' to choose one.
-You: /help
+You> /help
[Displays help table as above]
-You: /model gpt
+You> /model gpt
(Shows table of GPT models)
Enter model number: 1
Selected: GPT-4o (openai/gpt-4o)
-You: Hello, how are you?
+You> Hello, how are you?
Streaming response... (Press Ctrl+C to cancel)
Hello! I'm doing great, thanks for asking. How can I help you today?
Type 'c' to copy response to clipboard, or press Enter to continue: c
Response copied to clipboard!
-You: Analyze this text @~/notes.txt
+You> /clear
+Screen cleared. Ready for your next input!
+
+You> Analyze this text @~/notes.txt
Streaming response... (Press Ctrl+C to cancel)
Based on the attached file, the text discusses...
-You: exit
+You> [↑ arrow key pressed - recalls previous message: Analyze this text @~/notes.txt]
+[Edit as needed and press Enter]
+
+You> exit
Goodbye!
```
- **Streaming**: Enabled by default for live responses; press Ctrl+C mid-stream to cancel (supported by most providers).
- **File Limits**: Max 10MB per file; only images for vision models, plain text otherwise. Supports `@~/relative/path` or absolute paths.
+- **Arrow Key History**: Sessions retains a history per run (resets on exit), allowing quick re-use or modification of inputs for iterative conversations.
- **Error Recovery**: If no models fetch initially, check your API key. Prompts guide you through setup.
For more on OpenRouter models and features (e.g., tool calling), see [openrouter.ai/docs](https://openrouter.ai/docs).
@@ -132,6 +144,8 @@ Edit any setting during a session without restarting. The database persists sett
- **No Models Available?** Ensure your API key is valid and has access to models [openrouter.ai](https://openrouter.ai/docs/api-keys). Check network connectivity.
- **Streaming Issues?** Some models/providers may fall back to non-streaming. Toggle with `/config stream off`.
- **File Attachment Errors?** Confirm paths are absolute (e.g., `@/home/user/file.png`) and files are under 10MB. Unsupported MIME types will be rejected.
+- **Arrow Key Issues?** Ensure `prompt_toolkit` is installed; arrow keys work in supported terminals (TTY environments). Falls back gracefully in non-interactive modes.
+- **Clear Screen Fails?** ANSI escape sequences are used cross-platform [usavps.com](https://usavps.com/blog/46203/), but may fall back to newlines in rare cases.
- **API Errors?** Re-set your key or check model compatibility (e.g., vision models for images).
- **Permission Denied?** Ensure the app has read access to attached files and the database directory.
- **Installation Fails?** Verify Python version and try `pip install --upgrade pip`. Use `uv` for dependency resolution [github.com](https://github.com/Herc-Ch/readme-generator).
@@ -141,8 +155,7 @@ If issues persist, open a GitHub issue with error logs.
## 🤝 Contributing
-We welcome contributions to improve the OAI Chat App!
-
+We welcome contributions to improve the OAI Chat App! Follow standard practices: fork, branch, test, and submit PRs. Please include updates to this README for new features.
## 📜 License
@@ -151,7 +164,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
## 🙏 Acknowledgments
- Built with OpenRouter for model access [openrouter.ai](https://openrouter.ai).
-- Inspired by AI README generators for documentation structure [github.com](https://github.com/Herc-Ch/readme-generator), [github.com](https://github.com/owengretzinger/gitreadme), [github.com](https://github.com/Piyush64-bit/ReadMe-Generator), [github.com](https://github.com/waheed444/AI_Readme_Generator), [github.com](https://github.com/mrunankpawar/repo-readme-generator).
-- CLI framework via Typer and Rich for polished UX.
+- Interactive input features inspired by prompt_toolkit [python-prompt-toolkit.readthedocs.io](https://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html) and advanced CLIs like OrChat [github.com](https://github.com/oop7/OrChat), openRChat [github.com](https://github.com/rdhillbb/openRchat), for history and clearing functionality.
+- README structure inspired by AI generators for documentation polish [github.com](https://github.com/Herc-Ch/readme-generator), [github.com](https://github.com/owengretzinger/gitreadme), [github.com](https://github.com/Piyush64-bit/ReadMe-Generator), [github.com](https://github.com/waheed444/AI_Readme_Generator), [github.com](https://github.com/mrunankpawar/repo-readme-generator).
Star ⭐ if this app helps—it's open-source and free! Happy chatting!
\ No newline at end of file
diff --git a/oai.py b/oai.py
index 60e0fb3..f780523 100644
--- a/oai.py
+++ b/oai.py
@@ -1,4 +1,5 @@
#!/usr/bin/python3 -W ignore::DeprecationWarning
+import sys
import os
import requests
from pathlib import Path
@@ -14,6 +15,7 @@ import mimetypes
import base64
import re
import sqlite3 # Added for SQLite DB integration
+from prompt_toolkit import PromptSession
app = typer.Typer()
console = Console()
@@ -68,6 +70,17 @@ except Exception as e:
models_data = []
text_models = []
+# **NEW: Function to clear the screen using ANSI escape sequences (cross-platform)**
+def clear_screen():
+ """Clear the terminal screen using ANSI escape codes, with fallback to newlines."""
+ try:
+ # ANSI sequence to clear screen and move cursor to top-left
+ # Cf. [usavps.com](https://usavps.com/blog/46203/) and [phoenixnap.de](https://phoenixnap.de/kb/clear-terminal) for ANSI usage
+ print("\033[H\033[J", end="", flush=True)
+ except Exception:
+ # Fallback: Fill with newlines (simpler, per [medium.com](https://medium.com/@ryan_forrester_/c-screen-clearing-how-to-guide-cff5bf764ccd))
+ print("\n" * 100)
+
@app.command()
def chat():
"""Start the OAI chat app with OpenRouter models."""
@@ -99,9 +112,13 @@ def chat():
if not selected_model:
console.print("[bold yellow]No model selected. Use '/model' to choose one.[/]")
+ # NEW: Initialize PromptSession for input history and arrow keys
+ session = PromptSession(history=None) # 'None' uses InMemoryHistory by default; can be customized later for disk persistence
+
while True:
try:
- user_input = typer.prompt("You").strip()
+ # REPLACED: Use session.prompt() instead of typer.prompt() for history/arrow key support
+ user_input = session.prompt("You> ").strip()
if user_input.lower() in ["exit", "quit", "bye"]:
console.print("[bold yellow]Goodbye![/]")
return
@@ -181,7 +198,13 @@ def chat():
console.print(Panel(table, title="[bold green]Current Configurations[/]", title_align="left"))
continue
- # Handle /help command (new: display examples for each command)
+ # **NEW: Handle /clear command to clear the screen**
+ if user_input.lower() == "/clear":
+ clear_screen()
+ console.print("[bold cyan]Screen cleared. Ready for your next input![/]")
+ continue
+
+ # Handle /help command (updated: now includes /clear)
if user_input.lower() == "/help":
help_table = Table("Command", "Description", "Example", show_header=True, header_style="bold cyan")
help_table.add_row(
@@ -209,6 +232,11 @@ def chat():
"View all current configurations.",
"/config\n(Displays table of API Key, Base URL, etc.)"
)
+ help_table.add_row( # **NEW: Added /clear to help**
+ "/clear",
+ "Clear the terminal screen for a clean interface.",
+ "/clear\n[bold cyan]Screen cleared. Ready for your next input![/bold cyan]"
+ )
help_table.add_row(
"/help",
"Show this help menu with examples.",
@@ -217,7 +245,7 @@ def chat():
help_table.add_row(
"Chatting with files",
"Attach images or plain text files to messages using '@path'.",
- "Explain this @/Users/me/image.jpg\n(Attaches image.jpg if supported by the model)"
+ "Explain this @/Users/me/image.jpg\n(Attaches image.jpg if supported by model)"
)
help_table.add_row(
"Exiting",
@@ -337,6 +365,14 @@ def chat():
else:
console.print("[bold red]No response received.[/]")
+ except KeyboardInterrupt:
+ # NEW: Handle Ctrl+C during prompt input (continue loop instead of crashing)
+ console.print("\n[bold yellow]Input interrupted. Continuing...[/]")
+ continue
+ except EOFError:
+ # NEW: Handle Ctrl+D (exit loop gracefully)
+ console.print("\n[bold yellow]Goodbye![/]")
+ return
except Exception as e:
console.print(f"[bold red]Error: {e}[/]")
console.print("[bold yellow]Try again or use '/model' to select a different model.[/]")