"""State helpers for applying Ollama outputs to map data.
This module centralizes the domain logic for:
- building generation metadata
- applying generated descriptions to rooms
- attaching or clearing validation metadata
Keeping these operations here allows callbacks to remain thin and
makes unit testing easier.
"""
from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
# =============================================================================
# Metadata Builders
# =============================================================================
# =============================================================================
# Room Update Helpers
# =============================================================================
[docs]
def apply_generation_to_room(
*,
zone_data: dict,
room_id: str,
description: str,
generation_info: dict[str, Any] | None,
validation_info: dict[str, Any] | None,
) -> dict:
"""Return updated zone data with the generated description applied.
Parameters
----------
zone_data : dict
Current zone data object.
room_id : str
Room ID to update.
description : str
Generated description text to apply.
generation_info : dict[str, Any] | None
Metadata about the LLM generation; when None, metadata is cleared.
validation_info : dict[str, Any] | None
Validator metadata to attach; when None, validation info is cleared.
Returns
-------
dict
Updated zone data with modified room data.
Raises
------
KeyError
If room_id is not in the zone data.
"""
rooms = zone_data.get("rooms", {})
if room_id not in rooms:
raise KeyError(f"Room '{room_id}' not found")
# Create new dicts so Dash recognizes changes.
updated_zone = dict(zone_data)
updated_zone["rooms"] = dict(rooms)
updated_room = dict(rooms[room_id])
# Apply description text.
updated_room["description"] = description.strip()
# Attach or clear generation metadata.
if generation_info:
updated_room["llm_generation"] = generation_info
else:
updated_room.pop("llm_generation", None)
# Attach or clear validation metadata.
if validation_info:
updated_room["description_validation"] = validation_info
else:
updated_room.pop("description_validation", None)
updated_zone["rooms"][room_id] = updated_room
return updated_zone