PeterPinetree commited on
Commit
4b95bd0
·
verified ·
1 Parent(s): 06d02d3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -25
app.py CHANGED
@@ -75,7 +75,6 @@ def get_enhanced_system_prompt(genre=None):
75
  selected_genre = genre or "fantasy"
76
 
77
  system_message = f"""You are an interactive storyteller creating an immersive {selected_genre} choose-your-own-adventure story.
78
-
79
  For each response:
80
  1. Provide vivid sensory descriptions of the scene, environment, and characters
81
  2. Include meaningful dialogue or internal monologue that reveals character motivations
@@ -83,47 +82,75 @@ For each response:
83
  4. Maintain consistent world-building and character development
84
  5. Incorporate appropriate atmosphere and tone for a {selected_genre} setting
85
  6. Remember previous choices to create a coherent narrative arc
86
-
87
  Format your three options as:
88
  - Option 1: [Complete sentence describing a possible action]
89
  - Option 2: [Complete sentence describing a possible action]
90
  - Option 3: [Complete sentence describing a possible action]
91
-
92
  Keep responses engaging but concise (200-300 words maximum). If the user's input doesn't clearly indicate a choice, interpret their intent and move the story forward in the most logical direction."""
93
 
94
  return system_message
95
 
96
- def respond(message, history, genre=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  """Generate a response based on the current message and conversation history"""
98
  # Use a more detailed system prompt
99
  system_message = get_enhanced_system_prompt(genre)
100
 
101
  # Format history correctly for the API
102
  formatted_history = []
103
- for h in history:
104
- if isinstance(h, list) and len(h) == 2:
105
- # Handle old tuple format if it exists
106
- formatted_history.append({"role": "user", "content": h[0]})
107
- formatted_history.append({"role": "assistant", "content": h[1]})
108
- elif isinstance(h, dict) and "role" in h and "content" in h:
109
- # Handle new dictionary format
110
- formatted_history.append(h)
111
 
112
  # Create proper API messages
113
  api_messages = [{"role": "system", "content": system_message}]
114
 
115
- # Add limited history to prevent token overflow (only use recent exchanges)
116
- # Limit to last 5 exchanges
117
- memory_length = 5
118
- if formatted_history:
119
- for msg in formatted_history[-memory_length*2:]:
120
- api_messages.append(msg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  # Add current message
123
  api_messages.append({"role": "user", "content": message})
124
 
125
  # Special handling for story initialization
126
- if not history or message.lower() in ["start", "begin", "begin my adventure"]:
127
  # Add a specific instruction for starting a new story
128
  api_messages.append({
129
  "role": "system",
@@ -143,10 +170,13 @@ def respond(message, history, genre=None):
143
  delta = response.choices[0].delta.content
144
  if delta:
145
  bot_message += delta
146
- yield history + [[message, bot_message]]
 
 
 
147
  except Exception as e:
148
  error_message = f"Story magic temporarily interrupted. Please try again. (Error: {str(e)})"
149
- yield history + [[message, error_message]]
150
 
151
  def update_examples(genre):
152
  """Update the example prompts based on the selected genre"""
@@ -169,7 +199,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
169
  bubble_full_width=False,
170
  show_copy_button=True,
171
  avatar_images=(None, "🧙"),
172
- type="messages" # ✅ Fix for future Gradio updates
173
  )
174
  msg = gr.Textbox(
175
  placeholder="Describe what you want to do next in the story...",
@@ -190,6 +219,13 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
190
  value="fantasy"
191
  )
192
 
 
 
 
 
 
 
 
193
  # Initialize with fantasy examples
194
  examples_box = gr.Examples(
195
  examples=[[ex] for ex in get_examples_for_genre("fantasy")],
@@ -212,15 +248,33 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
212
  inputs=[genre],
213
  outputs=[examples_textbox]
214
  )
215
-
216
 
217
  # Set up event handlers for the chatbot
218
- msg.submit(respond, [msg, chatbot, genre], [chatbot])
219
- submit.click(respond, [msg, chatbot, genre], [chatbot])
220
 
221
  # Clear the chatbot for a new adventure
222
  clear.click(lambda: [], None, chatbot, queue=False)
223
  clear.click(lambda: "", None, msg, queue=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  if __name__ == "__main__":
226
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
75
  selected_genre = genre or "fantasy"
76
 
77
  system_message = f"""You are an interactive storyteller creating an immersive {selected_genre} choose-your-own-adventure story.
 
78
  For each response:
79
  1. Provide vivid sensory descriptions of the scene, environment, and characters
80
  2. Include meaningful dialogue or internal monologue that reveals character motivations
 
82
  4. Maintain consistent world-building and character development
83
  5. Incorporate appropriate atmosphere and tone for a {selected_genre} setting
84
  6. Remember previous choices to create a coherent narrative arc
 
85
  Format your three options as:
86
  - Option 1: [Complete sentence describing a possible action]
87
  - Option 2: [Complete sentence describing a possible action]
88
  - Option 3: [Complete sentence describing a possible action]
 
89
  Keep responses engaging but concise (200-300 words maximum). If the user's input doesn't clearly indicate a choice, interpret their intent and move the story forward in the most logical direction."""
90
 
91
  return system_message
92
 
93
+ def create_story_summary(chat_history):
94
+ """Create a concise summary of the story so far if the history gets too long"""
95
+ if len(chat_history) <= 2: # Not enough history to summarize
96
+ return None
97
+
98
+ # Extract just the content for summarization
99
+ story_text = ""
100
+ for user_msg, bot_msg in chat_history:
101
+ story_text += f"User: {user_msg}\nStory: {bot_msg}\n\n"
102
+
103
+ # Add a summary instruction
104
+ summary_instruction = {
105
+ "role": "system",
106
+ "content": "The conversation history is getting long. Please create a brief summary of the key plot points and character development so far to help maintain context without exceeding token limits."
107
+ }
108
+
109
+ return summary_instruction
110
+
111
+ def respond(message, chat_history, genre=None, use_full_memory=True):
112
  """Generate a response based on the current message and conversation history"""
113
  # Use a more detailed system prompt
114
  system_message = get_enhanced_system_prompt(genre)
115
 
116
  # Format history correctly for the API
117
  formatted_history = []
118
+ for user_msg, bot_msg in chat_history:
119
+ formatted_history.append({"role": "user", "content": user_msg})
120
+ formatted_history.append({"role": "assistant", "content": bot_msg})
 
 
 
 
 
121
 
122
  # Create proper API messages
123
  api_messages = [{"role": "system", "content": system_message}]
124
 
125
+ # Token management strategy
126
+ # Option 1: Use full history but potentially hit token limits
127
+ if use_full_memory and formatted_history:
128
+ # If there's a lot of history, we might need a summary
129
+ if len(formatted_history) > 20: # Arbitrary threshold, adjust as needed
130
+ summary_instruction = create_story_summary(chat_history[:len(chat_history)-5])
131
+ if summary_instruction:
132
+ api_messages.append(summary_instruction)
133
+
134
+ # Add only the most recent exchanges after the summary
135
+ for msg in formatted_history[-10:]:
136
+ api_messages.append(msg)
137
+ else:
138
+ # Add all history if it's not too long
139
+ for msg in formatted_history:
140
+ api_messages.append(msg)
141
+ # Option 2: Limited history - fallback if full memory is disabled
142
+ else:
143
+ # Set a larger memory length but still have a limit
144
+ memory_length = 10 # Increased from 5
145
+ if formatted_history:
146
+ for msg in formatted_history[-memory_length*2:]:
147
+ api_messages.append(msg)
148
 
149
  # Add current message
150
  api_messages.append({"role": "user", "content": message})
151
 
152
  # Special handling for story initialization
153
+ if not chat_history or message.lower() in ["start", "begin", "begin my adventure"]:
154
  # Add a specific instruction for starting a new story
155
  api_messages.append({
156
  "role": "system",
 
170
  delta = response.choices[0].delta.content
171
  if delta:
172
  bot_message += delta
173
+ # Create a new list for the updated chat history
174
+ new_history = chat_history.copy()
175
+ new_history.append((message, bot_message))
176
+ yield new_history
177
  except Exception as e:
178
  error_message = f"Story magic temporarily interrupted. Please try again. (Error: {str(e)})"
179
+ yield chat_history + [(message, error_message)]
180
 
181
  def update_examples(genre):
182
  """Update the example prompts based on the selected genre"""
 
199
  bubble_full_width=False,
200
  show_copy_button=True,
201
  avatar_images=(None, "🧙"),
 
202
  )
203
  msg = gr.Textbox(
204
  placeholder="Describe what you want to do next in the story...",
 
219
  value="fantasy"
220
  )
221
 
222
+ # Add a memory toggle option
223
+ full_memory = gr.Checkbox(
224
+ label="Full Story Memory",
225
+ value=True,
226
+ info="When enabled, the AI will try to remember the entire story"
227
+ )
228
+
229
  # Initialize with fantasy examples
230
  examples_box = gr.Examples(
231
  examples=[[ex] for ex in get_examples_for_genre("fantasy")],
 
248
  inputs=[genre],
249
  outputs=[examples_textbox]
250
  )
 
251
 
252
  # Set up event handlers for the chatbot
253
+ msg.submit(respond, [msg, chatbot, genre, full_memory], [chatbot])
254
+ submit.click(respond, [msg, chatbot, genre, full_memory], [chatbot])
255
 
256
  # Clear the chatbot for a new adventure
257
  clear.click(lambda: [], None, chatbot, queue=False)
258
  clear.click(lambda: "", None, msg, queue=False)
259
+
260
+ # Add a download story button
261
+ def save_story(chat_history):
262
+ if not chat_history:
263
+ return "No story to save yet!"
264
+
265
+ story_text = "# My Interactive Adventure\n\n"
266
+ for user_msg, bot_msg in chat_history:
267
+ story_text += f"**Player:** {user_msg}\n\n"
268
+ story_text += f"**Story:** {bot_msg}\n\n---\n\n"
269
+
270
+ return story_text
271
+
272
+ with gr.Row():
273
+ save_btn = gr.Button("Save Story as Markdown", variant="secondary")
274
+ story_output = gr.Markdown(visible=False)
275
+
276
+ save_btn.click(save_story, inputs=[chatbot], outputs=[story_output])
277
+ save_btn.click(lambda: True, None, story_output, js="() => {document.getElementById('story_output').scrollIntoView();}", queue=False)
278
 
279
  if __name__ == "__main__":
280
  demo.launch(server_name="0.0.0.0", server_port=7860)