Spaces:
Sleeping
Sleeping
docs: add comprehensive project README with setup and architecture details
Browse files
README.md
CHANGED
|
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# π€ Simple Chatbot
|
| 2 |
+
|
| 3 |
+
A sleek, real-time AI chatbot built with **FastAPI** and vanilla **HTML/CSS/JS**, powered by [OpenRouter](https://openrouter.ai/) for free access to various AI models.
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+

|
| 7 |
+

|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## β¨ Features
|
| 12 |
+
|
| 13 |
+
| Feature | Description |
|
| 14 |
+
|---------|-------------|
|
| 15 |
+
| π **Streaming Responses** | AI replies appear in real-time, token by token β no waiting for the full response |
|
| 16 |
+
| π¬ **Conversation Memory** | Full chat history is maintained within a session so the AI remembers context |
|
| 17 |
+
| π¨ **Premium Dark UI** | Glassmorphism design with ambient gradient blobs and smooth animations |
|
| 18 |
+
| β‘ **Quick Suggestions** | Clickable prompt starters on the welcome screen to get started fast |
|
| 19 |
+
| π **Markdown Rendering** | Supports bold, italic, inline code, and code blocks in responses |
|
| 20 |
+
| π± **Responsive Design** | Works beautifully on desktop and mobile screens |
|
| 21 |
+
| π **New Chat** | One-click reset to clear history and start fresh |
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## π Project Structure
|
| 26 |
+
|
| 27 |
+
```
|
| 28 |
+
Simple Chatbot/
|
| 29 |
+
βββ main.py # FastAPI backend β API routes & OpenRouter integration
|
| 30 |
+
βββ static/
|
| 31 |
+
β βββ index.html # Frontend HTML β chat UI layout
|
| 32 |
+
β βββ style.css # Styling β dark theme, glassmorphism, animations
|
| 33 |
+
β βββ script.js # Frontend logic β streaming, history, markdown
|
| 34 |
+
βββ .env # Environment variables (API key)
|
| 35 |
+
βββ pyproject.toml # Python project config & dependencies
|
| 36 |
+
βββ uv.lock # Dependency lock file
|
| 37 |
+
βββ README.md # You are here!
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## π Getting Started
|
| 43 |
+
|
| 44 |
+
### Prerequisites
|
| 45 |
+
|
| 46 |
+
- **Python 3.13+** installed
|
| 47 |
+
- **[uv](https://docs.astral.sh/uv/)** package manager (recommended) or `pip`
|
| 48 |
+
- An **OpenRouter API key** β get one free at [openrouter.ai/keys](https://openrouter.ai/keys)
|
| 49 |
+
|
| 50 |
+
### 1. Clone the Repository
|
| 51 |
+
|
| 52 |
+
```bash
|
| 53 |
+
git clone <your-repo-url>
|
| 54 |
+
cd "Simple Chatbot"
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
### 2. Set Up Environment Variables
|
| 58 |
+
|
| 59 |
+
Create a `.env` file in the project root:
|
| 60 |
+
|
| 61 |
+
```env
|
| 62 |
+
OPENROUTER_API_KEY=sk-or-v1-your-api-key-here
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
> β οΈ **Never commit your `.env` file to version control.** It's already in `.gitignore`.
|
| 66 |
+
|
| 67 |
+
### 3. Install Dependencies
|
| 68 |
+
|
| 69 |
+
**Using uv (recommended):**
|
| 70 |
+
|
| 71 |
+
```bash
|
| 72 |
+
uv sync
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
**Using pip:**
|
| 76 |
+
|
| 77 |
+
```bash
|
| 78 |
+
pip install fastapi uvicorn openai python-dotenv
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### 4. Run the Server
|
| 82 |
+
|
| 83 |
+
```bash
|
| 84 |
+
uv run python -m uvicorn main:app --reload --port 8000
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
### 5. Open the Chatbot
|
| 88 |
+
|
| 89 |
+
Navigate to **[http://127.0.0.1:8000](http://127.0.0.1:8000)** in your browser. That's it! π
|
| 90 |
+
|
| 91 |
+
---
|
| 92 |
+
|
| 93 |
+
## π§ How It Works
|
| 94 |
+
|
| 95 |
+
### Architecture Overview
|
| 96 |
+
|
| 97 |
+
```
|
| 98 |
+
ββββββββββββββββ POST /api/chat ββββββββββββββββ Stream ββββββββββββββββ
|
| 99 |
+
β β ββββββββββββββββββββββββββββΊ β β ββββββββββββββββΊ β β
|
| 100 |
+
β Browser β { messages: [...] } β FastAPI β completions β OpenRouter β
|
| 101 |
+
β (Frontend) β ββββββββββββββββββββββββββ β (Backend) β ββββββββββββββ β (AI API) β
|
| 102 |
+
β β Streaming text chunks β β SSE chunks β β
|
| 103 |
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
| 104 |
+
```
|
| 105 |
+
|
| 106 |
+
### Step-by-Step Flow
|
| 107 |
+
|
| 108 |
+
1. **User types a message** in the textarea and hits Enter (or clicks send)
|
| 109 |
+
2. **Frontend** appends the message to the local `conversationHistory` array
|
| 110 |
+
3. **Frontend sends** the full conversation history to `POST /api/chat`
|
| 111 |
+
4. **Backend** forwards the messages to OpenRouter's API with `stream=True`
|
| 112 |
+
5. **Backend streams** each text chunk back to the frontend as it arrives
|
| 113 |
+
6. **Frontend renders** each chunk in real-time with a blinking cursor animation
|
| 114 |
+
7. **Assistant response** is saved to `conversationHistory` for context in future messages
|
| 115 |
+
|
| 116 |
+
### API Endpoint
|
| 117 |
+
|
| 118 |
+
#### `POST /api/chat`
|
| 119 |
+
|
| 120 |
+
Streams a chat completion from the AI model.
|
| 121 |
+
|
| 122 |
+
**Request Body:**
|
| 123 |
+
|
| 124 |
+
```json
|
| 125 |
+
{
|
| 126 |
+
"messages": [
|
| 127 |
+
{ "role": "user", "content": "Hello, who are you?" },
|
| 128 |
+
{ "role": "assistant", "content": "I'm an AI assistant..." },
|
| 129 |
+
{ "role": "user", "content": "Tell me a joke" }
|
| 130 |
+
]
|
| 131 |
+
}
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
**Response:** `text/plain` streamed response (chunked transfer encoding)
|
| 135 |
+
|
| 136 |
+
---
|
| 137 |
+
|
| 138 |
+
## π§ Memory & Context
|
| 139 |
+
|
| 140 |
+
The chatbot maintains **in-session memory**:
|
| 141 |
+
|
| 142 |
+
- β
**Within a session** β the AI remembers everything you've said
|
| 143 |
+
- β **Across page refreshes** β memory is lost (stored in browser JS only)
|
| 144 |
+
- β **Across sessions** β no database persistence
|
| 145 |
+
|
| 146 |
+
The full conversation history is sent with every request, so the AI model has complete context to generate relevant responses.
|
| 147 |
+
|
| 148 |
+
---
|
| 149 |
+
|
| 150 |
+
## βοΈ Configuration
|
| 151 |
+
|
| 152 |
+
### Changing the AI Model
|
| 153 |
+
|
| 154 |
+
In `main.py`, modify the `model` parameter:
|
| 155 |
+
|
| 156 |
+
```python
|
| 157 |
+
stream = client.chat.completions.create(
|
| 158 |
+
model="openrouter/free", # β Change this
|
| 159 |
+
messages=[m.model_dump() for m in request.messages],
|
| 160 |
+
stream=True,
|
| 161 |
+
)
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
**Popular free models on OpenRouter:**
|
| 165 |
+
|
| 166 |
+
| Model | ID |
|
| 167 |
+
|-------|----|
|
| 168 |
+
| Auto (free tier) | `openrouter/free` |
|
| 169 |
+
| Gemma 3 | `google/gemma-3-27b-it:free` |
|
| 170 |
+
| Llama 4 Scout | `meta-llama/llama-4-scout:free` |
|
| 171 |
+
| Mistral Small | `mistralai/mistral-small-3.1-24b-instruct:free` |
|
| 172 |
+
|
| 173 |
+
Browse all models at [openrouter.ai/models](https://openrouter.ai/models).
|
| 174 |
+
|
| 175 |
+
### Changing the Port
|
| 176 |
+
|
| 177 |
+
```bash
|
| 178 |
+
uv run python -m uvicorn main:app --reload --port 3000
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
---
|
| 182 |
+
|
| 183 |
+
## π¦ Dependencies
|
| 184 |
+
|
| 185 |
+
| Package | Purpose |
|
| 186 |
+
|---------|---------|
|
| 187 |
+
| `fastapi` | Web framework for the API server |
|
| 188 |
+
| `uvicorn` | ASGI server to run FastAPI |
|
| 189 |
+
| `openai` | OpenAI-compatible client (works with OpenRouter) |
|
| 190 |
+
| `python-dotenv` | Loads `.env` variables into the environment |
|
| 191 |
+
|
| 192 |
+
---
|
| 193 |
+
|
| 194 |
+
## π οΈ Development
|
| 195 |
+
|
| 196 |
+
### Hot Reload
|
| 197 |
+
|
| 198 |
+
The server runs with `--reload`, so any changes to Python files will auto-restart the server. For frontend changes (HTML/CSS/JS), just refresh the browser.
|
| 199 |
+
|
| 200 |
+
### Project Dependencies
|
| 201 |
+
|
| 202 |
+
All dependencies are managed via `pyproject.toml` and locked in `uv.lock`. To add a new package:
|
| 203 |
+
|
| 204 |
+
```bash
|
| 205 |
+
uv add <package-name>
|
| 206 |
+
```
|
| 207 |
+
|
| 208 |
+
---
|
| 209 |
+
|
| 210 |
+
## π License
|
| 211 |
+
|
| 212 |
+
This project is open source and available under the [MIT License](LICENSE).
|
| 213 |
+
|
| 214 |
+
---
|
| 215 |
+
|
| 216 |
+
## π Acknowledgments
|
| 217 |
+
|
| 218 |
+
- [OpenRouter](https://openrouter.ai/) β Free AI model access
|
| 219 |
+
- [FastAPI](https://fastapi.tiangolo.com/) β Modern Python web framework
|
| 220 |
+
- [Inter Font](https://rsms.me/inter/) β Clean UI typography
|