Full-stack real-time group chat with Rust/Axum backend and Riot.js frontend. Features: - Auth (register/login/JWT), rooms, invites, WebSocket messaging - AI responses via OpenRouter with tool calling (Brave Search + web fetch) - Real-time tool usage indicators (searching/reading page) - Collapsible tool results in message bubbles - AI stats bar (model, tokens, speed, response time) persisted to DB - Room soft-delete, /clear command, dynamic model fetching - Markdown rendering with code highlighting and copy buttons Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.9 KiB
3.9 KiB
Role
You are an Expert Full-Stack Developer specializing in Rust (Axum), modern JavaScript (Riot.js), and AI API Integration.
Goal
Create a complete "Phase 1" implementation plan and the core file structure for a Real-Time Group Chat Application powered by OpenRouter.
Project Context
This application is a group chat where multiple humans can talk to each other and a single AI assistant.
- Phase 1 (Current Scope): Humans + 1 System AI in a shared chatroom.
- Phase 2 (Future): Multiple AI Agents added to the chat.
- Critical Requirement: The architecture must be event-driven to support the future addition of autonomous agents.
Tech Stack Requirements
- Backend: Rust (using Axum framework).
- AI Engine: OpenRouter API (Support for user-selectable models like Claude 3.7, Llama 3, GPT-4, etc.).
- Real-time: WebSockets (using
tokio-tungsteniteor Axum's built-inwsextractor). - Frontend: Vite with Riot.js (v9+).
- Database: SQLite (managed via
sqlxfor async Rust) - keeping it simple for Phase 1 but strongly typed. - Styling: NO FRAMEWORKS. Use Custom CSS with CSS Variables (Custom Properties) for theming. Leverage Riot.js scoped styles.
Functional Requirements & Specification
-
User System:
- Simple email/password registration (Argon2 hashing).
- JWT-based authentication for HTTP and WebSocket upgrades.
- Users can "Invite" others via email (generate a unique link).
-
Chat Engine & OpenRouter Integration:
- Room Creation: When a user starts a chat, they must be able to select which OpenRouter Model ID (e.g.,
anthropic/claude-3.7-sonnet,meta-llama/llama-3-70b-instruct) drives that specific room. - Group Context: The AI must understand it is in a "Room" with multiple people.
- Message Structure:
sender_id(UUID)sender_name(Display Name)timestamp(UTC)content(Markdown string)mentions(Array of User IDs tagged)
- AI Trigger: When the AI is mentioned or (optionally) on every message, the backend sends the recent chat history to OpenRouter.
- Room Creation: When a user starts a chat, they must be able to select which OpenRouter Model ID (e.g.,
-
Frontend (Riot.js):
- Use
.riotcomponents. - Implement a Markdown renderer (e.g.,
markdown-it) with syntax highlighting (e.g.,highlight.js). - Model Selector: A dropdown in the "Create Chat" modal to pick the OpenRouter model.
- Design System:
- Create a
global.cssfor root variables (Dark Mode colors, spacing). - Use Riot's
<style>tag for component-level, scoped CSS. - The design should be professional, clean, and "Dark Mode" by default.
- Create a
- Use
Deliverables Needed From You
- Directory Structure: A comprehensive ASCII tree of the project structure (separating
server/andclient/). - Rust
Cargo.tomldependencies: The specific crates needed (reqwestfor OpenRouter API,axum,tokio,serde,sqlx, etc.). - Database Schema: The SQL migration code for:
usersrooms(Must include amodel_idcolumn to store the chosen OpenRouter model string)messagesinvites
- Core Backend Code:
- The WebSocket handler in Axum.
- The OpenRouter Service Function: A Rust function that takes
(room_history, model_id)and sends the request tohttps://openrouter.ai/api/v1/chat/completions. - The
Broadcastloop that sends AI responses back to the room.
- Core Frontend Code:
- The
vite.config.jssetup for Riot. - The
global.cssfile defining the color palette (Professional Dark Mode). - The
chat-room.riotcomponent demonstrating the message loop, Markdown rendering, and scoped CSS.
- The
Please ignore strict error handling for edge cases to keep the code readable, but ensure concurrency safety in the Rust WebSocket manager. Start by outlining the folder structure.