The "Make it Easy" AI Roleplay Tool.
"A solid move against the bloat. Repo looks cleanβgreat stack for quick setups." β Grok (xAI)
Most AI tools require a 2GB Docker image and 50 configuration menus. AI Characters Chat is different. It's built on a simple philosophy: Keep it Easy.
npm installnpm run db:resetnpm run db:seed- Start Roleplaying.
- Multi-User with Separate Histories: Each user has their own isolated chat history. Your dark fantasy RP won't mix with your coding assistant chat.
- Real-time Streaming (SSE): Text flows onto the screen as it's generated β no waiting for full responses.
- Character Management: Full CRUD UI at
/charactersβ no JSON editing. Per-character temperature, max tokens, system prompt, scenario, and avatar. - AI Image Generation: Generate images via FLUX model on Together AI. Supports 7 aspect ratios, steps, and guidance control.
- Smart Context Summarization: When chat history exceeds the limit, the AI automatically condenses it into a summary to stay focused while saving tokens.
- Markdown + Code Highlighting: Full support for bold, italics, lists, and code blocks via Marked + Highlight.js.
- Image Uploads to Chat: Send images to vision-capable models with auto-resizing via Sharp.
- Profile Management: Update display name and password from the nav menu.
- Password Security: Passwords hashed with bcrypt.
- Tools (Agents): AI can create text files, read text files, and generate images.
| Package | Role |
|---|---|
| Fastify 5 (TypeScript) | HTTP server β fast, low-overhead |
SQLite (sqlite + sqlite3) |
Local database, zero config |
| @fastify/session + @fastify/cookie | Session-based auth (PHP-style $_SESSION) |
| @fastify/multipart | File upload handling |
| @fastify/static | Static file serving |
| axios | HTTP client for AI API calls |
| bcrypt | Password hashing |
| eventsource-parser | SSE stream parsing from OpenRouter |
| fastify-sse-v2 | SSE response to frontend |
| sharp | Image resize/compress before AI vision input |
| pino / pino-pretty | Structured logging |
| tsx | Run TypeScript directly, no compile step in dev |
| Library | Role |
|---|---|
| Alpine.js 3 | Reactive UI without the bloat |
| Bootstrap 5 | Layout and components |
| Marked | Markdown rendering |
| Highlight.js | Code syntax highlighting |
| DOMPurify | XSS protection |
| Vanilla JS | Application logic per page |
| Service | Role |
|---|---|
| OpenRouter API | Chat completions β supports Grok, Claude, GPT, Llama, etc. |
| Together AI | Image generation via FLUX.2-dev (or any compatible model) |
| Route | Description |
|---|---|
/ |
Login / Register |
/chat |
Main chat interface with SSE streaming |
/characters |
Character management dashboard |
/image-gen |
AI image generator |
src/
βββ backend/
β βββ server.ts # Entry point
β βββ app.ts # Fastify plugin registration
β βββ seed.ts # DB seed script
β βββ config/
β β βββ config.ts # All env vars and defaults
β βββ database/
β β βββ schema.sql # Table definitions
β β βββ reset.ts # Drops and recreates DB
β β βββ sqlite.ts # dbRepo β Repository Pattern
β βββ routes/
β β βββ auth.routes.ts # Login, register, profile
β β βββ character.routes.ts # CRUD for characters
β β βββ chat.routes.ts # SSE streaming endpoint
β β βββ image.routes.ts # Image generation & history
β βββ services/
β β βββ ai.service.ts # OpenRouter SSE + summarization
β β βββ image.service.ts # Together AI image generation
β βββ types/
β βββ *.ts # TypeScript interfaces
β βββ tools/
β βββ definitions.ts # Tool definitions for Grok
β βββ handlers.ts # Tool implementations
βββ frontend/
βββ app_chat.js # Chat page logic
βββ app_characters.js # Characters page logic
βββ app_image_gen.js # Image gen page logic
βββ app_login.js # Auth page logic
βββ config.js # Runtime config (prefix, etc.)
βββ styles.css # Global styles (cyberpunk theme)
βββ icons/ # UI icons
views/
βββ chat.html
βββ characters.html
βββ image-gen.html
βββ index.html
storage/
βββ generated/ # Saved generated images (gitignored)
Session-based auth β no JWT juggling:
- Login β
request.session.useris set (like PHP's$_SESSION) - Cookie β
session_idmanaged server-side automatically - Guard β
server.authenticatedecorator protects all private routes (returns 401 if no session) - Passwords β Hashed with
bcrypt(10 rounds)
- Streams from OpenRouter via SSE using
eventsource-parser - Builds context:
system_prompt+scenario+ history window - Auto-summarizes when
messages.length > maxHistoryMessages(default: 20) - Injects summary as a system message to maintain continuity
- Sends prompt + aspect ratio β resolves to FLUX-optimized pixel dimensions (multiples of 32, ~1 MP)
- Downloads image from remote URL β saves to
storage/generated/ - Serves via
/storage/generated/:filestatic route - Supports: steps, guidance scale, aspect ratio (7 presets), reference images
- User-uploaded images for chat: resized to 1024Γ1024, 80% JPEG quality before sending to vision model
- AI can create text files, read text files, and generate images.
- Tool definitions in
src/backend/tools/definitions.ts - Tool handlers in
src/backend/tools/handlers.ts
AI_DEFAULT_MODELβ fallback model slugTOGETHER_IMAGE_MODELβ image model slug (e.g.black-forest-labs/FLUX.2-dev)
aiTemperature(0.7) β global creativity defaultmaxHistoryMessages(20) β summarization triggeraiFrequencyPenalty/aiPresencePenaltyβ repetition control
temperatureβ individual creativity overridemax_tokensβ response length capsystem_promptβ personality definitionscenarioβ current context/location
enabledβ enable/disable tool
npm installnpm run db:reset
npm run db:seedCreates tables, admin user, and example characters.
Copy .env.example to .env and fill in your keys:
PORT=3000
HOST=0.0.0.0
# Chat AI (OpenRouter)
API_URL=https://openrouter.ai/api/v1/chat/completions
API_KEY=your_openrouter_api_key_here
AI_DEFAULT_MODEL=x-ai/grok-2-1212
# Session
SESSION_SECRET=your_long_random_string_here_min_32_chars
# Image Generation (Together AI)
TOGETHER_API_KEY=your_together_api_key_here
TOGETHER_IMAGE_API_URL=https://api.together.xyz/v1/images/generations
TOGETHER_IMAGE_MODEL=black-forest-labs/FLUX.2-dev# Development (hot-reload via tsx watch)
npm run dev
# Production
npm run build
npm run startBuilt with a touch of sarcasm and faith in a digital future.
Author: Norayr Petrosyan β MIT License