74f64731ab
- Neuer lib/format.ts: gb/fmtBytes/fmtSize/fmtEta/fmtCtx zentral; aus DashboardView/SystemView/ModelsView entdoppelt und importiert. - CustomDialog: document.getElementById -> useRef (kein DOM-Query, robuster). - api.ts: GitInfo/ComponentVersion/Versions typisiert, SystemStatus.versions ergänzt; App.tsx nutzt SystemStatus statt any. tsc grün, Build grün, Dashboard verifiziert (keine Konsolenfehler, Formatierer rendern identisch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
246 lines
5.4 KiB
TypeScript
246 lines
5.4 KiB
TypeScript
// Schmaler Fetch-Helfer gegen das MC-2-Backend (/api/*).
|
|
|
|
export async function api<T = unknown>(path: string, init?: RequestInit): Promise<T> {
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
...init?.headers,
|
|
} as Record<string, string>
|
|
|
|
const sudoPassword = localStorage.getItem("mc_sudo_password")
|
|
const hfToken = localStorage.getItem("mc_hf_token")
|
|
|
|
if (sudoPassword) {
|
|
headers["X-Sudo-Password"] = sudoPassword
|
|
}
|
|
|
|
let body = init?.body
|
|
const method = init?.method?.toUpperCase() || "GET"
|
|
if (method === "POST") {
|
|
if (typeof body === "string") {
|
|
try {
|
|
const data = JSON.parse(body)
|
|
let changed = false
|
|
if (sudoPassword && !("sudo_password" in data)) {
|
|
data["sudo_password"] = sudoPassword
|
|
changed = true
|
|
}
|
|
if (hfToken && !("hf_token" in data)) {
|
|
data["hf_token"] = hfToken
|
|
changed = true
|
|
}
|
|
if (changed) {
|
|
body = JSON.stringify(data)
|
|
}
|
|
} catch (e) {
|
|
// ignore JSON parse errors
|
|
}
|
|
} else if (!body) {
|
|
const data: Record<string, any> = {}
|
|
if (sudoPassword) data["sudo_password"] = sudoPassword
|
|
if (hfToken) data["hf_token"] = hfToken
|
|
if (Object.keys(data).length > 0) {
|
|
body = JSON.stringify(data)
|
|
}
|
|
}
|
|
}
|
|
|
|
const res = await fetch(path, {
|
|
...init,
|
|
headers,
|
|
body,
|
|
})
|
|
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
|
|
return res.json() as Promise<T>
|
|
}
|
|
|
|
export interface Capabilities {
|
|
moe: boolean
|
|
active_b: number | null
|
|
tools: "yes" | "likely" | "no"
|
|
vision: boolean
|
|
coder: boolean
|
|
reasoning: boolean
|
|
embedding: boolean
|
|
ctx: number | null
|
|
params_b: number | null
|
|
arch: string | null
|
|
}
|
|
|
|
export interface Fit {
|
|
level: "perfect" | "marginal" | "too_tight"
|
|
text: string
|
|
req_gb: number
|
|
tps: number
|
|
}
|
|
|
|
export interface ModelInfo {
|
|
name: string
|
|
role: string | null
|
|
aliases: string[]
|
|
api_ids: string[]
|
|
ctx: number | null
|
|
ttl: number | null
|
|
cmd: string
|
|
gguf_path: string
|
|
filename: string
|
|
quant: string
|
|
size_bytes: number | null
|
|
incomplete: boolean
|
|
prompt_cache: boolean
|
|
spec_draft_model: string | null
|
|
parallel_slots: number
|
|
capabilities: Capabilities
|
|
}
|
|
|
|
export interface DiscoverModel {
|
|
name: string
|
|
author: string
|
|
repo: string
|
|
role: string
|
|
params_b: number
|
|
quant: string
|
|
tags: string[]
|
|
downloads: number
|
|
fit: Fit
|
|
optimal_ctx: number
|
|
caps: Capabilities
|
|
}
|
|
|
|
export interface DiscoverCategory {
|
|
role: string
|
|
title: string
|
|
icon: string
|
|
models: DiscoverModel[]
|
|
recommended: string | null
|
|
}
|
|
|
|
export interface DiscoverResp {
|
|
updated: number
|
|
categories: DiscoverCategory[]
|
|
sys_ram_gb: number
|
|
}
|
|
|
|
export interface RoutingResp {
|
|
mode?: string
|
|
endpoint?: string
|
|
heavy_threshold_chars?: number
|
|
routes: { name: string; target: string }[]
|
|
fallbacks: Record<string, string[]>[]
|
|
context_window_fallbacks: Record<string, string[]>[]
|
|
gateway_reachable: boolean
|
|
}
|
|
|
|
export interface GitInfo {
|
|
hash: string
|
|
date: string
|
|
subject: string
|
|
branch: string
|
|
dirty: boolean
|
|
path: string
|
|
}
|
|
|
|
// Engine kann git-, binary- oder unbekannte Version sein — Felder je nach `type`.
|
|
export interface ComponentVersion {
|
|
type: "git" | "binary" | "unknown"
|
|
hash?: string
|
|
date?: string
|
|
subject?: string
|
|
branch?: string
|
|
dirty?: boolean
|
|
path?: string
|
|
version_text?: string
|
|
}
|
|
|
|
export interface Versions {
|
|
mc2: GitInfo | null
|
|
engine: ComponentVersion
|
|
hermes_ui: GitInfo | null
|
|
hermes_agent: GitInfo | null
|
|
}
|
|
|
|
export interface SystemStatus {
|
|
cpu: { percent: number; cores: number | null }
|
|
ram: { total: number; used: number; percent: number }
|
|
gpu: {
|
|
busy_percent: number | null
|
|
vram_used: number | null
|
|
vram_total: number | null
|
|
gtt_used?: number | null
|
|
gtt_total?: number | null
|
|
} | null
|
|
temp: { cpu?: number; gpu?: number } | null
|
|
disk: { total: number; used: number; percent: number } | null
|
|
versions?: Versions
|
|
}
|
|
|
|
export interface ServicesResp {
|
|
services: { name: string; url: string; ok: boolean }[]
|
|
links: { engine_ui: string; gateway: string; hermes_webui: string }
|
|
}
|
|
|
|
export interface UpdatesResp {
|
|
os: number
|
|
engine: number
|
|
models: number
|
|
model_list: { role: string; title: string; repo: string }[]
|
|
last_check?: number | null
|
|
}
|
|
|
|
export interface ConnectTool {
|
|
label: string
|
|
lang: string
|
|
snippet: string
|
|
note: string
|
|
}
|
|
export interface ConnectResp {
|
|
host: string
|
|
gateway_url: string
|
|
tools: Record<string, ConnectTool>
|
|
}
|
|
|
|
export interface Memory {
|
|
id: string
|
|
content: string
|
|
category: string
|
|
source: string
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface DedupeResult {
|
|
groups: { keep: { id: string; content: string; category: string }; remove: { id: string; content: string }[] }[]
|
|
duplicate_count: number
|
|
removed: number
|
|
applied: boolean
|
|
}
|
|
|
|
export interface AgentStatus {
|
|
gateway_url: string
|
|
webui_url: string
|
|
gateway_reachable: boolean
|
|
webui_reachable: boolean
|
|
home_exists: boolean
|
|
brain_model?: string
|
|
has_config: boolean
|
|
has_skills: boolean
|
|
has_memories: boolean
|
|
}
|
|
|
|
export interface Job {
|
|
id: string
|
|
label: string
|
|
state: "queued" | "running" | "done" | "failed" | "canceled"
|
|
progress?: number
|
|
total_bytes?: number
|
|
done_bytes?: number
|
|
rate_bps?: number
|
|
eta_s?: number
|
|
}
|
|
|
|
export interface Health {
|
|
status: string
|
|
version: string
|
|
engine_reachable: boolean
|
|
gateway_reachable: boolean
|
|
}
|