{{ role.icon }} {{ role.name }}
{{ role.title }}
{{ role.description }}
# 🎨 Crumbforest Roles & Groups Architecture
## 🎯 Vision
**Statt 8x .sh Files → 1x JSON Config mit Rollen, Gruppen & Themes**
### Ziele:
1. ✅ **Unified Role System** - Ein JSON statt vieler Shell Scripts
2. ✅ **Group-based Theming** - CSS/Template per Gruppe (#barrierefrei)
3. ✅ **Module Loading** - Zusätzliche Features per Gruppe
4. ✅ **Separation** - home/demo/admin mit eigenen Designs
5. ✅ **Web UI** - HTML Interface für Roles (nicht nur Terminal)
---
## 📋 JSON Schema: `crumbforest_config.json`
```json
{
"version": "1.0.0",
"groups": {
"home": {
"name": "Home (Öffentlich)",
"theme": "pico-default",
"template_base": "base_public.html",
"css_files": ["pico.min.css", "crumbforest_public.css"],
"features": ["info", "contact"],
"navbar": ["home", "about", "contact"],
"description": "Neutrale öffentliche Ansicht"
},
"demo": {
"name": "Demo User",
"theme": "pico-accessible",
"template_base": "base_demo.html",
"css_files": ["pico.min.css", "crumbforest_accessible.css"],
"features": ["roles_web", "search", "chat"],
"navbar": ["dashboard", "roles", "search"],
"description": "Demo-Zugang mit Role-Chat UI"
},
"admin": {
"name": "Admin",
"theme": "pico-admin",
"template_base": "base_admin.html",
"css_files": ["pico.min.css", "crumbforest_admin.css"],
"features": ["roles_web", "roles_terminal", "search", "rag_admin", "user_management"],
"navbar": ["dashboard", "roles", "rag", "users", "settings"],
"description": "Vollzugriff mit Terminal-Zugang"
},
"accessible": {
"name": "Barrierefrei",
"theme": "pico-high-contrast",
"template_base": "base_accessible.html",
"css_files": ["pico.min.css", "crumbforest_high_contrast.css", "screen_reader.css"],
"features": ["roles_web", "search", "tts", "high_contrast"],
"navbar": ["dashboard", "roles", "search", "settings"],
"font_size": "large",
"contrast": "high",
"description": "Hochkontrast, große Schrift, TTS"
}
},
"roles": {
"dumbo": {
"id": "dumbo",
"name": "🐘 DumboSQL",
"title": "SQL Translator",
"description": "A kind and patient SQL translator in the Crumbforest",
"model": "openai/gpt-3.5-turbo",
"temperature": 0.4,
"system_prompt": "You are DumboSQL – a kind and patient SQL translator in the Crumbforest. You speak to children like a gentle teacher with a big heart. You remember previous questions when helpful, and always respond in a friendly, encouraging, and clear way.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "sql_formatting"],
"icon": "🐘",
"color": "#6c757d",
"tags": ["sql", "database", "beginner-friendly"]
},
"snakepy": {
"id": "snakepy",
"name": "🐍 SnakePy",
"title": "Python Expert",
"description": "A wise python who teaches programming with patience",
"model": "openai/gpt-4o-mini",
"temperature": 0.3,
"system_prompt": "You are SnakePy – a wise and friendly Python expert in the Crumbforest. You explain Python concepts clearly, provide working code examples, and encourage learners. You are patient and adapt to the user's skill level.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "code_execution", "syntax_highlighting"],
"icon": "🐍",
"color": "#3776ab",
"tags": ["python", "coding", "teaching"]
},
"pepperphp": {
"id": "pepperphp",
"name": "🌶️ PepperPHP",
"title": "PHP Specialist",
"description": "A spicy PHP expert with a passion for web development",
"model": "openai/gpt-4o-mini",
"temperature": 0.3,
"system_prompt": "You are PepperPHP – a passionate PHP expert in the Crumbforest. You love web development, know all PHP versions, and can help with frameworks like Laravel, Symfony. You're enthusiastic but also practical.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "code_execution", "composer_help"],
"icon": "🌶️",
"color": "#777bb4",
"tags": ["php", "web", "backend"]
},
"templatus": {
"id": "templatus",
"name": "📄 Templatus",
"title": "Template Master",
"description": "Expert for Jinja2, HTML, and frontend templating",
"model": "anthropic/claude-3-5-sonnet",
"temperature": 0.3,
"system_prompt": "You are Templatus – a meticulous template expert in the Crumbforest. You master Jinja2, HTML, CSS, and creating beautiful, accessible web interfaces. You value clean code and user experience.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "template_preview", "html_validator"],
"icon": "📄",
"color": "#e44d26",
"tags": ["templates", "html", "jinja2", "frontend"]
},
"funkfox": {
"id": "funkfox",
"name": "🦊 FunkFox",
"title": "JavaScript Wizard",
"description": "A clever fox who makes JavaScript fun and functional",
"model": "openai/gpt-4o-mini",
"temperature": 0.4,
"system_prompt": "You are FunkFox – a clever and playful JavaScript expert in the Crumbforest. You make JS fun, teach functional programming, and help with modern frameworks like React, Vue. You're enthusiastic about clean code.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "code_execution", "npm_help"],
"icon": "🦊",
"color": "#f7df1e",
"tags": ["javascript", "frontend", "functional"]
},
"schraubaer": {
"id": "schraubaer",
"name": "🔧 Schraubaer",
"title": "Hardware Helper",
"description": "A handy bear who knows everything about Raspberry Pi and hardware",
"model": "openai/gpt-4o-mini",
"temperature": 0.3,
"system_prompt": "You are Schraubaer – a practical hardware expert in the Crumbforest. You know Raspberry Pi, Arduino, electronics, and Linux systems. You give clear, hands-on advice for building and fixing things.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "gpio_help", "circuit_diagrams"],
"icon": "🔧",
"color": "#c51a4a",
"tags": ["hardware", "raspberry-pi", "electronics"]
},
"schnecki": {
"id": "schnecki",
"name": "🐌 Schnecki",
"title": "Slow Tech Guide",
"description": "A gentle snail who teaches mindful, sustainable technology",
"model": "anthropic/claude-3-5-sonnet",
"temperature": 0.6,
"system_prompt": "You are Schnecki – a gentle and wise slow-tech advocate in the Crumbforest. You teach mindful technology use, sustainability, energy efficiency, and the value of taking time. You encourage breaks and reflection.",
"group_access": ["demo", "admin"],
"features": ["chat", "history", "mindfulness_tips", "green_tech"],
"icon": "🐌",
"color": "#8b4513",
"tags": ["slow-tech", "sustainability", "mindfulness"]
},
"kungfutaube": {
"id": "kungfutaube",
"name": "🕊️ KungfuTaube",
"title": "Security Sensei",
"description": "A peaceful but vigilant dove teaching web security",
"model": "anthropic/claude-3-5-sonnet",
"temperature": 0.2,
"system_prompt": "You are KungfuTaube – a calm but alert security expert in the Crumbforest. You teach web security, DSGVO compliance, safe coding practices, and encryption. You balance protection with usability.",
"group_access": ["admin"],
"features": ["chat", "history", "security_scan", "dsgvo_check"],
"icon": "🕊️",
"color": "#6f42c1",
"tags": ["security", "dsgvo", "encryption", "admin-only"]
}
},
"theme_variants": {
"pico-default": {
"name": "Standard",
"css": "pico.min.css",
"colors": {
"primary": "#1095c1",
"secondary": "#6c757d",
"contrast": "#000000"
}
},
"pico-accessible": {
"name": "Barrierefrei",
"css": "pico.min.css",
"custom_css": "accessible.css",
"colors": {
"primary": "#0066cc",
"secondary": "#333333",
"contrast": "#ffffff"
},
"font_size_base": "18px",
"line_height": "1.8"
},
"pico-high-contrast": {
"name": "Hochkontrast",
"css": "pico.min.css",
"custom_css": "high_contrast.css",
"colors": {
"primary": "#ffff00",
"secondary": "#ffffff",
"contrast": "#000000",
"background": "#000000",
"text": "#ffffff"
},
"font_size_base": "20px",
"line_height": "2.0",
"border_width": "3px"
},
"pico-admin": {
"name": "Admin Dark",
"css": "pico.min.css",
"custom_css": "admin_dark.css",
"colors": {
"primary": "#00d4aa",
"secondary": "#6c757d",
"contrast": "#ffffff",
"background": "#1a1a1a",
"text": "#e0e0e0"
}
}
}
}
```
---
## 🏗️ Architektur-Komponenten
### 1. FastAPI Router: `/routers/crumbforest_roles.py`
```python
from fastapi import APIRouter, Depends, Request, Form
from fastapi.responses import HTMLResponse, JSONResponse
import httpx
from typing import Optional
router = APIRouter()
# Load config
import json
with open('crumbforest_config.json') as f:
config = json.load(f)
@router.get("/roles", response_class=HTMLResponse)
async def roles_dashboard(req: Request, user = Depends(current_user)):
"""
Show available roles based on user's group.
"""
user_group = user.get('group', 'demo')
# Filter roles by group access
available_roles = {
rid: role for rid, role in config['roles'].items()
if user_group in role['group_access']
}
return req.app.state.render(
req,
"crumbforest/roles_dashboard.html",
roles=available_roles,
user_group=user_group
)
@router.get("/roles/{role_id}", response_class=HTMLResponse)
async def role_chat(req: Request, role_id: str, user = Depends(current_user)):
"""
Chat interface for a specific role.
"""
role = config['roles'].get(role_id)
if not role:
raise HTTPException(404, "Role not found")
user_group = user.get('group', 'demo')
if user_group not in role['group_access']:
raise HTTPException(403, "Access denied")
return req.app.state.render(
req,
"crumbforest/role_chat.html",
role=role
)
@router.post("/roles/{role_id}/ask")
async def ask_role(
req: Request,
role_id: str,
question: str = Form(...),
user = Depends(current_user)
):
"""
Send question to role and get AI response.
"""
role = config['roles'].get(role_id)
if not role:
raise HTTPException(404, "Role not found")
# Get conversation history from session
history = req.session.get(f'role_history_{role_id}', [])
# Build messages
messages = [
{"role": "system", "content": role['system_prompt']}
] + history + [
{"role": "user", "content": question}
]
# Call OpenRouter API
async with httpx.AsyncClient() as client:
response = await client.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {settings.openrouter_api_key}",
"Content-Type": "application/json"
},
json={
"model": role['model'],
"temperature": role['temperature'],
"messages": messages
}
)
result = response.json()
answer = result['choices'][0]['message']['content']
# Update history
history.append({"role": "user", "content": question})
history.append({"role": "assistant", "content": answer})
req.session[f'role_history_{role_id}'] = history[-10:] # Keep last 10
return JSONResponse({
"role": role_id,
"question": question,
"answer": answer,
"usage": result.get('usage', {})
})
```
### 2. Template: `templates/crumbforest/roles_dashboard.html`
```html
{% extends group_config.template_base %}
{% block title %}Crumbforest Roles{% endblock %}
{% block content %}
Choose your learning companion! {{ role.title }} {{ role.description }} {{ role.description }}🌲 Crumbforest Characters
{{ role.icon }}
{{ role.name }}
{{ role.icon }} {{ role.name }}