File size: 2,172 Bytes
414dc55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""Case lifecycle: create a new case (generate, or load by ID) and fetch a public view.

New Case generates a fresh, solvable mystery via the in-process LLM (buffered one-ahead);
if generation is unavailable (no weights / load failure) it falls back to the GRAYMOOR-3107
golden case so the loop is always playable. Generated cases are persisted by Case ID, so a
shared ID reloads the identical mystery. The sealed solution is never in any response here.
"""

from __future__ import annotations

from fastapi import APIRouter, HTTPException

from ..persistence.golden import golden_exists, load_golden
from ..persistence.run_store import create_run
from .dto import CaseResponse, NewCaseRequest
from .public_view import golden_to_public
from .runtime import RUNTIME

router = APIRouter(prefix="/api", tags=["case"])

DEFAULT_CASE_ID = "GRAYMOOR-3107"


def _golden_response(case_id: str) -> CaseResponse:
    run = create_run(case_id)
    return CaseResponse(case_id=case_id, run_id=run.run_id, case=golden_to_public(load_golden(case_id)))


@router.post("/case", response_model=CaseResponse)
def new_case(req: NewCaseRequest) -> CaseResponse:
    if req.case_id:
        if golden_exists(req.case_id):
            return _golden_response(req.case_id)
        loaded = RUNTIME.load_generated_run(req.case_id)
        if loaded is not None:
            public, run_id = loaded
            return CaseResponse(case_id=public.id, run_id=run_id, case=public)
        return _golden_response(DEFAULT_CASE_ID)

    generated = RUNTIME.new_generated_run()
    if generated is not None:
        public, run_id = generated
        return CaseResponse(case_id=public.id, run_id=run_id, case=public)
    return _golden_response(DEFAULT_CASE_ID)


@router.get("/case/{case_id}", response_model=CaseResponse)
def get_case(case_id: str) -> CaseResponse:
    if golden_exists(case_id):
        return _golden_response(case_id)
    loaded = RUNTIME.load_generated_run(case_id)
    if loaded is not None:
        public, run_id = loaded
        return CaseResponse(case_id=public.id, run_id=run_id, case=public)
    raise HTTPException(status_code=404, detail=f"case not found: {case_id}")