"""Interaction generation orchestration.""" from __future__ import annotations from pydantic import BaseModel from ai import prompts from ai.modal_client import extract_json, generate from world.relationships import get_relationship class InteractionResult(BaseModel): interaction_type: str description: str entity_a_memory_addition: str entity_b_memory_addition: str relationship_change: str new_relationship_description: str | None = None notable_outcome: str | None = None book_of_ages_entry: str def generate_interaction( entity_a: dict, entity_b: dict, location: dict, current_event: dict | None = None, ) -> InteractionResult: existing = get_relationship(entity_a["id"], entity_b["id"]) if existing: rel_desc = f"{existing['relationship_type']} (strength {existing['strength']}): {existing['description']}" else: rel_desc = "None — first meeting" event_title = current_event["title"] if current_event else "None" event_desc = current_event["description"] if current_event else "None" # Build quest context lines quest_a = entity_a.get("active_quest") quest_b = entity_b.get("active_quest") quest_context = "" if quest_a: quest_context += f"\nACTIVE QUEST for {entity_a['name']}: {quest_a}" if quest_b: quest_context += f"\nACTIVE QUEST for {entity_b['name']}: {quest_b}" if quest_context: quest_context = f"\n--- PLAYER-ASSIGNED QUESTS (weave these into the interaction outcome) ---{quest_context}\n" user_prompt = prompts.INTERACTION_USER.format( location_name=location["name"], location_description=location["short_description"], current_event_title=event_title, current_event_description=event_desc + quest_context, entity_a_name=entity_a["name"], entity_a_type=entity_a["type"], entity_a_appearance_summary=entity_a["appearance"][:200], entity_a_traits=", ".join(entity_a["personality_traits"]), entity_a_primary_goal=entity_a["primary_goal"], entity_a_primary_fear=entity_a["primary_fear"], entity_a_speech_style=entity_a["speech_style"], entity_a_memory_summary=entity_a["memory_summary"] or "Nothing yet — newly arrived.", existing_relationship_description=rel_desc, entity_b_name=entity_b["name"], entity_b_type=entity_b["type"], entity_b_appearance_summary=entity_b["appearance"][:200], entity_b_traits=", ".join(entity_b["personality_traits"]), entity_b_primary_goal=entity_b["primary_goal"], entity_b_primary_fear=entity_b["primary_fear"], entity_b_speech_style=entity_b["speech_style"], entity_b_memory_summary=entity_b["memory_summary"] or "Nothing yet — newly arrived.", ) raw = generate(prompts.INTERACTION_SYSTEM, user_prompt, temperature=0.85) data = extract_json(raw) return InteractionResult(**data)