Sentinel AI is a fully-featured, production-ready AI Assistant powered by FastAPI, SQLAlchemy, SQLModel, and OpenRouter. It offers seamless web-based chat interactions backed by secure JWT authentication, a strict SQLite database engine, and a proprietary Crisis Detection Mirror to detect and log high-risk user inputs.
This repository is built for ultimate cross-platform compatibility, natively supporting Local Development, Docker, and Render (Free & Starter Tiers).
- Decoupled Business Logic: Separation of concerns between API endpoints, database operations (
repository.py), and AI generation (chat_service.py). - Secure JWT Authentication: Stateless tokens managed via HTTPOnly cookies using
bcryptpassword hashing. - Crisis Detection System: A parallel LLM meta-prompt classification system that transparently evaluates all messages for
SAFE,LOW_RISK,MEDIUM_RISK, andHIGH_RISKcategories. - Dual-Layer Persistence:
- Primary: SQLite via SQLModel for users, sessions, messages, and incidents.
- Secondary: A flat-file JSON mirror (
crises_store/crises_detection.json) dedicated exclusively to non-SAFE security incidents.
- Dynamic Deployment: Pathlib-driven architecture allows seamless SQLite volume mounting via
DATABASE_URLacross Render and Docker environments without hardcoded paths.
project_main/
├── api/ # FastAPI routers and schemas
├── database/ # SQLModel models, database engine, and repository
├── static/ # CSS and frontend assets
├── templates/ # Jinja2 HTML templates
├── storage/ # Primary SQLite database (assistant.db)
├── crises_store/ # Secondary JSON mirror (crises_detection.json)
├── backups/ # SQLite backups
├── exports/ # Conversation exports (.json, .md, .txt)
├── logs/ # Application logs (app.log)
├── config.py # Environment variables & Pathlib setup
├── startup.py # Pre-flight environment validations
└── main.py / run_api.py # Application entry points
By default, the SQLite database resides at storage/assistant.db. When deploying to Render or Docker, this path is overridden using the DATABASE_URL environment variable to point to a persistent volume (e.g., /data/assistant.db).
- User logs in.
- The server generates a JWT token and sets it as an
HTTPOnlycookie (access_token). - Every subsequent request reads this cookie, verifies the signature against
JWT_SECRET, and injects the authenticated user into the FastAPI context.
- User submits a message.
- The message is secretly sent to an LLM evaluator (
detector.py). - If classified as anything other than
SAFE, it is simultaneously stored in SQLite and appended tocrises_store/crises_detection.json. - The conversation then proceeds normally.
- Clone the repository:
git clone https://github.com/hammad986/terminal-ai-assistant.git - Install requirements:
pip install -r requirements.txt - Copy
.env.exampleto.envand fill outOPENROUTER_API_KEYandJWT_SECRET. - Run the API:
python run_api.py
We provide a complete docker-compose.yml.
- Fill out your
.envfile. - Run
docker-compose up -d --build. - The database is automatically persisted in a Docker named volume.
- Fork this repository and link it to your Render account.
- Create a new Web Service.
- Use the included
render.yamlconfiguration. - Set your
OPENROUTER_API_KEYandJWT_SECRETin the Render Dashboard. Note: The Free Tier does not support persistent disks. Your SQLite database will be ephemeral and wiped upon every restart.
If you upgrade to the Starter Tier ($7/mo), Render will automatically provision the sqlite-data disk defined in render.yaml, mount it to /data, and your history will be permanently saved.
Q: My application is crashing on startup with a JWT or API Key error?
A: startup.py enforces strict validations. Ensure your .env contains OPENROUTER_API_KEY and a JWT_SECRET that is at least 32 characters long.
Q: Why does my Render database get wiped? A: Render's Free Tier does not support persistent disks. You must use the Starter Tier to preserve SQLite data.
Q: Where are the logs?
A: Logs are located in logs/app.log and automatically rotate at 1MB.
MIT License.
Developed by Muhammed Hammad S. Powered by FastAPI and OpenRouter.