FastAPI server for streamed, tag-based NPC turns.
- accepts a WebSocket connection from Godot
- stores per-agent streamed-turn history
- normalizes incoming game events
- requests the latest runtime agent spec from Godot before each turn
- builds the active-turn prompt for the agent
- streams XML-tag output from the LLM
- forwards turn lifecycle and tag stream messages back to Godot
- accepts the Godot-confirmed
agent_turn_resultbuffer for history/logging - writes conversation and LLM-input logs on disconnect
- Godot connects to
/ws. - Godot sends
interaction_eventwhen an agent should react. - The server requests
get_agent_stateto fetch the latest prompt parts. - The server starts one streamed LLM turn for that event.
- The server sends:
agent_turn_startedagent_tag_openagent_tag_chunkagent_tag_closeagent_turn_interruptedwhen a newer event cancels the streamagent_turn_finishedwhen the streamed turn ends normally - Godot uses those explicit turn lifecycle messages to manage the local turn buffer.
- Godot assembles and returns
agent_turn_result. - The server appends that confirmed AI turn to history for later prompts and logs.
src/server.pyWebSocket entrypoint, runtime message routing, and active turn orchestration.src/active_stream_controller.pyServer-side streamed-turn controller that runs the LLM and parses XML tags.src/agent_spec.pyRuntime agent spec model plus character dossier builder.src/session.pyPer-agent session state for the active runtime.src/protocol.pyPayload normalization for agent state and incoming events.src/conversation_log.pyConversation and LLM-input logging.src/config.pyLLM configuration and model factory helpers.src/logging_utils.pyStructured server logging helpers.
pinginteraction_eventnotification_eventagent_state_snapshotagent_turn_resulttool_results
pongget_agent_stateagent_turn_startedagent_turn_interruptedagent_turn_finishedagent_tag_openagent_tag_chunkagent_tag_closeerror
Structured server logs are emitted through src/logging_utils.py.
- default log level:
INFO - override with:
GAME_AGENT_LOG_LEVEL=DEBUG
Conversation logs are written to logs/ on disconnect.
- Python 3.11+
- OpenAI-compatible chat endpoint
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtExample environment:
OPENAI_API_KEY=your-api-key
LLM_MODEL=anthropic/claude-3.5-sonnet
OPENAI_API_BASE=https://openrouter.ai/api/v1
ACTIVE_STREAM_LLM_MODEL=uvicorn src.server:app --host 0.0.0.0 --port 8000