Compare commits
34 Commits
0712b1c422
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 10d95951a3 | |||
| 50d3177e9e | |||
| 86a9d54e70 | |||
| 600b50f239 | |||
| a7c9657ff1 | |||
| e47bd3bf87 | |||
| 41437e1751 | |||
| 8c70e0558f | |||
| 0bd1590681 | |||
| 26d1430d6a | |||
| bc05747f5f | |||
| 71bac12cd9 | |||
| 9da17c824d | |||
| d8cb4a768b | |||
| b9230772ed | |||
| 9b4bc63e1a | |||
| 501f226542 | |||
| 2444ca0811 | |||
| 828475ae4f | |||
| cdb7baa197 | |||
| 9707121a59 | |||
| e364ecfc51 | |||
| 5d32489c3c | |||
| 83e9793dce | |||
| 84d3e0df67 | |||
| 30e6af61ca | |||
| 32fc57fab0 | |||
| efa3ccbd26 | |||
| b9ea771ff0 | |||
| 4866c11245 | |||
| e0239aceda | |||
| 4694114ff9 | |||
| ab6ae14bbc | |||
| a9b686f0d1 |
3631
CELIA 3.8.json
Normal file
3631
CELIA 3.8.json
Normal file
File diff suppressed because one or more lines are too long
92
README.md
92
README.md
@@ -1,28 +1,36 @@
|
||||
# Claudia
|
||||
|
||||
Beautiful AI desktop companion built with Tauri and Rust.
|
||||
Desktop AI chat application built with Tauri and Rust, focused on roleplay and character-based interactions.
|
||||
|
||||
## Features
|
||||
|
||||
### Core Features
|
||||
- 🎨 **Beautiful glassmorphic UI** with gradient backgrounds and blur effects
|
||||
- 🔧 **Bring-your-own-API** - supports any Anthropic-compatible API
|
||||
- ✅ **API validation** via /v1/models endpoint
|
||||
- 💬 **Full conversation context** - AI remembers your entire conversation
|
||||
- 💾 **Persistent chat history** - conversations saved between sessions
|
||||
- 🎯 **Custom window controls** - drag, minimize, maximize, close
|
||||
### Chat
|
||||
- Streaming responses with real-time display
|
||||
- Full markdown rendering with syntax highlighting
|
||||
- Message swipes (multiple response alternatives)
|
||||
- Edit and regenerate from any message
|
||||
- Per-character conversation history
|
||||
- Copy code blocks with one click
|
||||
|
||||
### Message Display
|
||||
- 📝 **Full markdown rendering** - headers, lists, tables, links, blockquotes
|
||||
- 🎨 **Syntax highlighting** - beautiful code blocks with highlight.js
|
||||
- 📋 **Copy code blocks** - one-click copy button on hover
|
||||
- ✨ **Smooth animations** - elegant message transitions
|
||||
### Characters
|
||||
- V2/V3 character card import/export (PNG format)
|
||||
- Multiple characters with avatar support
|
||||
- Full character editor (description, personality, scenario, examples, etc.)
|
||||
- Character-specific chat history
|
||||
|
||||
### User Experience
|
||||
- ⌨️ **Keyboard shortcuts** - Enter or Ctrl+Enter to send, Shift+Enter for new lines
|
||||
- 🗑️ **Clear conversations** - easily start fresh
|
||||
- 🎯 **Auto-resizing input** - textarea grows with your message
|
||||
- 🎭 **Light/dark mode** - automatic based on system preferences
|
||||
### Roleplay Tools
|
||||
- World Info/Lorebook system with keyword detection and priority
|
||||
- Author's Note with configurable positioning
|
||||
- User Personas with chat/character locking
|
||||
- Prompt Presets with instruction blocks
|
||||
- Message Examples from character cards
|
||||
- Regex Scripts for text transformations
|
||||
- Token counter with per-section breakdown
|
||||
|
||||
### API
|
||||
- Bring-your-own-API (Anthropic-compatible)
|
||||
- Automatic model detection via /v1/models
|
||||
- API validation and error handling
|
||||
|
||||
## Running
|
||||
|
||||
@@ -31,31 +39,49 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Build:
|
||||
Build for production:
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
**Note**: The dev script includes `WEBKIT_DISABLE_DMABUF_RENDERER=1` to fix Wayland compatibility issues on KDE Plasma.
|
||||
|
||||
## Configuration
|
||||
|
||||
On first launch, click settings and configure:
|
||||
On first launch, configure in Settings:
|
||||
- Base URL (e.g., https://api.anthropic.com)
|
||||
- API Key
|
||||
- Model (validated from /v1/models endpoint)
|
||||
- Model
|
||||
|
||||
- Config stored in `~/.config/claudia/config.json`
|
||||
- Chat history stored in `~/.config/claudia/history.json`
|
||||
Config stored in `~/.config/claudia/config.json`
|
||||
|
||||
## Usage
|
||||
## Keyboard Shortcuts
|
||||
|
||||
### Keyboard Shortcuts
|
||||
- **Enter** - Send message
|
||||
- **Shift+Enter** - New line in message
|
||||
- **Shift+Enter** - New line
|
||||
- **Ctrl+Enter** - Send message (alternative)
|
||||
- **Up Arrow** - Edit last user message (when input is at start)
|
||||
- **Left/Right Arrow** - Navigate between response alternatives
|
||||
- **Escape** - Close panels/modals, cancel editing
|
||||
- **Ctrl+K** - Focus message input
|
||||
- **Ctrl+P** - Open command palette (quick access to all actions)
|
||||
- **Ctrl+/** - Toggle Roleplay Tools panel
|
||||
|
||||
### Interface
|
||||
- **Drag header** - Move window around your desktop
|
||||
- **Trash icon** - Clear conversation history
|
||||
- **Settings icon** - Configure API settings
|
||||
- **Minimize/Maximize** - Window controls
|
||||
## Roadmap
|
||||
|
||||
See [ROADMAP.md](ROADMAP.md) for detailed development plans.
|
||||
|
||||
**Current Focus:** Chat Branching/Checkpoints for non-linear conversation exploration
|
||||
|
||||
**Upcoming:**
|
||||
- Chat branching with timeline visualization
|
||||
- Character expression sprites
|
||||
- Group chats with multiple characters
|
||||
- Quick replies and macro system
|
||||
- Context templates for different model formats
|
||||
|
||||
## Development
|
||||
|
||||
Built with:
|
||||
- Tauri 2.0
|
||||
- Rust backend
|
||||
- Vanilla JavaScript frontend
|
||||
- tiktoken-rs for token counting
|
||||
|
||||
504
ROADMAP.md
Normal file
504
ROADMAP.md
Normal file
@@ -0,0 +1,504 @@
|
||||
# Claudia Roleplay Enhancement Roadmap
|
||||
|
||||
## Current Status
|
||||
|
||||
### ✅ Implemented Features
|
||||
- V2/V3 Character Card Import/Export
|
||||
- Message Swipes (multiple response alternatives)
|
||||
- Streaming Responses with toggle
|
||||
- Character Management (multiple characters)
|
||||
- Character Avatars with upload and zoom
|
||||
- Expanded Character Editor (all v2/v3 fields)
|
||||
- Prompt Presets System (built-in and custom presets with instruction blocks)
|
||||
- Editable Built-in Presets with Restore to Default
|
||||
- World Info/Lorebook System (keyword detection, priority, insertion)
|
||||
- Author's Note (configurable depth and positioning)
|
||||
- User Personas (identity management with chat/character locking)
|
||||
- Regex Scripts (global and character-scoped text transformations)
|
||||
- Chat History Import/Export (JSON format)
|
||||
- Enhanced Message Controls (delete, pin, hide, continue, regenerate any message)
|
||||
- Token Counter (real-time display with per-section breakdown)
|
||||
- Message Examples (character card examples injected into context)
|
||||
- Chat Branching/Checkpoints (create, switch, delete, rename branches from any message)
|
||||
|
||||
### 🎯 Current Focus: Quality of Life & Polish
|
||||
**Next Up:** Implementing high-impact QoL features to reduce friction and improve user experience - starting with Toast Notifications, Command Palette, Auto-save, Drag & Drop, and Chat Search.
|
||||
|
||||
**Recent Completion:** Chat Branching/Checkpoints - Full conversation branching system allowing users to create and explore alternate conversation paths from any message point. Each branch maintains its own complete message history with a branch manager modal for easy navigation.
|
||||
|
||||
## Phase 1: Core Roleplay Infrastructure (High Priority)
|
||||
**Goal: Enable basic roleplay-focused prompt engineering**
|
||||
|
||||
### 1. World Info/Lorebook System ✅
|
||||
- [x] Create UI for managing lorebook entries (keyword, content, priority)
|
||||
- [x] Implement keyword detection in recent messages
|
||||
- [x] Add context injection before message generation
|
||||
- [x] Support recursive entry activation
|
||||
- [x] Per-character lorebook assignment
|
||||
- [x] Import/export lorebook files
|
||||
|
||||
**Why Important:** World Info is the foundation of consistent roleplay. It allows dynamic context injection based on what's currently relevant in the conversation, saving tokens while maintaining world consistency.
|
||||
|
||||
### 2. Author's Note ✅
|
||||
- [x] Add configurable Author's Note field (inserted at depth 1-5)
|
||||
- [x] Position control (after system, before/after examples, etc.)
|
||||
- [x] Per-character Author's Note support
|
||||
- [x] Template variables in Author's Note
|
||||
|
||||
**Why Important:** Author's Note is considered better than system prompts for roleplay because it appears closer to the actual conversation, reducing AI tendency to ignore or forget instructions.
|
||||
|
||||
### 3. Jailbreak Templates ✅ (Implemented as Prompt Presets)
|
||||
- [x] Add jailbreak template field in settings (Prompt Presets with system additions)
|
||||
- [x] Preset jailbreak templates for roleplay (Built-in presets: Default, Roleplay, Creative Writing, Assistant)
|
||||
- [x] Per-character jailbreak override option (Active preset per character)
|
||||
- [x] Template preview and testing (Editable instruction blocks with live preview)
|
||||
|
||||
**Why Important:** Many roleplay scenarios require specific prompting to work well with API safety filters and to maintain character consistency.
|
||||
|
||||
## Phase 2: Enhanced Character Features (High Priority)
|
||||
**Goal: Better character representation and user identity**
|
||||
|
||||
### 1. User Personas ✅
|
||||
- [x] Create persona management UI (name, description, avatar)
|
||||
- [x] Chat-level persona locking
|
||||
- [x] Character-level persona locking
|
||||
- [x] Default persona setting
|
||||
- [x] Quick persona switching
|
||||
|
||||
**Why Important:** Allows users to have multiple identities for different roleplay scenarios without manually changing their name and description each time.
|
||||
|
||||
### 2. Character Expressions/Sprites
|
||||
- [ ] Support for emotion-based character images
|
||||
- [ ] Sentiment analysis of AI responses (local model)
|
||||
- [ ] 28+ emotion presets (happy, sad, angry, neutral, etc.)
|
||||
- [ ] Expression sprite packs (import/export)
|
||||
- [ ] Manual expression override with /emote command
|
||||
- [ ] Sprite positioning options (beside chat, behind chat, etc.)
|
||||
|
||||
**Why Important:** Visual representation of character emotions dramatically enhances immersion and makes conversations feel more alive.
|
||||
|
||||
### 3. Message Examples in Context ✅
|
||||
- [x] Actually use mes_example field from character cards
|
||||
- [x] Format and inject into prompt properly
|
||||
- [x] Position control in context
|
||||
- [x] Token budget allocation for examples
|
||||
|
||||
**Why Important:** Message examples help the AI understand the character's voice and writing style, leading to more accurate portrayals.
|
||||
|
||||
## Phase 3: Advanced Chat Management (Medium Priority)
|
||||
**Goal: Non-linear conversation control**
|
||||
|
||||
### 1. Chat Branching/Checkpoints ✅
|
||||
- [x] Save conversation state at any message
|
||||
- [x] Create branches from any point
|
||||
- [x] Switch between branches
|
||||
- [x] Visual branch indicator in UI
|
||||
- [x] Branch naming and organization
|
||||
- [x] Delete branches
|
||||
- [ ] Merge branches (deferred - nice to have)
|
||||
|
||||
**Why Important:** Roleplay often involves exploring "what if" scenarios. Branching lets you explore different conversation paths without losing previous progress.
|
||||
|
||||
### 2. Enhanced Message Controls ✅
|
||||
- [x] Delete individual messages (not just clearing all)
|
||||
- [x] Regenerate any message (not just last)
|
||||
- [x] Continue incomplete messages
|
||||
- [x] Message pinning (keep certain messages in context)
|
||||
- [x] Message folding/hiding
|
||||
- [ ] Bulk message operations (deferred - nice to have)
|
||||
|
||||
**Why Important:** Fine-grained control over conversation history allows users to craft the perfect roleplay session.
|
||||
|
||||
### 3. Timeline Visualization
|
||||
- [ ] Visual tree of chat branches
|
||||
- [ ] Quick navigation between branches
|
||||
- [ ] Branch metadata (creation date, message count, etc.)
|
||||
- [ ] Visual diff between branches
|
||||
- [ ] Merge branch capability
|
||||
|
||||
**Why Important:** Makes managing complex branching conversations intuitive and prevents users from getting lost.
|
||||
|
||||
## Phase 4: Multi-Character/Group Chats (Medium Priority)
|
||||
**Goal: Enable complex multi-character scenarios**
|
||||
|
||||
### 1. Group Chat Foundation
|
||||
- [ ] Create group chat data structure
|
||||
- [ ] UI for managing group members
|
||||
- [ ] Add/remove characters from groups
|
||||
- [ ] Group chat history management
|
||||
- [ ] Per-group settings
|
||||
|
||||
**Why Important:** Many roleplay scenarios involve multiple characters interacting. Group chats enable DM-style gameplay and complex social scenarios.
|
||||
|
||||
### 2. Reply Management
|
||||
- [ ] Manual character selection
|
||||
- [ ] Natural order (mention-based)
|
||||
- [ ] Talkativeness settings per character (0-100%)
|
||||
- [ ] Auto-mode (characters respond automatically)
|
||||
- [ ] Character muting/unmuting
|
||||
- [ ] Reply order presets
|
||||
|
||||
**Why Important:** Gives users control over conversation flow while allowing for spontaneous multi-character interactions.
|
||||
|
||||
### 3. Group Chat UI
|
||||
- [ ] Character indicators on messages
|
||||
- [ ] Character list sidebar
|
||||
- [ ] Mute/unmute controls
|
||||
- [ ] Character ordering/priority
|
||||
- [ ] Group-wide lorebook support
|
||||
|
||||
**Why Important:** Clear visual indicators make group conversations easy to follow.
|
||||
|
||||
## Phase 5: Context & Token Management (Medium Priority)
|
||||
**Goal: Visibility and control over context usage**
|
||||
|
||||
### 1. Token Counter ✅
|
||||
- [x] Real-time token count display
|
||||
- [x] Per-section breakdown (system, history, WI, etc.)
|
||||
- [ ] Visual context budget indicator (deferred)
|
||||
- [ ] Dotted line showing context cutoff in chat (deferred)
|
||||
- [ ] Warning when approaching limit (deferred)
|
||||
|
||||
**Why Important:** Understanding what's in context and what's being cut is crucial for debugging issues and optimizing prompts. Core functionality complete - visual enhancements can be added later.
|
||||
|
||||
### 2. Context Templates
|
||||
- [ ] Customizable prompt assembly order
|
||||
- [ ] Handlebars template support
|
||||
- [ ] Presets for different model types (Alpaca, ChatML, Llama, etc.)
|
||||
- [ ] Template preview
|
||||
- [ ] Variable substitution visualization
|
||||
|
||||
**Why Important:** Different models expect different prompt formats. Templates ensure prompts are formatted correctly for each model.
|
||||
|
||||
### 3. Smart Context Management
|
||||
- [ ] Summarization of old messages
|
||||
- [ ] Automatic message trimming
|
||||
- [ ] Priority-based context allocation
|
||||
- [ ] Context budget per source (system, WI, history, etc.)
|
||||
- [ ] Smart message selection (keep important messages)
|
||||
|
||||
**Why Important:** Efficient context usage means longer, more coherent conversations without running out of tokens.
|
||||
|
||||
## Phase 6: Power User Features (Low Priority)
|
||||
**Goal: Advanced customization and automation**
|
||||
|
||||
### 1. Quick Replies
|
||||
- [ ] Preset message buttons
|
||||
- [ ] Macro support in quick replies
|
||||
- [ ] Import/export QR sets
|
||||
- [ ] Character-specific QR sets
|
||||
- [ ] Conditional quick replies
|
||||
- [ ] Quick reply categories/folders
|
||||
|
||||
**Why Important:** Speeds up common actions and reduces repetitive typing in roleplay scenarios.
|
||||
|
||||
### 2. Macro System
|
||||
- [ ] Basic macros ({{user}}, {{char}}, {{random}}, etc.)
|
||||
- [ ] Date/time macros
|
||||
- [ ] Conditional macros
|
||||
- [ ] Custom macro definitions
|
||||
- [ ] Nested macro support
|
||||
- [ ] Macro debugging
|
||||
|
||||
**Why Important:** Makes prompts and messages dynamic and reusable across different scenarios.
|
||||
|
||||
### 3. Regex Scripts ✅
|
||||
- [x] Global and character-scoped scripts
|
||||
- [x] Text transformation on messages
|
||||
- [x] Auto-markdown formatting
|
||||
- [x] Import/export regex presets
|
||||
- [x] Regex testing interface
|
||||
- [x] Script priority/ordering
|
||||
|
||||
**Why Important:** Allows automatic text formatting, correction, and enhancement without manual intervention.
|
||||
|
||||
### 4. Hotkey System
|
||||
- [ ] Customizable keyboard shortcuts
|
||||
- [ ] Quick actions (regen, edit, delete, etc.)
|
||||
- [ ] Markdown formatting hotkeys
|
||||
- [ ] Quick Reply hotkeys
|
||||
- [ ] Navigation hotkeys
|
||||
- [ ] Hotkey conflict detection
|
||||
|
||||
**Why Important:** Power users rely on keyboard shortcuts for efficient workflow.
|
||||
|
||||
## Phase 7: Polish & UX (Ongoing)
|
||||
**Goal: Better user experience for roleplay**
|
||||
|
||||
### 1. Instruct Mode Support
|
||||
- [ ] Preset templates (Alpaca, ChatML, Llama, etc.)
|
||||
- [ ] Custom template creation
|
||||
- [ ] Auto-detect model format from API
|
||||
- [ ] Instruction wrapping for system/user/assistant messages
|
||||
|
||||
**Why Important:** Ensures compatibility with instruction-tuned models that expect specific formats.
|
||||
|
||||
### 2. Export/Import Improvements
|
||||
- [ ] Export chats as markdown
|
||||
- [ ] Export chats as formatted text
|
||||
- [x] Export chats as JSON with metadata
|
||||
- [x] Import chats from other formats
|
||||
- [ ] Bulk character import
|
||||
- [ ] Character pack support (multiple characters + lorebooks)
|
||||
|
||||
**Why Important:** Sharing and migrating content between platforms and backing up work.
|
||||
|
||||
### 3. UI Enhancements
|
||||
- [ ] Message timestamps
|
||||
- [ ] Character indicators in messages
|
||||
- [ ] Better settings organization (categories, search)
|
||||
- [ ] Theme customization (colors, fonts, etc.)
|
||||
- [ ] Compact/cozy view modes
|
||||
- [ ] Responsive design for different screen sizes
|
||||
- [ ] Accessibility improvements
|
||||
|
||||
**Why Important:** Better UI means less friction and more immersion in roleplay.
|
||||
|
||||
## Phase 8: Quality of Life & Polish (High Priority)
|
||||
**Goal: Reduce friction, improve feedback, and enhance overall user experience**
|
||||
|
||||
### 1. Toast Notification System
|
||||
- [ ] Create toast component (bottom-right positioning)
|
||||
- [ ] Success/error/info/warning variants
|
||||
- [ ] Auto-dismiss with configurable timeout
|
||||
- [ ] Queue multiple toasts
|
||||
- [ ] Hook into all major actions (save, delete, import, export, etc.)
|
||||
|
||||
**Why Important:** Users currently have no immediate feedback when actions succeed or fail. Toasts provide instant visual confirmation without blocking workflow.
|
||||
|
||||
### 2. Command Palette
|
||||
- [ ] Ctrl+P to open command palette modal
|
||||
- [ ] Fuzzy search for all actions
|
||||
- [ ] Keyboard navigation (arrow keys, enter, escape)
|
||||
- [ ] Recent/frequent actions at top
|
||||
- [ ] Show keyboard shortcuts in results
|
||||
- [ ] Categories (Chat, Character, Settings, etc.)
|
||||
|
||||
**Why Important:** Power users want keyboard-first workflow. Command palette dramatically speeds up common actions without memorizing shortcuts.
|
||||
|
||||
### 3. Auto-save & Recovery
|
||||
- [ ] Auto-save unsent message in input field
|
||||
- [ ] Restore unsent message after app restart
|
||||
- [ ] Draft system for in-progress edits
|
||||
- [ ] Session recovery (restore scroll position, open panels)
|
||||
- [ ] Crash recovery with last known state
|
||||
|
||||
**Why Important:** Losing work due to crashes or accidental closes is extremely frustrating. Auto-save provides a safety net for all user work.
|
||||
|
||||
### 4. Drag & Drop Support
|
||||
- [ ] Drag character card PNGs to import
|
||||
- [ ] Drag lorebook JSON files to import
|
||||
- [ ] Drag chat history JSON to import
|
||||
- [ ] Drag images to set as character avatar
|
||||
- [ ] Drop zone overlay with visual feedback
|
||||
- [ ] Support for multiple file drops
|
||||
|
||||
**Why Important:** Drag & drop feels natural and is much faster than navigate-click-select workflow. Modern desktop apps are expected to support this.
|
||||
|
||||
### 5. Search in Chat History
|
||||
- [ ] Ctrl+F to open search bar
|
||||
- [ ] Highlight all matches in messages
|
||||
- [ ] Navigate between results (prev/next buttons)
|
||||
- [ ] Case-insensitive search
|
||||
- [ ] Search counter (e.g., "3 of 42 matches")
|
||||
- [ ] Clear search and restore view
|
||||
|
||||
**Why Important:** Long roleplay sessions can span hundreds of messages. Finding specific content without search is tedious and time-consuming.
|
||||
|
||||
### 6. Context Menus (Right-Click)
|
||||
- [ ] Right-click messages for actions (edit, delete, regenerate, branch, copy)
|
||||
- [ ] Right-click character dropdown for quick actions
|
||||
- [ ] Right-click World Info entries for edit/delete
|
||||
- [ ] Right-click in message input for paste/clear/templates
|
||||
- [ ] Context-aware menu items
|
||||
|
||||
**Why Important:** Right-click is muscle memory for desktop users. Faster than hovering to reveal action buttons.
|
||||
|
||||
### 7. Better Feedback & Confirmations
|
||||
- [ ] Confirmation dialogs for destructive actions (delete character, clear chat)
|
||||
- [ ] Loading spinners for API calls
|
||||
- [ ] Progress bars for file imports
|
||||
- [ ] "Saving..." / "Saved" indicators
|
||||
- [ ] Success messages for completed actions
|
||||
|
||||
**Why Important:** Users should never wonder if an action succeeded or is still processing. Clear feedback prevents confusion and repeated clicks.
|
||||
|
||||
### 8. Undo/Redo System
|
||||
- [ ] Undo message edit (Ctrl+Z)
|
||||
- [ ] Undo message delete
|
||||
- [ ] Undo character field changes
|
||||
- [ ] Undo World Info changes
|
||||
- [ ] Action history panel (optional)
|
||||
- [ ] Redo support (Ctrl+Shift+Z)
|
||||
|
||||
**Why Important:** Mistakes happen. An undo system provides a safety net and encourages experimentation without fear of losing work.
|
||||
|
||||
### 9. Settings Search
|
||||
- [ ] Search bar at top of settings panel
|
||||
- [ ] Fuzzy search across all setting names and descriptions
|
||||
- [ ] Highlight matching settings
|
||||
- [ ] Collapse/expand sections based on matches
|
||||
- [ ] "Recently changed" section
|
||||
|
||||
**Why Important:** With 22+ features, finding specific settings is tedious. Search makes configuration much faster.
|
||||
|
||||
### 10. Character Management Enhancements
|
||||
- [ ] Recent characters quick-switch dropdown
|
||||
- [ ] Character search/filter by name or tags
|
||||
- [ ] Character folders/categories
|
||||
- [ ] Duplicate character (as template)
|
||||
- [ ] Favorite/star characters
|
||||
- [ ] Sort options (name, date created, last used)
|
||||
|
||||
**Why Important:** Managing 10+ characters becomes messy. Better organization tools scale with user's character collection.
|
||||
|
||||
### 11. Enhanced Keyboard Support
|
||||
- [ ] Full keyboard navigation in all modals (Tab, Arrow keys, Enter)
|
||||
- [ ] Escape to close any open panel/modal
|
||||
- [ ] Vim-style navigation mode (optional, j/k for scroll)
|
||||
- [ ] Keyboard shortcut hints on hover
|
||||
- [ ] Focus indicators for keyboard navigation
|
||||
|
||||
**Why Important:** Keyboard navigation should work everywhere. Current implementation is inconsistent across different UI sections.
|
||||
|
||||
### 12. Export/Share Enhancements
|
||||
- [ ] Export conversation as formatted HTML
|
||||
- [ ] Export conversation as formatted PDF
|
||||
- [ ] Export as markdown with proper formatting
|
||||
- [ ] Copy conversation to clipboard (formatted)
|
||||
- [ ] Export individual messages
|
||||
|
||||
**Why Important:** Users want to share and archive conversations in readable formats, not just JSON.
|
||||
|
||||
### 13. Accessibility Improvements
|
||||
- [ ] ARIA labels for all interactive elements
|
||||
- [ ] Screen reader support
|
||||
- [ ] High contrast mode option
|
||||
- [ ] Larger click targets option (accessibility mode)
|
||||
- [ ] Reduced motion mode (respect prefers-reduced-motion)
|
||||
- [ ] Focus indicators for keyboard navigation
|
||||
|
||||
**Why Important:** Accessibility makes the app usable for everyone, including users with disabilities. It's also often legally required.
|
||||
|
||||
### 14. Better Visual Feedback
|
||||
- [ ] Smooth transitions for panel open/close
|
||||
- [ ] Hover states for all interactive elements
|
||||
- [ ] Active state indicators (focused panel)
|
||||
- [ ] Better empty states with helpful text
|
||||
- [ ] Skeleton loaders for content loading
|
||||
- [ ] Micro-animations for actions (delete, save, etc.)
|
||||
|
||||
**Why Important:** Visual polish makes the app feel responsive and professional. Small animations provide context for state changes.
|
||||
|
||||
### 15. Smart Defaults & Templates
|
||||
- [ ] Scenario templates (fantasy RPG, sci-fi, modern, etc.)
|
||||
- [ ] Pre-filled World Info templates
|
||||
- [ ] Character card templates
|
||||
- [ ] Quick-start wizard for new users
|
||||
- [ ] Import from popular character repositories
|
||||
|
||||
**Why Important:** Reduces friction for new users and speeds up common tasks. Templates provide starting points for customization.
|
||||
|
||||
## Implementation Priority Ranking
|
||||
|
||||
### Must-Have for Basic Roleplay:
|
||||
1. **World Info/Lorebooks** - Core feature for consistent roleplay
|
||||
2. **Author's Note** - Better prompt control than system prompts alone
|
||||
3. **Token Counter** - Visibility into what's happening
|
||||
4. **Message Examples Usage** - Better character accuracy
|
||||
|
||||
### Important for Good Roleplay:
|
||||
5. **User Personas** - Identity management
|
||||
6. **Chat Branching** - Non-linear exploration
|
||||
7. **Enhanced Message Controls** - Fine-grained editing
|
||||
8. **Jailbreak Templates** - Handle various scenarios
|
||||
|
||||
### Great for Enhanced Experience:
|
||||
9. **Expression Sprites** - Visual immersion
|
||||
10. **Quick Replies + Macros** - Efficiency
|
||||
11. **Context Templates** - Model compatibility
|
||||
12. **Group Chats** - Complex scenarios
|
||||
|
||||
### Nice to Have:
|
||||
13. **Timeline Visualization** - Advanced branch management
|
||||
14. **Regex Scripts** - Automation
|
||||
15. **Hotkeys** - Power user efficiency
|
||||
16. **Smart Context Management** - Optimization
|
||||
|
||||
## Research Sources
|
||||
|
||||
This roadmap is based on research into SillyTavern's features and best practices from the roleplay AI community:
|
||||
- SillyTavern official documentation (docs.sillytavern.app)
|
||||
- Character card specifications (V2/V3 format)
|
||||
- Community presets and guides on HuggingFace
|
||||
- Roleplay community feedback and feature requests
|
||||
|
||||
## Technical Considerations
|
||||
|
||||
### Data Structures Needed:
|
||||
- Lorebook entries (keyword, content, priority, insertion order, depth)
|
||||
- Personas (name, description, avatar, chat/character locks)
|
||||
- Chat branches (branch point, parent branch, metadata)
|
||||
- Expression mappings (emotion → image file)
|
||||
- Quick replies (text, macros, conditions, categories)
|
||||
- Context templates (format strings, variables, presets)
|
||||
|
||||
### Backend Changes Required:
|
||||
- Context assembly refactor (modular system for injecting different sources)
|
||||
- Token counting integration (model-specific tokenizers)
|
||||
- Sentiment analysis (local model or API integration)
|
||||
- Branching chat storage (tree structure instead of linear)
|
||||
- Group chat message routing (multi-character generation)
|
||||
|
||||
### UI Additions Needed:
|
||||
- Lorebook editor panel
|
||||
- Persona management panel
|
||||
- Branch visualization widget
|
||||
- Token counter display
|
||||
- Group chat member list
|
||||
- Quick reply buttons
|
||||
- Expression sprite overlay
|
||||
- Context template editor
|
||||
|
||||
## Version Milestones
|
||||
|
||||
### v0.2.0 - "Roleplay Foundation"
|
||||
- World Info/Lorebooks
|
||||
- Author's Note
|
||||
- Token Counter
|
||||
- Better Message Controls
|
||||
|
||||
### v0.3.0 - "Character Enhancement"
|
||||
- User Personas
|
||||
- Expression Sprites
|
||||
- Message Examples Usage
|
||||
- Jailbreak Templates
|
||||
|
||||
### v0.4.0 - "Advanced Chat"
|
||||
- Chat Branching
|
||||
- Timeline Visualization
|
||||
- Group Chats (basic)
|
||||
|
||||
### v0.5.0 - "Power User"
|
||||
- Quick Replies
|
||||
- Macros
|
||||
- Regex Scripts
|
||||
- Hotkeys
|
||||
|
||||
### v1.0.0 - "Feature Complete"
|
||||
- All planned features implemented
|
||||
- Polished UI
|
||||
- Comprehensive documentation
|
||||
- Import/Export from SillyTavern
|
||||
|
||||
## Notes
|
||||
|
||||
- Focus on **compatibility with SillyTavern** where possible (character cards, lorebooks, etc.)
|
||||
- Keep **performance** in mind - roleplay sessions can be long
|
||||
- Maintain **desktop-first** design - power users prefer desktop interfaces
|
||||
- Consider **offline-first** approach - local models are popular for roleplay
|
||||
- Remember **privacy** - roleplay content is often sensitive
|
||||
|
||||
---
|
||||
|
||||
Last updated: 2025-10-16
|
||||
62
src-tauri/Cargo.lock
generated
62
src-tauri/Cargo.lock
generated
@@ -270,6 +270,21 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.3"
|
||||
@@ -352,6 +367,17 @@ dependencies = [
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
@@ -502,8 +528,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
@@ -1020,6 +1048,16 @@ dependencies = [
|
||||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7493d4c459da9f84325ad297371a6b2b8a162800873a22e3b6b6512e61d18c05"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
@@ -3459,6 +3497,12 @@ version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
@@ -4194,9 +4238,11 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"futures",
|
||||
"image",
|
||||
"png",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4204,6 +4250,7 @@ dependencies = [
|
||||
"tauri-build",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-opener",
|
||||
"tiktoken-rs",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
@@ -4525,6 +4572,21 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiktoken-rs"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c314e7ce51440f9e8f5a497394682a57b7c323d0f4d0a6b1b13c429056e0e234"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
"bstr",
|
||||
"fancy-regex",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.44"
|
||||
|
||||
@@ -31,4 +31,7 @@ bytes = "1"
|
||||
png = "0.17"
|
||||
base64 = "0.21"
|
||||
image = "0.24"
|
||||
regex = "1"
|
||||
chrono = "0.4"
|
||||
tiktoken-rs = "0.5"
|
||||
|
||||
|
||||
2172
src-tauri/src/lib.rs
2172
src-tauri/src/lib.rs
File diff suppressed because it is too large
Load Diff
532
src/index.html
532
src/index.html
@@ -15,10 +15,20 @@
|
||||
<div class="app-container">
|
||||
<header class="app-header">
|
||||
<div class="header-content">
|
||||
<div class="header-left-controls">
|
||||
<button id="roleplay-btn" class="icon-btn" title="Roleplay Tools">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="character-display">
|
||||
<div class="avatar-circle"></div>
|
||||
<span id="character-header-name"></span>
|
||||
</div>
|
||||
<div id="feature-badges" class="feature-badges">
|
||||
<!-- Feature badges will be added here dynamically -->
|
||||
</div>
|
||||
<div class="character-controls">
|
||||
<div class="select-wrapper">
|
||||
<select id="character-select" class="character-select"></select>
|
||||
@@ -30,6 +40,18 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="header-controls">
|
||||
<button id="import-chat-btn" class="icon-btn" title="Import conversation">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M8 11V3M5 8l3 3 3-3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 13h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="export-chat-btn" class="icon-btn" title="Export conversation">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M8 3v8M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 13h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="clear-btn" class="icon-btn" title="Clear conversation">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M3 4h10M6 4V3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v1M5 4v8a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
@@ -55,7 +77,233 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="settings-panel" id="settings-panel" style="display: none;">
|
||||
<!-- Roleplay sidebar overlay -->
|
||||
<div class="roleplay-overlay" id="roleplay-overlay"></div>
|
||||
|
||||
<!-- Roleplay sidebar (left) -->
|
||||
<div class="roleplay-panel" id="roleplay-panel">
|
||||
<div class="roleplay-header">
|
||||
<h2>Roleplay Tools</h2>
|
||||
<button id="close-roleplay-btn" class="icon-btn">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<line x1="4" y1="4" x2="12" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<line x1="12" y1="4" x2="4" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="roleplay-tabs">
|
||||
<button class="roleplay-tab-btn active" data-tab="worldinfo">World Info</button>
|
||||
<button class="roleplay-tab-btn" data-tab="authorsnote">Author's Note</button>
|
||||
<button class="roleplay-tab-btn" data-tab="persona">Persona</button>
|
||||
<button class="roleplay-tab-btn" data-tab="presets">Prompt Preset</button>
|
||||
</div>
|
||||
|
||||
<div id="worldinfo-tab" class="roleplay-tab-content active">
|
||||
<div class="roleplay-content">
|
||||
<div class="form-group">
|
||||
<label>World Info / Lorebook</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 12px;">
|
||||
Create entries that inject context when keywords are mentioned.
|
||||
</p>
|
||||
<label for="recursion-depth" style="font-size: 13px; margin-top: 8px;">Recursion Depth</label>
|
||||
<input
|
||||
type="number"
|
||||
id="recursion-depth"
|
||||
min="0"
|
||||
max="10"
|
||||
value="3"
|
||||
style="width: 80px; margin-bottom: 8px;"
|
||||
/>
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin-bottom: 12px;">
|
||||
Maximum depth for cascading World Info activation. When a World Info entry is triggered, its content is scanned for additional keywords up to this depth. (Default: 3)
|
||||
</p>
|
||||
<button type="button" id="add-worldinfo-btn" class="btn-secondary" style="width: 100%;">
|
||||
+ Add Entry
|
||||
</button>
|
||||
</div>
|
||||
<div id="worldinfo-list" class="worldinfo-list">
|
||||
<!-- World info entries will be added here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="authorsnote-tab" class="roleplay-tab-content">
|
||||
<div class="roleplay-content">
|
||||
<div class="form-group">
|
||||
<label for="authors-note-text">Author's Note</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
|
||||
Instructions inserted near the end of the prompt before the latest messages.
|
||||
</p>
|
||||
<textarea
|
||||
id="authors-note-text"
|
||||
placeholder="Write in present tense. Focus on sensory details..."
|
||||
rows="6"
|
||||
></textarea>
|
||||
<div style="background: var(--bg-secondary); padding: 8px; border-radius: 4px; margin-top: 8px;">
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin: 0 0 4px 0; font-weight: 500;">Template Variables:</p>
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin: 0; font-family: monospace;">
|
||||
{{char}} - Character name<br/>
|
||||
{{user}} - User/Persona name<br/>
|
||||
{{date}} - Current date (YYYY-MM-DD)<br/>
|
||||
{{time}} - Current time (HH:MM)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="authors-note-enabled" />
|
||||
Enable Author's Note
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" id="save-authors-note-btn" class="btn-primary" style="width: 100%; margin-bottom: 20px;">
|
||||
Save Author's Note
|
||||
</button>
|
||||
|
||||
<!-- Message Examples Section -->
|
||||
<div class="form-group" style="border-top: 1px solid var(--border); padding-top: 16px;">
|
||||
<label>Message Examples</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
|
||||
Use character card's message examples to teach the AI the character's voice and style.
|
||||
</p>
|
||||
<label>
|
||||
<input type="checkbox" id="examples-enabled" />
|
||||
Enable Message Examples
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="examples-position">Examples Position</label>
|
||||
<select id="examples-position" style="width: 100%;">
|
||||
<option value="after_system">After System Prompt (Recommended)</option>
|
||||
<option value="before_history">Before Message History</option>
|
||||
</select>
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin-top: 4px;">
|
||||
Where to inject examples in the context. After system prompt works best for most models.
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" id="save-examples-btn" class="btn-primary" style="width: 100%;">
|
||||
Save Examples Settings
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="persona-tab" class="roleplay-tab-content">
|
||||
<div class="roleplay-content">
|
||||
<div class="form-group">
|
||||
<label for="persona-name">Persona Name</label>
|
||||
<input
|
||||
type="text"
|
||||
id="persona-name"
|
||||
placeholder="Your character name"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="persona-description">Persona Description</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
|
||||
Describe yourself as the user in this roleplay.
|
||||
</p>
|
||||
<textarea
|
||||
id="persona-description"
|
||||
placeholder="Describe your character's appearance, personality, background..."
|
||||
rows="8"
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="persona-enabled" />
|
||||
Enable Persona
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" id="save-persona-btn" class="btn-primary" style="width: 100%;">
|
||||
Save Persona
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="presets-tab" class="roleplay-tab-content">
|
||||
<div class="roleplay-content">
|
||||
<div class="form-group">
|
||||
<label for="preset-select">Prompt Preset</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
|
||||
Choose a preset to apply specialized prompting strategies for different use cases.
|
||||
</p>
|
||||
<select id="preset-select" style="width: 100%; margin-bottom: 12px;">
|
||||
<option value="">No Preset</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Preset Info/Editor -->
|
||||
<div id="preset-info" style="display: none; background: var(--bg-secondary); padding: 12px; border-radius: 6px; margin-bottom: 16px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
||||
<div style="font-weight: 500; color: var(--text-primary);">
|
||||
<span id="preset-name"></span>
|
||||
<span id="preset-builtin-badge" style="display: none; font-size: 10px; color: var(--text-secondary); margin-left: 8px; padding: 2px 6px; background: var(--bg-primary); border-radius: 3px;">Built-in</span>
|
||||
<span id="preset-modified-badge" style="display: none; font-size: 10px; color: var(--accent); margin-left: 8px; padding: 2px 6px; background: var(--bg-primary); border-radius: 3px;">Modified</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 4px;">
|
||||
<button type="button" id="restore-preset-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">Restore to Default</button>
|
||||
<button type="button" id="duplicate-preset-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">Duplicate</button>
|
||||
<button type="button" id="delete-preset-btn" class="worldinfo-btn worldinfo-btn-danger" style="display: none; font-size: 11px; padding: 4px 8px;">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
<p id="preset-description" style="color: var(--text-secondary); font-size: 12px; margin-bottom: 12px;"></p>
|
||||
|
||||
<!-- System Additions (Read-only preview for built-in, editable for custom) -->
|
||||
<div id="preset-system-section" style="margin-bottom: 12px;">
|
||||
<div style="font-size: 11px; color: var(--text-secondary); margin-bottom: 4px;">
|
||||
<strong>System Additions:</strong>
|
||||
</div>
|
||||
<div id="preset-system-readonly" style="display: none; background: var(--bg-primary); padding: 8px; border-radius: 4px; font-size: 11px; white-space: pre-wrap;"></div>
|
||||
<textarea id="preset-system-editable" style="display: none; width: 100%; min-height: 60px; font-size: 11px;" placeholder="Additional text to prepend to system prompt..."></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Instruction Blocks Editor -->
|
||||
<div id="preset-instructions-section">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
||||
<div style="font-size: 11px; color: var(--text-secondary);">
|
||||
<strong>Instruction Blocks:</strong>
|
||||
</div>
|
||||
<button type="button" id="add-instruction-btn" class="worldinfo-btn" style="display: none; font-size: 11px; padding: 4px 8px;">+ Add Block</button>
|
||||
</div>
|
||||
<div id="preset-instructions-list" style="background: var(--bg-primary); padding: 8px; border-radius: 4px; margin-bottom: 12px;">
|
||||
<!-- Instructions will be listed here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Author's Note Default -->
|
||||
<div id="preset-authors-note-section" style="margin-bottom: 12px;">
|
||||
<div style="font-size: 11px; color: var(--text-secondary); margin-bottom: 4px;">
|
||||
<strong>Default Author's Note:</strong>
|
||||
</div>
|
||||
<div id="preset-authors-note-readonly" style="display: none; background: var(--bg-primary); padding: 8px; border-radius: 4px; font-size: 11px; white-space: pre-wrap;"></div>
|
||||
<textarea id="preset-authors-note-editable" style="display: none; width: 100%; min-height: 60px; font-size: 11px;" placeholder="Default Author's Note if user hasn't set one..."></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Save Changes Button (only for custom presets) -->
|
||||
<button type="button" id="save-preset-changes-btn" class="btn-secondary" style="display: none; width: 100%; margin-bottom: 8px;">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button type="button" id="apply-preset-btn" class="btn-primary" style="width: 100%; margin-bottom: 8px;" disabled>
|
||||
Apply Preset
|
||||
</button>
|
||||
|
||||
<button type="button" id="create-preset-btn" class="btn-secondary" style="width: 100%;">
|
||||
Create Custom Preset
|
||||
</button>
|
||||
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin-top: 12px; padding: 8px; background: var(--bg-secondary); border-radius: 4px;">
|
||||
<strong>Note:</strong> Custom presets will be stored in ~/.config/claudia/presets/ and will be available across all characters.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings overlay backdrop -->
|
||||
<div class="settings-overlay" id="settings-overlay"></div>
|
||||
|
||||
<div class="settings-panel" id="settings-panel">
|
||||
<div class="settings-header">
|
||||
<h2>Settings</h2>
|
||||
<button id="close-settings-btn" class="icon-btn">
|
||||
@@ -69,6 +317,7 @@
|
||||
<div class="settings-tabs">
|
||||
<button class="tab-btn active" data-tab="api">API</button>
|
||||
<button class="tab-btn" data-tab="character">Character</button>
|
||||
<button class="tab-btn" data-tab="appearance">Appearance</button>
|
||||
</div>
|
||||
|
||||
<div id="api-tab" class="tab-content active">
|
||||
@@ -104,6 +353,19 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="context-limit">Context Limit (tokens)</label>
|
||||
<input
|
||||
type="number"
|
||||
id="context-limit"
|
||||
placeholder="200000"
|
||||
value="200000"
|
||||
min="1000"
|
||||
step="1000"
|
||||
/>
|
||||
<small style="color: var(--text-secondary); margin-top: 4px; display: block;">Maximum tokens for model context (e.g., 200000 for Claude)</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="stream-toggle" />
|
||||
@@ -125,6 +387,18 @@
|
||||
<label for="character-settings-select">Select Character</label>
|
||||
<select id="character-settings-select"></select>
|
||||
</div>
|
||||
|
||||
<!-- Basic Info Section -->
|
||||
<div class="settings-section" data-section="basic">
|
||||
<div class="settings-section-header">
|
||||
<div class="settings-section-title">
|
||||
<svg class="settings-section-icon" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Basic Information
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-section-content">
|
||||
<div class="form-group">
|
||||
<label for="character-name">Character Name</label>
|
||||
<input
|
||||
@@ -174,9 +448,22 @@
|
||||
rows="2"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Roleplay Details Section -->
|
||||
<div class="settings-section collapsed" data-section="roleplay">
|
||||
<div class="settings-section-header">
|
||||
<div class="settings-section-title">
|
||||
<svg class="settings-section-icon" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Roleplay Details
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-section-content">
|
||||
<div class="form-group">
|
||||
<label for="character-personality">Personality Tags (Optional)</label>
|
||||
<label for="character-personality">Personality Tags</label>
|
||||
<input
|
||||
type="text"
|
||||
id="character-personality"
|
||||
@@ -185,16 +472,16 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-description">Description (Optional)</label>
|
||||
<label for="character-description">Description</label>
|
||||
<textarea
|
||||
id="character-description"
|
||||
placeholder="Detailed character description, appearance, background..."
|
||||
rows="10"
|
||||
rows="8"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-scenario">Scenario (Optional)</label>
|
||||
<label for="character-scenario">Scenario</label>
|
||||
<textarea
|
||||
id="character-scenario"
|
||||
placeholder="The setting or situation where the character exists..."
|
||||
@@ -203,16 +490,29 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-mes-example">Message Example (Optional)</label>
|
||||
<label for="character-mes-example">Message Examples</label>
|
||||
<textarea
|
||||
id="character-mes-example"
|
||||
placeholder="Example dialogue from the character..."
|
||||
rows="4"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Settings Section -->
|
||||
<div class="settings-section collapsed" data-section="advanced">
|
||||
<div class="settings-section-header">
|
||||
<div class="settings-section-title">
|
||||
<svg class="settings-section-icon" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Advanced Settings
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-section-content">
|
||||
<div class="form-group">
|
||||
<label for="character-post-history">Post-History Instructions (Optional)</label>
|
||||
<label for="character-post-history">Post-History Instructions</label>
|
||||
<textarea
|
||||
id="character-post-history"
|
||||
placeholder="Instructions to apply after chat history..."
|
||||
@@ -221,16 +521,29 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-alt-greetings">Alternate Greetings (Optional)</label>
|
||||
<label for="character-alt-greetings">Alternate Greetings</label>
|
||||
<textarea
|
||||
id="character-alt-greetings"
|
||||
placeholder="One greeting per line..."
|
||||
rows="3"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Metadata Section -->
|
||||
<div class="settings-section collapsed" data-section="metadata">
|
||||
<div class="settings-section-header">
|
||||
<div class="settings-section-title">
|
||||
<svg class="settings-section-icon" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
Metadata
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-section-content">
|
||||
<div class="form-group">
|
||||
<label for="character-tags">Tags (Optional)</label>
|
||||
<label for="character-tags">Tags</label>
|
||||
<input
|
||||
type="text"
|
||||
id="character-tags"
|
||||
@@ -239,7 +552,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-creator">Creator (Optional)</label>
|
||||
<label for="character-creator">Creator</label>
|
||||
<input
|
||||
type="text"
|
||||
id="character-creator"
|
||||
@@ -248,7 +561,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-version">Character Version (Optional)</label>
|
||||
<label for="character-version">Character Version</label>
|
||||
<input
|
||||
type="text"
|
||||
id="character-version"
|
||||
@@ -257,26 +570,28 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="character-creator-notes">Creator Notes (Optional)</label>
|
||||
<label for="character-creator-notes">Creator Notes</label>
|
||||
<textarea
|
||||
id="character-creator-notes"
|
||||
placeholder="Notes from the creator..."
|
||||
rows="2"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="character-message" class="validation-message"></div>
|
||||
|
||||
<button type="submit" id="save-character-btn" class="btn-primary">
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button type="submit" id="save-character-btn" class="btn-primary" style="flex: 1;">
|
||||
Save Character
|
||||
</button>
|
||||
<button type="button" id="delete-character-btn" class="btn-danger">
|
||||
Delete Character
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border-color);">
|
||||
<label>Character Card Import/Export</label>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button type="button" id="import-character-btn" class="btn-secondary" style="flex: 1;">
|
||||
Import v2 Card
|
||||
</button>
|
||||
@@ -284,9 +599,67 @@
|
||||
Export v2 Card
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="appearance-tab" class="tab-content">
|
||||
<div class="settings-form">
|
||||
<div class="form-group">
|
||||
<label for="theme-select">Theme</label>
|
||||
<select id="theme-select" class="theme-select">
|
||||
<option value="dark">Dark (Default)</option>
|
||||
<option value="darker">Darker</option>
|
||||
<option value="midnight">Midnight Blue</option>
|
||||
<option value="forest">Forest</option>
|
||||
<option value="sunset">Sunset</option>
|
||||
<option value="light">Light</option>
|
||||
</select>
|
||||
<small style="color: var(--text-secondary); margin-top: 4px; display: block;">Choose your preferred color scheme</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="view-mode-select">View Mode</label>
|
||||
<select id="view-mode-select" class="view-mode-select">
|
||||
<option value="compact">Compact - Tight spacing, smaller text</option>
|
||||
<option value="cozy">Cozy - Balanced spacing (Default)</option>
|
||||
<option value="comfortable">Comfortable - Spacious layout</option>
|
||||
</select>
|
||||
<small style="color: var(--text-secondary); margin-top: 4px; display: block;">Adjust message density and spacing</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="font-size-slider">
|
||||
Font Size: <span id="font-size-value">100%</span>
|
||||
</label>
|
||||
<input
|
||||
type="range"
|
||||
id="font-size-slider"
|
||||
min="80"
|
||||
max="140"
|
||||
value="100"
|
||||
step="10"
|
||||
class="font-size-slider"
|
||||
/>
|
||||
<div style="display: flex; justify-content: space-between; margin-top: 4px;">
|
||||
<small style="color: var(--text-secondary);">Small (80%)</small>
|
||||
<small style="color: var(--text-secondary);">Large (140%)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="theme-preview-container">
|
||||
<div class="theme-preview-label">Preview</div>
|
||||
<div class="theme-preview">
|
||||
<div class="theme-preview-message user-preview">
|
||||
<div class="theme-preview-content">User message</div>
|
||||
</div>
|
||||
<div class="theme-preview-message assistant-preview">
|
||||
<div class="theme-preview-avatar"></div>
|
||||
<div class="theme-preview-content">Assistant response</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="input-container">
|
||||
@@ -305,10 +678,88 @@
|
||||
</form>
|
||||
<div class="status-bar">
|
||||
<span id="status-text" class="status-text">Ready</span>
|
||||
<div id="token-counter" class="token-counter">
|
||||
<span id="token-count-total" class="token-count">0 tokens</span>
|
||||
<button id="token-details-btn" class="token-details-btn" title="Show breakdown">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none">
|
||||
<circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/>
|
||||
<path d="M8 7v4M8 5h.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Token Breakdown Tooltip -->
|
||||
<div id="token-breakdown" class="token-breakdown" style="display: none;">
|
||||
<div class="token-breakdown-header">Token Breakdown</div>
|
||||
<div class="token-breakdown-list">
|
||||
<div class="token-breakdown-item">
|
||||
<span>System Prompt:</span>
|
||||
<span id="token-system">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Preset Instructions:</span>
|
||||
<span id="token-preset">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Persona:</span>
|
||||
<span id="token-persona">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>World Info:</span>
|
||||
<span id="token-worldinfo">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Author's Note:</span>
|
||||
<span id="token-authorsnote">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Message Examples:</span>
|
||||
<span id="token-examples">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Message History:</span>
|
||||
<span id="token-history">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Current Input:</span>
|
||||
<span id="token-input">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-total">
|
||||
<span>Total:</span>
|
||||
<span id="token-total-detail">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Toast Container -->
|
||||
<div id="toast-container" class="toast-container"></div>
|
||||
|
||||
<!-- Command Palette -->
|
||||
<div id="command-palette-modal" class="command-palette-modal" style="display: none;">
|
||||
<div class="command-palette-overlay"></div>
|
||||
<div class="command-palette-content">
|
||||
<div class="command-palette-search">
|
||||
<svg class="command-palette-search-icon" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
||||
<circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M12.5 12.5L17 17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<input
|
||||
type="text"
|
||||
id="command-palette-input"
|
||||
class="command-palette-input"
|
||||
placeholder="Type a command or search..."
|
||||
autocomplete="off"
|
||||
/>
|
||||
<kbd class="command-palette-hint">Esc to close</kbd>
|
||||
</div>
|
||||
<div id="command-palette-results" class="command-palette-results">
|
||||
<!-- Command results will be dynamically populated here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Avatar zoom modal -->
|
||||
<div id="avatar-modal" class="avatar-modal" style="display: none;">
|
||||
<div class="avatar-modal-overlay"></div>
|
||||
@@ -316,5 +767,50 @@
|
||||
<img id="avatar-modal-img" src="" alt="Avatar" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New Character modal -->
|
||||
<div id="new-character-modal" class="new-character-modal" style="display: none;">
|
||||
<div class="new-character-overlay"></div>
|
||||
<div class="new-character-content">
|
||||
<div class="new-character-header">
|
||||
<h3>Create New Character</h3>
|
||||
<button id="close-new-character-btn" class="icon-btn">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<line x1="4" y1="4" x2="12" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<line x1="12" y1="4" x2="4" y2="12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<form id="new-character-form">
|
||||
<div class="form-group">
|
||||
<label for="new-character-name">Character Name</label>
|
||||
<input
|
||||
type="text"
|
||||
id="new-character-name"
|
||||
placeholder="Enter a name for the new character"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="new-character-system-prompt">System Prompt</label>
|
||||
<textarea
|
||||
id="new-character-system-prompt"
|
||||
placeholder="You are a helpful AI assistant..."
|
||||
rows="6"
|
||||
required
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="new-character-actions">
|
||||
<button type="button" id="cancel-new-character-btn" class="btn-secondary">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn-primary">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
3376
src/main.js
3376
src/main.js
File diff suppressed because it is too large
Load Diff
1685
src/styles.css
1685
src/styles.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user