case0 / web /src /api.ts
HusseinEid's picture
Case Zero - initial public release (fully local: Qwen2.5-1.5B via llama.cpp + Supertonic, custom pixel-noir SPA via gradio.Server)
414dc55
// Typed client for the Case Zero game API (served by gradio.Server under /api).
import type { InterrogateResult, PublicCase, VerdictResult } from './types'
export interface CaseResponse {
caseId: string
runId: string
case: PublicCase
}
async function postJSON<T>(url: string, body: unknown): Promise<T> {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
if (!res.ok) throw new Error(`POST ${url} failed: ${res.status}`)
return (await res.json()) as T
}
async function getJSON<T>(url: string): Promise<T> {
const res = await fetch(url)
if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`)
return (await res.json()) as T
}
export interface NewCaseRequest {
seed?: number
caseId?: string
difficulty?: string
}
export function newCase(req: NewCaseRequest = {}): Promise<CaseResponse> {
return postJSON<CaseResponse>('/api/case', req)
}
export function getCase(caseId: string): Promise<CaseResponse> {
return getJSON<CaseResponse>(`/api/case/${encodeURIComponent(caseId)}`)
}
export interface InterrogateBody {
questionId?: string
freeText?: string
presentEvidenceId?: string
}
export function interrogate(
runId: string,
suspectId: string,
body: InterrogateBody,
): Promise<InterrogateResult> {
return postJSON<InterrogateResult>(
`/api/run/${encodeURIComponent(runId)}/interrogate/${encodeURIComponent(suspectId)}`,
body,
)
}
export function getHint(runId: string, screen: string): Promise<{ hint: string }> {
return getJSON<{ hint: string }>(
`/api/run/${encodeURIComponent(runId)}/hint?screen=${encodeURIComponent(screen)}`,
)
}
export interface AccuseBody {
suspectId: string
motiveId: string
evidenceIds: string[]
}
export function accuse(runId: string, body: AccuseBody): Promise<VerdictResult> {
return postJSON<VerdictResult>(`/api/run/${encodeURIComponent(runId)}/accuse`, body)
}