Files
mission-control-v2/frontend/src/lib/api.ts
T

214 lines
4.7 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
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 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
}
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
}