From ed6844cf2433f1c7de48197268041f93232d6194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=92=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87=20=D0=91=D0=B0?= =?UTF-8?q?=D0=B1=D0=B0=D0=B9=D0=BA=D0=B8=D0=BD?= Date: Thu, 28 May 2026 12:06:05 +0000 Subject: [PATCH] feat: solution for 69b1a07c67bbf488a1177da4 --- .../69b1a07c67bbf488a1177da4/solution.py | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 solutions/69b1a07c67bbf488a1177da4/solution.py diff --git a/solutions/69b1a07c67bbf488a1177da4/solution.py b/solutions/69b1a07c67bbf488a1177da4/solution.py new file mode 100644 index 0000000..129cffb --- /dev/null +++ b/solutions/69b1a07c67bbf488a1177da4/solution.py @@ -0,0 +1,103 @@ +from langchain_openai import ChatOpenAI +from pydantic import SecretStr +from langgraph.graph import StateGraph, START, END +from langgraph.checkpoint.memory import InMemorySaver +from langgraph.types import interrupt, Command +import questionary + +# LLM configuration with placeholders +llm = ChatOpenAI( + model="openai/gpt-oss-20b", + base_url='https://platform.brojs.ru/jrnl-bh/api/inference/v1', + api_key=SecretStr("jrnl_30283ab953615cbb6846ff9940a1eedce0b76d7b2f59a2394f29e74643e6a90d"), + temperature=0.7, +) + +# State definition +class GameState(dict): + topic: str | None = None + intro: str | None = None + options: list[str] | None = None + choice: str | None = None + ending: str | None = None + +# Node to generate intro and options +def generate_intro(state: GameState) -> GameState: + topic = state.get("topic", "неизвестная тема") + prompt = f"""Тема: {topic}. Придумай короткую завязку (2–3 предложения) и ровно 3 варианта действий героя. Ответь в формате: +Завязка: +<текст> +Варианты: +1) <вариант1> +2) <вариант2> +3) <вариант3>""" + response = llm.invoke(prompt).content + # Parse response + parts = response.split("Варианты:") + intro_part = parts[0].replace("Завязка:", "").strip() + options_part = parts[1] if len(parts) > 1 else "" + options = [opt.strip() for opt in options_part.splitlines() if opt.strip()] + state["intro"] = intro_part + state["options"] = options + # Interrupt to ask user + return interrupt( + { + "type": "choice", + "question": f"{intro_part}\n\nЧто делаем?", + "options": options, + } + ) + +# Node to handle resume after choice and generate ending +def generate_ending(state: GameState) -> GameState: + intro = state.get("intro", "") + choice = state.get("choice", "") + prompt = f"""Завязка: {intro} +Выбор пользователя: {choice} +Допиши короткую концовку (2–3 предложения).""" + ending = llm.invoke(prompt).content.strip() + state["ending"] = ending + return state + +# Build graph +graph_builder = StateGraph(GameState) +graph_builder.add_node("generate_intro", generate_intro) +graph_builder.add_node("generate_ending", generate_ending) +graph_builder.set_entry_point("generate_intro") +graph_builder.add_edge(START, "generate_intro") +graph_builder.add_edge("generate_intro", "generate_ending") # continue after interrupt +graph_builder.add_edge("generate_ending", END) + +# Compile with checkpoint +checkpoint = InMemorySaver() +app = graph_builder.compile(checkpointer=checkpoint) + +def run_game(topic: str): + state = GameState({"topic": topic}) + config = {"configurable": {"thread_id": "game_thread"}} + # First stream until interrupt + for chunk in app.stream(state, config): + if "__interrupt__" in chunk: + payload = chunk["__interrupt__"][0].value # dict from interrupt() + answer = questionary.select( + payload["question"], + choices=payload["options"] + ).ask() + # Resume with user's choice + resume_payload = {"choice": answer} + for res_chunk in app.stream(Command(resume=resume_payload), config): + if "ending" in res_chunk: + print("\n[LLM] Концовка:", res_chunk["ending"]) + # Final state + final_state = checkpoint.get("game_thread") + print("\nИтоговое состояние:") + print("Тема:", final_state.get("topic")) + print("Завязка:", final_state.get("intro")) + print("Выбор:", final_state.get("choice")) + print("Концовка:", final_state.get("ending")) + +if __name__ == "__main__": + topic_input = input("Введите тему истории: ").strip() + if not topic_input: + topic_input = "космический кот" + run_game(topic_input) \ No newline at end of file