diff --git a/frontend/commander-ai-lab-ui/src/api/lab.ts b/frontend/commander-ai-lab-ui/src/api/lab.ts index a243950..09bbdbe 100644 --- a/frontend/commander-ai-lab-ui/src/api/lab.ts +++ b/frontend/commander-ai-lab-ui/src/api/lab.ts @@ -2,7 +2,8 @@ import { get, post } from './client' import type { LabDeck, LabStatus, LabResult, LabHistoryEntry, PreconDeck } from '../types' export async function getLabDecks() { - return get('/api/lab/decks') + const res = await get<{ decks: LabDeck[] } | LabDeck[]>('/api/lab/decks') + return Array.isArray(res) ? res : (res as { decks: LabDeck[] }).decks || [] } export async function startBatchSim(config: { decks: string[]; games: number; threads?: number; use_deepseek?: boolean; deepseek_deck?: string }) { @@ -22,11 +23,13 @@ export async function getLabResult() { } export async function getLabHistory() { - return get('/api/lab/history') + const res = await get<{ results: LabHistoryEntry[] } | LabHistoryEntry[]>('/api/lab/history') + return Array.isArray(res) ? res : (res as { results: LabHistoryEntry[] }).results || [] } export async function getPrecons() { - return get('/api/lab/precons') + const res = await get<{ precons: PreconDeck[] } | PreconDeck[]>('/api/lab/precons') + return Array.isArray(res) ? res : (res as { precons: PreconDeck[] }).precons || [] } export async function installPrecon(name: string) { diff --git a/lab_api.py b/lab_api.py index 36c94b4..c80336c 100644 --- a/lab_api.py +++ b/lab_api.py @@ -129,14 +129,19 @@ class StartResponse(BaseModel): message: str = "" class StatusResponse(BaseModel): - batchId: str - running: bool - completed: int - total: int - threads: int - elapsedMs: int + batchId: str = "" + running: bool = False + completed: int = 0 + total: int = 0 + threads: int = 0 + elapsedMs: int = 0 error: Optional[str] = None - simsPerSec: float = 0.0 # v24 (Issue #5): Real-time throughput + simsPerSec: float = 0.0 + # React SPA aliases (same data, expected field names) + run_id: str = "" + games_completed: int = 0 + total_games: int = 0 + current_decks: list = [] class DeckInfo(BaseModel): name: str @@ -431,8 +436,10 @@ async def get_status(batchId: Optional[str] = None): return StatusResponse( batchId="", running=False, completed=0, total=0, threads=0, elapsedMs=0, error=None, simsPerSec=0.0, + run_id="", games_completed=0, total_games=0, current_decks=[], ) elapsed = int((datetime.now() - state.start_time).total_seconds() * 1000) + deck_names = getattr(state, 'deck_names', []) if hasattr(state, 'deck_names') else [] return StatusResponse( batchId=state.batch_id, running=state.running, @@ -442,6 +449,11 @@ async def get_status(batchId: Optional[str] = None): elapsedMs=elapsed if state.running else state.elapsed_ms, error=state.error, simsPerSec=state.sims_per_sec, + # React SPA fields + run_id=state.batch_id, + games_completed=state.completed_games, + total_games=state.total_games, + current_decks=deck_names, )