Frontend: Voice-Umzug in Desktop-App, MC3-Prototyp, UI-Rework-Dateien auf lucy-v2, dist konsistent
- VoiceView + components/voice + lib/voice entfernt (lebt jetzt in client/lucy-desktop)
- mc3/: Basisstation-Prototyp hinter #mc3-Weiche (non-destruktiv)
- roleMeta/useLucyHealth/useExpertMode/ExpertToggle/LucyHealthCard/WarmSetManager (UI-Rework, auf main a341d25 committet, hier nachgezogen)
- dist frisch gebaut (Asset-Stand war inkonsistent: alte geloescht, neue untracked)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import {
|
||||
Brain,
|
||||
BrainCog,
|
||||
Code,
|
||||
Eye,
|
||||
BookMarked,
|
||||
Telescope,
|
||||
type LucideIcon,
|
||||
} from "lucide-react"
|
||||
|
||||
// ── EINE Quelle der Wahrheit für ALLE Serving-Rollen ────────────────────────
|
||||
// Klartext statt Kürzel: jede Rolle bekommt einen Zweck-Namen, ein Icon und
|
||||
// eine Ein-Satz-Erklärung, damit die UI ohne Fachjargon verständlich ist.
|
||||
// Das technische Kürzel (`role`) bleibt für den späteren Experten-Modus erhalten.
|
||||
//
|
||||
// Die Rollen hier spiegeln den ECHTEN Stand der Box (/api/models → role):
|
||||
// hermes · heavy · coder · coder-lite · vision · embed · scout
|
||||
// (Kein Phantom-`fast`: das ist nur ein Lane-Alias, keine Modell-Rolle. Lucys
|
||||
// Alltags-Hirn ist die Rolle `hermes` = Qwen3.6.)
|
||||
|
||||
export interface RoleMeta {
|
||||
role: string // technisches Kürzel (Experten-Modus)
|
||||
label: string // Klartext-Zweckname
|
||||
short: string // Kurzform für enge Badges
|
||||
icon: LucideIcon
|
||||
desc: string // Tooltip / Erklärung in einfacher Sprache
|
||||
tone: string // Farbklassen fürs Badge
|
||||
protected?: boolean // Hirn & Gedächtnis: lebenswichtig → nicht löschbar/entladbar (Etappe 3)
|
||||
}
|
||||
|
||||
// Reihenfolge = Anzeige-Reihenfolge in den Slot-Übersichten (Wichtigstes zuerst).
|
||||
export const ROLE_META: RoleMeta[] = [
|
||||
{
|
||||
role: "hermes",
|
||||
label: "Lucys Hirn",
|
||||
short: "Hirn",
|
||||
icon: Brain,
|
||||
desc: "Lucys Alltags-Verstand — denkt und redet mit dir. Immer bereit.",
|
||||
tone: "bg-indigo-500/15 text-indigo-400 border-indigo-500/25",
|
||||
protected: true,
|
||||
},
|
||||
{
|
||||
role: "embed",
|
||||
label: "Lucys Gedächtnis",
|
||||
short: "Gedächtnis",
|
||||
icon: BookMarked,
|
||||
desc: "Merkt sich Wichtiges und findet es später wieder.",
|
||||
tone: "bg-emerald-500/15 text-emerald-400 border-emerald-500/25",
|
||||
protected: true,
|
||||
},
|
||||
{
|
||||
role: "vision",
|
||||
label: "Lucys Augen",
|
||||
short: "Augen",
|
||||
icon: Eye,
|
||||
desc: "Sieht Bilder und Screenshots und beschreibt, was drauf ist.",
|
||||
tone: "bg-pink-500/15 text-pink-400 border-pink-500/25",
|
||||
},
|
||||
{
|
||||
role: "heavy",
|
||||
label: "Großes Hirn",
|
||||
short: "Groß",
|
||||
icon: BrainCog,
|
||||
desc: "Das schwere Geschütz — wird für besonders knifflige Fragen dazugeholt.",
|
||||
tone: "bg-amber-500/15 text-amber-400 border-amber-500/25",
|
||||
},
|
||||
{
|
||||
role: "coder-lite",
|
||||
label: "Programmierer (schnell)",
|
||||
short: "Code schnell",
|
||||
icon: Code,
|
||||
desc: "Schnelles Programmieren im Alltag.",
|
||||
tone: "bg-violet-500/15 text-violet-400 border-violet-500/25",
|
||||
},
|
||||
{
|
||||
role: "coder",
|
||||
label: "Programmierer (gründlich)",
|
||||
short: "Code gründlich",
|
||||
icon: Code,
|
||||
desc: "Schreibt und prüft Code besonders sorgfältig — für schwere Coding-Aufgaben.",
|
||||
tone: "bg-fuchsia-500/15 text-fuchsia-400 border-fuchsia-500/25",
|
||||
},
|
||||
{
|
||||
role: "scout",
|
||||
label: "Späher",
|
||||
short: "Späher",
|
||||
icon: Telescope,
|
||||
desc: "Schneller erster Blick und grobe Einschätzung.",
|
||||
tone: "bg-teal-500/15 text-teal-400 border-teal-500/25",
|
||||
},
|
||||
]
|
||||
|
||||
// Kanonische Rollen-Reihenfolge (ersetzt die alte, veraltete ROLES-Liste).
|
||||
export const ROLES: string[] = ROLE_META.map((m) => m.role)
|
||||
|
||||
const BY_ROLE: Record<string, RoleMeta> = Object.fromEntries(
|
||||
ROLE_META.map((m) => [m.role, m]),
|
||||
)
|
||||
|
||||
// Fallback für unbekannte/neue Rollen — nie „undefined", damit die UID nicht bricht.
|
||||
const UNKNOWN = (role?: string | null): RoleMeta => ({
|
||||
role: role || "?",
|
||||
label: role || "unbekannt",
|
||||
short: role || "?",
|
||||
icon: Brain,
|
||||
desc: "Rolle ohne hinterlegten Klartext-Namen.",
|
||||
tone: "bg-slate-500/15 text-slate-300 border-slate-500/25",
|
||||
})
|
||||
|
||||
// Aliase, die auf eine echte Rolle zeigen (z.B. Lane-Alias `fast` = Hirn).
|
||||
const ALIAS: Record<string, string> = {
|
||||
fast: "hermes",
|
||||
coder_lite: "coder-lite",
|
||||
}
|
||||
|
||||
export function roleMeta(role?: string | null): RoleMeta {
|
||||
if (!role) return UNKNOWN(role)
|
||||
return BY_ROLE[role] || BY_ROLE[ALIAS[role]] || UNKNOWN(role)
|
||||
}
|
||||
|
||||
// Klartext-Name einer Rolle (mit optionaler Kurzform).
|
||||
export const roleLabel = (role?: string | null, short = false) =>
|
||||
short ? roleMeta(role).short : roleMeta(role).label
|
||||
|
||||
// Farbton — bleibt kompatibel zur bisherigen roleTone()-Signatur.
|
||||
export const roleTone = (role?: string | null) => roleMeta(role).tone
|
||||
Reference in New Issue
Block a user