Zeitachse (24h-Historie), Verbinden-Autofill, Modelltausch abgesichert

Paket 1 - Metrik-Historie mit Zeitachse (User: 'WANN war Last?'):
- services/metrics_history.py: 10s-Sampler (CPU/RAM/GPU/Disk + Token-Totale) in
  24h-Ringpuffer (aelteres faellt automatisch raus, nichts waechst unbegrenzt),
  persistiert alle 5 min -> uebersteht Deploys; GET /api/system/history?minutes
  mit Downsampling auf ~300 Punkte; Lifespan-Task in app.py
- Cockpit-Karten System-Status + Token-Durchsatz: Bereichs-Schalter Live/1h/24h,
  sichtbare Zeitachse (HH:MM:SS bei kurzen, HH:MM bei langen Fenstern), Tooltip
  zeigt Uhrzeit; Token-Raten in 1h/24h aus Totale-Deltas

Paket 2 - Verbinden selbsterklaerend:
- Box-IP vorbefuellt aus window.location.hostname (Dev-Fallback bleibt)
- MCP-Scriptpfad-Feld aus der Kopfzeile in die 'Gedaechtnis anbinden'-Karte
  verschoben, mit Erklaerung WANN man es braucht

Paket 3 - Modelltausch-Loecher gestopft (Review 16.07.):
- install: Registrierung OHNE Alias-Umzug; Rolle wird erst NACH erfolgreichem
  Download uebernommen (on_done) - hermes dabei durch den warm-bewussten
  set_agent_brain-Flow statt rohem Alias-Move (Lucy waere sonst bis Download-
  Ende tot gewesen); Re-Install erhaelt bestehende Aliase
- set_role_alias: lebenswichtige Aliase (hermes/embed) des Ziel-Modells
  ueberleben jeden Rollen-Klick (Qwen3.6 haelt live hermes+fast!)
- Rollen-Endpoint verweigert Rollen-Wechsel am Halter geschuetzter Aliase
  mit klarer Anleitung; Werkbank sperrt die Rollen-Chips sichtbar

Verifiziert: py_compile + Sampler-Smoke (2 Punkte, Persist ok) + Alias-Logik-
Unittest (3 Faelle) + Browser (Zeitachse tickt, Schalter, Leerzustand, Verbinden).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-16 01:08:03 +02:00
co-authored by Claude Fable 5
parent 26224804ed
commit 71192b3db0
36 changed files with 562 additions and 213 deletions
+36 -19
View File
@@ -72,8 +72,16 @@ function CodeWindow({
)
}
// Die Box-Adresse kennt der Browser schon — er ist ja über sie verbunden. Nur im
// Dev-Modus (localhost + Vite-Proxy) greift der bekannte LAN-Fallback.
function defaultHost(): string {
const h = window.location.hostname
if (h && h !== "localhost" && h !== "127.0.0.1") return h
return "192.168.178.151"
}
export function ConnectView() {
const [host, setHost] = useState(localStorage.getItem("mc_host") || "192.168.178.151")
const [host, setHost] = useState(localStorage.getItem("mc_host") || defaultHost())
const [mcpPath, setMcpPath] = useState(localStorage.getItem("mc_mcp_path") || "")
// Legacy-Tools (roher /v1-Zugang) leben im Ausklapper — Hermes Desktop ist der Hauptweg.
const [active, setActive] = useState("kilo")
@@ -187,11 +195,12 @@ export function ConnectView() {
</p>
</div>
{/* Gemeinsame Variablen */}
<div className="grid gap-4 md:grid-cols-2 p-5 mc-card">
<div className="space-y-1.5">
{/* Box-Adresse — vorbefüllt aus der Browser-URL; anfassen nur, wenn sich die Box-IP ändert. */}
<div className="p-5 mc-card">
<div className="space-y-1.5 max-w-md">
<label className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5">
<Globe className="h-3.5 w-3.5 text-primary" /> Box LAN IP-Adresse
<span className="normal-case font-semibold tracking-normal text-muted-foreground/60"> vorbefüllt aus der Adresse dieser Seite</span>
</label>
<input
value={host}
@@ -201,21 +210,9 @@ export function ConnectView() {
placeholder="z.B. 192.168.178.151"
className="w-full h-9 rounded-lg border border-border/60 bg-background/40 px-3 font-mono text-xs outline-none focus:ring-1 focus:ring-primary/50 text-foreground"
/>
</div>
<div className="space-y-1.5">
<label className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5">
<FolderOpen className="h-3.5 w-3.5 text-violet-400" /> Lokaler MCP-Scriptpfad
<span className="text-violet-400/70 normal-case font-semibold tracking-normal">(nur Leitung 2)</span>
</label>
<input
value={mcpPath}
onChange={(e) => saveMcpPath(e.target.value)}
aria-label="Lokaler MCP-Scriptpfad"
spellCheck={false}
placeholder="z.B. F:\Coding Stuff\mission-control-2\mcp\mcp_memory.py"
className="w-full h-9 rounded-lg border border-border/60 bg-background/40 px-3 font-mono text-xs outline-none focus:ring-1 focus:ring-violet-500/50 text-foreground"
/>
<p className="text-[10px] text-muted-foreground/70">
Wird in alle Snippets eingebacken. Ändern musst du sie nur, wenn die Box eine neue IP bekommt.
</p>
</div>
</div>
@@ -332,6 +329,26 @@ export function ConnectView() {
<span>{data.memory.note}</span>
</div>
{/* Der Pfad wirkt NUR auf dieses Snippet — deshalb wohnt das Feld hier,
nicht mehr prominent in der Kopfzeile („Wann brauche ich das?"). */}
<div className="space-y-1.5">
<label className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5">
<FolderOpen className="h-3.5 w-3.5 text-violet-400" /> Wo liegt mcp_memory.py auf DIESEM PC?
</label>
<input
value={mcpPath}
onChange={(e) => saveMcpPath(e.target.value)}
aria-label="Lokaler MCP-Scriptpfad"
spellCheck={false}
placeholder="z.B. F:\Coding Stuff\mission-control-2\mcp\mcp_memory.py"
className="w-full h-9 rounded-lg border border-border/60 bg-background/40 px-3 font-mono text-xs outline-none focus:ring-1 focus:ring-violet-500/50 text-foreground"
/>
<p className="text-[10px] text-muted-foreground/70">
Nur nötig, wenn du das Gedächtnis in einem PC-Tool anschließt das Script läuft lokal
und spricht mit der Box. Der Pfad landet direkt im Snippet unten.
</p>
</div>
<CodeWindow
tool={data.memory}
fileName="mcp.json"