Reorganize and consolidate documentation
Documentation Structure: - Created docs/features/ for all feature documentation - Moved CONTEXTUAL_RESPONSE_FEATURE.md, DEMO_SESSION.md, FIXES_SUMMARY.md, PROMPT_IMPROVEMENTS.md to docs/features/ - Moved TESTING_GUIDE.md and TEST_RESULTS.md to docs/development/ - Created comprehensive docs/features/README.md with feature catalog Cleanup: - Removed outdated CURRENT_STATUS.md and SESSION_SUMMARY.md - Removed duplicate files in docs/development/ - Consolidated scattered documentation Main README Updates: - Reorganized key features into categories (Core, AI, Technical) - Added Demo Session section with quick-access info - Updated Quick Start section with bash start.sh instructions - Added direct links to feature documentation Documentation Hub Updates: - Updated docs/README.md with new structure - Added features section at top - Added current status (v0.2.0) - Added documentation map visualization - Better quick links for different user types New Files: - CHANGELOG.md - Version history following Keep a Changelog format - docs/features/README.md - Complete feature catalog and index Result: Clean, organized documentation structure with clear navigation
This commit is contained in:
168
docs/README.md
168
docs/README.md
@@ -1,66 +1,152 @@
|
||||
# 📚 Storyteller RPG - Documentation
|
||||
# 📚 Storyteller RPG Documentation
|
||||
|
||||
Welcome to the Storyteller RPG documentation. All project documentation is organized here by category.
|
||||
Welcome to the Storyteller RPG documentation hub. All project documentation is organized here for easy navigation.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Documentation Structure
|
||||
## 📂 Documentation Structure
|
||||
|
||||
### 🚀 [setup/](./setup/)
|
||||
**Getting started guides and quick references**
|
||||
### ✨ [Features](./features/)
|
||||
|
||||
- **[QUICKSTART.md](./setup/QUICKSTART.md)** - 5-minute quick start guide
|
||||
- **[QUICK_REFERENCE.md](./setup/QUICK_REFERENCE.md)** - Quick reference for common tasks
|
||||
Comprehensive feature documentation with examples and guides.
|
||||
|
||||
### 📋 [planning/](./planning/)
|
||||
**Product roadmaps and feature planning**
|
||||
- **[Features Overview](./features/README.md)** - Complete feature catalog
|
||||
- **[Demo Session Guide](./features/DEMO_SESSION.md)** - Using the pre-configured test session
|
||||
- **[Context-Aware Responses](./features/CONTEXTUAL_RESPONSE_FEATURE.md)** - Multi-character AI generation
|
||||
- **[Prompt Engineering](./features/PROMPT_IMPROVEMENTS.md)** - LLM prompt techniques
|
||||
- **[Bug Fixes](./features/FIXES_SUMMARY.md)** - Recent fixes and improvements
|
||||
|
||||
- **[MVP_ROADMAP.md](./planning/MVP_ROADMAP.md)** - MVP feature requirements and roadmap
|
||||
- **[NEXT_STEPS.md](./planning/NEXT_STEPS.md)** - Detailed future development roadmap
|
||||
- **[PROJECT_PLAN.md](./planning/PROJECT_PLAN.md)** - Overall project planning and goals
|
||||
### 🚀 [Setup Guides](./setup/)
|
||||
|
||||
### 📖 [reference/](./reference/)
|
||||
**Technical references and guides**
|
||||
Get started quickly with installation and configuration guides.
|
||||
|
||||
- **[LLM_GUIDE.md](./reference/LLM_GUIDE.md)** - Guide to available LLM models
|
||||
- **[PROJECT_FILES_REFERENCE.md](./reference/PROJECT_FILES_REFERENCE.md)** - Complete file structure reference
|
||||
- **[Quickstart Guide](./setup/QUICKSTART.md)** - Step-by-step setup instructions
|
||||
- **[Quick Reference](./setup/QUICK_REFERENCE.md)** - Common commands and workflows
|
||||
|
||||
### 🔧 [development/](./development/)
|
||||
**Development session notes and implementation details**
|
||||
### 📋 [Planning & Roadmap](./planning/)
|
||||
|
||||
- **[SESSION_SUMMARY.md](./development/SESSION_SUMMARY.md)** - Complete development session summary
|
||||
- **[IMPLEMENTATION_SUMMARY.md](./development/IMPLEMENTATION_SUMMARY.md)** - Technical implementation details
|
||||
Project vision, milestones, and future plans.
|
||||
|
||||
- **[Project Plan](./planning/PROJECT_PLAN.md)** - Overall project structure and goals
|
||||
- **[MVP Roadmap](./planning/MVP_ROADMAP.md)** - Minimum viable product phases
|
||||
- **[Next Steps](./planning/NEXT_STEPS.md)** - Immediate priorities and tasks
|
||||
|
||||
### 🔧 [Development](./development/)
|
||||
|
||||
Technical implementation details and testing.
|
||||
|
||||
- **[MVP Progress](./development/MVP_PROGRESS.md)** - Current status and achievements
|
||||
- **[Testing Guide](./development/TESTING_GUIDE.md)** - How to test the application
|
||||
- **[Test Results](./development/TEST_RESULTS.md)** - Latest test results
|
||||
|
||||
### 📖 [Reference](./reference/)
|
||||
|
||||
Technical guides and comprehensive references.
|
||||
|
||||
- **[LLM Guide](./reference/LLM_GUIDE.md)** - Working with different AI models
|
||||
- **[Project Files Reference](./reference/PROJECT_FILES_REFERENCE.md)** - Complete file structure
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Quick Navigation
|
||||
## 🔗 Quick Links
|
||||
|
||||
**New to the project?**
|
||||
1. Start with the main [README.md](../README.md) in the root directory
|
||||
2. Follow [setup/QUICKSTART.md](./setup/QUICKSTART.md) to get running
|
||||
3. Review [planning/MVP_ROADMAP.md](./planning/MVP_ROADMAP.md) to understand the vision
|
||||
### For New Users
|
||||
1. ⚡ Start with [Quickstart Guide](./setup/QUICKSTART.md)
|
||||
2. 🎮 Try the [Demo Session](./features/DEMO_SESSION.md) (pre-configured!)
|
||||
3. 📖 Review [Features Overview](./features/README.md) to see what's possible
|
||||
4. 🤖 Check [LLM Guide](./reference/LLM_GUIDE.md) for model selection
|
||||
|
||||
**Want to contribute?**
|
||||
1. Read [development/SESSION_SUMMARY.md](./development/SESSION_SUMMARY.md) for architecture
|
||||
2. Check [planning/NEXT_STEPS.md](./planning/NEXT_STEPS.md) for feature priorities
|
||||
3. Refer to [reference/PROJECT_FILES_REFERENCE.md](./reference/PROJECT_FILES_REFERENCE.md) for code navigation
|
||||
### For Developers
|
||||
1. 🔧 Read [MVP Progress](./development/MVP_PROGRESS.md) for current state
|
||||
2. 🧪 Check [Testing Guide](./development/TESTING_GUIDE.md)
|
||||
3. 📁 Review [Project Files Reference](./reference/PROJECT_FILES_REFERENCE.md)
|
||||
4. 🚀 Follow [Next Steps](./planning/NEXT_STEPS.md) for contribution areas
|
||||
|
||||
**Looking for specific info?**
|
||||
- **Setup/Installation** → [setup/](./setup/)
|
||||
- **Features & Roadmap** → [planning/](./planning/)
|
||||
- **API/Models/Files** → [reference/](./reference/)
|
||||
- **Architecture** → [development/](./development/)
|
||||
### For Storytellers
|
||||
1. 🎭 See [Features Guide](./features/README.md) for all tools
|
||||
2. 🧠 Learn about [Context-Aware Responses](./features/CONTEXTUAL_RESPONSE_FEATURE.md)
|
||||
3. 💡 Use [Quick Reference](./setup/QUICK_REFERENCE.md) for common tasks
|
||||
4. 🎲 Start with [Demo Session](./features/DEMO_SESSION.md) for practice
|
||||
|
||||
---
|
||||
|
||||
## 📊 Documentation Overview
|
||||
## 📊 Current Status (v0.2.0)
|
||||
|
||||
| Category | Files | Purpose |
|
||||
|----------|-------|---------|
|
||||
| **Setup** | 2 | Getting started and quick references |
|
||||
| **Planning** | 3 | Roadmaps, feature plans, project goals |
|
||||
| **Reference** | 2 | Technical guides and file references |
|
||||
| **Development** | 2 | Session notes and implementation details |
|
||||
### ✅ Completed Features
|
||||
- Private/public/mixed messaging system
|
||||
- Context-aware AI response generator
|
||||
- Demo session with pre-configured characters
|
||||
- Real-time WebSocket communication
|
||||
- Multi-LLM support (GPT-4o, Claude, Llama, etc.)
|
||||
- AI-assisted storyteller suggestions
|
||||
- Session ID quick copy
|
||||
- Full conversation history
|
||||
|
||||
### 🚧 Coming Soon
|
||||
- Database persistence
|
||||
- Character sheets & stats
|
||||
- Dice rolling mechanics
|
||||
- Combat system
|
||||
- Image generation
|
||||
- Voice messages
|
||||
|
||||
See [MVP Roadmap](./planning/MVP_ROADMAP.md) for the complete timeline.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documentation Principles
|
||||
|
||||
This documentation follows these principles:
|
||||
|
||||
- **Progressive Disclosure**: Start simple, dive deeper as needed
|
||||
- **Always Current**: Updated with each feature implementation
|
||||
- **Example-Driven**: Real code examples and use cases
|
||||
- **Clear Structure**: Logical organization for easy navigation
|
||||
- **Feature-Focused**: Detailed guides for every feature
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Documentation Map
|
||||
|
||||
```
|
||||
docs/
|
||||
├── features/ ← Feature guides & examples
|
||||
│ ├── README.md
|
||||
│ ├── DEMO_SESSION.md
|
||||
│ ├── CONTEXTUAL_RESPONSE_FEATURE.md
|
||||
│ ├── PROMPT_IMPROVEMENTS.md
|
||||
│ └── FIXES_SUMMARY.md
|
||||
├── setup/ ← Installation & quick start
|
||||
│ ├── QUICKSTART.md
|
||||
│ └── QUICK_REFERENCE.md
|
||||
├── planning/ ← Roadmap & future plans
|
||||
│ ├── PROJECT_PLAN.md
|
||||
│ ├── MVP_ROADMAP.md
|
||||
│ └── NEXT_STEPS.md
|
||||
├── development/ ← Technical & testing docs
|
||||
│ ├── MVP_PROGRESS.md
|
||||
│ ├── TESTING_GUIDE.md
|
||||
│ └── TEST_RESULTS.md
|
||||
└── reference/ ← Technical references
|
||||
├── LLM_GUIDE.md
|
||||
└── PROJECT_FILES_REFERENCE.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing to Documentation
|
||||
|
||||
Found a typo or want to improve the docs? Contributions are welcome!
|
||||
|
||||
1. Documentation lives in the `docs/` folder
|
||||
2. Use clear, concise language
|
||||
3. Include examples where helpful
|
||||
4. Keep formatting consistent
|
||||
5. Update relevant indexes when adding new docs
|
||||
|
||||
---
|
||||
|
||||
**Need help?** Start with the [Quickstart Guide](./setup/QUICKSTART.md) or check the main [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# Implementation Summary
|
||||
|
||||
## ✅ Completed Features
|
||||
|
||||
### Backend (`main.py`)
|
||||
- **Isolated Character Sessions**: Each character has a separate conversation history that only they and the storyteller can see
|
||||
- **Private WebSocket Channels**:
|
||||
- `/ws/character/{session_id}/{character_id}` - Character's private connection
|
||||
- `/ws/storyteller/{session_id}` - Storyteller's master connection
|
||||
- **Message Routing**: Messages flow privately between storyteller and individual characters
|
||||
- **Scene Broadcasting**: Storyteller can narrate scenes visible to all characters
|
||||
- **Real-time Updates**: WebSocket events for character joins, messages, and responses
|
||||
- **Pending Response Tracking**: System tracks which characters are waiting for storyteller responses
|
||||
- **AI Suggestions** (Optional): Endpoint for AI-assisted storyteller response generation
|
||||
|
||||
### Frontend Components
|
||||
|
||||
#### 1. **SessionSetup.js**
|
||||
- Create new session (storyteller)
|
||||
- Join existing session (character)
|
||||
- Character creation with name, description, and personality
|
||||
- Beautiful gradient UI with modern styling
|
||||
|
||||
#### 2. **CharacterView.js**
|
||||
- Private chat interface with storyteller
|
||||
- Real-time message delivery via WebSocket
|
||||
- Scene narration display
|
||||
- Conversation history preservation
|
||||
- Connection status indicator
|
||||
|
||||
#### 3. **StorytellerView.js**
|
||||
- Dashboard showing all characters
|
||||
- Character list with pending response indicators
|
||||
- Click character to view their private conversation
|
||||
- Individual response system for each character
|
||||
- Scene narration broadcast to all characters
|
||||
- Visual indicators for pending messages
|
||||
|
||||
### Styling (`App.css`)
|
||||
- Modern gradient theme (purple/blue)
|
||||
- Responsive design
|
||||
- Smooth animations and transitions
|
||||
- Clear visual hierarchy
|
||||
- Mobile-friendly layout
|
||||
|
||||
### Documentation
|
||||
- **README.md**: Comprehensive guide with architecture, features, and API docs
|
||||
- **QUICKSTART.md**: Fast setup and testing guide
|
||||
- **.env.example**: Environment variable template
|
||||
|
||||
## 🔐 Privacy Implementation
|
||||
|
||||
The core requirement - **isolated character sessions** - is implemented through:
|
||||
|
||||
1. **Separate Data Structures**: Each character has `conversation_history: List[Message]`
|
||||
2. **WebSocket Isolation**: Separate WebSocket connections per character
|
||||
3. **Message Routing**: Messages only sent to intended recipient
|
||||
4. **Storyteller View**: Only storyteller can see all conversations
|
||||
5. **Scene Broadcast**: Shared narrations go to all, but conversations stay private
|
||||
|
||||
## 🎯 Workflow
|
||||
|
||||
```
|
||||
Character A → Storyteller: "I search the room"
|
||||
Character B → Storyteller: "I attack the guard"
|
||||
↓
|
||||
Storyteller sees both messages separately
|
||||
↓
|
||||
Storyteller → Character A: "You find a hidden key"
|
||||
Storyteller → Character B: "You miss your swing"
|
||||
↓
|
||||
Character A only sees their conversation
|
||||
Character B only sees their conversation
|
||||
```
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
windsurf-project/
|
||||
├── main.py # FastAPI backend with WebSocket support
|
||||
├── requirements.txt # Python dependencies
|
||||
├── .env.example # Environment template
|
||||
├── README.md # Full documentation
|
||||
├── QUICKSTART.md # Quick start guide
|
||||
├── IMPLEMENTATION_SUMMARY.md # This file
|
||||
└── frontend/
|
||||
├── package.json
|
||||
└── src/
|
||||
├── App.js # Main app router
|
||||
├── App.css # All styling
|
||||
└── components/
|
||||
├── SessionSetup.js # Session creation/join
|
||||
├── CharacterView.js # Character interface
|
||||
└── StorytellerView.js # Storyteller dashboard
|
||||
```
|
||||
|
||||
## 🚀 To Run
|
||||
|
||||
**Backend:**
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
**Frontend:**
|
||||
```bash
|
||||
cd frontend && npm start
|
||||
```
|
||||
|
||||
## 🎨 Design Decisions
|
||||
|
||||
1. **WebSocket over REST**: Real-time bidirectional communication required for instant message delivery
|
||||
2. **In-Memory Storage**: Simple session management; can be replaced with database for production
|
||||
3. **Component-Based Frontend**: Separate views for different roles (setup, character, storyteller)
|
||||
4. **Message Model**: Includes sender, content, timestamp for rich conversation history
|
||||
5. **Pending Response Flag**: Helps storyteller track which characters need attention
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
- Database persistence (PostgreSQL/MongoDB)
|
||||
- User authentication
|
||||
- Character sheets with stats
|
||||
- Dice rolling system
|
||||
- Voice/audio support
|
||||
- Mobile apps
|
||||
- Multi-storyteller support
|
||||
- Group chat rooms (for party discussions)
|
||||
@@ -1,502 +0,0 @@
|
||||
# 📝 Development Session Summary
|
||||
|
||||
**Date:** October 11, 2025
|
||||
**Project:** Storyteller RPG Application
|
||||
**Status:** ✅ Fully Functional MVP Complete
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Project Overview
|
||||
|
||||
Built a **storyteller-centric roleplaying application** where multiple AI character bots or human players interact with a storyteller through **completely isolated, private conversations**.
|
||||
|
||||
### Core Concept
|
||||
- **Characters communicate ONLY with the storyteller** (never with each other by default)
|
||||
- **Each character has separate memory/LLM sessions** - their responses are isolated
|
||||
- **Storyteller sees all conversations** but responds to each character individually
|
||||
- **Characters cannot see other characters' messages or responses**
|
||||
- Characters can use **different AI models** (GPT-4, Claude, Llama, etc.) giving each unique personalities
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture Built
|
||||
|
||||
### Backend: FastAPI + WebSockets
|
||||
**File:** `/home/aodhan/projects/apps/storyteller/main.py` (398 lines)
|
||||
|
||||
**Key Components:**
|
||||
1. **Data Models:**
|
||||
- `GameSession` - Manages the game session and all characters
|
||||
- `Character` - Stores character info, LLM model, and private conversation history
|
||||
- `Message` - Individual message with sender, content, timestamp
|
||||
- `ConnectionManager` - Handles WebSocket connections
|
||||
|
||||
2. **WebSocket Endpoints:**
|
||||
- `/ws/character/{session_id}/{character_id}` - Private character connection
|
||||
- `/ws/storyteller/{session_id}` - Storyteller dashboard connection
|
||||
|
||||
3. **REST Endpoints:**
|
||||
- `POST /sessions/` - Create new game session
|
||||
- `GET /sessions/{session_id}` - Get session details
|
||||
- `POST /sessions/{session_id}/characters/` - Add character to session
|
||||
- `GET /sessions/{session_id}/characters/{character_id}/conversation` - Get conversation history
|
||||
- `POST /sessions/{session_id}/generate_suggestion` - AI-assisted storyteller responses
|
||||
- `GET /models` - List available LLM models
|
||||
|
||||
4. **LLM Integration:**
|
||||
- **OpenAI**: GPT-4o, GPT-4 Turbo, GPT-3.5 Turbo
|
||||
- **OpenRouter**: Claude 3.5, Llama 3.1, Gemini Pro, Mistral, Cohere, 100+ models
|
||||
- `call_llm()` function routes to appropriate provider based on model ID
|
||||
- Each character can use a different model
|
||||
|
||||
5. **Message Flow:**
|
||||
```
|
||||
Character sends message → WebSocket → Stored in Character.conversation_history
|
||||
↓
|
||||
Forwarded to Storyteller
|
||||
↓
|
||||
Storyteller responds → WebSocket → Stored in Character.conversation_history
|
||||
↓
|
||||
Sent ONLY to that Character
|
||||
```
|
||||
|
||||
### Frontend: React
|
||||
**Files:**
|
||||
- `frontend/src/App.js` - Main router component
|
||||
- `frontend/src/components/SessionSetup.js` (180 lines) - Session creation/joining
|
||||
- `frontend/src/components/CharacterView.js` (141 lines) - Character interface
|
||||
- `frontend/src/components/StorytellerView.js` (243 lines) - Storyteller dashboard
|
||||
- `frontend/src/App.css` (704 lines) - Complete styling
|
||||
|
||||
**Key Features:**
|
||||
1. **SessionSetup Component:**
|
||||
- Create new session (becomes storyteller)
|
||||
- Join existing session (becomes character)
|
||||
- Select LLM model for character
|
||||
- Model selector fetches available models from backend
|
||||
|
||||
2. **CharacterView Component:**
|
||||
- Private conversation with storyteller
|
||||
- WebSocket connection for real-time updates
|
||||
- See scene narrations from storyteller
|
||||
- Character info display (name, description, personality)
|
||||
- Connection status indicator
|
||||
|
||||
3. **StorytellerView Component:**
|
||||
- Dashboard showing all characters
|
||||
- Click character to view their private conversation
|
||||
- Respond to characters individually
|
||||
- Narrate scenes visible to all characters
|
||||
- Pending response indicators (red badges)
|
||||
- Character cards showing:
|
||||
- Name, description, personality
|
||||
- LLM model being used
|
||||
- Message count
|
||||
- Pending status
|
||||
|
||||
4. **UI/UX Design:**
|
||||
- Beautiful gradient purple theme
|
||||
- Responsive design
|
||||
- Real-time message updates
|
||||
- Auto-scroll to latest messages
|
||||
- Clear visual distinction between sent/received messages
|
||||
- Session ID prominently displayed for sharing
|
||||
- Empty states with helpful instructions
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Key Technical Decisions
|
||||
|
||||
### 1. **Isolated Conversations (Privacy-First)**
|
||||
- Each `Character` object has its own `conversation_history: List[Message]`
|
||||
- Messages are never broadcast to all clients
|
||||
- WebSocket routing ensures messages only go to intended recipient
|
||||
- Storyteller has separate WebSocket endpoint to see all
|
||||
|
||||
### 2. **Multi-LLM Support**
|
||||
- Characters choose model at creation time
|
||||
- Stored in `Character.llm_model` field
|
||||
- Backend dynamically routes API calls based on model prefix:
|
||||
- `gpt-*` → OpenAI API
|
||||
- Everything else → OpenRouter API
|
||||
- Enables creative gameplay with different AI personalities
|
||||
|
||||
### 3. **In-Memory Storage (Current)**
|
||||
- `sessions: Dict[str, GameSession]` stores all active sessions
|
||||
- Fast and simple for MVP
|
||||
- **Limitation:** Data lost on server restart
|
||||
- **Next step:** Add database persistence (see NEXT_STEPS.md)
|
||||
|
||||
### 4. **WebSocket-First Architecture**
|
||||
- Real-time bidirectional communication
|
||||
- Native WebSocket API (not socket.io)
|
||||
- JSON message format with `type` field for routing
|
||||
- Separate connections for characters and storyteller
|
||||
|
||||
### 5. **Scene Narration System**
|
||||
- Storyteller can broadcast "scene" messages
|
||||
- Sent to all connected characters simultaneously
|
||||
- Stored in `GameSession.current_scene` and `scene_history`
|
||||
- Different from private character-storyteller messages
|
||||
|
||||
---
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
storyteller/
|
||||
├── main.py # FastAPI backend (398 lines)
|
||||
├── requirements.txt # Python dependencies
|
||||
├── .env.example # API key template
|
||||
├── .env # Your API keys (gitignored)
|
||||
├── README.md # Comprehensive documentation
|
||||
├── QUICKSTART.md # 5-minute setup guide
|
||||
├── NEXT_STEPS.md # Future development roadmap
|
||||
├── SESSION_SUMMARY.md # This file
|
||||
├── start.sh # Auto-start script
|
||||
├── dev.sh # Development mode script
|
||||
└── frontend/
|
||||
├── package.json # Node dependencies
|
||||
├── public/
|
||||
│ └── index.html # HTML template
|
||||
└── src/
|
||||
├── App.js # Main router
|
||||
├── App.css # All styles (704 lines)
|
||||
├── index.js # React entry point
|
||||
└── components/
|
||||
├── SessionSetup.js # Session creation/joining
|
||||
├── CharacterView.js # Character interface
|
||||
└── StorytellerView.js # Storyteller dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 How to Run
|
||||
|
||||
### Quick Start (Automated)
|
||||
```bash
|
||||
cd /home/aodhan/projects/apps/storyteller
|
||||
chmod +x start.sh
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### Manual Start
|
||||
```bash
|
||||
# Terminal 1 - Backend
|
||||
cd /home/aodhan/projects/apps/storyteller
|
||||
source .venv/bin/activate # or: source venv/bin/activate
|
||||
python main.py
|
||||
|
||||
# Terminal 2 - Frontend
|
||||
cd /home/aodhan/projects/apps/storyteller/frontend
|
||||
npm start
|
||||
```
|
||||
|
||||
### Environment Setup
|
||||
```bash
|
||||
# Copy example and add your API keys
|
||||
cp .env.example .env
|
||||
|
||||
# Edit .env and add at least one:
|
||||
# OPENAI_API_KEY=sk-... # For GPT models
|
||||
# OPENROUTER_API_KEY=sk-... # For Claude, Llama, etc.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Important Implementation Details
|
||||
|
||||
### WebSocket Message Types
|
||||
|
||||
**Character → Storyteller:**
|
||||
```json
|
||||
{
|
||||
"type": "message",
|
||||
"content": "I search the room for clues"
|
||||
}
|
||||
```
|
||||
|
||||
**Storyteller → Character:**
|
||||
```json
|
||||
{
|
||||
"type": "storyteller_response",
|
||||
"message": {
|
||||
"id": "...",
|
||||
"sender": "storyteller",
|
||||
"content": "You find a hidden letter",
|
||||
"timestamp": "2025-10-11T20:30:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Storyteller → All Characters:**
|
||||
```json
|
||||
{
|
||||
"type": "narrate_scene",
|
||||
"content": "The room grows dark as thunder rumbles"
|
||||
}
|
||||
```
|
||||
|
||||
**Storyteller receives character message:**
|
||||
```json
|
||||
{
|
||||
"type": "character_message",
|
||||
"character_id": "uuid",
|
||||
"character_name": "Aragorn",
|
||||
"message": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Character joined notification:**
|
||||
```json
|
||||
{
|
||||
"type": "character_joined",
|
||||
"character": {
|
||||
"id": "uuid",
|
||||
"name": "Legolas",
|
||||
"description": "...",
|
||||
"llm_model": "gpt-4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### LLM Integration
|
||||
|
||||
**Function:** `call_llm(model, messages, temperature, max_tokens)`
|
||||
|
||||
**Routing Logic:**
|
||||
```python
|
||||
if model.startswith("gpt-") or model.startswith("o1-"):
|
||||
# Use OpenAI client
|
||||
response = await client.chat.completions.create(...)
|
||||
else:
|
||||
# Use OpenRouter via httpx
|
||||
response = await http_client.post("https://openrouter.ai/api/v1/chat/completions", ...)
|
||||
```
|
||||
|
||||
**Available Models (as of this session):**
|
||||
- OpenAI: gpt-4o, gpt-4-turbo, gpt-4, gpt-3.5-turbo
|
||||
- Anthropic (via OpenRouter): claude-3.5-sonnet, claude-3-opus, claude-3-haiku
|
||||
- Meta: llama-3.1-70b, llama-3.1-8b
|
||||
- Google: gemini-pro-1.5
|
||||
- Mistral: mistral-large
|
||||
- Cohere: command-r-plus
|
||||
|
||||
---
|
||||
|
||||
## 🎨 UI/UX Highlights
|
||||
|
||||
### Color Scheme
|
||||
- Primary gradient: Purple (`#667eea` → `#764ba2`)
|
||||
- Background: White cards on gradient
|
||||
- Messages: Blue (sent) / Gray (received)
|
||||
- Pending indicators: Red badges
|
||||
- Status: Green (connected) / Gray (disconnected)
|
||||
|
||||
### Key UX Features
|
||||
1. **Session ID prominently displayed** for easy sharing
|
||||
2. **Pending response badges** show storyteller which characters are waiting
|
||||
3. **Character cards** with all relevant info at a glance
|
||||
4. **Empty states** guide users on what to do next
|
||||
5. **Connection status** always visible
|
||||
6. **Auto-scroll** to latest message
|
||||
7. **Keyboard shortcuts** (Enter to send)
|
||||
8. **Model selector** with descriptions helping users choose
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Known Limitations & TODO
|
||||
|
||||
### Current Limitations
|
||||
1. **No persistence** - Sessions lost on server restart
|
||||
2. **No authentication** - Anyone with session ID can join
|
||||
3. **No message editing/deletion** - Messages are permanent
|
||||
4. **No character limit** on messages (could be abused)
|
||||
5. **No rate limiting** - API calls not throttled
|
||||
6. **No offline support** - Requires active connection
|
||||
7. **No mobile optimization** - Works but could be better
|
||||
8. **No sound notifications** - Easy to miss new messages
|
||||
|
||||
### Security Considerations
|
||||
- **CORS is wide open** (`allow_origins=["*"]`) - Restrict in production
|
||||
- **No input validation** on message content - Add sanitization
|
||||
- **API keys in environment** - Good, but consider secrets manager
|
||||
- **No session expiration** - Sessions live forever in memory
|
||||
- **WebSocket not authenticated** - Anyone with session ID can connect
|
||||
|
||||
### Performance Considerations
|
||||
- **In-memory storage** - Won't scale to many sessions
|
||||
- **No message pagination** - All history loaded at once
|
||||
- **No connection pooling** - Each character = new WebSocket
|
||||
- **No caching** - LLM calls always go to API
|
||||
|
||||
---
|
||||
|
||||
## 💡 What Makes This Special
|
||||
|
||||
### Unique Features
|
||||
1. **Each character uses a different AI model** - Creates emergent gameplay
|
||||
2. **Completely private conversations** - True secret communication
|
||||
3. **Storyteller-centric design** - Built for tabletop RPG flow
|
||||
4. **Real-time updates** - Feels like a chat app
|
||||
5. **Model flexibility** - 100+ LLMs via OpenRouter
|
||||
6. **Zero configuration** - Works out of the box
|
||||
|
||||
### Design Philosophy
|
||||
- **Storyteller is the hub** - All communication flows through them
|
||||
- **Privacy first** - Characters truly can't see each other's messages
|
||||
- **Flexibility** - Support for any LLM model
|
||||
- **Simplicity** - Clean, intuitive interface
|
||||
- **Real-time** - No page refreshes needed
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Context for Continuing Development
|
||||
|
||||
### If Starting a New Chat Session
|
||||
|
||||
**What works:**
|
||||
- ✅ Backend fully functional with all endpoints
|
||||
- ✅ Frontend complete with all views
|
||||
- ✅ WebSocket communication working
|
||||
- ✅ Multi-LLM support implemented
|
||||
- ✅ Scene narration working
|
||||
- ✅ Private conversations isolated correctly
|
||||
|
||||
**Quick test to verify everything:**
|
||||
```bash
|
||||
# 1. Start servers
|
||||
./start.sh
|
||||
|
||||
# 2. Create session as storyteller
|
||||
# 3. Join session as character (new browser/incognito)
|
||||
# 4. Send message from character
|
||||
# 5. Verify storyteller sees it
|
||||
# 6. Respond from storyteller
|
||||
# 7. Verify character receives it
|
||||
# 8. Test scene narration
|
||||
```
|
||||
|
||||
**Common issues:**
|
||||
- **Port 8000/3000 already in use** - `start.sh` kills existing processes
|
||||
- **WebSocket won't connect** - Check backend is running, check browser console
|
||||
- **LLM not responding** - Verify API keys in `.env`
|
||||
- **npm/pip dependencies missing** - Run install commands
|
||||
|
||||
### Files to Modify for Common Tasks
|
||||
|
||||
**Add new WebSocket message type:**
|
||||
1. Update message handler in `main.py` (character or storyteller endpoint)
|
||||
2. Update frontend component to send/receive new type
|
||||
|
||||
**Add new REST endpoint:**
|
||||
1. Add `@app.post()` or `@app.get()` in `main.py`
|
||||
2. Add fetch call in appropriate frontend component
|
||||
|
||||
**Modify UI:**
|
||||
1. Edit component in `frontend/src/components/`
|
||||
2. Edit styles in `frontend/src/App.css`
|
||||
|
||||
**Add new LLM provider:**
|
||||
1. Update `call_llm()` function in `main.py`
|
||||
2. Update `get_available_models()` endpoint
|
||||
3. Add model options in `SessionSetup.js`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Project Statistics
|
||||
|
||||
- **Total Lines of Code:** ~1,700
|
||||
- **Backend:** ~400 lines (Python/FastAPI)
|
||||
- **Frontend:** ~1,300 lines (React/JavaScript/CSS)
|
||||
- **Time to MVP:** 1 session
|
||||
- **Dependencies:** 8 Python packages, 5 npm packages (core)
|
||||
- **API Endpoints:** 6 REST + 2 WebSocket
|
||||
- **React Components:** 3 main + 1 router
|
||||
- **Supported LLMs:** 15+ models across 6 providers
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Learning Resources Used
|
||||
|
||||
### Technologies
|
||||
- **FastAPI:** https://fastapi.tiangolo.com/
|
||||
- **WebSockets:** https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
||||
- **React:** https://react.dev/
|
||||
- **OpenAI API:** https://platform.openai.com/docs
|
||||
- **OpenRouter:** https://openrouter.ai/docs
|
||||
|
||||
### Key Concepts Implemented
|
||||
- WebSocket bidirectional communication
|
||||
- Async Python with FastAPI
|
||||
- React state management with hooks
|
||||
- Multi-provider LLM routing
|
||||
- Real-time message delivery
|
||||
- Isolated conversation contexts
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes for Future You
|
||||
|
||||
### Why certain decisions were made:
|
||||
- **WebSocket instead of polling:** Real-time updates without constant HTTP requests
|
||||
- **Separate endpoints for character/storyteller:** Clean separation of concerns, different message types
|
||||
- **In-memory storage first:** Fastest MVP, can migrate to DB later
|
||||
- **Multi-LLM from start:** Makes the app unique and interesting
|
||||
- **No socket.io:** Native WebSocket simpler for this use case
|
||||
- **Private conversations:** Core feature that differentiates from group chat apps
|
||||
|
||||
### What went smoothly:
|
||||
- FastAPI made WebSocket implementation easy
|
||||
- React components stayed clean and modular
|
||||
- OpenRouter integration was straightforward
|
||||
- UI came together nicely with gradients
|
||||
|
||||
### What could be improved:
|
||||
- Database persistence is the obvious next step
|
||||
- Error handling could be more robust
|
||||
- Mobile experience needs work
|
||||
- Need proper authentication system
|
||||
- Testing suite would be valuable
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Recommended Next Actions
|
||||
|
||||
**Immediate (Next Session):**
|
||||
1. Test the app end-to-end to ensure everything works after IDE crash
|
||||
2. Add AI suggestion button to storyteller UI (backend ready, just needs frontend)
|
||||
3. Implement session persistence with SQLite
|
||||
|
||||
**Short Term (This Week):**
|
||||
4. Add dice rolling system
|
||||
5. Add typing indicators
|
||||
6. Improve error messages
|
||||
|
||||
**Medium Term (This Month):**
|
||||
7. Add authentication
|
||||
8. Implement character sheets
|
||||
9. Add image generation for scenes
|
||||
|
||||
See **NEXT_STEPS.md** for detailed roadmap with priorities and implementation notes.
|
||||
|
||||
---
|
||||
|
||||
## 📞 Session Handoff Checklist
|
||||
|
||||
- ✅ All files verified and up-to-date
|
||||
- ✅ Architecture documented
|
||||
- ✅ Key decisions explained
|
||||
- ✅ Next steps outlined
|
||||
- ✅ Common issues documented
|
||||
- ✅ Code structure mapped
|
||||
- ✅ API contracts specified
|
||||
- ✅ Testing instructions provided
|
||||
|
||||
**You're ready to continue development!** 🎉
|
||||
|
||||
---
|
||||
|
||||
*Generated: October 11, 2025*
|
||||
*Project Location: `/home/aodhan/projects/apps/storyteller`*
|
||||
*Status: Production-ready MVP*
|
||||
283
docs/development/TESTING_GUIDE.md
Normal file
283
docs/development/TESTING_GUIDE.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# 🧪 Testing Guide - New Features
|
||||
|
||||
**Quick test scenarios for the enhanced message system and AI suggestions**
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
Both servers are running:
|
||||
- **Frontend:** http://localhost:3000
|
||||
- **Backend API:** http://localhost:8000
|
||||
- **API Docs:** http://localhost:8000/docs
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 1: AI-Assisted Responses ✨
|
||||
|
||||
**Time:** 2 minutes
|
||||
|
||||
1. Open http://localhost:3000
|
||||
2. Click "Create New Session"
|
||||
3. Enter session name: "Test Game"
|
||||
4. Click "Create Session"
|
||||
5. Copy the Session ID
|
||||
6. Open new browser tab (incognito/private)
|
||||
7. Paste Session ID and join as character:
|
||||
- Name: "Thorin"
|
||||
- Description: "A brave dwarf warrior"
|
||||
- Personality: "Serious and gruff"
|
||||
8. As Thorin, send a message: "I examine the dark cave entrance carefully"
|
||||
9. Switch back to Storyteller tab
|
||||
10. Click on Thorin in the character list
|
||||
11. Click "✨ AI Suggest" button
|
||||
12. Watch as AI generates a response
|
||||
13. Edit if needed and click "Send Private Response"
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ AI Suggest button appears
|
||||
- ✅ Shows "⏳ Generating..." while processing
|
||||
- ✅ Populates textarea with AI suggestion
|
||||
- ✅ Can edit before sending
|
||||
- ✅ Character receives the response
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 2: Private Messages 🔒
|
||||
|
||||
**Time:** 3 minutes
|
||||
|
||||
Using the same session from above:
|
||||
|
||||
1. As Thorin (character window):
|
||||
- Ensure message type is "🔒 Private"
|
||||
- Send: "I try to sneak past the guard"
|
||||
2. Open another incognito window
|
||||
3. Join same session as new character:
|
||||
- Name: "Elara"
|
||||
- Description: "An elven archer"
|
||||
4. As Elara, check if you see Thorin's message
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ Thorin's private message appears in storyteller view
|
||||
- ✅ Elara DOES NOT see Thorin's private message
|
||||
- ✅ Only Thorin and Storyteller see the private message
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 3: Public Messages 📢
|
||||
|
||||
**Time:** 3 minutes
|
||||
|
||||
Using characters from above:
|
||||
|
||||
1. As Thorin:
|
||||
- Select "📢 Public" from message type dropdown
|
||||
- Send: "I draw my axe and step forward boldly!"
|
||||
2. Check Storyteller view
|
||||
3. Check Elara's view
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ Message appears in "📢 Public Actions" section
|
||||
- ✅ Storyteller sees it in public feed
|
||||
- ✅ Elara sees it in her public feed
|
||||
- ✅ Message is visible to ALL characters
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 4: Mixed Messages 🔀
|
||||
|
||||
**Time:** 4 minutes
|
||||
|
||||
This is the most interesting feature!
|
||||
|
||||
1. As Thorin:
|
||||
- Select "🔀 Mixed" from message type dropdown
|
||||
- Public textarea: "I approach the merchant and start haggling loudly"
|
||||
- Private textarea: "While arguing, I signal to Elara to check the back room"
|
||||
- Click "Send Mixed Message"
|
||||
2. Check what each player sees:
|
||||
- As Elara: Look at public feed
|
||||
- As Storyteller: Look at both public feed and Thorin's private conversation
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ Elara sees in public feed: "I approach the merchant and start haggling loudly"
|
||||
- ✅ Elara DOES NOT see the private signal
|
||||
- ✅ Storyteller sees BOTH parts
|
||||
- ✅ Public action broadcast to all
|
||||
- ✅ Secret signal only to storyteller
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 5: Multiple Characters Interaction 👥
|
||||
|
||||
**Time:** 5 minutes
|
||||
|
||||
**Goal:** Test that the public/private system works with multiple players
|
||||
|
||||
1. Keep Thorin and Elara connected
|
||||
2. Have both send public messages:
|
||||
- Thorin (public): "I stand guard at the door"
|
||||
- Elara (public): "I scout ahead quietly"
|
||||
3. Have both send private messages:
|
||||
- Thorin (private): "I'm really tired and might fall asleep"
|
||||
- Elara (private): "I don't trust Thorin, something seems off"
|
||||
4. Check each view:
|
||||
- Thorin's view
|
||||
- Elara's view
|
||||
- Storyteller's view
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ Both characters see all public messages
|
||||
- ✅ Thorin only sees his own private messages
|
||||
- ✅ Elara only sees her own private messages
|
||||
- ✅ Storyteller sees ALL messages from both
|
||||
- ✅ Each character has isolated private conversation with storyteller
|
||||
|
||||
---
|
||||
|
||||
## Test Scenario 6: Storyteller Responses with AI 🎲
|
||||
|
||||
**Time:** 5 minutes
|
||||
|
||||
1. As Storyteller, select Thorin
|
||||
2. Review his private message about being tired
|
||||
3. Click "✨ AI Suggest"
|
||||
4. Review the AI-generated response
|
||||
5. Edit to add personal touch
|
||||
6. Send to Thorin
|
||||
7. Select Elara
|
||||
8. Use AI Suggest for her as well
|
||||
9. Send different response to Elara
|
||||
|
||||
**Expected Results:**
|
||||
- ✅ AI generates contextual responses based on character's LLM model
|
||||
- ✅ Each response is private (other character doesn't see it)
|
||||
- ✅ Can edit AI suggestions before sending
|
||||
- ✅ Each character receives personalized response
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Known Issues to Test For
|
||||
|
||||
### Minor Issues
|
||||
- [ ] Do public messages show character names clearly?
|
||||
- [ ] Does mixed message format look good in all views?
|
||||
- [ ] Are timestamps readable?
|
||||
- [ ] Does page refresh lose messages? (Yes - needs DB)
|
||||
|
||||
### Edge Cases
|
||||
- [ ] What happens if character disconnects during message?
|
||||
- [ ] Can storyteller respond to character with no messages?
|
||||
- [ ] What if AI Suggest fails (API error)?
|
||||
- [ ] How does UI handle very long messages?
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Feature Validation Checklist
|
||||
|
||||
### Enhanced Message System
|
||||
- [ ] Private messages stay private
|
||||
- [ ] Public messages broadcast correctly
|
||||
- [ ] Mixed messages split properly
|
||||
- [ ] Message type selector works
|
||||
- [ ] UI distinguishes message types visually
|
||||
|
||||
### AI Suggestions
|
||||
- [ ] Button appears in storyteller view
|
||||
- [ ] Loading state shows during generation
|
||||
- [ ] Suggestion populates textarea
|
||||
- [ ] Can edit before sending
|
||||
- [ ] Works with all character LLM models
|
||||
|
||||
### Real-time Updates
|
||||
- [ ] Messages appear instantly
|
||||
- [ ] Character list updates when players join
|
||||
- [ ] Pending indicators work
|
||||
- [ ] Connection status accurate
|
||||
|
||||
---
|
||||
|
||||
## 📊 Performance Tests
|
||||
|
||||
### Load Testing (Optional)
|
||||
1. Open 5+ character windows
|
||||
2. Send public messages rapidly
|
||||
3. Check if all see updates
|
||||
4. Monitor for lag or missed messages
|
||||
|
||||
**Expected:** Should handle 5-10 concurrent users smoothly
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Visual Inspection
|
||||
|
||||
### Character View
|
||||
- [ ] Public feed is clearly distinguished
|
||||
- [ ] Private conversation is obvious
|
||||
- [ ] Message type selector is intuitive
|
||||
- [ ] Mixed message form is clear
|
||||
- [ ] Current scene displays properly
|
||||
|
||||
### Storyteller View
|
||||
- [ ] Character cards show correctly
|
||||
- [ ] Pending indicators visible
|
||||
- [ ] Public feed displays recent actions
|
||||
- [ ] AI Suggest button prominent
|
||||
- [ ] Conversation switching smooth
|
||||
|
||||
---
|
||||
|
||||
## 💡 Testing Tips
|
||||
|
||||
1. **Use Incognito Windows:** Easy way to test multiple characters
|
||||
2. **Keep DevTools Open:** Check console for errors
|
||||
3. **Test on Mobile:** Responsive design important
|
||||
4. **Try Different LLMs:** Each character can use different model
|
||||
5. **Test Disconnect/Reconnect:** Close tab and rejoin
|
||||
|
||||
---
|
||||
|
||||
## 🎬 Demo Script
|
||||
|
||||
**For showing off the features:**
|
||||
|
||||
1. Create session as Storyteller
|
||||
2. Join as 2 characters in separate windows
|
||||
3. Character 1 sends public: "I greet everyone cheerfully"
|
||||
4. Character 2 sees it and responds public: "I nod silently"
|
||||
5. Character 1 sends mixed:
|
||||
- Public: "I offer to share my food"
|
||||
- Private: "I'm watching Character 2, they seem suspicious"
|
||||
6. Character 2 only sees the public offer
|
||||
7. Storyteller clicks Character 1, uses AI Suggest
|
||||
8. Sends personalized response to Character 1
|
||||
9. Storyteller responds to Character 2 differently
|
||||
|
||||
**This demonstrates:**
|
||||
- Public broadcast
|
||||
- Private isolation
|
||||
- Mixed message splitting
|
||||
- AI-assisted responses
|
||||
- Personalized storytelling
|
||||
|
||||
---
|
||||
|
||||
## ✅ Sign-Off Checklist
|
||||
|
||||
Before considering Phase 1 complete:
|
||||
|
||||
- [ ] All 6 test scenarios pass
|
||||
- [ ] No console errors
|
||||
- [ ] UI looks good
|
||||
- [ ] Messages route correctly
|
||||
- [ ] AI suggestions work
|
||||
- [ ] Real-time updates function
|
||||
- [ ] Multiple characters tested
|
||||
- [ ] Storyteller view functional
|
||||
|
||||
---
|
||||
|
||||
**Happy Testing!** 🎉
|
||||
|
||||
If you find any issues, note them in `docs/development/MVP_PROGRESS.md` under "Known Issues"
|
||||
400
docs/development/TEST_RESULTS.md
Normal file
400
docs/development/TEST_RESULTS.md
Normal file
@@ -0,0 +1,400 @@
|
||||
# 🧪 Test Suite Results
|
||||
|
||||
**Date:** October 11, 2025
|
||||
**Branch:** mvp-phase-02
|
||||
**Test Framework:** pytest 7.4.3
|
||||
**Coverage:** 78% (219 statements, 48 missed)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Test Summary
|
||||
|
||||
### Overall Results
|
||||
- ✅ **48 Tests Passed**
|
||||
- ❌ **6 Tests Failed**
|
||||
- ⚠️ **10 Warnings**
|
||||
- **Total Tests:** 54
|
||||
- **Success Rate:** 88.9%
|
||||
|
||||
---
|
||||
|
||||
## ✅ Passing Test Suites
|
||||
|
||||
### Test Models (test_models.py)
|
||||
**Status:** ✅ All Passed (25/25)
|
||||
|
||||
Tests all Pydantic models work correctly:
|
||||
|
||||
#### TestMessage Class
|
||||
- ✅ `test_message_creation_default` - Default message creation
|
||||
- ✅ `test_message_creation_private` - Private message properties
|
||||
- ✅ `test_message_creation_public` - Public message properties
|
||||
- ✅ `test_message_creation_mixed` - Mixed message with public/private parts
|
||||
- ✅ `test_message_timestamp_format` - ISO format timestamps
|
||||
- ✅ `test_message_unique_ids` - UUID generation
|
||||
|
||||
#### TestCharacter Class
|
||||
- ✅ `test_character_creation_minimal` - Basic character creation
|
||||
- ✅ `test_character_creation_full` - Full character with all fields
|
||||
- ✅ `test_character_conversation_history` - Message history management
|
||||
- ✅ `test_character_pending_response_flag` - Pending status tracking
|
||||
|
||||
#### TestGameSession Class
|
||||
- ✅ `test_session_creation` - Session initialization
|
||||
- ✅ `test_session_add_character` - Adding characters
|
||||
- ✅ `test_session_multiple_characters` - Multiple character management
|
||||
- ✅ `test_session_scene_history` - Scene tracking
|
||||
- ✅ `test_session_public_messages` - Public message feed
|
||||
|
||||
#### TestMessageVisibility Class
|
||||
- ✅ `test_private_message_properties` - Private message structure
|
||||
- ✅ `test_public_message_properties` - Public message structure
|
||||
- ✅ `test_mixed_message_properties` - Mixed message splitting
|
||||
|
||||
#### TestCharacterIsolation Class
|
||||
- ✅ `test_separate_conversation_histories` - Conversation isolation
|
||||
- ✅ `test_public_messages_vs_private_history` - Feed distinction
|
||||
|
||||
**Key Validations:**
|
||||
- Message visibility system working correctly
|
||||
- Character isolation maintained
|
||||
- UUID generation for all entities
|
||||
- Conversation history preservation
|
||||
|
||||
### Test API (test_api.py)
|
||||
**Status:** ✅ All Passed (23/23)
|
||||
|
||||
Tests all REST API endpoints:
|
||||
|
||||
#### TestSessionEndpoints
|
||||
- ✅ `test_create_session` - POST /sessions/
|
||||
- ✅ `test_create_session_generates_unique_ids` - ID uniqueness
|
||||
- ✅ `test_get_session` - GET /sessions/{id}
|
||||
- ✅ `test_get_nonexistent_session` - 404 handling
|
||||
|
||||
#### TestCharacterEndpoints
|
||||
- ✅ `test_add_character_minimal` - POST /characters/ (minimal)
|
||||
- ✅ `test_add_character_full` - POST /characters/ (full)
|
||||
- ✅ `test_add_character_to_nonexistent_session` - Error handling
|
||||
- ✅ `test_add_multiple_characters` - Multiple character creation
|
||||
- ✅ `test_get_character_conversation` - GET /conversation
|
||||
|
||||
#### TestModelsEndpoint
|
||||
- ✅ `test_get_models` - GET /models
|
||||
- ✅ `test_models_include_required_fields` - Model structure validation
|
||||
|
||||
#### TestPendingMessages
|
||||
- ✅ `test_get_pending_messages_empty` - Empty pending list
|
||||
- ✅ `test_get_pending_messages_nonexistent_session` - Error handling
|
||||
|
||||
#### TestSessionState
|
||||
- ✅ `test_session_persists_in_memory` - State persistence
|
||||
- ✅ `test_public_messages_in_session` - public_messages field exists
|
||||
|
||||
#### TestMessageVisibilityAPI
|
||||
- ✅ `test_session_includes_public_messages_field` - API includes new fields
|
||||
- ✅ `test_character_has_conversation_history` - History field exists
|
||||
|
||||
**Key Validations:**
|
||||
- All REST endpoints working
|
||||
- Proper error handling (404s)
|
||||
- New message fields in API responses
|
||||
- Session state preservation
|
||||
|
||||
---
|
||||
|
||||
## ❌ Failing Tests
|
||||
|
||||
### Test WebSockets (test_websockets.py)
|
||||
**Status:** ⚠️ 6 Failed, 17 Passed (17/23)
|
||||
|
||||
#### Failing Tests
|
||||
|
||||
1. **`test_character_sends_message`**
|
||||
- **Issue:** Message not persisting in character history
|
||||
- **Cause:** TestClient WebSocket doesn't process async handlers fully
|
||||
- **Impact:** Low - Manual testing shows this works in production
|
||||
|
||||
2. **`test_private_message_routing`**
|
||||
- **Issue:** Private messages not added to history
|
||||
- **Cause:** Same as above - async processing issue in tests
|
||||
- **Impact:** Low - Functionality works in actual app
|
||||
|
||||
3. **`test_public_message_routing`**
|
||||
- **Issue:** Public messages not in public feed
|
||||
- **Cause:** TestClient limitation with WebSocket handlers
|
||||
- **Impact:** Low - Works in production
|
||||
|
||||
4. **`test_mixed_message_routing`**
|
||||
- **Issue:** Mixed messages not routing properly
|
||||
- **Cause:** Async handler not completing in test
|
||||
- **Impact:** Low - Feature works in actual app
|
||||
|
||||
5. **`test_storyteller_responds_to_character`**
|
||||
- **Issue:** Response not added to conversation
|
||||
- **Cause:** WebSocket send_json() not triggering handlers
|
||||
- **Impact:** Low - Production functionality confirmed
|
||||
|
||||
6. **`test_storyteller_narrates_scene`**
|
||||
- **Issue:** Scene not updating in session
|
||||
- **Cause:** Async processing not completing
|
||||
- **Impact:** Low - Scene narration works in app
|
||||
|
||||
#### Passing WebSocket Tests
|
||||
|
||||
- ✅ `test_character_websocket_connection` - Connection succeeds
|
||||
- ✅ `test_character_websocket_invalid_session` - Error handling
|
||||
- ✅ `test_character_websocket_invalid_character` - Error handling
|
||||
- ✅ `test_character_receives_history` - History delivery works
|
||||
- ✅ `test_storyteller_websocket_connection` - ST connection works
|
||||
- ✅ `test_storyteller_sees_all_characters` - ST sees all data
|
||||
- ✅ `test_storyteller_websocket_invalid_session` - Error handling
|
||||
- ✅ `test_multiple_character_connections` - Multiple connections
|
||||
- ✅ `test_storyteller_and_character_simultaneous` - Concurrent connections
|
||||
- ✅ `test_messages_persist_after_disconnect` - Persistence works
|
||||
- ✅ `test_reconnect_receives_history` - Reconnection works
|
||||
|
||||
**Root Cause Analysis:**
|
||||
|
||||
The failing tests are all related to a limitation of FastAPI's TestClient with WebSockets. When using `websocket.send_json()` in tests, the message is sent but the backend's async `onmessage` handler doesn't complete synchronously in the test context.
|
||||
|
||||
**Why This Is Acceptable:**
|
||||
1. **Production Works:** Manual testing confirms all features work
|
||||
2. **Connection Tests Pass:** WebSocket connections themselves work
|
||||
3. **State Tests Pass:** Message persistence after disconnect works
|
||||
4. **Test Framework Limitation:** Not a code issue
|
||||
|
||||
**Solutions:**
|
||||
1. Accept these failures (recommended - they test production behavior we've manually verified)
|
||||
2. Mock the WebSocket handlers for unit testing
|
||||
3. Use integration tests with real WebSocket connections
|
||||
4. Add e2e tests with Playwright
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Warnings
|
||||
|
||||
### Pydantic Deprecation Warnings (10 occurrences)
|
||||
|
||||
**Warning:**
|
||||
```
|
||||
PydanticDeprecatedSince20: The `dict` method is deprecated;
|
||||
use `model_dump` instead.
|
||||
```
|
||||
|
||||
**Locations in main.py:**
|
||||
- Line 152: `msg.dict()` in character WebSocket
|
||||
- Line 180, 191: `message.dict()` in character message routing
|
||||
- Line 234: `msg.dict()` in storyteller state
|
||||
|
||||
**Fix Required:**
|
||||
Replace all `.dict()` calls with `.model_dump()` for Pydantic V2 compatibility.
|
||||
|
||||
**Impact:** Low - Works fine but should be updated for future Pydantic v3
|
||||
|
||||
---
|
||||
|
||||
## 📈 Code Coverage
|
||||
|
||||
**Overall Coverage:** 78% (219 statements, 48 missed)
|
||||
|
||||
### Covered Code
|
||||
- ✅ Models (Message, Character, GameSession) - 100%
|
||||
- ✅ Session management endpoints - 95%
|
||||
- ✅ Character management endpoints - 95%
|
||||
- ✅ WebSocket connection handling - 85%
|
||||
- ✅ Message routing logic - 80%
|
||||
|
||||
### Uncovered Code (48 statements)
|
||||
Main gaps in coverage:
|
||||
|
||||
1. **LLM Integration (lines 288-327)**
|
||||
- `call_llm()` function
|
||||
- OpenAI API calls
|
||||
- OpenRouter API calls
|
||||
- **Reason:** Requires API keys and external services
|
||||
- **Fix:** Mock API responses in tests
|
||||
|
||||
2. **AI Suggestion Endpoint (lines 332-361)**
|
||||
- `/generate_suggestion` endpoint
|
||||
- Context building
|
||||
- LLM prompt construction
|
||||
- **Reason:** Depends on LLM integration
|
||||
- **Fix:** Add mocked tests
|
||||
|
||||
3. **Models Endpoint (lines 404-407)**
|
||||
- `/models` endpoint branches
|
||||
- **Reason:** Simple branches, low priority
|
||||
- **Fix:** Add tests for different API key configurations
|
||||
|
||||
4. **Pending Messages Endpoint (lines 418, 422, 437-438)**
|
||||
- Edge cases in pending message handling
|
||||
- **Reason:** Not exercised in current tests
|
||||
- **Fix:** Add edge case tests
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Test Quality Assessment
|
||||
|
||||
### Strengths
|
||||
✅ **Comprehensive Model Testing** - All Pydantic models fully tested
|
||||
✅ **API Endpoint Coverage** - All REST endpoints have tests
|
||||
✅ **Error Handling** - 404s and invalid inputs tested
|
||||
✅ **Isolation Testing** - Character privacy tested
|
||||
✅ **State Persistence** - Session state verified
|
||||
✅ **Connection Testing** - WebSocket connections validated
|
||||
|
||||
### Areas for Improvement
|
||||
⚠️ **WebSocket Handlers** - Need better async testing approach
|
||||
⚠️ **LLM Integration** - Needs mocked tests
|
||||
⚠️ **AI Suggestions** - Not tested yet
|
||||
⚠️ **Pydantic V2** - Update deprecated .dict() calls
|
||||
|
||||
---
|
||||
|
||||
## 📝 Recommendations
|
||||
|
||||
### Immediate (Before Phase 2)
|
||||
|
||||
1. **Fix Pydantic Deprecation Warnings**
|
||||
```python
|
||||
# Replace in main.py
|
||||
msg.dict() → msg.model_dump()
|
||||
```
|
||||
**Time:** 5 minutes
|
||||
**Priority:** Medium
|
||||
|
||||
2. **Accept WebSocket Test Failures**
|
||||
- Document as known limitation
|
||||
- Features work in production
|
||||
- Add integration tests later
|
||||
**Time:** N/A
|
||||
**Priority:** Low
|
||||
|
||||
### Phase 2 Test Additions
|
||||
|
||||
3. **Add Character Profile Tests**
|
||||
- Test race/class/personality fields
|
||||
- Test profile-based LLM prompts
|
||||
- Test character import/export
|
||||
**Time:** 2 hours
|
||||
**Priority:** High
|
||||
|
||||
4. **Mock LLM Integration**
|
||||
```python
|
||||
@pytest.fixture
|
||||
def mock_llm_response():
|
||||
return "Mocked AI response"
|
||||
```
|
||||
**Time:** 1 hour
|
||||
**Priority:** Medium
|
||||
|
||||
5. **Add Integration Tests**
|
||||
- Real WebSocket connections
|
||||
- End-to-end message flow
|
||||
- Multi-character scenarios
|
||||
**Time:** 3 hours
|
||||
**Priority:** Medium
|
||||
|
||||
### Future (Post-MVP)
|
||||
|
||||
6. **E2E Tests with Playwright**
|
||||
- Browser automation
|
||||
- Full user flows
|
||||
- Visual regression testing
|
||||
**Time:** 1 week
|
||||
**Priority:** Low
|
||||
|
||||
7. **Load Testing**
|
||||
- Concurrent users
|
||||
- Message throughput
|
||||
- WebSocket stability
|
||||
**Time:** 2 days
|
||||
**Priority:** Low
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Running Tests
|
||||
|
||||
### Run All Tests
|
||||
```bash
|
||||
.venv/bin/pytest
|
||||
```
|
||||
|
||||
### Run Specific Test File
|
||||
```bash
|
||||
.venv/bin/pytest tests/test_models.py -v
|
||||
```
|
||||
|
||||
### Run Specific Test
|
||||
```bash
|
||||
.venv/bin/pytest tests/test_models.py::TestMessage::test_message_creation_default -v
|
||||
```
|
||||
|
||||
### Run with Coverage Report
|
||||
```bash
|
||||
.venv/bin/pytest --cov=main --cov-report=html
|
||||
# Open htmlcov/index.html in browser
|
||||
```
|
||||
|
||||
### Run Only Passing Tests (Skip WebSocket)
|
||||
```bash
|
||||
.venv/bin/pytest tests/test_models.py tests/test_api.py -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Test Statistics
|
||||
|
||||
| Category | Count | Percentage |
|
||||
|----------|-------|------------|
|
||||
| **Total Tests** | 54 | 100% |
|
||||
| **Passed** | 48 | 88.9% |
|
||||
| **Failed** | 6 | 11.1% |
|
||||
| **Warnings** | 10 | N/A |
|
||||
| **Code Coverage** | 78% | N/A |
|
||||
|
||||
### Test Distribution
|
||||
- **Model Tests:** 25 (46%)
|
||||
- **API Tests:** 23 (43%)
|
||||
- **WebSocket Tests:** 6 failed + 17 passed = 23 (43%) ← Note: Overlap with failed tests
|
||||
|
||||
### Coverage Distribution
|
||||
- **Covered:** 171 statements (78%)
|
||||
- **Missed:** 48 statements (22%)
|
||||
- **Main Focus:** Core business logic, models, API
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
**The test suite is production-ready** with minor caveats:
|
||||
|
||||
1. **Core Functionality Fully Tested**
|
||||
- Models work correctly
|
||||
- API endpoints function properly
|
||||
- Message visibility system validated
|
||||
- Character isolation confirmed
|
||||
|
||||
2. **Known Limitations**
|
||||
- WebSocket async tests fail due to test framework
|
||||
- Production functionality manually verified
|
||||
- Not a blocker for Phase 2
|
||||
|
||||
3. **Code Quality**
|
||||
- 78% coverage is excellent for MVP
|
||||
- Critical paths all tested
|
||||
- Error handling validated
|
||||
|
||||
4. **Next Steps**
|
||||
- Fix Pydantic warnings (5 min)
|
||||
- Add Phase 2 character profile tests
|
||||
- Consider integration tests later
|
||||
|
||||
**Recommendation:** ✅ **Proceed with Phase 2 implementation**
|
||||
|
||||
The failing WebSocket tests are a testing framework limitation, not code issues. All manual testing confirms the features work correctly in production. The 88.9% pass rate and 78% code coverage provide strong confidence in the codebase.
|
||||
|
||||
---
|
||||
|
||||
**Great job setting up the test suite!** 🎉 This gives us a solid foundation to build Phase 2 with confidence.
|
||||
393
docs/features/CONTEXTUAL_RESPONSE_FEATURE.md
Normal file
393
docs/features/CONTEXTUAL_RESPONSE_FEATURE.md
Normal file
@@ -0,0 +1,393 @@
|
||||
# 🧠 Context-Aware Response Generator
|
||||
|
||||
**Feature Added:** October 11, 2025
|
||||
**Status:** ✅ Complete and Tested
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Context-Aware Response Generator allows storytellers to generate AI responses that take into account multiple characters' actions and messages simultaneously. This is a powerful tool for creating cohesive narratives that incorporate everyone's contributions.
|
||||
|
||||
---
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. **Multi-Character Selection** 🎭
|
||||
- Select one or more characters to include in the context
|
||||
- Visual indicators show which characters have pending messages
|
||||
- "Select All Pending" quick action button
|
||||
- Character selection with checkboxes showing message count
|
||||
|
||||
### 2. **Two Response Types** 📝
|
||||
|
||||
#### Scene Description (Broadcast)
|
||||
- Generates a narrative that addresses all selected characters
|
||||
- Can be used as a scene narration (broadcast to all)
|
||||
- Perfect for environmental descriptions or group events
|
||||
|
||||
#### Individual Responses (Private)
|
||||
- Generates personalized responses for each selected character
|
||||
- **Automatically parses and distributes** responses to individual characters
|
||||
- Sends privately to each character's conversation
|
||||
- Clears pending response flags
|
||||
|
||||
### 3. **Smart Context Building** 🔍
|
||||
|
||||
The system automatically gathers and includes:
|
||||
- Current scene description
|
||||
- Recent public actions (last 5)
|
||||
- Each character's profile (name, description, personality)
|
||||
- Recent conversation history (last 3 messages per character)
|
||||
- Optional additional context from storyteller
|
||||
|
||||
### 4. **Response Parsing** 🔧
|
||||
|
||||
For individual responses, the system recognizes multiple formats:
|
||||
```
|
||||
**For Bargin:** Your response here
|
||||
**For Willow:** Your response here
|
||||
|
||||
or
|
||||
|
||||
For Bargin: Your response here
|
||||
For Willow: Your response here
|
||||
```
|
||||
|
||||
The backend automatically:
|
||||
1. Parses each character's section
|
||||
2. Adds to their private conversation history
|
||||
3. Clears their pending response flag
|
||||
4. Sends via WebSocket if connected
|
||||
|
||||
---
|
||||
|
||||
## How to Use
|
||||
|
||||
### As a Storyteller:
|
||||
|
||||
1. **Open the Generator**
|
||||
- Click "▶ Show Generator" in the storyteller dashboard
|
||||
- The section expands with all controls
|
||||
|
||||
2. **Select Characters**
|
||||
- Check the boxes for characters you want to include
|
||||
- Or click "Select All Pending" for quick selection
|
||||
- See selection summary below checkboxes
|
||||
|
||||
3. **Choose Response Type**
|
||||
- **Scene Description:** For general narration or environmental descriptions
|
||||
- **Individual Responses:** For personalized replies to each character
|
||||
|
||||
4. **Configure Options**
|
||||
- Select LLM model (GPT-4o, GPT-4, etc.)
|
||||
- Add optional context/guidance for the AI
|
||||
|
||||
5. **Generate**
|
||||
- Click "✨ Generate Context-Aware Response"
|
||||
- Wait for AI generation (a few seconds)
|
||||
- Review the generated response
|
||||
|
||||
6. **Use the Response**
|
||||
- For scenes: Click "Use as Scene" to populate the scene textarea
|
||||
- For individual: Responses are automatically sent to characters
|
||||
- You'll get a confirmation alert showing who received responses
|
||||
|
||||
---
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Backend Endpoint
|
||||
|
||||
**POST** `/sessions/{session_id}/generate_contextual_response`
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"character_ids": ["char-id-1", "char-id-2"],
|
||||
"response_type": "individual" | "scene",
|
||||
"model": "gpt-4o",
|
||||
"additional_context": "Make it dramatic"
|
||||
}
|
||||
```
|
||||
|
||||
**Response (Individual):**
|
||||
```json
|
||||
{
|
||||
"response": "Full generated response with all sections",
|
||||
"model_used": "gpt-4o",
|
||||
"characters_included": [{"id": "...", "name": "..."}],
|
||||
"response_type": "individual",
|
||||
"individual_responses_sent": {
|
||||
"Bargin": "Individual response text",
|
||||
"Willow": "Individual response text"
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### Context Building
|
||||
|
||||
The prompt sent to the LLM includes:
|
||||
|
||||
```
|
||||
You are the storyteller/game master in an RPG session. Here's what the characters have done:
|
||||
|
||||
Current Scene: [if set]
|
||||
|
||||
Recent public actions:
|
||||
- Public message 1
|
||||
- Public message 2
|
||||
|
||||
Character: Bargin
|
||||
Description: A dwarf warrior
|
||||
Personality: Gruff and brave
|
||||
Recent messages:
|
||||
Bargin: I push open the door
|
||||
You (Storyteller): You hear creaking hinges
|
||||
|
||||
Character: Willow
|
||||
Description: An elven archer
|
||||
Personality: Cautious and observant
|
||||
Recent messages:
|
||||
Willow: I look for traps
|
||||
You (Storyteller): Roll for perception
|
||||
|
||||
Additional context: [if provided]
|
||||
|
||||
Generate [scene/individual responses based on type]
|
||||
```
|
||||
|
||||
### Response Parsing (Individual Mode)
|
||||
|
||||
The backend uses regex patterns to extract individual responses:
|
||||
|
||||
```python
|
||||
patterns = [
|
||||
r'\*\*For CharName:\*\*\s*(.*?)(?=\*\*For\s+\w+:|\Z)',
|
||||
r'For CharName:\s*(.*?)(?=For\s+\w+:|\Z)',
|
||||
r'\*\*CharName:\*\*\s*(.*?)(?=\*\*\w+:|\Z)',
|
||||
r'CharName:\s*(.*?)(?=\w+:|\Z)',
|
||||
]
|
||||
```
|
||||
|
||||
Each matched section is:
|
||||
1. Extracted and trimmed
|
||||
2. Added to character's conversation history
|
||||
3. Sent via WebSocket if character is connected
|
||||
4. Pending flag cleared
|
||||
|
||||
---
|
||||
|
||||
## UI Components
|
||||
|
||||
### Generator Section
|
||||
|
||||
Located in `StorytellerView`, between the scene section and character list:
|
||||
|
||||
**Visual Design:**
|
||||
- Pink/red gradient header (stands out from other sections)
|
||||
- Collapsible with show/hide toggle
|
||||
- Clear sections for each configuration step
|
||||
- Visual feedback for pending characters
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 🧠 AI Context-Aware Response Generator │
|
||||
│ ▼ Hide │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Description text │
|
||||
│ │
|
||||
│ Character Selection │
|
||||
│ ☑ Bargin (●) (3 msgs) │
|
||||
│ ☑ Willow (2 msgs) │
|
||||
│ │
|
||||
│ Response Type: [Scene/Individual ▼] │
|
||||
│ Model: [GPT-4o ▼] │
|
||||
│ Additional Context: [textarea] │
|
||||
│ │
|
||||
│ [✨ Generate Context-Aware Response] │
|
||||
│ │
|
||||
│ Generated Response: │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ Response text here... │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ [Use as Scene] [Clear] │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
### For Storytellers
|
||||
✅ **Save Time** - Generate responses considering all players at once
|
||||
✅ **Consistency** - AI maintains narrative coherence across characters
|
||||
✅ **Context Awareness** - Responses reference recent actions and personality
|
||||
✅ **Flexibility** - Choose between broadcast scenes or individual replies
|
||||
✅ **Efficiency** - Automatic distribution of individual responses
|
||||
|
||||
### For Players
|
||||
✅ **Better Immersion** - Responses feel more connected to the story
|
||||
✅ **No Waiting** - Storyteller can respond to multiple players quickly
|
||||
✅ **Personalization** - Individual responses tailored to each character
|
||||
✅ **Privacy Maintained** - Individual responses still private
|
||||
|
||||
---
|
||||
|
||||
## Example Use Cases
|
||||
|
||||
### Use Case 1: Party Splits Up
|
||||
**Scenario:** Bargin goes through the front door, Willow scouts around back
|
||||
|
||||
**Action:**
|
||||
1. Select both Bargin and Willow
|
||||
2. Choose "Individual Responses"
|
||||
3. Add context: "The building is guarded"
|
||||
4. Generate
|
||||
|
||||
**Result:**
|
||||
- Bargin gets: "As you push open the door, guards immediately turn toward you..."
|
||||
- Willow gets: "Around the back, you spot an unguarded window..."
|
||||
|
||||
### Use Case 2: Group Enters New Area
|
||||
**Scenario:** All players enter a mysterious temple
|
||||
|
||||
**Action:**
|
||||
1. Select all characters
|
||||
2. Choose "Scene Description"
|
||||
3. Generate
|
||||
|
||||
**Result:**
|
||||
A cohesive scene describing the temple that references all characters' recent actions and reactions.
|
||||
|
||||
### Use Case 3: Quick Responses to Pending Messages
|
||||
**Scenario:** 3 characters have asked questions
|
||||
|
||||
**Action:**
|
||||
1. Click "Select All Pending (3)"
|
||||
2. Choose "Individual Responses"
|
||||
3. Generate
|
||||
|
||||
**Result:**
|
||||
All three characters receive personalized answers, pending flags cleared.
|
||||
|
||||
---
|
||||
|
||||
## Additional Feature: Session ID Copy Button
|
||||
|
||||
**Also Added:** Copy button next to Session ID in Storyteller dashboard
|
||||
|
||||
**Usage:**
|
||||
- Click "📋 Copy" button next to the Session ID
|
||||
- ID copied to clipboard
|
||||
- Alert confirms successful copy
|
||||
- Makes sharing sessions easy
|
||||
|
||||
**Location:** Storyteller header, next to session ID code
|
||||
|
||||
---
|
||||
|
||||
## CSS Classes Added
|
||||
|
||||
```css
|
||||
.contextual-section
|
||||
.contextual-header
|
||||
.contextual-generator
|
||||
.contextual-description
|
||||
.character-selection
|
||||
.selection-header
|
||||
.btn-small
|
||||
.character-checkboxes
|
||||
.character-checkbox
|
||||
.checkbox-label
|
||||
.pending-badge-small
|
||||
.message-count
|
||||
.selection-summary
|
||||
.response-type-selector
|
||||
.response-type-help
|
||||
.model-selector-contextual
|
||||
.additional-context
|
||||
.btn-large
|
||||
.generated-response
|
||||
.response-content
|
||||
.response-actions
|
||||
.session-id-container
|
||||
.btn-copy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Manual Testing Checklist
|
||||
|
||||
- [ ] Select single character - generates response
|
||||
- [ ] Select multiple characters - includes all in context
|
||||
- [ ] Scene description - generates cohesive narrative
|
||||
- [ ] Individual responses - parses and sends to each character
|
||||
- [ ] "Select All Pending" button - selects correct characters
|
||||
- [ ] Additional context - influences AI generation
|
||||
- [ ] Model selection - uses chosen model
|
||||
- [ ] Copy session ID button - copies to clipboard
|
||||
- [ ] Collapse/expand generator - UI works correctly
|
||||
- [ ] Character receives individual response - appears in their conversation
|
||||
- [ ] Pending flags cleared - after individual responses sent
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements for later versions:
|
||||
|
||||
1. **Response Templates** - Save common response patterns
|
||||
2. **Batch Actions** - Send same scene to subset of characters
|
||||
3. **Response History** - View previous generated responses
|
||||
4. **Fine-tune Prompts** - Custom prompt templates per game
|
||||
5. **Voice/Tone Settings** - Adjust AI personality (serious/playful/dark)
|
||||
6. **Character Reactions** - Generate suggested player reactions
|
||||
7. **Conversation Summaries** - AI summary of what happened
|
||||
8. **Export Context** - Save context for reference
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Backend
|
||||
- `main.py`
|
||||
- Added `ContextualResponseRequest` model
|
||||
- Added `/generate_contextual_response` endpoint
|
||||
- Added response parsing logic
|
||||
- Added individual message distribution
|
||||
|
||||
### Frontend
|
||||
- `frontend/src/components/StorytellerView.js`
|
||||
- Added contextual response state variables
|
||||
- Added character selection functions
|
||||
- Added response generation function
|
||||
- Added copy session ID function
|
||||
- Added generator UI section
|
||||
|
||||
- `frontend/src/App.css`
|
||||
- Added `.contextual-*` styles
|
||||
- Added `.character-checkbox` styles
|
||||
- Added `.btn-copy` styles
|
||||
- Added `.session-id-container` styles
|
||||
- Added `.response-type-help` styles
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The Context-Aware Response Generator is a powerful tool that significantly improves storyteller efficiency. By allowing the storyteller to generate responses that consider multiple characters simultaneously, it:
|
||||
|
||||
- Reduces response time
|
||||
- Improves narrative consistency
|
||||
- Maintains privacy through automatic distribution
|
||||
- Provides flexibility between scene and individual responses
|
||||
- Makes managing multiple players much easier
|
||||
|
||||
Combined with the session ID copy button, these features make the storyteller experience more streamlined and professional.
|
||||
|
||||
**Status:** ✅ Ready for use!
|
||||
328
docs/features/DEMO_SESSION.md
Normal file
328
docs/features/DEMO_SESSION.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# 🎲 Demo Session - "The Cursed Tavern"
|
||||
|
||||
**Pre-configured test session for quick development and testing**
|
||||
|
||||
---
|
||||
|
||||
## Quick Access
|
||||
|
||||
When you start the server, a demo session is automatically created with:
|
||||
|
||||
- **Session ID:** `demo-session-001`
|
||||
- **Session Name:** "The Cursed Tavern"
|
||||
- **2 Pre-configured Characters**
|
||||
- **Starting Scene & Adventure Hook**
|
||||
|
||||
---
|
||||
|
||||
## How to Use
|
||||
|
||||
### From the Home Page (Easiest)
|
||||
|
||||
Three big colorful buttons appear at the top:
|
||||
|
||||
1. **🎲 Join as Storyteller** - Opens storyteller dashboard
|
||||
2. **⚔️ Play as Bargin (Dwarf Warrior)** - Opens character view as Bargin
|
||||
3. **🏹 Play as Willow (Elf Ranger)** - Opens character view as Willow
|
||||
|
||||
Just click and you're in!
|
||||
|
||||
### Manual Access
|
||||
|
||||
If you want to manually enter the session:
|
||||
|
||||
**As Storyteller:**
|
||||
- Session ID: `demo-session-001`
|
||||
|
||||
**As Bargin:**
|
||||
- Session ID: `demo-session-001`
|
||||
- Character ID: `char-bargin-001`
|
||||
|
||||
**As Willow:**
|
||||
- Session ID: `demo-session-001`
|
||||
- Character ID: `char-willow-002`
|
||||
|
||||
---
|
||||
|
||||
## Characters
|
||||
|
||||
### Bargin Ironforge ⚔️
|
||||
|
||||
**Race:** Dwarf
|
||||
**Class:** Warrior
|
||||
**Personality:** Brave but reckless. Loves a good fight and a strong ale. Quick to anger but fiercely loyal to companions.
|
||||
|
||||
**Description:**
|
||||
A stout dwarf warrior with a braided red beard and battle-scarred armor. Carries a massive war axe named 'Grudgekeeper'.
|
||||
|
||||
**Character ID:** `char-bargin-001`
|
||||
**LLM Model:** GPT-3.5 Turbo
|
||||
|
||||
---
|
||||
|
||||
### Willow Moonwhisper 🏹
|
||||
|
||||
**Race:** Elf
|
||||
**Class:** Ranger
|
||||
**Personality:** Cautious and observant. Prefers to scout ahead and avoid unnecessary conflict. Has an affinity for nature and animals.
|
||||
|
||||
**Description:**
|
||||
An elven ranger with silver hair and piercing green eyes. Moves silently through shadows, bow always at the ready.
|
||||
|
||||
**Character ID:** `char-willow-002`
|
||||
**LLM Model:** GPT-3.5 Turbo
|
||||
|
||||
---
|
||||
|
||||
## The Adventure
|
||||
|
||||
### Scenario: The Cursed Tavern
|
||||
|
||||
The village of Millhaven has a problem. The old Rusty Flagon tavern, once a cheerful gathering place, has become a source of terror. Locals report:
|
||||
|
||||
- **Ghostly figures** moving through the windows
|
||||
- **Unearthly screams** echoing from within
|
||||
- **Eerie green light** flickering after dark
|
||||
- Strange whispers that drive people mad
|
||||
|
||||
The village elder has hired adventurers to investigate and put an end to the disturbances.
|
||||
|
||||
### Starting Scene
|
||||
|
||||
```
|
||||
You stand outside the weathered doors of the Rusty Flagon tavern.
|
||||
Strange whispers echo from within, and the windows flicker with an
|
||||
eerie green light. The townspeople warned you about this place,
|
||||
but the reward for investigating is too good to pass up.
|
||||
```
|
||||
|
||||
### Initial Message (Both Characters)
|
||||
|
||||
When the characters first join, they see:
|
||||
|
||||
```
|
||||
Welcome to the Cursed Tavern adventure! You've been hired by the
|
||||
village elder to investigate strange happenings at the old tavern.
|
||||
Locals report seeing ghostly figures and hearing unearthly screams.
|
||||
Your mission: discover what's causing the disturbances and put an
|
||||
end to it. What would you like to do?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Scenarios
|
||||
|
||||
### Test the Message System
|
||||
|
||||
1. **Private Messages:**
|
||||
- Bargin: "I quietly check the door for traps"
|
||||
- Willow: "I scan the area for signs of danger"
|
||||
- Storyteller should see both privately
|
||||
|
||||
2. **Public Messages:**
|
||||
- Bargin: "I kick open the door!" (public)
|
||||
- Willow should see this action
|
||||
- Storyteller sees it too
|
||||
|
||||
3. **Mixed Messages:**
|
||||
- Bargin (public): "I step inside boldly"
|
||||
- Bargin (private): "I'm actually terrified but don't want Willow to know"
|
||||
- Willow sees: "I step inside boldly"
|
||||
- Storyteller sees: Both parts
|
||||
|
||||
### Test Context-Aware Responses
|
||||
|
||||
1. Select both Bargin and Willow in storyteller dashboard
|
||||
2. Click "Select All Pending"
|
||||
3. Choose "Individual Responses"
|
||||
4. Generate context-aware response
|
||||
5. Verify each character receives their personalized response
|
||||
|
||||
### Test AI Suggestions
|
||||
|
||||
1. As storyteller, view Bargin's conversation
|
||||
2. Click "✨ AI Suggest"
|
||||
3. Review generated suggestion
|
||||
4. Edit and send
|
||||
|
||||
---
|
||||
|
||||
## Development Benefits
|
||||
|
||||
This demo session eliminates the need to:
|
||||
|
||||
- Create a new session every time you restart the server
|
||||
- Manually create character profiles
|
||||
- Enter character descriptions and personalities
|
||||
- Type in session IDs repeatedly
|
||||
- Set up test scenarios
|
||||
|
||||
Just restart the server and click one button to test!
|
||||
|
||||
---
|
||||
|
||||
## Server Startup Output
|
||||
|
||||
When you start the server with `bash start.sh`, you'll see:
|
||||
|
||||
```
|
||||
============================================================
|
||||
🎲 DEMO SESSION CREATED!
|
||||
============================================================
|
||||
Session ID: demo-session-001
|
||||
Session Name: The Cursed Tavern
|
||||
|
||||
Characters:
|
||||
1. Bargin Ironforge (ID: char-bargin-001)
|
||||
A stout dwarf warrior with a braided red beard and battle-scarred armor...
|
||||
|
||||
2. Willow Moonwhisper (ID: char-willow-002)
|
||||
An elven ranger with silver hair and piercing green eyes...
|
||||
|
||||
Scenario: The Cursed Tavern
|
||||
Scene: You stand outside the weathered doors of the Rusty Flagon tavern...
|
||||
|
||||
============================================================
|
||||
To join as Storyteller: Use session ID 'demo-session-001'
|
||||
To join as Bargin: Use session ID 'demo-session-001' + character ID 'char-bargin-001'
|
||||
To join as Willow: Use session ID 'demo-session-001' + character ID 'char-willow-002'
|
||||
============================================================
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Customization
|
||||
|
||||
Want to modify the demo session? Edit `create_demo_session()` in `main.py`:
|
||||
|
||||
### Change Characters
|
||||
|
||||
```python
|
||||
# Modify character attributes
|
||||
bargin = Character(
|
||||
name="Your Character Name",
|
||||
description="Your description",
|
||||
personality="Your personality",
|
||||
llm_model="gpt-4", # Change model
|
||||
# ...
|
||||
)
|
||||
```
|
||||
|
||||
### Change Scenario
|
||||
|
||||
```python
|
||||
demo_session = GameSession(
|
||||
name="Your Adventure Name",
|
||||
current_scene="Your starting scene...",
|
||||
scene_history=["Your backstory..."]
|
||||
)
|
||||
```
|
||||
|
||||
### Add More Characters
|
||||
|
||||
```python
|
||||
# Create a third character
|
||||
third_char = Character(...)
|
||||
demo_session.characters[third_char.id] = third_char
|
||||
```
|
||||
|
||||
### Change Session ID
|
||||
|
||||
```python
|
||||
demo_session_id = "my-custom-id"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Disabling Demo Session
|
||||
|
||||
If you want to disable auto-creation of the demo session, comment out this line in `main.py`:
|
||||
|
||||
```python
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
# create_demo_session() # Comment this out
|
||||
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Implementation
|
||||
|
||||
The demo session is created in the `create_demo_session()` function in `main.py`, which:
|
||||
|
||||
1. Creates a `GameSession` object
|
||||
2. Creates two `Character` objects
|
||||
3. Adds an initial storyteller message to both character histories
|
||||
4. Stores the session in the in-memory `sessions` dictionary
|
||||
5. Prints session info to the console
|
||||
|
||||
### Frontend Integration
|
||||
|
||||
The home page (`SessionSetup.js`) includes three quick-access functions:
|
||||
|
||||
- `joinDemoStoryteller()` - Calls `onCreateSession("demo-session-001")`
|
||||
- `joinDemoBargin()` - Calls `onJoinSession("demo-session-001", "char-bargin-001")`
|
||||
- `joinDemoWillow()` - Calls `onJoinSession("demo-session-001", "char-willow-002")`
|
||||
|
||||
These bypass the normal session creation/joining flow.
|
||||
|
||||
---
|
||||
|
||||
## Why This Matters
|
||||
|
||||
During development and testing, you'll restart the server **dozens of times**. Without a demo session, each restart requires:
|
||||
|
||||
1. Click "Create Session"
|
||||
2. Enter session name
|
||||
3. Wait for creation
|
||||
4. Copy session ID
|
||||
5. Open new window
|
||||
6. Paste session ID
|
||||
7. Enter character name
|
||||
8. Enter character description
|
||||
9. Enter personality
|
||||
10. Select model
|
||||
11. Click join
|
||||
12. Repeat for second character
|
||||
|
||||
With the demo session:
|
||||
|
||||
1. Click one button
|
||||
|
||||
**That's a huge time saver!**
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
When database persistence is implemented, you could:
|
||||
|
||||
- Save demo session to database on first run
|
||||
- Load multiple pre-configured adventures
|
||||
- Create a "Quick Start Gallery" of scenarios
|
||||
- Import/export demo sessions as JSON
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Does the demo session persist across server restarts?**
|
||||
A: No, it's recreated fresh each time. This ensures a clean state for testing.
|
||||
|
||||
**Q: Can I have multiple demo sessions?**
|
||||
A: Yes! Just create additional sessions with different IDs in the startup function.
|
||||
|
||||
**Q: Will the demo session interfere with real sessions?**
|
||||
A: No, it's just another session in memory. You can create regular sessions alongside it.
|
||||
|
||||
**Q: Can I modify character stats mid-session?**
|
||||
A: Not yet, but you can edit the character objects directly in the code and restart.
|
||||
|
||||
---
|
||||
|
||||
**Happy Testing!** 🎲✨
|
||||
314
docs/features/FIXES_SUMMARY.md
Normal file
314
docs/features/FIXES_SUMMARY.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# 🔧 Bug Fixes & Improvements
|
||||
|
||||
**Date:** October 11, 2025
|
||||
**Status:** ✅ Complete
|
||||
|
||||
---
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
### 1. **Character Chat Log History** 🔒
|
||||
|
||||
**Problem:**
|
||||
Players could only see the most recent storyteller response in their conversation. Previous messages disappeared, making it impossible to review the conversation context.
|
||||
|
||||
**Root Cause:**
|
||||
The character WebSocket handler was only listening for `storyteller_response` message type, but the context-aware response generator was sending `new_message` type.
|
||||
|
||||
**Solution:**
|
||||
Updated `CharacterView.js` to handle both message types:
|
||||
|
||||
```javascript
|
||||
// Before
|
||||
else if (data.type === 'storyteller_response') {
|
||||
setMessages(prev => [...prev, data.message]);
|
||||
}
|
||||
|
||||
// After
|
||||
else if (data.type === 'storyteller_response' || data.type === 'new_message') {
|
||||
setMessages(prev => [...prev, data.message]);
|
||||
}
|
||||
```
|
||||
|
||||
**Impact:**
|
||||
✅ Characters now see full conversation history
|
||||
✅ Context is preserved when reading back messages
|
||||
✅ Individual responses from context-aware generator appear correctly
|
||||
|
||||
---
|
||||
|
||||
### 2. **Pydantic Deprecation Warnings** ⚠️
|
||||
|
||||
**Problem:**
|
||||
10 deprecation warnings when running the application:
|
||||
|
||||
```
|
||||
PydanticDeprecatedSince20: The `dict` method is deprecated;
|
||||
use `model_dump` instead.
|
||||
```
|
||||
|
||||
**Root Cause:**
|
||||
Using Pydantic V1 `.dict()` method with Pydantic V2 models.
|
||||
|
||||
**Solution:**
|
||||
Replaced all 9 instances of `.dict()` with `.model_dump()` in `main.py`:
|
||||
|
||||
**Locations Fixed:**
|
||||
1. Line 152: Character history in WebSocket
|
||||
2. Line 153: Public messages in WebSocket
|
||||
3. Line 180: Public message broadcasting
|
||||
4. Line 191: Mixed message broadcasting
|
||||
5. Line 207: Character message forwarding
|
||||
6. Line 234: Session state conversation history
|
||||
7. Line 240: Session state public messages
|
||||
8. Line 262: Storyteller response
|
||||
9. Line 487: Context-aware individual responses
|
||||
10. Line 571: Pending messages
|
||||
11. Line 594: Character conversation endpoint
|
||||
|
||||
**Impact:**
|
||||
✅ No more deprecation warnings
|
||||
✅ Code is Pydantic V2 compliant
|
||||
✅ Future-proof for Pydantic V3
|
||||
|
||||
---
|
||||
|
||||
### 3. **Session ID Copy Button** 📋
|
||||
|
||||
**Problem:**
|
||||
No easy way to share the session ID with players. Had to manually select and copy the ID.
|
||||
|
||||
**Root Cause:**
|
||||
Missing UI affordance for common action.
|
||||
|
||||
**Solution:**
|
||||
Added copy button with clipboard API:
|
||||
|
||||
```javascript
|
||||
// Copy function
|
||||
const copySessionId = () => {
|
||||
navigator.clipboard.writeText(sessionId).then(() => {
|
||||
alert('✅ Session ID copied to clipboard!');
|
||||
}).catch(err => {
|
||||
alert('Failed to copy session ID. Please copy it manually.');
|
||||
});
|
||||
};
|
||||
|
||||
// UI
|
||||
<div className="session-id-container">
|
||||
<p className="session-id">
|
||||
Session ID: <code>{sessionId}</code>
|
||||
</p>
|
||||
<button className="btn-copy" onClick={copySessionId}>
|
||||
📋 Copy
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Impact:**
|
||||
✅ One-click session ID copying
|
||||
✅ Better UX for storytellers
|
||||
✅ Easier to share sessions with players
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Backend
|
||||
- `main.py`
|
||||
- Fixed all `.dict()` → `.model_dump()` (9 instances)
|
||||
- Already had correct WebSocket message types
|
||||
|
||||
### Frontend
|
||||
- `frontend/src/components/CharacterView.js`
|
||||
- Added `new_message` type handling in WebSocket listener
|
||||
|
||||
- `frontend/src/components/StorytellerView.js`
|
||||
- Added `copySessionId()` function
|
||||
- Added session ID container with copy button
|
||||
|
||||
- `frontend/src/App.css`
|
||||
- Added `.session-id-container` styles
|
||||
- Added `.btn-copy` styles with hover effects
|
||||
|
||||
---
|
||||
|
||||
## Testing Performed
|
||||
|
||||
### Character Chat Log
|
||||
- [x] Send multiple messages as character
|
||||
- [x] Receive multiple responses from storyteller
|
||||
- [x] Verify all messages remain visible
|
||||
- [x] Scroll through full conversation history
|
||||
- [x] Receive individual response from context-aware generator
|
||||
- [x] Confirm response appears in chat log
|
||||
|
||||
### Pydantic Warnings
|
||||
- [x] Run backend server
|
||||
- [x] Create session
|
||||
- [x] Join as character
|
||||
- [x] Send/receive messages
|
||||
- [x] Verify no deprecation warnings in console
|
||||
|
||||
### Copy Button
|
||||
- [x] Click copy button
|
||||
- [x] Verify clipboard contains session ID
|
||||
- [x] Verify success alert appears
|
||||
- [x] Paste session ID to confirm it worked
|
||||
|
||||
---
|
||||
|
||||
## Verification Commands
|
||||
|
||||
```bash
|
||||
# Run backend and check for warnings
|
||||
.venv/bin/python main.py
|
||||
# Should see no deprecation warnings
|
||||
|
||||
# Test conversation history
|
||||
# 1. Create session
|
||||
# 2. Join as character
|
||||
# 3. Send 3 messages
|
||||
# 4. Storyteller responds to each
|
||||
# 5. Check character view shows all 6 messages (3 sent + 3 received)
|
||||
|
||||
# Test copy button
|
||||
# 1. Create session as storyteller
|
||||
# 2. Click "📋 Copy" button
|
||||
# 3. Paste into text editor
|
||||
# 4. Should match session ID displayed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Before & After
|
||||
|
||||
### Character Chat Log
|
||||
|
||||
**Before:**
|
||||
```
|
||||
Your conversation:
|
||||
You: I search for traps
|
||||
Storyteller: You find a hidden mechanism <-- Only latest visible
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
Your conversation:
|
||||
You: I approach the door
|
||||
Storyteller: The door is locked
|
||||
You: I check for traps
|
||||
Storyteller: You find a hidden mechanism
|
||||
You: I try to disarm it
|
||||
Storyteller: Roll for dexterity <-- All messages visible
|
||||
```
|
||||
|
||||
### Pydantic Warnings
|
||||
|
||||
**Before:**
|
||||
```
|
||||
INFO: Uvicorn running on http://0.0.0.0:8000
|
||||
⚠️ PydanticDeprecatedSince20: The `dict` method is deprecated...
|
||||
⚠️ PydanticDeprecatedSince20: The `dict` method is deprecated...
|
||||
⚠️ PydanticDeprecatedSince20: The `dict` method is deprecated...
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
INFO: Uvicorn running on http://0.0.0.0:8000
|
||||
(clean, no warnings)
|
||||
```
|
||||
|
||||
### Session ID Copy
|
||||
|
||||
**Before:**
|
||||
```
|
||||
Session ID: abc123-def456-ghi789
|
||||
(must manually select and copy)
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
Session ID: abc123-def456-ghi789 [📋 Copy]
|
||||
(one click to copy!)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact Summary
|
||||
|
||||
### For Players
|
||||
- ✅ **Can review full conversation** - No more lost context
|
||||
- ✅ **Better immersion** - See the full story unfold
|
||||
- ✅ **Reference past actions** - Remember what happened
|
||||
|
||||
### For Storytellers
|
||||
- ✅ **Easy session sharing** - Copy button for session ID
|
||||
- ✅ **Clean console** - No deprecation warnings
|
||||
- ✅ **Reliable message delivery** - All message types work
|
||||
|
||||
### For Developers
|
||||
- ✅ **Code quality** - Pydantic V2 compliant
|
||||
- ✅ **Future-proof** - Ready for Pydantic V3
|
||||
- ✅ **Better UX** - Copy button pattern for other IDs
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
|
||||
### Why This Matters
|
||||
|
||||
**Conversation History:**
|
||||
RPG conversations build on each other. Players need to see:
|
||||
- What they asked
|
||||
- How the storyteller responded
|
||||
- The progression of events
|
||||
- Clues and information gathered
|
||||
|
||||
Without full history, the experience is broken.
|
||||
|
||||
**Pydantic Compliance:**
|
||||
Deprecation warnings aren't just annoying—they indicate future breaking changes. Fixing them now prevents issues when Pydantic V3 releases.
|
||||
|
||||
**Copy Button:**
|
||||
Small UX improvements add up. Making session sharing frictionless means more games, more players, better experience.
|
||||
|
||||
---
|
||||
|
||||
## Future Improvements
|
||||
|
||||
Based on these fixes, potential future enhancements:
|
||||
|
||||
1. **Export Conversation** - Button to export full chat log
|
||||
2. **Search Messages** - Find specific text in conversation
|
||||
3. **Message Timestamps** - Show when each message was sent
|
||||
4. **Copy Individual Messages** - Copy button per message
|
||||
5. **Conversation Summaries** - AI summary of what happened
|
||||
|
||||
---
|
||||
|
||||
## Commit Message
|
||||
|
||||
```
|
||||
Fix character chat history and Pydantic deprecation warnings
|
||||
|
||||
- Fix: Character chat log now shows full conversation history
|
||||
- CharacterView now handles both 'storyteller_response' and 'new_message' types
|
||||
- Fixes issue where only most recent message was visible
|
||||
|
||||
- Fix: Replace all .dict() with .model_dump() for Pydantic V2
|
||||
- Eliminates 10 deprecation warnings
|
||||
- Future-proof for Pydantic V3
|
||||
- Updated 9 locations in main.py
|
||||
|
||||
- Feature: Add copy button for session ID
|
||||
- One-click clipboard copy in storyteller dashboard
|
||||
- Improved UX for session sharing
|
||||
- Added .btn-copy styles with hover effects
|
||||
|
||||
Fixes critical chat history bug and code quality issues
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**All fixes tested and working!** ✅
|
||||
395
docs/features/PROMPT_IMPROVEMENTS.md
Normal file
395
docs/features/PROMPT_IMPROVEMENTS.md
Normal file
@@ -0,0 +1,395 @@
|
||||
# 🔧 Individual Response Prompt Improvements
|
||||
|
||||
**Date:** October 12, 2025
|
||||
**Status:** ✅ Complete
|
||||
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
When generating individual responses for multiple characters, the LLM output format was inconsistent, making parsing unreliable. The system tried multiple regex patterns to handle various formats:
|
||||
|
||||
- `**For CharName:** response text`
|
||||
- `For CharName: response text`
|
||||
- `**CharName:** response text`
|
||||
- `CharName: response text`
|
||||
|
||||
This led to parsing failures and 500 errors when responses didn't match expected patterns.
|
||||
|
||||
---
|
||||
|
||||
## Solution
|
||||
|
||||
### 1. **Explicit Format Instructions** 📋
|
||||
|
||||
Updated the prompt to explicitly tell the LLM the exact format required:
|
||||
|
||||
```
|
||||
IMPORTANT: Format your response EXACTLY as follows, with each character's response on a separate line:
|
||||
|
||||
[Bargin Ironforge] Your response for Bargin Ironforge here (2-3 sentences)
|
||||
[Willow Moonwhisper] Your response for Willow Moonwhisper here (2-3 sentences)
|
||||
|
||||
Use EXACTLY this format with square brackets and character names. Do not add any other text before or after.
|
||||
```
|
||||
|
||||
**Why square brackets?**
|
||||
- Clear delimiters that aren't commonly used in prose
|
||||
- Easy to parse with regex
|
||||
- Visually distinct from narrative text
|
||||
- Less ambiguous than asterisks or "For X:"
|
||||
|
||||
---
|
||||
|
||||
### 2. **Enhanced System Prompt** 🤖
|
||||
|
||||
Added specific instruction to the system prompt for individual responses:
|
||||
|
||||
```python
|
||||
system_prompt = "You are a creative and engaging RPG storyteller/game master."
|
||||
if request.response_type == "individual":
|
||||
system_prompt += " When asked to format responses with [CharacterName] brackets, you MUST follow that exact format precisely. Use square brackets around each character's name, followed by their response text."
|
||||
```
|
||||
|
||||
This reinforces the format requirement at the system level, making the LLM more likely to comply.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Simplified Parsing Logic** 🔍
|
||||
|
||||
Replaced the multi-pattern fallback system with a single, clear pattern:
|
||||
|
||||
**Before** (4+ patterns, order-dependent):
|
||||
```python
|
||||
patterns = [
|
||||
rf'\*\*For {re.escape(char_name)}:\*\*\s*(.*?)(?=\*\*For\s+\w+:|\Z)',
|
||||
rf'For {re.escape(char_name)}:\s*(.*?)(?=For\s+\w+:|\Z)',
|
||||
rf'\*\*{re.escape(char_name)}:\*\*\s*(.*?)(?=\*\*\w+:|\Z)',
|
||||
rf'{re.escape(char_name)}:\s*(.*?)(?=\w+:|\Z)',
|
||||
]
|
||||
```
|
||||
|
||||
**After** (single pattern):
|
||||
```python
|
||||
pattern = rf'\[{re.escape(char_name)}\]\s*(.*?)(?=\[[\w\s]+\]|\Z)'
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
- `\[{re.escape(char_name)}\]` - Matches `[CharacterName]`
|
||||
- `\s*` - Matches optional whitespace after bracket
|
||||
- `(.*?)` - Captures the response text (non-greedy)
|
||||
- `(?=\[[\w\s]+\]|\Z)` - Stops at the next `[Name]` or end of string
|
||||
|
||||
---
|
||||
|
||||
### 4. **Response Cleanup** 🧹
|
||||
|
||||
Added whitespace normalization to handle multi-line responses:
|
||||
|
||||
```python
|
||||
# Clean up any trailing newlines or extra whitespace
|
||||
individual_response = ' '.join(individual_response.split())
|
||||
```
|
||||
|
||||
This ensures responses look clean even if the LLM adds line breaks.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Bug Fix: WebSocket Reference** 🐛
|
||||
|
||||
Fixed the undefined `character_connections` error:
|
||||
|
||||
**Before:**
|
||||
```python
|
||||
if char_id in character_connections:
|
||||
await character_connections[char_id].send_json({...})
|
||||
```
|
||||
|
||||
**After:**
|
||||
```python
|
||||
char_key = f"{session_id}_{char_id}"
|
||||
if char_key in manager.active_connections:
|
||||
await manager.send_to_client(char_key, {...})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. **Frontend Help Text** 💬
|
||||
|
||||
Updated the UI to show the expected format:
|
||||
|
||||
```jsx
|
||||
<p className="response-type-help">
|
||||
💡 The AI will generate responses in this format:
|
||||
<code>[CharacterName] Response text here</code>.
|
||||
Each response is automatically parsed and sent privately
|
||||
to the respective character.
|
||||
</p>
|
||||
```
|
||||
|
||||
With styled code block for visibility.
|
||||
|
||||
---
|
||||
|
||||
## Example Output
|
||||
|
||||
### Input Context
|
||||
```
|
||||
Characters:
|
||||
- Bargin Ironforge (Dwarf Warrior)
|
||||
- Willow Moonwhisper (Elf Ranger)
|
||||
|
||||
Bargin: I kick down the door!
|
||||
Willow: I ready my bow and watch for danger.
|
||||
```
|
||||
|
||||
### Expected LLM Output (New Format)
|
||||
```
|
||||
[Bargin Ironforge] The door crashes open with a loud BANG, revealing a dark hallway lit by flickering torches. You hear shuffling footsteps approaching from the shadows.
|
||||
|
||||
[Willow Moonwhisper] Your keen elven senses detect movement ahead—at least three humanoid shapes lurking in the darkness. Your arrow is nocked and ready.
|
||||
```
|
||||
|
||||
### Parsing Result
|
||||
- **Bargin receives:** "The door crashes open with a loud BANG, revealing a dark hallway lit by flickering torches. You hear shuffling footsteps approaching from the shadows."
|
||||
- **Willow receives:** "Your keen elven senses detect movement ahead—at least three humanoid shapes lurking in the darkness. Your arrow is nocked and ready."
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
### Reliability ✅
|
||||
- Single, predictable format
|
||||
- Clear parsing logic
|
||||
- No fallback pattern hunting
|
||||
- Fewer edge cases
|
||||
|
||||
### Developer Experience 🛠️
|
||||
- Easier to debug (one pattern to check)
|
||||
- Clear expectations in logs
|
||||
- Explicit format in prompts
|
||||
|
||||
### LLM Performance 🤖
|
||||
- Unambiguous instructions
|
||||
- Format provided as example
|
||||
- System prompt reinforcement
|
||||
- Less confusion about structure
|
||||
|
||||
### User Experience 👥
|
||||
- Consistent behavior
|
||||
- Reliable message delivery
|
||||
- Clear documentation
|
||||
- No mysterious failures
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Case 1: Two Characters
|
||||
**Input:** Bargin and Willow selected
|
||||
**Expected:** Both receive individual responses
|
||||
**Result:** ✅ Both messages delivered
|
||||
|
||||
### Test Case 2: Special Characters in Names
|
||||
**Input:** Character named "Sir O'Brien"
|
||||
**Expected:** `[Sir O'Brien] response`
|
||||
**Result:** ✅ Regex escaping handles it
|
||||
|
||||
### Test Case 3: Multi-line Responses
|
||||
**Input:** LLM adds line breaks in response
|
||||
**Expected:** Whitespace normalized
|
||||
**Result:** ✅ Clean single-line response
|
||||
|
||||
### Test Case 4: Missing Character
|
||||
**Input:** Response missing one character
|
||||
**Expected:** Only matched characters receive messages
|
||||
**Result:** ✅ No errors, partial delivery
|
||||
|
||||
---
|
||||
|
||||
## Edge Cases Handled
|
||||
|
||||
### 1. Character Name with Spaces
|
||||
```
|
||||
[Willow Moonwhisper] Your response here
|
||||
```
|
||||
✅ Pattern handles spaces: `[\w\s]+`
|
||||
|
||||
### 2. Character Name with Apostrophes
|
||||
```
|
||||
[O'Brien] Your response here
|
||||
```
|
||||
✅ `re.escape()` handles special characters
|
||||
|
||||
### 3. Response with Square Brackets
|
||||
```
|
||||
[Bargin] You see [a strange symbol] on the wall.
|
||||
```
|
||||
✅ Pattern stops at next `[Name]`, not inline brackets
|
||||
|
||||
### 4. Empty Response
|
||||
```
|
||||
[Bargin]
|
||||
[Willow] Your response here
|
||||
```
|
||||
✅ Check `if individual_response:` prevents sending empty messages
|
||||
|
||||
### 5. LLM Adds Extra Text
|
||||
```
|
||||
Here are the responses:
|
||||
[Bargin] Your response here
|
||||
[Willow] Your response here
|
||||
```
|
||||
✅ Pattern finds brackets regardless of prefix
|
||||
|
||||
---
|
||||
|
||||
## Fallback Behavior
|
||||
|
||||
If parsing fails completely (no matches found):
|
||||
- `sent_responses` dict is empty
|
||||
- Frontend alert shows "0 characters" sent
|
||||
- Storyteller can see raw response and manually send
|
||||
- No characters receive broken messages
|
||||
|
||||
This fail-safe prevents bad data from reaching players.
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Backend
|
||||
- `main.py`
|
||||
- Updated prompt generation for individual responses
|
||||
- Added explicit format instructions
|
||||
- Enhanced system prompt
|
||||
- Simplified parsing logic with single pattern
|
||||
- Fixed WebSocket manager reference bug
|
||||
- Added whitespace cleanup
|
||||
|
||||
### Frontend
|
||||
- `frontend/src/components/StorytellerView.js`
|
||||
- Updated help text with format example
|
||||
- Added inline code styling
|
||||
|
||||
- `frontend/src/App.css`
|
||||
- Added `.response-type-help code` styles
|
||||
- Styled code blocks in help text
|
||||
|
||||
---
|
||||
|
||||
## Performance Impact
|
||||
|
||||
### Before
|
||||
- 4 regex patterns tested per character
|
||||
- Potential O(n×m) complexity (n chars, m patterns)
|
||||
- More CPU cycles on pattern matching
|
||||
|
||||
### After
|
||||
- 1 regex pattern per character
|
||||
- O(n) complexity
|
||||
- Faster parsing
|
||||
- Less memory allocation
|
||||
|
||||
**Impact:** Negligible for 2-5 characters, but scales better for larger parties.
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Potential Improvements
|
||||
|
||||
1. **JSON Format Alternative**
|
||||
```json
|
||||
{
|
||||
"Bargin Ironforge": "Response here",
|
||||
"Willow Moonwhisper": "Response here"
|
||||
}
|
||||
```
|
||||
Pros: Structured, machine-readable
|
||||
Cons: Less natural for LLMs, more verbose
|
||||
|
||||
2. **Markdown Section Headers**
|
||||
```markdown
|
||||
## Bargin Ironforge
|
||||
Response here
|
||||
|
||||
## Willow Moonwhisper
|
||||
Response here
|
||||
```
|
||||
Pros: Natural for LLMs, readable
|
||||
Cons: More complex parsing
|
||||
|
||||
3. **XML/SGML Style**
|
||||
```xml
|
||||
<response for="Bargin">Response here</response>
|
||||
<response for="Willow">Response here</response>
|
||||
```
|
||||
Pros: Self-documenting, strict
|
||||
Cons: Verbose, less natural
|
||||
|
||||
**Decision:** Stick with `[Name]` format for simplicity and LLM-friendliness.
|
||||
|
||||
---
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### No Breaking Changes
|
||||
- Scene responses unchanged
|
||||
- Existing functionality preserved
|
||||
- Only individual response format changed
|
||||
|
||||
### Backward Compatibility
|
||||
- Old sessions work normally
|
||||
- No database migrations needed (in-memory)
|
||||
- Frontend automatically shows new format
|
||||
|
||||
---
|
||||
|
||||
## Verification Commands
|
||||
|
||||
```bash
|
||||
# Start server (shows demo session info)
|
||||
bash start.sh
|
||||
|
||||
# Test individual responses
|
||||
1. Open storyteller dashboard
|
||||
2. Open two character windows (Bargin, Willow)
|
||||
3. Both characters send messages
|
||||
4. Storyteller selects both characters
|
||||
5. Choose "Individual Responses"
|
||||
6. Generate response
|
||||
7. Check both characters receive their messages
|
||||
|
||||
# Check logs for format
|
||||
# Look for: [CharacterName] response text
|
||||
tail -f logs/backend.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- ✅ **Zero 500 errors** on individual response generation
|
||||
- ✅ **100% parsing success rate** with new format
|
||||
- ✅ **Clear format documentation** for users
|
||||
- ✅ **Single regex pattern** (down from 4)
|
||||
- ✅ **Fixed WebSocket bug** (manager reference)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Problem:** Inconsistent LLM output formats caused parsing failures and 500 errors.
|
||||
|
||||
**Solution:** Explicit `[CharacterName] response` format with clear instructions and simplified parsing.
|
||||
|
||||
**Result:** Reliable individual message delivery with predictable, debuggable behavior.
|
||||
|
||||
**Key Insight:** When working with LLMs, explicit format examples in the prompt are more effective than trying to handle multiple format variations in code.
|
||||
|
||||
---
|
||||
|
||||
**Status: Ready for Testing** ✅
|
||||
|
||||
Try generating individual responses and verify that both characters receive their messages correctly!
|
||||
179
docs/features/README.md
Normal file
179
docs/features/README.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 🎭 Features Documentation
|
||||
|
||||
Detailed documentation for all Storyteller RPG features.
|
||||
|
||||
---
|
||||
|
||||
## Feature Guides
|
||||
|
||||
### Core Features
|
||||
|
||||
#### [Demo Session](./DEMO_SESSION.md)
|
||||
Pre-configured test session that auto-loads on startup. Includes two characters (Bargin & Willow) and "The Cursed Tavern" adventure. Perfect for development and testing.
|
||||
|
||||
**Quick Access:**
|
||||
- Session ID: `demo-session-001`
|
||||
- One-click buttons on home page
|
||||
- No setup required
|
||||
|
||||
---
|
||||
|
||||
#### [Context-Aware Response Generator](./CONTEXTUAL_RESPONSE_FEATURE.md)
|
||||
AI-powered tool for storytellers to generate responses considering multiple characters' actions simultaneously.
|
||||
|
||||
**Key Features:**
|
||||
- Multi-character selection
|
||||
- Scene descriptions (broadcast to all)
|
||||
- Individual responses (private to each)
|
||||
- Automatic parsing and distribution
|
||||
- Smart context building
|
||||
|
||||
---
|
||||
|
||||
### Technical Documentation
|
||||
|
||||
#### [Prompt Engineering Improvements](./PROMPT_IMPROVEMENTS.md)
|
||||
Details on how we improved the LLM prompts for reliable individual response parsing using the `[CharacterName]` format.
|
||||
|
||||
**Topics Covered:**
|
||||
- Square bracket format rationale
|
||||
- Regex parsing patterns
|
||||
- System prompt enhancements
|
||||
- Edge case handling
|
||||
|
||||
---
|
||||
|
||||
#### [Bug Fixes Summary](./FIXES_SUMMARY.md)
|
||||
Comprehensive list of bugs fixed in the latest release.
|
||||
|
||||
**Fixed Issues:**
|
||||
- Character chat history showing only recent messages
|
||||
- Pydantic deprecation warnings (.dict → .model_dump)
|
||||
- WebSocket manager reference errors
|
||||
- Session ID copy functionality
|
||||
|
||||
---
|
||||
|
||||
## Feature Overview by Category
|
||||
|
||||
### For Storytellers 🎲
|
||||
|
||||
| Feature | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| **Session Management** | Create/join sessions, manage characters | ✅ Complete |
|
||||
| **Scene Narration** | Broadcast scene descriptions to all players | ✅ Complete |
|
||||
| **Private Responses** | Send individual messages to characters | ✅ Complete |
|
||||
| **AI Suggestions** | Get AI-generated response suggestions | ✅ Complete |
|
||||
| **Context-Aware Generator** | Generate responses considering multiple characters | ✅ Complete |
|
||||
| **Pending Message Tracking** | See which characters need responses | ✅ Complete |
|
||||
| **Demo Session** | Pre-loaded test scenario for quick start | ✅ Complete |
|
||||
|
||||
### For Players 🎭
|
||||
|
||||
| Feature | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| **Character Creation** | Define name, description, personality | ✅ Complete |
|
||||
| **Private Messages** | Send private messages to storyteller | ✅ Complete |
|
||||
| **Public Actions** | Broadcast actions visible to all players | ✅ Complete |
|
||||
| **Mixed Messages** | Public action + private thoughts | ✅ Complete |
|
||||
| **Scene Viewing** | See current scene description | ✅ Complete |
|
||||
| **Public Feed** | View all players' public actions | ✅ Complete |
|
||||
| **Conversation History** | Full chat log with storyteller | ✅ Complete |
|
||||
|
||||
### Message System 📨
|
||||
|
||||
| Feature | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| **Private Messages** | One-on-one conversation | ✅ Complete |
|
||||
| **Public Messages** | Visible to all players | ✅ Complete |
|
||||
| **Mixed Messages** | Public + private components | ✅ Complete |
|
||||
| **Real-time Updates** | WebSocket-based live updates | ✅ Complete |
|
||||
| **Message Persistence** | In-memory storage (session lifetime) | ✅ Complete |
|
||||
|
||||
### AI Integration 🤖
|
||||
|
||||
| Feature | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| **Multiple LLM Support** | GPT-4o, GPT-4, GPT-3.5, Claude, Llama | ✅ Complete |
|
||||
| **AI Response Suggestions** | Quick response generation | ✅ Complete |
|
||||
| **Context-Aware Generation** | Multi-character context building | ✅ Complete |
|
||||
| **Structured Output Parsing** | [CharacterName] format parsing | ✅ Complete |
|
||||
| **Temperature Control** | Creative vs. focused responses | ✅ Complete |
|
||||
|
||||
---
|
||||
|
||||
## Coming Soon 🚀
|
||||
|
||||
### Planned Features
|
||||
|
||||
- **Database Persistence** - Save sessions and characters permanently
|
||||
- **Character Sheets** - Stats, inventory, abilities
|
||||
- **Dice Rolling** - Built-in dice mechanics
|
||||
- **Combat System** - Turn-based combat management
|
||||
- **Image Generation** - AI-generated scene/character images
|
||||
- **Voice Messages** - Audio message support
|
||||
- **Session Export** - Export conversation logs
|
||||
- **User Authentication** - Account system with saved preferences
|
||||
|
||||
---
|
||||
|
||||
## Feature Request Process
|
||||
|
||||
Want to suggest a new feature?
|
||||
|
||||
1. **Check existing documentation** - Feature might already exist
|
||||
2. **Review roadmap** - Check if it's already planned (see [MVP_ROADMAP.md](../planning/MVP_ROADMAP.md))
|
||||
3. **Create an issue** - Describe the feature and use case
|
||||
4. **Discuss implementation** - We'll evaluate feasibility and priority
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
### v0.2.0 - Context-Aware Features (October 2025)
|
||||
- ✅ Context-aware response generator
|
||||
- ✅ Demo session with pre-configured characters
|
||||
- ✅ Improved prompt engineering for parsing
|
||||
- ✅ Bug fixes (chat history, Pydantic warnings)
|
||||
- ✅ Session ID copy button
|
||||
|
||||
### v0.1.0 - MVP Phase 1 (October 2025)
|
||||
- ✅ Basic session management
|
||||
- ✅ Character creation and joining
|
||||
- ✅ Private/public/mixed messaging
|
||||
- ✅ Real-time WebSocket communication
|
||||
- ✅ Scene narration
|
||||
- ✅ AI-assisted responses
|
||||
- ✅ Multiple LLM support
|
||||
|
||||
---
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── features/ ← You are here
|
||||
│ ├── README.md
|
||||
│ ├── DEMO_SESSION.md
|
||||
│ ├── CONTEXTUAL_RESPONSE_FEATURE.md
|
||||
│ ├── PROMPT_IMPROVEMENTS.md
|
||||
│ └── FIXES_SUMMARY.md
|
||||
├── development/
|
||||
│ ├── MVP_PROGRESS.md
|
||||
│ ├── TESTING_GUIDE.md
|
||||
│ └── TEST_RESULTS.md
|
||||
├── planning/
|
||||
│ ├── MVP_ROADMAP.md
|
||||
│ ├── PROJECT_PLAN.md
|
||||
│ └── NEXT_STEPS.md
|
||||
├── setup/
|
||||
│ ├── QUICKSTART.md
|
||||
│ └── QUICK_REFERENCE.md
|
||||
└── reference/
|
||||
├── PROJECT_FILES_REFERENCE.md
|
||||
└── LLM_GUIDE.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Need help?** Check the [main README](../../README.md) or the [Quick Start Guide](../setup/QUICKSTART.md).
|
||||
Reference in New Issue
Block a user