feat(api): wire /dm/narrate — 200 prose | 502 model_error | 422 invalid log
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,8 @@ from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .canon_log import validate_canon_log
|
||||
from .narrate import run as narrate_run
|
||||
from .ollama_client import ModelError
|
||||
|
||||
app = FastAPI(title="coc-rpg proxy", version="0.0.1")
|
||||
|
||||
@@ -52,7 +54,10 @@ def health() -> dict:
|
||||
|
||||
@app.post("/dm/narrate")
|
||||
def narrate(req: TurnRequest = Depends(valid_turn)) -> dict:
|
||||
return {"detail": "not implemented"}
|
||||
try:
|
||||
return {"prose": narrate_run(req.canon_log)}
|
||||
except ModelError as exc:
|
||||
raise HTTPException(status_code=502, detail={"model_error": str(exc)})
|
||||
|
||||
|
||||
@app.post("/dm/adjudicate")
|
||||
|
||||
39
api/tests/test_narrate_endpoint.py
Normal file
39
api/tests/test_narrate_endpoint.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
import app.main as main
|
||||
import app.narrate as narrate
|
||||
from app.ollama_client import ModelError
|
||||
|
||||
client = TestClient(main.app)
|
||||
VALID = json.loads((Path(__file__).parent / "fixtures" / "canon_log_valid.json").read_text())
|
||||
|
||||
|
||||
def test_valid_log_returns_prose(monkeypatch):
|
||||
monkeypatch.setattr(narrate.ollama_client, "chat", lambda *a, **k: "You stand on the wharf.")
|
||||
monkeypatch.setattr(narrate.call_log, "record", lambda **kw: None) # keep test output pristine
|
||||
r = client.post("/dm/narrate", json={"canon_log": VALID})
|
||||
assert r.status_code == 200
|
||||
assert r.json() == {"prose": "You stand on the wharf."}
|
||||
|
||||
|
||||
def test_model_error_maps_to_502(monkeypatch):
|
||||
def boom(*a, **k):
|
||||
raise ModelError("upstream down")
|
||||
|
||||
monkeypatch.setattr(narrate.ollama_client, "chat", boom)
|
||||
monkeypatch.setattr(narrate.call_log, "record", lambda **kw: None)
|
||||
r = client.post("/dm/narrate", json={"canon_log": VALID})
|
||||
assert r.status_code == 502
|
||||
assert "model_error" in r.json()["detail"]
|
||||
|
||||
|
||||
def test_invalid_log_still_422(monkeypatch):
|
||||
monkeypatch.setattr(narrate.ollama_client, "chat", lambda *a, **k: "x")
|
||||
bad = json.loads(json.dumps(VALID))
|
||||
bad["player"]["luck"] = 5 # §7 leak — schema rejects
|
||||
r = client.post("/dm/narrate", json={"canon_log": bad})
|
||||
assert r.status_code == 422
|
||||
assert "canon_log_errors" in r.json()["detail"]
|
||||
Reference in New Issue
Block a user