Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -129,48 +129,58 @@ class StorytellerWorkflow(Workflow):
|
|
129 |
|
130 |
|
131 |
# --- Gradio UI and Application Logic ---
|
132 |
-
|
133 |
-
# game_state holds our workflow instance
|
134 |
-
workflow = game_state
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
139 |
event = StartEvent()
|
140 |
else:
|
141 |
# For subsequent turns, create a UserChoice event
|
142 |
event = UserChoice(choice=user_input)
|
143 |
|
144 |
# --- THIS IS THE CORRECTED LOGIC ---
|
145 |
-
#
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
|
|
|
|
|
|
161 |
story_display = f"{textwrap.fill(narrative, width=80)}\n\nChoices:{choices}"
|
162 |
|
163 |
image_path = None
|
164 |
-
if
|
165 |
image_path = await generate_image(narrative, HF_TOKEN)
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
# Graceful fallback
|
172 |
return None, "An unexpected error occurred. The story cannot continue.", "", None
|
173 |
-
|
174 |
def create_demo():
|
175 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
176 |
# State object to hold the workflow instance between turns
|
|
|
129 |
|
130 |
|
131 |
# --- Gradio UI and Application Logic ---
|
132 |
+
# This is the final, correct version of the main application logic function.
|
|
|
|
|
133 |
|
134 |
+
async def run_turn(user_input, game_state):
|
135 |
+
# game_state is now a dictionary: {'inventory': [], 'last_story_part': None}
|
136 |
+
|
137 |
+
# On the first turn, initialize the game state
|
138 |
+
if game_state is None:
|
139 |
+
game_state = {'inventory': [], 'last_story_part': None}
|
140 |
event = StartEvent()
|
141 |
else:
|
142 |
# For subsequent turns, create a UserChoice event
|
143 |
event = UserChoice(choice=user_input)
|
144 |
|
145 |
# --- THIS IS THE CORRECTED LOGIC ---
|
146 |
+
# 1. Create a fresh workflow instance for this turn
|
147 |
+
workflow = StorytellerWorkflow()
|
148 |
+
|
149 |
+
# 2. Create a context object and load our game state into its store
|
150 |
+
# This is how we pass the inventory and story history to the step
|
151 |
+
ctx = Context(store={
|
152 |
+
"inventory": game_state['inventory'],
|
153 |
+
"last_story_part": game_state['last_story_part']
|
154 |
+
})
|
155 |
+
|
156 |
+
# 3. Call the specific step method directly
|
157 |
+
result_event = await workflow.generate_story_part(event, ctx)
|
158 |
+
# ---
|
159 |
+
|
160 |
+
# Process the result from the step
|
161 |
+
if isinstance(result_event, StoryEnd):
|
162 |
+
return None, result_event.final_message, "", None # Reset the state
|
163 |
+
|
164 |
+
if isinstance(result_event, StoryContext):
|
165 |
+
narrative, choices = result_event.story_part.split("Choices:", 1)
|
166 |
story_display = f"{textwrap.fill(narrative, width=80)}\n\nChoices:{choices}"
|
167 |
|
168 |
image_path = None
|
169 |
+
if result_event.is_new_scene and HF_TOKEN:
|
170 |
image_path = await generate_image(narrative, HF_TOKEN)
|
171 |
|
172 |
+
# Update the game state for the next turn
|
173 |
+
new_game_state = {
|
174 |
+
'inventory': result_event.inventory,
|
175 |
+
'last_story_part': result_event.story_part
|
176 |
+
}
|
177 |
+
inventory_text = f"**Inventory:** {', '.join(new_game_state['inventory']) if new_game_state['inventory'] else 'Empty'}"
|
178 |
+
|
179 |
+
return image_path, story_display, inventory_text, new_game_state
|
180 |
|
181 |
# Graceful fallback
|
182 |
return None, "An unexpected error occurred. The story cannot continue.", "", None
|
183 |
+
|
184 |
def create_demo():
|
185 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
186 |
# State object to hold the workflow instance between turns
|