Spaces:
Running
Running
File size: 3,010 Bytes
d8e2b36 9ec6bf4 8517b46 9ec6bf4 d8e2b36 ee968a7 d8e2b36 f8bbabf d8e2b36 70bca69 d8e2b36 9ec6bf4 d8e2b36 9ec6bf4 60e195a 9ec6bf4 d8e2b36 9ec6bf4 d8e2b36 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
"""Entry point for executing a graph step."""
import logging
from dataclasses import asdict
from typing import Dict, Optional
import uuid
from agent.utils import with_retries
from agent.image_agent import generate_image_prompt
from agent.tools import generate_scene_image
from agent.llm_graph import GraphState, llm_game_graph
from agent.models import UserState
from agent.redis_state import get_user_state
logger = logging.getLogger(__name__)
async def process_step(
user_hash: str,
step: str,
setting: Optional[str] = None,
character: Optional[dict] = None,
genre: Optional[str] = None,
choice_text: Optional[str] = None,
) -> Dict:
"""Run one interaction step through the graph."""
logger.info("[Runner] Step %s for user %s", step, user_hash)
graph_state = GraphState(user_hash=user_hash, step=step)
if step == "start":
assert setting and character and genre, "Missing start parameters"
graph_state.setting = setting
graph_state.character = character
graph_state.genre = genre
elif step == "choose":
assert choice_text, "choice_text is required"
graph_state.choice_text = choice_text
final_state = await with_retries(lambda: llm_game_graph.ainvoke(asdict(graph_state)))
user_state: UserState = await get_user_state(user_hash)
response: Dict = {}
ending = final_state.get("ending")
if ending and ending.get("ending_reached"):
ending_info = ending["ending"]
if (
("description" not in ending_info or not ending_info["description"])
and user_state.story_frame
):
for e in user_state.story_frame.endings:
if e.id == ending_info.get("id"):
ending_info["description"] = e.description
break
ending_desc = ending_info.get("description") or ending_info.get(
"condition", ""
)
change_scene = await generate_image_prompt(user_hash, ending_desc)
if change_scene.change_scene == "no_change":
change_scene.change_scene = "change_completely"
if not change_scene.scene_description:
change_scene.scene_description = ending_desc
image_path = await generate_scene_image.ainvoke(
{
"user_hash": user_hash,
"scene_id": f"ending_{uuid.uuid4()}",
"change_scene": change_scene,
}
)
response["ending"] = ending_info
response["image"] = image_path
response["game_over"] = True
else:
if (
user_state.current_scene_id
and user_state.current_scene_id in user_state.scenes
):
current_scene = user_state.scenes[
user_state.current_scene_id
].dict()
else:
current_scene = final_state.get("scene")
response["scene"] = current_scene
response["game_over"] = False
return response
|