fix
This commit is contained in:
@@ -292,6 +292,78 @@ async def stats(
|
||||
}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Name bank — get/update character name banks per language
|
||||
# --------------------------------------------------------------------------- #
|
||||
@router.get("/names/{language}")
|
||||
async def get_name_bank(
|
||||
language: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_user: User = Depends(require_admin),
|
||||
) -> dict:
|
||||
"""Get the character name bank for a language."""
|
||||
names = await get_setting(db, f"character_names.{language}")
|
||||
if not isinstance(names, list):
|
||||
names = []
|
||||
return {"language": language, "names": names, "count": len(names)}
|
||||
|
||||
|
||||
@router.put("/names/{language}")
|
||||
async def update_name_bank(
|
||||
language: str,
|
||||
body: dict,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_user: User = Depends(require_admin),
|
||||
) -> dict:
|
||||
"""Update the character name bank for a language.
|
||||
|
||||
Body: {names: ["name1", "name2", ...]}
|
||||
"""
|
||||
names = body.get("names", [])
|
||||
if not isinstance(names, list):
|
||||
raise HTTPException(400, "names must be an array")
|
||||
# Validate all entries are strings
|
||||
cleaned = [str(n).strip() for n in names if str(n).strip()]
|
||||
await set_setting(db, f"character_names.{language}", cleaned)
|
||||
return {"language": language, "names": cleaned, "count": len(cleaned)}
|
||||
|
||||
|
||||
@router.post("/names/{language}/add")
|
||||
async def add_name_to_bank(
|
||||
language: str,
|
||||
body: dict,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_user: User = Depends(require_admin),
|
||||
) -> dict:
|
||||
"""Add a single name to the bank. Body: {name: "..."}"""
|
||||
name = body.get("name", "").strip()
|
||||
if not name:
|
||||
raise HTTPException(400, "name is required")
|
||||
names = await get_setting(db, f"character_names.{language}")
|
||||
if not isinstance(names, list):
|
||||
names = []
|
||||
if name not in names:
|
||||
names.append(name)
|
||||
await set_setting(db, f"character_names.{language}", names)
|
||||
return {"language": language, "names": names, "count": len(names)}
|
||||
|
||||
|
||||
@router.delete("/names/{language}/{name}")
|
||||
async def remove_name_from_bank(
|
||||
language: str,
|
||||
name: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_user: User = Depends(require_admin),
|
||||
) -> dict:
|
||||
"""Remove a name from the bank."""
|
||||
names = await get_setting(db, f"character_names.{language}")
|
||||
if not isinstance(names, list):
|
||||
names = []
|
||||
names = [n for n in names if n != name]
|
||||
await set_setting(db, f"character_names.{language}", names)
|
||||
return {"language": language, "names": names, "count": len(names)}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# LLM model list — fetch available models from the LLM provider
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
@@ -13,6 +13,7 @@ from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_current_user, get_settings_dict
|
||||
from app.config import get_settings
|
||||
from app.core.llm import LlmClient, MockLlmClient
|
||||
from app.core.logging import get_logger
|
||||
from app.db import get_db
|
||||
@@ -91,6 +92,39 @@ async def get_state(
|
||||
}
|
||||
|
||||
|
||||
@router.get("/worlds/{world_id}/history")
|
||||
async def get_history(
|
||||
world_id: uuid.UUID,
|
||||
before: int | None = None, # sequence_number to load before (for pagination)
|
||||
limit: int = 20,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
user=Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""Return full chat history with pagination (for scroll-up loading)."""
|
||||
world = await _load_world(db, world_id, user)
|
||||
stmt = select(Step).where(
|
||||
Step.world_id == world.id, Step.deleted_at.is_(None)
|
||||
)
|
||||
if before is not None:
|
||||
stmt = stmt.where(Step.sequence_number < before)
|
||||
stmt = stmt.order_by(Step.sequence_number.desc()).limit(limit)
|
||||
rows = (await db.execute(stmt)).scalars().all()
|
||||
steps = [
|
||||
{
|
||||
"id": str(s.id), "sequence_number": s.sequence_number,
|
||||
"player_action": s.player_action, "scene_text": s.scene_text,
|
||||
"suggested_actions": s.suggested_actions, "created_at": s.created_at.isoformat(),
|
||||
}
|
||||
for s in reversed(rows) # oldest first
|
||||
]
|
||||
has_more = len(rows) == limit
|
||||
return {
|
||||
"steps": steps,
|
||||
"has_more": has_more,
|
||||
"oldest_sequence": steps[0]["sequence_number"] if steps else None,
|
||||
}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# World builder stream (SSE)
|
||||
# --------------------------------------------------------------------------- #
|
||||
@@ -107,7 +141,7 @@ async def builder_stream(
|
||||
preset = (
|
||||
await db.execute(select(WorldPreset).where(WorldPreset.id == world.preset_id))
|
||||
).scalar_one_or_none()
|
||||
emitter = SseEmitter()
|
||||
emitter = SseEmitter(debug=get_settings().debug)
|
||||
player_name = (world.environment or {}).get("player", {}).get("name", "Hero")
|
||||
notes = world.description
|
||||
llm = _llm_factory(settings)
|
||||
@@ -152,7 +186,7 @@ async def editor_stream(
|
||||
settings: dict = Depends(get_settings_dict),
|
||||
) -> StreamingResponse:
|
||||
world = await _load_world(db, world_id, user)
|
||||
emitter = SseEmitter()
|
||||
emitter = SseEmitter(debug=get_settings().debug)
|
||||
llm = _llm_factory(settings)
|
||||
|
||||
async def run_bg():
|
||||
@@ -234,7 +268,7 @@ async def iterate_stream(
|
||||
).scalar_one_or_none()
|
||||
if step is None:
|
||||
raise HTTPException(404, "step not found")
|
||||
emitter = SseEmitter()
|
||||
emitter = SseEmitter(debug=get_settings().debug)
|
||||
llm = _llm_factory(settings)
|
||||
|
||||
async def run_bg():
|
||||
@@ -349,7 +383,7 @@ async def intro_stream(
|
||||
settings: dict = Depends(get_settings_dict),
|
||||
) -> StreamingResponse:
|
||||
world = await _load_world(db, world_id, user)
|
||||
emitter = SseEmitter()
|
||||
emitter = SseEmitter(debug=get_settings().debug)
|
||||
llm = _llm_factory(settings)
|
||||
|
||||
async def run_bg():
|
||||
|
||||
Reference in New Issue
Block a user