Add rulebook RAG pipeline and LLM-driven game setup wizard
RAG: switch Postgres to pgvector, chunk and embed the three D&D rulebooks locally via sentence-transformers, and retrieve relevant excerpts per DM turn (query = latest player message) to ground the system prompt. Retrieval runs off the event loop and is capped by a relevance threshold and a max character budget so it can't blow up context size or cost. Game setup wizard: creating a game now opens a short chat where the DM asks about genre, length, and the player's experience level, then proposes a name and description via a tool call. The player can edit both before creating the game. Stateless endpoint — the frontend carries the conversation, no DB needed since the game doesn't exist yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,14 @@ import uuid
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
logger = logging.getLogger("app.llm.orchestrator")
|
||||
|
||||
from app.config import settings
|
||||
from app.llm.client import get_dm_system_prompt, get_llm_client
|
||||
from app.llm.context import build_context
|
||||
from app.llm.tools import character_sheet, dice
|
||||
from app.models.message import Message
|
||||
from app.rag.retrieval import build_rag_block
|
||||
|
||||
logger = logging.getLogger("app.llm.orchestrator")
|
||||
|
||||
MAX_TOOL_ROUNDS = 5
|
||||
MAX_TOKENS = 4096
|
||||
@@ -38,9 +39,18 @@ async def _execute_tool_call(
|
||||
return {"error": str(exc)}
|
||||
|
||||
|
||||
async def run_dm_turn(session: AsyncSession, game_id: uuid.UUID) -> Message:
|
||||
async def run_dm_turn(
|
||||
session: AsyncSession, game_id: uuid.UUID, latest_player_message: str | None = None
|
||||
) -> Message:
|
||||
client = get_llm_client()
|
||||
messages = [{"role": "system", "content": get_dm_system_prompt()}]
|
||||
system_prompt = get_dm_system_prompt()
|
||||
|
||||
if latest_player_message:
|
||||
rag_block = await build_rag_block(session, latest_player_message)
|
||||
if rag_block:
|
||||
system_prompt = f"{system_prompt}\n\n{rag_block}"
|
||||
|
||||
messages = [{"role": "system", "content": system_prompt}]
|
||||
messages.extend(await build_context(session, game_id))
|
||||
|
||||
final_text = ""
|
||||
|
||||
Reference in New Issue
Block a user