v27.3: Fix blank page — response shape mismatches
1. /api/lab/status: StatusResponse now includes run_id, games_completed,
total_games, current_decks aliases so the React SPA gets the field
names it expects.
2. /api/lab/decks returns {decks: [...]}, /api/lab/history returns
{results: [...]}, /api/lab/precons returns {precons: [...]} — but
the frontend expected bare arrays. Updated lab.ts API client to
unwrap these wrapper objects automatically.
This commit is contained in:
1 parent
e00e7a4dfe
commit
1e05f0fb5e
2 files changed
+25
-10
No files matched your search
@@ -2,7 +2,8 @@ import { get, post } from './client'
|
||||
import type { LabDeck, LabStatus, LabResult, LabHistoryEntry, PreconDeck } from '../types'
|
||||
|
||||
export async function getLabDecks() {
|
||||
return get<LabDeck[]>('/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<LabHistoryEntry[]>('/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<PreconDeck[]>('/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) {
|
||||
|
||||
+19
-7
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user