Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -122,22 +122,28 @@ def add_scene_to_story_orchestrator(
|
|
122 |
|
123 |
log_accumulator = [f"**π Scene {current_story_obj.current_scene_number + 1} - {time.strftime('%H:%M:%S')}**"]
|
124 |
|
125 |
-
# Initialize
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
ret_story_state = current_story_obj
|
127 |
ret_gallery = current_story_obj.get_all_scenes_for_gallery_display()
|
128 |
-
ret_latest_image = None
|
129 |
-
|
130 |
-
ret_status_bar_html = "<p class='processing_text status_text'>Processing...</p>"
|
131 |
-
|
132 |
|
133 |
-
# Initial UI
|
134 |
yield {
|
135 |
-
output_status_bar: gr.HTML(value=f"<p class='processing_text status_text'>π Weaving Scene {current_story_obj.current_scene_number + 1}...</p>"),
|
136 |
-
output_latest_scene_image: gr.Image(value=create_placeholder_image("π¨ Conjuring visuals..."), visible=True),
|
137 |
-
output_latest_scene_narrative: gr.Markdown(value=" Musing narrative...", visible=True),
|
138 |
engage_button: gr.Button(interactive=False),
|
139 |
surprise_button: gr.Button(interactive=False),
|
140 |
-
|
|
|
|
|
|
|
141 |
}
|
142 |
|
143 |
try:
|
@@ -156,13 +162,21 @@ def add_scene_to_story_orchestrator(
|
|
156 |
text_response = None
|
157 |
if text_model_info["type"] == "gemini": text_response = generate_text_gemini(user_p, model_id=text_model_info["id"], system_prompt=system_p, max_tokens=768 if narrative_length.startswith("Detailed") else 400)
|
158 |
elif text_model_info["type"] == "hf_text": text_response = generate_text_hf(user_p, model_id=text_model_info["id"], system_prompt=system_p, max_tokens=768 if narrative_length.startswith("Detailed") else 400)
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
|
164 |
-
|
165 |
-
yield { output_latest_scene_narrative: gr.Markdown(value=
|
166 |
output_interaction_log_markdown: gr.Markdown(value="\n".join(log_accumulator)) }
|
167 |
|
168 |
# --- 2. Generate Image ---
|
@@ -179,13 +193,22 @@ def add_scene_to_story_orchestrator(
|
|
179 |
image_response = None
|
180 |
if selected_image_provider_type == "stability_ai": image_response = generate_image_stabilityai(full_image_prompt, negative_prompt=negative_prompt_text or COMMON_NEGATIVE_PROMPTS, steps=40 if image_quality=="High Detail" else 25)
|
181 |
elif selected_image_provider_type == "dalle": image_response = generate_image_dalle(full_image_prompt, quality="hd" if image_quality=="High Detail" else "standard")
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
|
187 |
ret_latest_image = image_generated_pil if image_generated_pil else create_placeholder_image("Image Gen Failed", color="#401010")
|
188 |
-
yield { output_latest_scene_image: gr.Image(value=ret_latest_image),
|
189 |
output_interaction_log_markdown: gr.Markdown(value="\n".join(log_accumulator)) }
|
190 |
|
191 |
# --- 3. Add Scene to Story Object ---
|
@@ -208,45 +231,44 @@ def add_scene_to_story_orchestrator(
|
|
208 |
# --- 4. Prepare Final Values for Return Tuple ---
|
209 |
ret_gallery = current_story_obj.get_all_scenes_for_gallery_display()
|
210 |
_ , latest_narr_for_display_final_str_temp = current_story_obj.get_latest_scene_details_for_display()
|
211 |
-
ret_latest_narrative_str = latest_narr_for_display_final_str_temp
|
212 |
|
213 |
-
|
|
|
214 |
|
215 |
progress(1.0, desc="Scene Complete!")
|
216 |
|
217 |
except ValueError as ve:
|
218 |
log_accumulator.append(f"\n**INPUT/CONFIG ERROR:** {ve}")
|
219 |
-
ret_status_bar_html = f"<p class='error_text status_text'>β CONFIGURATION ERROR: {ve}</p>"
|
220 |
ret_latest_narrative_str = f"## Error\n{ve}"
|
221 |
except Exception as e:
|
222 |
log_accumulator.append(f"\n**UNEXPECTED RUNTIME ERROR:** {type(e).__name__} - {e}\n{traceback.format_exc()}")
|
223 |
-
ret_status_bar_html = f"<p class='error_text status_text'>β UNEXPECTED ERROR: {type(e).__name__}. Check logs.</p>"
|
224 |
ret_latest_narrative_str = f"## Unexpected Error\n{type(e).__name__}: {e}\nSee log for details."
|
225 |
finally:
|
226 |
current_total_time = time.time() - start_time
|
227 |
log_accumulator.append(f" Cycle ended at {time.strftime('%H:%M:%S')}. Total time: {current_total_time:.2f}s")
|
228 |
-
ret_log_str = "\n".join(log_accumulator)
|
229 |
|
230 |
-
# This final yield updates button states and the log
|
231 |
-
# It does NOT
|
232 |
yield {
|
233 |
engage_button: gr.Button(interactive=True),
|
234 |
surprise_button: gr.Button(interactive=True),
|
235 |
-
output_interaction_log_markdown: gr.Markdown(value=ret_log_str) #
|
236 |
}
|
237 |
|
238 |
-
#
|
239 |
-
# of the `engage_button.click()` method.
|
240 |
return (
|
241 |
ret_story_state,
|
242 |
ret_gallery,
|
243 |
ret_latest_image,
|
244 |
-
gr.Markdown(value=ret_latest_narrative_str),
|
245 |
-
|
246 |
-
gr.Markdown(value=ret_log_str)
|
247 |
)
|
248 |
|
249 |
-
|
250 |
def clear_story_state_ui_wrapper():
|
251 |
new_story = Story()
|
252 |
placeholder_img = create_placeholder_image("Your StoryVerse is a blank canvas...", color="#1A1A2E", text_color="#A0A0C0")
|
@@ -267,25 +289,23 @@ def surprise_me_func():
|
|
267 |
# --- Gradio UI Definition ---
|
268 |
with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨ - AI Story & World Weaver") as story_weaver_demo:
|
269 |
# --- Define Python variables for UI components that need to be updated by `yield` or `return` ---
|
270 |
-
# State
|
271 |
story_state_output = gr.State(Story())
|
272 |
-
|
273 |
-
# Input Column (some inputs are also outputs for clear/surprise)
|
274 |
scene_prompt_input = gr.Textbox()
|
275 |
image_style_input = gr.Dropdown()
|
276 |
artist_style_input = gr.Textbox()
|
277 |
-
|
278 |
-
#
|
|
|
|
|
|
|
|
|
279 |
output_latest_scene_image = gr.Image()
|
280 |
output_latest_scene_narrative = gr.Markdown()
|
281 |
-
output_gallery = gr.Gallery()
|
282 |
output_status_bar = gr.HTML()
|
283 |
output_interaction_log_markdown = gr.Markdown()
|
284 |
-
|
285 |
-
# Buttons (interactivity updated by yield)
|
286 |
engage_button = gr.Button()
|
287 |
surprise_button = gr.Button()
|
288 |
-
|
289 |
|
290 |
# --- Layout the UI ---
|
291 |
gr.Markdown("<div align='center'><h1>β¨ StoryVerse Omega β¨</h1>\n<h3>Craft Immersive Multimodal Worlds with AI</h3></div>")
|
@@ -306,16 +326,13 @@ with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨
|
|
306 |
with gr.Column(scale=7, min_width=450):
|
307 |
gr.Markdown("### π‘ **Craft Your Scene**", elem_classes="input-section-header")
|
308 |
with gr.Group():
|
309 |
-
scene_prompt_input = gr.Textbox(lines=7, label="Scene Vision (Description, Dialogue, Action):", placeholder="e.g., Amidst swirling cosmic dust
|
310 |
-
|
311 |
with gr.Row(elem_classes=["compact-row"]):
|
312 |
with gr.Column(scale=2):
|
313 |
image_style_input = gr.Dropdown(choices=["Default (Cinematic Realism)"] + sorted(list(STYLE_PRESETS.keys())), value="Default (Cinematic Realism)", label="Visual Style Preset")
|
314 |
with gr.Column(scale=2):
|
315 |
-
artist_style_input = gr.Textbox(label="Artistic Inspiration (Optional):", placeholder="e.g., Moebius
|
316 |
-
|
317 |
-
negative_prompt_input = gr.Textbox(lines=2, label="Exclude from Image (Negative Prompt):", placeholder="Default exclusions applied. Add more if needed.", value=COMMON_NEGATIVE_PROMPTS)
|
318 |
-
|
319 |
with gr.Accordion("βοΈ Advanced AI Configuration", open=False):
|
320 |
with gr.Group():
|
321 |
text_model_dropdown = gr.Dropdown(choices=list(TEXT_MODELS.keys()), value=UI_DEFAULT_TEXT_MODEL_KEY, label="Narrative AI Engine")
|
@@ -323,12 +340,10 @@ with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨
|
|
323 |
with gr.Row():
|
324 |
narrative_length_dropdown = gr.Dropdown(["Short (1 paragraph)", "Medium (2-3 paragraphs)", "Detailed (4+ paragraphs)"], value="Medium (2-3 paragraphs)", label="Narrative Detail")
|
325 |
image_quality_dropdown = gr.Dropdown(["Standard", "High Detail", "Sketch Concept"], value="Standard", label="Image Detail/Style")
|
326 |
-
|
327 |
with gr.Row(elem_classes=["compact-row"], equal_height=True):
|
328 |
engage_button = gr.Button("π Weave This Scene!", variant="primary", scale=3, icon="β¨")
|
329 |
surprise_button = gr.Button("π² Surprise Me!", variant="secondary", scale=1, icon="π")
|
330 |
clear_story_button = gr.Button("ποΈ New Story", variant="stop", scale=1, icon="β»οΈ")
|
331 |
-
|
332 |
output_status_bar = gr.HTML(value="<p class='processing_text status_text'>Ready to weave your first masterpiece!</p>")
|
333 |
|
334 |
with gr.Column(scale=10, min_width=700):
|
@@ -337,10 +352,8 @@ with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨
|
|
337 |
with gr.TabItem("π Latest Scene", id="latest_scene_tab"):
|
338 |
output_latest_scene_image = gr.Image(label="Latest Scene Image", type="pil", interactive=False, show_download_button=True, height=512, show_label=False, elem_classes=["panel_image"])
|
339 |
output_latest_scene_narrative = gr.Markdown()
|
340 |
-
|
341 |
with gr.TabItem("π Story Scroll", id="story_scroll_tab"):
|
342 |
output_gallery = gr.Gallery(label="Story Scroll", show_label=False, columns=4, object_fit="cover", height=700, preview=True, allow_preview=True, elem_classes=["gallery_output"])
|
343 |
-
|
344 |
with gr.TabItem("βοΈ Interaction Log", id="log_tab"):
|
345 |
with gr.Accordion(label="Developer Interaction Log", open=False):
|
346 |
output_interaction_log_markdown = gr.Markdown("Log will appear here...")
|
@@ -353,22 +366,17 @@ with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨
|
|
353 |
text_model_dropdown, image_provider_dropdown,
|
354 |
narrative_length_dropdown, image_quality_dropdown
|
355 |
],
|
356 |
-
outputs=[
|
357 |
-
story_state_output,
|
358 |
-
|
359 |
-
output_latest_scene_image,
|
360 |
-
output_latest_scene_narrative,
|
361 |
-
output_status_bar,
|
362 |
-
output_interaction_log_markdown
|
363 |
]
|
364 |
)
|
365 |
clear_story_button.click(
|
366 |
fn=clear_story_state_ui_wrapper,
|
367 |
inputs=[],
|
368 |
outputs=[
|
369 |
-
story_state_output, output_gallery,
|
370 |
-
|
371 |
-
output_status_bar, output_interaction_log_markdown,
|
372 |
scene_prompt_input
|
373 |
]
|
374 |
)
|
@@ -377,7 +385,6 @@ with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨
|
|
377 |
inputs=[],
|
378 |
outputs=[scene_prompt_input, image_style_input, artist_style_input]
|
379 |
)
|
380 |
-
|
381 |
gr.Examples(
|
382 |
examples=[
|
383 |
["A lone, weary traveler on a mechanical steed crosses a vast, crimson desert under twin suns. Dust devils dance in the distance.", "Sci-Fi Western", "Moebius", "greenery, water, modern city"],
|
|
|
122 |
|
123 |
log_accumulator = [f"**π Scene {current_story_obj.current_scene_number + 1} - {time.strftime('%H:%M:%S')}**"]
|
124 |
|
125 |
+
# Initialize values for the final return tuple
|
126 |
+
# These will be updated throughout the try block.
|
127 |
+
# Order must match engage_button.click outputs list:
|
128 |
+
# story_state_output, output_gallery, output_latest_scene_image,
|
129 |
+
# output_latest_scene_narrative, output_status_bar, output_interaction_log_markdown
|
130 |
+
|
131 |
+
# Set initial/default values for the elements that will be returned
|
132 |
ret_story_state = current_story_obj
|
133 |
ret_gallery = current_story_obj.get_all_scenes_for_gallery_display()
|
134 |
+
ret_latest_image = None # Will be PIL.Image or None
|
135 |
+
ret_latest_narrative_md = gr.Markdown(value="## Processing...\nNarrative being woven...")
|
136 |
+
ret_status_bar_html = gr.HTML(value="<p class='processing_text status_text'>Processing...</p>")
|
137 |
+
ret_log_md = gr.Markdown(value="\n".join(log_accumulator))
|
138 |
|
139 |
+
# Initial UI updates (disabling buttons, setting placeholders) are done via yield
|
140 |
yield {
|
|
|
|
|
|
|
141 |
engage_button: gr.Button(interactive=False),
|
142 |
surprise_button: gr.Button(interactive=False),
|
143 |
+
output_status_bar: gr.HTML(value=f"<p class='processing_text status_text'>π Weaving Scene {current_story_obj.current_scene_number + 1}...</p>"),
|
144 |
+
output_latest_scene_image: gr.Image(value=create_placeholder_image("π¨ Conjuring visuals...")),
|
145 |
+
output_latest_scene_narrative: gr.Markdown(value=" Musing narrative..."),
|
146 |
+
output_interaction_log_markdown: ret_log_md # Initial log
|
147 |
}
|
148 |
|
149 |
try:
|
|
|
162 |
text_response = None
|
163 |
if text_model_info["type"] == "gemini": text_response = generate_text_gemini(user_p, model_id=text_model_info["id"], system_prompt=system_p, max_tokens=768 if narrative_length.startswith("Detailed") else 400)
|
164 |
elif text_model_info["type"] == "hf_text": text_response = generate_text_hf(user_p, model_id=text_model_info["id"], system_prompt=system_p, max_tokens=768 if narrative_length.startswith("Detailed") else 400)
|
165 |
+
|
166 |
+
if text_response and text_response.success:
|
167 |
+
narrative_text_generated = basic_text_cleanup(text_response.text)
|
168 |
+
log_accumulator.append(f" Narrative: Success. (Snippet: {narrative_text_generated[:50]}...)")
|
169 |
+
elif text_response:
|
170 |
+
narrative_text_generated = f"**Narrative Error ({text_model_key}):** {text_response.error}"
|
171 |
+
log_accumulator.append(f" Narrative: FAILED - {text_response.error}")
|
172 |
+
else:
|
173 |
+
log_accumulator.append(f" Narrative: FAILED - No response object from {text_model_key}.")
|
174 |
+
else:
|
175 |
+
narrative_text_generated = "**Narrative Error:** Selected text model not available or misconfigured."
|
176 |
+
log_accumulator.append(f" Narrative: FAILED - Model '{text_model_key}' not available.")
|
177 |
|
178 |
+
ret_latest_narrative_str_content = f"## Scene Idea: {scene_prompt_text}\n\n{narrative_text_generated}"
|
179 |
+
yield { output_latest_scene_narrative: gr.Markdown(value=ret_latest_narrative_str_content),
|
180 |
output_interaction_log_markdown: gr.Markdown(value="\n".join(log_accumulator)) }
|
181 |
|
182 |
# --- 2. Generate Image ---
|
|
|
193 |
image_response = None
|
194 |
if selected_image_provider_type == "stability_ai": image_response = generate_image_stabilityai(full_image_prompt, negative_prompt=negative_prompt_text or COMMON_NEGATIVE_PROMPTS, steps=40 if image_quality=="High Detail" else 25)
|
195 |
elif selected_image_provider_type == "dalle": image_response = generate_image_dalle(full_image_prompt, quality="hd" if image_quality=="High Detail" else "standard")
|
196 |
+
|
197 |
+
if image_response and image_response.success:
|
198 |
+
image_generated_pil = image_response.image
|
199 |
+
log_accumulator.append(f" Image: Success from {image_response.provider}.")
|
200 |
+
elif image_response:
|
201 |
+
image_generation_error_message = f"**Image Error ({image_response.provider}):** {image_response.error}"
|
202 |
+
log_accumulator.append(f" Image: FAILED - {image_response.error}")
|
203 |
+
else:
|
204 |
+
image_generation_error_message = f"**Image Error:** No response object from {image_provider_key} service."
|
205 |
+
log_accumulator.append(f" Image: FAILED - No response object from {image_provider_key}.")
|
206 |
+
else:
|
207 |
+
image_generation_error_message = "**Image Error:** Selected image provider not available or misconfigured."
|
208 |
+
log_accumulator.append(f" Image: FAILED - Provider '{image_provider_key}' unavailable.")
|
209 |
|
210 |
ret_latest_image = image_generated_pil if image_generated_pil else create_placeholder_image("Image Gen Failed", color="#401010")
|
211 |
+
yield { output_latest_scene_image: gr.Image(value=ret_latest_image), # Use gr.Image() for update
|
212 |
output_interaction_log_markdown: gr.Markdown(value="\n".join(log_accumulator)) }
|
213 |
|
214 |
# --- 3. Add Scene to Story Object ---
|
|
|
231 |
# --- 4. Prepare Final Values for Return Tuple ---
|
232 |
ret_gallery = current_story_obj.get_all_scenes_for_gallery_display()
|
233 |
_ , latest_narr_for_display_final_str_temp = current_story_obj.get_latest_scene_details_for_display()
|
234 |
+
ret_latest_narrative_str = latest_narr_for_display_final_str_temp # This is a string
|
235 |
|
236 |
+
status_html_str_temp = f"<p class='error_text status_text'>Scene {current_story_obj.current_scene_number} added with errors.</p>" if final_scene_error else f"<p class='success_text status_text'>π Scene {current_story_obj.current_scene_number} woven!</p>"
|
237 |
+
ret_status_bar_html = gr.HTML(value=status_html_str_temp) # Convert to HTML update
|
238 |
|
239 |
progress(1.0, desc="Scene Complete!")
|
240 |
|
241 |
except ValueError as ve:
|
242 |
log_accumulator.append(f"\n**INPUT/CONFIG ERROR:** {ve}")
|
243 |
+
ret_status_bar_html = gr.HTML(value=f"<p class='error_text status_text'>β CONFIGURATION ERROR: {ve}</p>")
|
244 |
ret_latest_narrative_str = f"## Error\n{ve}"
|
245 |
except Exception as e:
|
246 |
log_accumulator.append(f"\n**UNEXPECTED RUNTIME ERROR:** {type(e).__name__} - {e}\n{traceback.format_exc()}")
|
247 |
+
ret_status_bar_html = gr.HTML(value=f"<p class='error_text status_text'>β UNEXPECTED ERROR: {type(e).__name__}. Check logs.</p>")
|
248 |
ret_latest_narrative_str = f"## Unexpected Error\n{type(e).__name__}: {e}\nSee log for details."
|
249 |
finally:
|
250 |
current_total_time = time.time() - start_time
|
251 |
log_accumulator.append(f" Cycle ended at {time.strftime('%H:%M:%S')}. Total time: {current_total_time:.2f}s")
|
252 |
+
ret_log_str = "\n".join(log_accumulator) # Prepare final log string
|
253 |
|
254 |
+
# This final yield updates button states and the log markdown component.
|
255 |
+
# It does NOT update components that are part of the main `return` statement's responsibility.
|
256 |
yield {
|
257 |
engage_button: gr.Button(interactive=True),
|
258 |
surprise_button: gr.Button(interactive=True),
|
259 |
+
output_interaction_log_markdown: gr.Markdown(value=ret_log_str) # Update log via yield
|
260 |
}
|
261 |
|
262 |
+
# The final `return` provides values for the components listed in `engage_button.click(outputs=...)`
|
|
|
263 |
return (
|
264 |
ret_story_state,
|
265 |
ret_gallery,
|
266 |
ret_latest_image,
|
267 |
+
gr.Markdown(value=ret_latest_narrative_str), # Ensure it's a Gradio update object
|
268 |
+
ret_status_bar_html, # Already a Gradio update object
|
269 |
+
gr.Markdown(value=ret_log_str) # Ensure it's a Gradio update object for the log too
|
270 |
)
|
271 |
|
|
|
272 |
def clear_story_state_ui_wrapper():
|
273 |
new_story = Story()
|
274 |
placeholder_img = create_placeholder_image("Your StoryVerse is a blank canvas...", color="#1A1A2E", text_color="#A0A0C0")
|
|
|
289 |
# --- Gradio UI Definition ---
|
290 |
with gr.Blocks(theme=omega_theme, css=omega_css, title="β¨ StoryVerse Omega β¨ - AI Story & World Weaver") as story_weaver_demo:
|
291 |
# --- Define Python variables for UI components that need to be updated by `yield` or `return` ---
|
|
|
292 |
story_state_output = gr.State(Story())
|
|
|
|
|
293 |
scene_prompt_input = gr.Textbox()
|
294 |
image_style_input = gr.Dropdown()
|
295 |
artist_style_input = gr.Textbox()
|
296 |
+
# negative_prompt_input will be defined in layout
|
297 |
+
# text_model_dropdown will be defined in layout
|
298 |
+
# image_provider_dropdown will be defined in layout
|
299 |
+
# narrative_length_dropdown will be defined in layout
|
300 |
+
# image_quality_dropdown will be defined in layout
|
301 |
+
output_gallery = gr.Gallery()
|
302 |
output_latest_scene_image = gr.Image()
|
303 |
output_latest_scene_narrative = gr.Markdown()
|
|
|
304 |
output_status_bar = gr.HTML()
|
305 |
output_interaction_log_markdown = gr.Markdown()
|
|
|
|
|
306 |
engage_button = gr.Button()
|
307 |
surprise_button = gr.Button()
|
308 |
+
clear_story_button = gr.Button()
|
309 |
|
310 |
# --- Layout the UI ---
|
311 |
gr.Markdown("<div align='center'><h1>β¨ StoryVerse Omega β¨</h1>\n<h3>Craft Immersive Multimodal Worlds with AI</h3></div>")
|
|
|
326 |
with gr.Column(scale=7, min_width=450):
|
327 |
gr.Markdown("### π‘ **Craft Your Scene**", elem_classes="input-section-header")
|
328 |
with gr.Group():
|
329 |
+
scene_prompt_input = gr.Textbox(lines=7, label="Scene Vision (Description, Dialogue, Action):", placeholder="e.g., Amidst swirling cosmic dust...")
|
|
|
330 |
with gr.Row(elem_classes=["compact-row"]):
|
331 |
with gr.Column(scale=2):
|
332 |
image_style_input = gr.Dropdown(choices=["Default (Cinematic Realism)"] + sorted(list(STYLE_PRESETS.keys())), value="Default (Cinematic Realism)", label="Visual Style Preset")
|
333 |
with gr.Column(scale=2):
|
334 |
+
artist_style_input = gr.Textbox(label="Artistic Inspiration (Optional):", placeholder="e.g., Moebius...")
|
335 |
+
negative_prompt_input = gr.Textbox(lines=2, label="Exclude from Image (Negative Prompt):", value=COMMON_NEGATIVE_PROMPTS)
|
|
|
|
|
336 |
with gr.Accordion("βοΈ Advanced AI Configuration", open=False):
|
337 |
with gr.Group():
|
338 |
text_model_dropdown = gr.Dropdown(choices=list(TEXT_MODELS.keys()), value=UI_DEFAULT_TEXT_MODEL_KEY, label="Narrative AI Engine")
|
|
|
340 |
with gr.Row():
|
341 |
narrative_length_dropdown = gr.Dropdown(["Short (1 paragraph)", "Medium (2-3 paragraphs)", "Detailed (4+ paragraphs)"], value="Medium (2-3 paragraphs)", label="Narrative Detail")
|
342 |
image_quality_dropdown = gr.Dropdown(["Standard", "High Detail", "Sketch Concept"], value="Standard", label="Image Detail/Style")
|
|
|
343 |
with gr.Row(elem_classes=["compact-row"], equal_height=True):
|
344 |
engage_button = gr.Button("π Weave This Scene!", variant="primary", scale=3, icon="β¨")
|
345 |
surprise_button = gr.Button("π² Surprise Me!", variant="secondary", scale=1, icon="π")
|
346 |
clear_story_button = gr.Button("ποΈ New Story", variant="stop", scale=1, icon="β»οΈ")
|
|
|
347 |
output_status_bar = gr.HTML(value="<p class='processing_text status_text'>Ready to weave your first masterpiece!</p>")
|
348 |
|
349 |
with gr.Column(scale=10, min_width=700):
|
|
|
352 |
with gr.TabItem("π Latest Scene", id="latest_scene_tab"):
|
353 |
output_latest_scene_image = gr.Image(label="Latest Scene Image", type="pil", interactive=False, show_download_button=True, height=512, show_label=False, elem_classes=["panel_image"])
|
354 |
output_latest_scene_narrative = gr.Markdown()
|
|
|
355 |
with gr.TabItem("π Story Scroll", id="story_scroll_tab"):
|
356 |
output_gallery = gr.Gallery(label="Story Scroll", show_label=False, columns=4, object_fit="cover", height=700, preview=True, allow_preview=True, elem_classes=["gallery_output"])
|
|
|
357 |
with gr.TabItem("βοΈ Interaction Log", id="log_tab"):
|
358 |
with gr.Accordion(label="Developer Interaction Log", open=False):
|
359 |
output_interaction_log_markdown = gr.Markdown("Log will appear here...")
|
|
|
366 |
text_model_dropdown, image_provider_dropdown,
|
367 |
narrative_length_dropdown, image_quality_dropdown
|
368 |
],
|
369 |
+
outputs=[
|
370 |
+
story_state_output, output_gallery, output_latest_scene_image,
|
371 |
+
output_latest_scene_narrative, output_status_bar, output_interaction_log_markdown
|
|
|
|
|
|
|
|
|
372 |
]
|
373 |
)
|
374 |
clear_story_button.click(
|
375 |
fn=clear_story_state_ui_wrapper,
|
376 |
inputs=[],
|
377 |
outputs=[
|
378 |
+
story_state_output, output_gallery, output_latest_scene_image,
|
379 |
+
output_latest_scene_narrative, output_status_bar, output_interaction_log_markdown,
|
|
|
380 |
scene_prompt_input
|
381 |
]
|
382 |
)
|
|
|
385 |
inputs=[],
|
386 |
outputs=[scene_prompt_input, image_style_input, artist_style_input]
|
387 |
)
|
|
|
388 |
gr.Examples(
|
389 |
examples=[
|
390 |
["A lone, weary traveler on a mechanical steed crosses a vast, crimson desert under twin suns. Dust devils dance in the distance.", "Sci-Fi Western", "Moebius", "greenery, water, modern city"],
|