Spaces:
Running
Running
| import { adminFetch } from "./admin"; | |
| export type Difficulty = "easy" | "medium" | "hard"; | |
| export type PuzzleType = | |
| | "bridges" | |
| | "flow_free" | |
| | "galaxies" | |
| | "loopy" | |
| | "pattern" | |
| | "undead"; | |
| export type SessionResponse = { | |
| session_id: string; | |
| engine: string; | |
| puzzle_type: PuzzleType; | |
| difficulty: Difficulty; | |
| puzzle_id: string; | |
| args: string; | |
| status: string; | |
| started_at: string | null; | |
| payload: { | |
| problem_ascii: string; | |
| current_board_ascii: string; | |
| image_base64: string | null; | |
| }; | |
| }; | |
| export type PuzzleOption = { | |
| puzzle_id: string; | |
| title: string; | |
| sequence: number; | |
| puzzle_type: PuzzleType; | |
| difficulty: Difficulty; | |
| args: string; | |
| }; | |
| export type SubmitResponse = { | |
| solved: boolean; | |
| elapsed_ms: number | null; | |
| status: string; | |
| verification: Record<string, unknown>; | |
| }; | |
| export type LLMResults = { | |
| puzzle_id: string; | |
| models_solved: string[]; | |
| models_failed: string[]; | |
| }; | |
| export type LeaderboardEntry = { | |
| player_name: string; | |
| elapsed_ms: number | null; | |
| submission_count: number; | |
| solved: boolean; | |
| started_at: string | null; | |
| submitted_at: string | null; | |
| }; | |
| export type Leaderboard = { | |
| puzzle_id: string; | |
| entries: LeaderboardEntry[]; | |
| }; | |
| async function handle<T>(response: Response): Promise<T> { | |
| if (!response.ok) { | |
| let message = response.statusText; | |
| try { | |
| const payload = (await response.json()) as { detail?: string }; | |
| message = payload.detail ?? message; | |
| } catch { | |
| // Fall back to the HTTP status text. | |
| } | |
| throw new Error(message); | |
| } | |
| return (await response.json()) as T; | |
| } | |
| export async function createSession(input: { | |
| player_name: string; | |
| puzzle_type: PuzzleType; | |
| difficulty: Difficulty; | |
| puzzle_id?: string; | |
| }): Promise<SessionResponse> { | |
| return handle<SessionResponse>( | |
| await fetch("/api/sessions", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify(input), | |
| }), | |
| ); | |
| } | |
| export async function fetchPuzzleOptions( | |
| puzzleType: PuzzleType, | |
| difficulty: Difficulty, | |
| ): Promise<PuzzleOption[]> { | |
| const params = new URLSearchParams({ | |
| puzzle_type: puzzleType, | |
| difficulty, | |
| }); | |
| return handle<PuzzleOption[]>(await fetch(`/api/puzzles?${params.toString()}`)); | |
| } | |
| export async function fetchSession(sessionId: string): Promise<SessionResponse> { | |
| return handle<SessionResponse>(await fetch(`/api/sessions/${sessionId}`)); | |
| } | |
| export async function readySession( | |
| sessionId: string, | |
| ): Promise<{ status: string; started_at: string | null }> { | |
| return handle<{ status: string; started_at: string | null }>( | |
| await fetch(`/api/sessions/${sessionId}/ready`, { method: "POST" }), | |
| ); | |
| } | |
| export async function fetchLeaderboard( | |
| puzzleId: string, | |
| options: { includeTest?: boolean } = {}, | |
| ): Promise<Leaderboard> { | |
| const params = new URLSearchParams(); | |
| if (options.includeTest) { | |
| params.set("include_test", "true"); | |
| } | |
| const qs = params.toString() ? `?${params.toString()}` : ""; | |
| const response = await adminFetch( | |
| `/api/admin/leaderboard/${encodeURIComponent(puzzleId)}${qs}`, | |
| ); | |
| return handle<Leaderboard>(response); | |
| } | |
| export async function fetchLLMResults(puzzleId: string): Promise<LLMResults | null> { | |
| const response = await fetch(`/api/llm-results/${encodeURIComponent(puzzleId)}`); | |
| if (response.status === 404) { | |
| return null; | |
| } | |
| return handle<LLMResults>(response); | |
| } | |
| export async function submitSession( | |
| sessionId: string, | |
| boardAscii: string, | |
| ): Promise<SubmitResponse> { | |
| return handle<SubmitResponse>( | |
| await fetch(`/api/sessions/${sessionId}/submit`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ board_ascii: boardAscii }), | |
| }), | |
| ); | |
| } | |