"# DevAssist"
A lightweight command-line AI assistant for programming help — code review, debugging, and general language/library questions — built on top of OpenRouter, with automatic fallback across multiple free models so you're not stuck when one is overloaded or rate-limited.
- Multi-model fallback — configure a list of models; if one fails or is overloaded, DevAssist automatically retries with the next one
- Streaming responses rendered with proper Markdown formatting (headers, tables, syntax-highlighted code blocks) instead of raw text
- Repetition-loop protection — detects and stops runaway/degenerate model output automatically
- File-aware conversations
@filename— inline-include a file's contents in your message/file <path> [question]— send a full file plus an optional question in one line
- Automatic code file generation — ask for a script, and DevAssist can save the generated code straight to a directory of your choice with
/savecode - Clipboard integration —
/copygrabs the last response,/pastesends your clipboard content as the next message - Persistent conversation history with configurable context length, saved to disk between sessions
- Slash commands for switching models, clearing/viewing history, and exporting chats to Markdown
- Rich terminal UI — spinners, colored output, tables, and syntax-highlighted code
- Python 3.10+
- An OpenRouter API key
- Clone or download this repository.
- Install dependencies:
pip install -r requirements.txt - Create a
.envfile in the project folder:OPENROUTER_API_KEY=your_key_here - Run it:
python ask.py
Add the project folder to your system PATH and create a small wrapper script (ask.bat on Windows / a shell script on macOS/Linux) so you can just type ask from any terminal, in any folder.
Settings live in config.json (auto-created on first run) and can also be changed live with slash commands:
{
"default_model": "nvidia/nemotron-3-ultra-550b-a55b:free",
"models": [
"nvidia/nemotron-3-ultra-550b-a55b:free",
"poolside/laguna-m.1:free",
"poolside/laguna-xs-2.1:free",
"cohere/north-mini-code:free"
],
"temperature": 0.2,
"history_limit": 10,
"stream": true,
"reasoning": true,
"timeout": 120,
"output_dir": "./generated"
}| Command | Description |
|---|---|
/help |
Show all commands |
/clear |
Clear conversation history |
/history |
View conversation history |
/models |
List configured models |
/model <n> |
Switch the active model |
/save |
Export the chat to Markdown |
/copy |
Copy the last response to the clipboard |
/paste |
Send clipboard content as your next message |
/file <path> [question] |
Send a full file, optionally with a question |
/outdir <path> |
View or set the folder where generated code is saved |
/savecode [name] |
Save code block(s) from the last response to disk |
/quit |
Exit DevAssist |
You can also include any file inline in a message with @filename.
.
├── ask.py # Entry point / main loop
├── config.py # Config loading, saving, and defaults
├── history.py # Conversation history persistence
├── ui.py # Terminal rendering (Rich-based)
├── commands.py # Slash command handling, file loading
├── openrouter_client.py # OpenRouter API client with fallback/retry
├── requirements.txt
└── config.json # Generated on first run
DevAssist sends your conversation history to OpenRouter, streaming the response back token by token. If a model fails, times out, or returns nothing, it's automatically retried and then swapped for the next model in your configured list — so a single overloaded free-tier model doesn't block you from getting an answer.
When a response includes a full file (marked internally with a File: path/to/file.ext label), /savecode will write it straight to your configured output directory, creating folders as needed.
MIT — do whatever you'd like with this.