euler314 commited on
Commit
bf6e4ca
·
verified ·
1 Parent(s): adcecf4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +427 -106
app.py CHANGED
@@ -1614,6 +1614,11 @@ def main():
1614
  st.session_state.custom_model = "gpt-4o" # Default model
1615
  st.session_state.first_load_complete = False # Prevent refreshes on first load
1616
  st.session_state.pending_tab_switch = None # Track pending tab switches
 
 
 
 
 
1617
 
1618
  # Page configuration with improved layout
1619
  st.set_page_config(
@@ -1623,7 +1628,7 @@ def main():
1623
  initial_sidebar_state="expanded"
1624
  )
1625
 
1626
- # Custom CSS for improved UI
1627
  st.markdown("""
1628
  <style>
1629
  .main-header {
@@ -1721,6 +1726,67 @@ def main():
1721
  margin-top: 1rem;
1722
  border-left: 4px solid #ef4444;
1723
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1724
  </style>
1725
  """, unsafe_allow_html=True)
1726
 
@@ -1977,7 +2043,7 @@ class MyScene(Scene):
1977
  else:
1978
  st.success(st.session_state.status)
1979
 
1980
- # AI ASSISTANT TAB
1981
  with tabs[1]:
1982
  st.markdown("### 🤖 AI Animation Assistant")
1983
 
@@ -2052,10 +2118,12 @@ class MyScene(Scene):
2052
  "DeepSeek-R1",
2053
  "Meta-Llama-3.1-405B-Instruct",
2054
  "Llama-3.2-90B-Vision-Instruct",
2055
- "Llama-3.3-70B-Instruct"
2056
  "Llama-4-Scout-17B-16E-Instruct",
2057
  "Llama-4-Maverick-17B-128E-Instruct-FP8",
 
2058
  "gpt-4o",
 
2059
  "o3-mini",
2060
  "o1",
2061
  "o1-mini",
@@ -2080,46 +2148,287 @@ class MyScene(Scene):
2080
  st.session_state.ai_models['model_name'] = st.session_state.custom_model
2081
  st.success(f"Model updated to {st.session_state.custom_model}")
2082
 
2083
- # AI code generation
2084
  if st.session_state.ai_models and "client" in st.session_state.ai_models:
2085
- st.markdown("<div class='card'>", unsafe_allow_html=True)
2086
- st.markdown("#### Generate Animation from Description")
2087
- st.write("Describe the animation you want to create, or provide partial code to complete.")
2088
 
2089
- # Predefined animation ideas dropdown
2090
- animation_ideas = [
2091
- "Select an idea...",
2092
- "Create a 3D animation showing a sphere morphing into a torus",
2093
- "Show a visual proof of the Pythagorean theorem",
2094
- "Visualize a Fourier transform converting a signal from time domain to frequency domain",
2095
- "Create an animation explaining neural network forward propagation",
2096
- "Illustrate the concept of integration with area under a curve"
2097
- ]
2098
 
2099
- selected_idea = st.selectbox(
2100
- "Try one of these ideas",
2101
- options=animation_ideas
2102
- )
 
 
 
 
 
 
2103
 
2104
- prompt_value = selected_idea if selected_idea != "Select an idea..." else ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2105
 
2106
- code_input = st.text_area(
2107
- "Your Prompt or Code",
2108
- value=prompt_value,
2109
- placeholder="Example: Create an animation that shows a circle morphing into a square while changing color from red to blue",
2110
- height=150
2111
- )
2112
 
2113
- if st.button("Generate Animation Code", key="gen_ai_code"):
2114
- if code_input:
2115
- with st.spinner("AI is generating your animation code..."):
2116
- try:
2117
- # Direct implementation of code generation
2118
- client = st.session_state.ai_models["client"]
2119
- model_name = st.session_state.ai_models["model_name"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2120
 
2121
- # Create the prompt
2122
- prompt = f"""Write a complete Manim animation scene based on this code or idea:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2123
  {code_input}
2124
 
2125
  The code should be a complete, working Manim animation that includes:
@@ -2130,84 +2439,93 @@ The code should be a complete, working Manim animation that includes:
2130
 
2131
  Here's the complete Manim code:
2132
  """
2133
-
2134
- # Make API call directly
2135
- from azure.ai.inference.models import UserMessage
2136
- response = client.complete(
2137
- messages=[
2138
- UserMessage(prompt),
2139
- ],
2140
- max_tokens=1000,
2141
- model=model_name
2142
- )
2143
-
2144
- # Process the response
2145
- if response and response.choices and len(response.choices) > 0:
2146
- completed_code = response.choices[0].message.content
2147
 
2148
- # Extract code from markdown if present
2149
- if "```python" in completed_code:
2150
- completed_code = completed_code.split("```python")[1].split("```")[0]
2151
- elif "```" in completed_code:
2152
- completed_code = completed_code.split("```")[1].split("```")[0]
 
 
 
 
2153
 
2154
- # Add Scene class if missing
2155
- if "Scene" not in completed_code:
2156
- completed_code = f"""from manim import *
 
 
 
 
 
 
 
 
 
 
2157
 
2158
  class MyScene(Scene):
2159
  def construct(self):
2160
  {completed_code}"""
2161
-
2162
- # Store the generated code
2163
- st.session_state.generated_code = completed_code
2164
- else:
2165
- st.error("Failed to generate code. API returned an empty response.")
2166
- except Exception as e:
2167
- st.error(f"Error generating code: {str(e)}")
2168
- import traceback
2169
- st.code(traceback.format_exc())
2170
- else:
2171
- st.warning("Please enter a description or prompt first")
2172
-
2173
- st.markdown("</div>", unsafe_allow_html=True)
2174
-
2175
- # AI generated code display and actions
2176
- if "generated_code" in st.session_state and st.session_state.generated_code:
2177
- st.markdown("<div class='card'>", unsafe_allow_html=True)
2178
- st.markdown("#### Generated Animation Code")
2179
- st.code(st.session_state.generated_code, language="python")
2180
-
2181
- col_ai1, col_ai2 = st.columns(2)
2182
- with col_ai1:
2183
- if st.button("Use This Code", key="use_gen_code"):
2184
- st.session_state.code = st.session_state.generated_code
2185
- st.session_state.temp_code = st.session_state.generated_code
2186
- # Set pending tab switch to editor tab
2187
- st.session_state.pending_tab_switch = 0
2188
- st.rerun()
2189
 
2190
- with col_ai2:
2191
- if st.button("Render Preview", key="render_preview"):
2192
- with st.spinner("Rendering preview..."):
2193
- video_data, status = generate_manim_video(
2194
- st.session_state.generated_code,
2195
- "mp4",
2196
- "480p", # Use lowest quality for preview
2197
- ANIMATION_SPEEDS["Normal"]
2198
- )
2199
-
2200
- if video_data:
2201
- st.video(video_data)
2202
- st.download_button(
2203
- label="Download Preview",
2204
- data=video_data,
2205
- file_name=f"manim_preview_{int(time.time())}.mp4",
2206
- mime="video/mp4"
 
 
 
 
 
2207
  )
2208
- else:
2209
- st.error(f"Failed to generate preview: {status}")
2210
- st.markdown("</div>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
2211
  else:
2212
  st.warning("AI models not initialized. Please use the Debug Connection section to test API connectivity.")
2213
  else:
@@ -3046,3 +3364,6 @@ class PlotScene(Scene):
3046
 
3047
  if __name__ == "__main__":
3048
  main()
 
 
 
 
1614
  st.session_state.custom_model = "gpt-4o" # Default model
1615
  st.session_state.first_load_complete = False # Prevent refreshes on first load
1616
  st.session_state.pending_tab_switch = None # Track pending tab switches
1617
+
1618
+ # New chat-related session state variables
1619
+ st.session_state.chat_history = [] # Store chat messages
1620
+ st.session_state.user_message = "" # Current user message
1621
+ st.session_state.chat_export_data = None # For exporting chat
1622
 
1623
  # Page configuration with improved layout
1624
  st.set_page_config(
 
1628
  initial_sidebar_state="expanded"
1629
  )
1630
 
1631
+ # Custom CSS for improved UI (including chat UI styles)
1632
  st.markdown("""
1633
  <style>
1634
  .main-header {
 
1726
  margin-top: 1rem;
1727
  border-left: 4px solid #ef4444;
1728
  }
1729
+
1730
+ /* Chat UI styles */
1731
+ .chat-container {
1732
+ display: flex;
1733
+ flex-direction: column;
1734
+ height: 500px;
1735
+ overflow-y: auto;
1736
+ border: 1px solid #e0e0e0;
1737
+ border-radius: 10px;
1738
+ padding: 1rem;
1739
+ margin-bottom: 1rem;
1740
+ background-color: #f8f9fa;
1741
+ }
1742
+
1743
+ .user-message {
1744
+ align-self: flex-end;
1745
+ background-color: #4F46E5;
1746
+ color: white;
1747
+ border-radius: 18px 18px 0 18px;
1748
+ padding: 0.8rem 1rem;
1749
+ margin: 0.5rem 0;
1750
+ max-width: 80%;
1751
+ }
1752
+
1753
+ .ai-message {
1754
+ align-self: flex-start;
1755
+ background-color: #e0e0e0;
1756
+ color: #333;
1757
+ border-radius: 18px 18px 18px 0;
1758
+ padding: 0.8rem 1rem;
1759
+ margin: 0.5rem 0;
1760
+ max-width: 80%;
1761
+ }
1762
+
1763
+ .message-time {
1764
+ font-size: 0.7rem;
1765
+ color: #777;
1766
+ margin-top: 0.2rem;
1767
+ }
1768
+
1769
+ .chat-input {
1770
+ display: flex;
1771
+ margin-top: 1rem;
1772
+ }
1773
+
1774
+ .chat-input input {
1775
+ flex-grow: 1;
1776
+ padding: 0.8rem;
1777
+ border: 1px solid #ccc;
1778
+ border-radius: 5px;
1779
+ margin-right: 0.5rem;
1780
+ }
1781
+
1782
+ .chat-input button {
1783
+ padding: 0.8rem 1.5rem;
1784
+ background-color: #4F46E5;
1785
+ color: white;
1786
+ border: none;
1787
+ border-radius: 5px;
1788
+ cursor: pointer;
1789
+ }
1790
  </style>
1791
  """, unsafe_allow_html=True)
1792
 
 
2043
  else:
2044
  st.success(st.session_state.status)
2045
 
2046
+ # AI ASSISTANT TAB - ENHANCED WITH CHAT FUNCTIONALITY
2047
  with tabs[1]:
2048
  st.markdown("### 🤖 AI Animation Assistant")
2049
 
 
2118
  "DeepSeek-R1",
2119
  "Meta-Llama-3.1-405B-Instruct",
2120
  "Llama-3.2-90B-Vision-Instruct",
2121
+ "Llama-3.3-70B-Instruct",
2122
  "Llama-4-Scout-17B-16E-Instruct",
2123
  "Llama-4-Maverick-17B-128E-Instruct-FP8",
2124
+ "gpt-4o-mini",
2125
  "gpt-4o",
2126
+ "gpt-4.1",
2127
  "o3-mini",
2128
  "o1",
2129
  "o1-mini",
 
2148
  st.session_state.ai_models['model_name'] = st.session_state.custom_model
2149
  st.success(f"Model updated to {st.session_state.custom_model}")
2150
 
2151
+ # Enhanced chat interface
2152
  if st.session_state.ai_models and "client" in st.session_state.ai_models:
2153
+ st.markdown("#### 💬 AI Chat Interface")
2154
+ st.markdown("Chat with the AI about animation concepts, get code suggestions, and troubleshoot issues.")
 
2155
 
2156
+ # Chat history display container
2157
+ st.markdown("<div class='chat-container' id='chat-container'>", unsafe_allow_html=True)
 
 
 
 
 
 
 
2158
 
2159
+ # System message at the start if chat is empty
2160
+ if not st.session_state.chat_history:
2161
+ st.markdown(
2162
+ "<div class='ai-message'>"
2163
+ "Hello! I'm your Manim Animation Assistant. I can help you create and explain mathematical animations. "
2164
+ "Ask me about creating specific animations, explaining concepts, or troubleshooting your code."
2165
+ "<div class='message-time'>System</div>"
2166
+ "</div>",
2167
+ unsafe_allow_html=True
2168
+ )
2169
 
2170
+ # Display chat history
2171
+ for message in st.session_state.chat_history:
2172
+ if message["role"] == "user":
2173
+ st.markdown(
2174
+ f"<div class='user-message'>{message['content']}"
2175
+ f"<div class='message-time'>{message['time']}</div>"
2176
+ "</div>",
2177
+ unsafe_allow_html=True
2178
+ )
2179
+ else:
2180
+ st.markdown(
2181
+ f"<div class='ai-message'>{message['content']}"
2182
+ f"<div class='message-time'>{message['time']}</div>"
2183
+ "</div>",
2184
+ unsafe_allow_html=True
2185
+ )
2186
 
2187
+ st.markdown("</div>", unsafe_allow_html=True)
 
 
 
 
 
2188
 
2189
+ # Input form for new messages
2190
+ with st.form(key="chat_form", clear_on_submit=True):
2191
+ col1, col2 = st.columns([5, 1])
2192
+
2193
+ with col1:
2194
+ user_input = st.text_area(
2195
+ "Your message",
2196
+ value=st.session_state.user_message,
2197
+ key="user_input_area",
2198
+ placeholder="Ask about animation concepts, request code examples, or describe what you want to create...",
2199
+ height=100
2200
+ )
2201
+
2202
+ with col2:
2203
+ submit_button = st.form_submit_button("Send")
2204
+
2205
+ # Process form submission
2206
+ if submit_button and user_input:
2207
+ # Store user message in history
2208
+ current_time = datetime.now().strftime("%H:%M:%S")
2209
+ st.session_state.chat_history.append({
2210
+ "role": "user",
2211
+ "content": user_input,
2212
+ "time": current_time
2213
+ })
2214
+
2215
+ # Get AI response
2216
+ with st.spinner("AI is thinking..."):
2217
+ try:
2218
+ client = st.session_state.ai_models["client"]
2219
+ model_name = st.session_state.ai_models["model_name"]
2220
+
2221
+ # Convert chat history to API format
2222
+ from azure.ai.inference.models import UserMessage, AssistantMessage
2223
+
2224
+ # Create messages array for API
2225
+ messages = []
2226
+
2227
+ # Add system message with Manim context
2228
+ system_message = """
2229
+ I am a Manim Animation Assistant. I can help with:
2230
+ 1. Creating mathematical animations using Manim
2231
+ 2. Explaining animation concepts and techniques
2232
+ 3. Generating and debugging Manim code
2233
+ 4. Offering creative suggestions for visualizing concepts
2234
+
2235
+ When providing code, I'll make sure it's complete, runnable Manim code with proper imports and structure.
2236
+ """
2237
+
2238
+ # Add system message as first user message (workaround for some models)
2239
+ messages.append(UserMessage("You are a Manim animation expert assistant. Respond to my questions with helpful information about creating mathematical animations with Manim."))
2240
+
2241
+ # Add chat history (limited to last 10 messages for context window)
2242
+ for msg in st.session_state.chat_history[-10:]:
2243
+ if msg["role"] == "user":
2244
+ messages.append(UserMessage(msg["content"]))
2245
+ else:
2246
+ messages.append(AssistantMessage(msg["content"]))
2247
+
2248
+ # Get response from API
2249
+ response = client.complete(
2250
+ messages=messages,
2251
+ max_tokens=1000,
2252
+ model=model_name
2253
+ )
2254
+
2255
+ # Process the response
2256
+ if response and response.choices and len(response.choices) > 0:
2257
+ ai_response = response.choices[0].message.content
2258
+
2259
+ # Store AI response in history
2260
+ st.session_state.chat_history.append({
2261
+ "role": "assistant",
2262
+ "content": ai_response,
2263
+ "time": datetime.now().strftime("%H:%M:%S")
2264
+ })
2265
 
2266
+ # Look for code in the response
2267
+ if "```python" in ai_response and "```" in ai_response:
2268
+ # Extract code blocks
2269
+ code_blocks = []
2270
+ parts = ai_response.split("```python")
2271
+ for part in parts[1:]: # Skip the first part (before first code block)
2272
+ if "```" in part:
2273
+ code = part.split("```")[0].strip()
2274
+ code_blocks.append(code)
2275
+
2276
+ # If we have code blocks, offer to use the first one
2277
+ if code_blocks and "class" in code_blocks[0] and "Scene" in code_blocks[0]:
2278
+ st.info("Manim code detected in the response. Would you like to use it?")
2279
+ if st.button("Use This Code in Editor", key="use_chat_code"):
2280
+ st.session_state.code = code_blocks[0]
2281
+ st.session_state.temp_code = code_blocks[0]
2282
+ st.session_state.pending_tab_switch = 0 # Switch to editor tab
2283
+ st.rerun()
2284
+ else:
2285
+ # Handle empty response
2286
+ st.error("The AI model returned an empty response. Please try again.")
2287
+ except Exception as e:
2288
+ st.error(f"Error getting AI response: {str(e)}")
2289
+ import traceback
2290
+ st.code(traceback.format_exc())
2291
+
2292
+ # Add error message to chat
2293
+ st.session_state.chat_history.append({
2294
+ "role": "assistant",
2295
+ "content": f"Sorry, I encountered an error: {str(e)}. Please try again or check the connection.",
2296
+ "time": datetime.now().strftime("%H:%M:%S")
2297
+ })
2298
+
2299
+ # Clear the user input
2300
+ st.session_state.user_message = ""
2301
+ # Force a rerun to update the chat display
2302
+ st.rerun()
2303
+
2304
+ # Chat export options
2305
+ if st.session_state.chat_history:
2306
+ st.markdown("#### Chat Options")
2307
+ col1, col2 = st.columns(2)
2308
+
2309
+ with col1:
2310
+ if st.button("Export Chat", key="export_chat_btn"):
2311
+ # Format chat history as text
2312
+ chat_text = "# Manim Animation Chat Export\n\n"
2313
+ for msg in st.session_state.chat_history:
2314
+ role = "You" if msg["role"] == "user" else "AI Assistant"
2315
+ chat_text += f"## {role} ({msg['time']})\n\n{msg['content']}\n\n"
2316
+
2317
+ # Store in session state for download
2318
+ st.session_state.chat_export_data = chat_text
2319
+
2320
+ # Show download button
2321
+ st.download_button(
2322
+ "📥 Download Chat Text",
2323
+ data=st.session_state.chat_export_data,
2324
+ file_name=f"manim_chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md",
2325
+ mime="text/markdown"
2326
+ )
2327
+
2328
+ with col2:
2329
+ if st.button("Clear Chat", key="clear_chat_btn"):
2330
+ # Clear chat history
2331
+ st.session_state.chat_history = []
2332
+ st.success("Chat history cleared!")
2333
+ st.rerun()
2334
+
2335
+ # Additional AI features (code generation, etc.)
2336
+ with st.expander("✨ Animation Idea Generator"):
2337
+ st.markdown("Let the AI help you generate animation ideas based on concepts.")
2338
+
2339
+ concept_input = st.text_input(
2340
+ "Enter a mathematical or scientific concept:",
2341
+ placeholder="e.g., Pythagorean theorem, Wave interference, Neural networks"
2342
+ )
2343
+
2344
+ if st.button("Generate Animation Ideas", key="gen_ideas_btn"):
2345
+ if concept_input:
2346
+ with st.spinner("Generating ideas..."):
2347
+ try:
2348
+ # Get ideas from AI
2349
+ client = st.session_state.ai_models["client"]
2350
+ model_name = st.session_state.ai_models["model_name"]
2351
+
2352
+ idea_prompt = f"""Generate 3 creative animation ideas for visualizing the concept of "{concept_input}" using Manim.
2353
+ For each idea, provide:
2354
+ 1. A title
2355
+ 2. A brief description of what the animation would show
2356
+ 3. Key visual elements to include
2357
+
2358
+ Format your response with clear sections for each idea."""
2359
+
2360
+ from azure.ai.inference.models import UserMessage
2361
+ response = client.complete(
2362
+ messages=[
2363
+ UserMessage(idea_prompt),
2364
+ ],
2365
+ max_tokens=800,
2366
+ model=model_name
2367
+ )
2368
+
2369
+ if response and response.choices and len(response.choices) > 0:
2370
+ ideas = response.choices[0].message.content
2371
+ st.markdown("### Animation Ideas")
2372
+ st.markdown(ideas)
2373
+
2374
+ # Add to chat history
2375
+ st.session_state.chat_history.append({
2376
+ "role": "user",
2377
+ "content": f"Generate animation ideas for: {concept_input}",
2378
+ "time": datetime.now().strftime("%H:%M:%S")
2379
+ })
2380
+
2381
+ st.session_state.chat_history.append({
2382
+ "role": "assistant",
2383
+ "content": ideas,
2384
+ "time": datetime.now().strftime("%H:%M:%S")
2385
+ })
2386
+ else:
2387
+ st.error("Failed to generate ideas. The AI returned an empty response.")
2388
+ except Exception as e:
2389
+ st.error(f"Error generating ideas: {str(e)}")
2390
+ else:
2391
+ st.warning("Please enter a concept first")
2392
+
2393
+ # AI code generation
2394
+ with st.expander("🧩 Quick Code Generator"):
2395
+ st.markdown("#### Generate Animation from Description")
2396
+ st.write("Describe the animation you want to create, or provide partial code to complete.")
2397
+
2398
+ # Predefined animation ideas dropdown
2399
+ animation_ideas = [
2400
+ "Select an idea...",
2401
+ "Create a 3D animation showing a sphere morphing into a torus",
2402
+ "Show a visual proof of the Pythagorean theorem",
2403
+ "Visualize a Fourier transform converting a signal from time domain to frequency domain",
2404
+ "Create an animation explaining neural network forward propagation",
2405
+ "Illustrate the concept of integration with area under a curve"
2406
+ ]
2407
+
2408
+ selected_idea = st.selectbox(
2409
+ "Try one of these ideas",
2410
+ options=animation_ideas
2411
+ )
2412
+
2413
+ prompt_value = selected_idea if selected_idea != "Select an idea..." else ""
2414
+
2415
+ code_input = st.text_area(
2416
+ "Your Prompt or Code",
2417
+ value=prompt_value,
2418
+ placeholder="Example: Create an animation that shows a circle morphing into a square while changing color from red to blue",
2419
+ height=120
2420
+ )
2421
+
2422
+ if st.button("Generate Animation Code", key="gen_ai_code"):
2423
+ if code_input:
2424
+ with st.spinner("AI is generating your animation code..."):
2425
+ try:
2426
+ # Direct implementation of code generation
2427
+ client = st.session_state.ai_models["client"]
2428
+ model_name = st.session_state.ai_models["model_name"]
2429
+
2430
+ # Create the prompt
2431
+ prompt = f"""Write a complete Manim animation scene based on this code or idea:
2432
  {code_input}
2433
 
2434
  The code should be a complete, working Manim animation that includes:
 
2439
 
2440
  Here's the complete Manim code:
2441
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2442
 
2443
+ # Make API call directly
2444
+ from azure.ai.inference.models import UserMessage
2445
+ response = client.complete(
2446
+ messages=[
2447
+ UserMessage(prompt),
2448
+ ],
2449
+ max_tokens=1000,
2450
+ model=model_name
2451
+ )
2452
 
2453
+ # Process the response
2454
+ if response and response.choices and len(response.choices) > 0:
2455
+ completed_code = response.choices[0].message.content
2456
+
2457
+ # Extract code from markdown if present
2458
+ if "```python" in completed_code:
2459
+ completed_code = completed_code.split("```python")[1].split("```")[0]
2460
+ elif "```" in completed_code:
2461
+ completed_code = completed_code.split("```")[1].split("```")[0]
2462
+
2463
+ # Add Scene class if missing
2464
+ if "Scene" not in completed_code:
2465
+ completed_code = f"""from manim import *
2466
 
2467
  class MyScene(Scene):
2468
  def construct(self):
2469
  {completed_code}"""
2470
+
2471
+ # Store the generated code
2472
+ st.session_state.generated_code = completed_code
2473
+
2474
+ # Add to chat history
2475
+ st.session_state.chat_history.append({
2476
+ "role": "user",
2477
+ "content": f"Generate code for: {code_input}",
2478
+ "time": datetime.now().strftime("%H:%M:%S")
2479
+ })
2480
+
2481
+ st.session_state.chat_history.append({
2482
+ "role": "assistant",
2483
+ "content": f"Here's the Manim code for your request:\n\n```python\n{completed_code}\n```",
2484
+ "time": datetime.now().strftime("%H:%M:%S")
2485
+ })
2486
+ else:
2487
+ st.error("Failed to generate code. API returned an empty response.")
2488
+ except Exception as e:
2489
+ st.error(f"Error generating code: {str(e)}")
2490
+ import traceback
2491
+ st.code(traceback.format_exc())
2492
+ else:
2493
+ st.warning("Please enter a description or prompt first")
 
 
 
 
2494
 
2495
+ # AI generated code display and actions
2496
+ if "generated_code" in st.session_state and st.session_state.generated_code:
2497
+ st.markdown("#### Generated Animation Code")
2498
+ st.code(st.session_state.generated_code, language="python")
2499
+
2500
+ col_ai1, col_ai2 = st.columns(2)
2501
+ with col_ai1:
2502
+ if st.button("Use This Code", key="use_gen_code"):
2503
+ st.session_state.code = st.session_state.generated_code
2504
+ st.session_state.temp_code = st.session_state.generated_code
2505
+ # Set pending tab switch to editor tab
2506
+ st.session_state.pending_tab_switch = 0
2507
+ st.rerun()
2508
+
2509
+ with col_ai2:
2510
+ if st.button("Render Preview", key="render_preview"):
2511
+ with st.spinner("Rendering preview..."):
2512
+ video_data, status = generate_manim_video(
2513
+ st.session_state.generated_code,
2514
+ "mp4",
2515
+ "480p", # Use lowest quality for preview
2516
+ ANIMATION_SPEEDS["Normal"]
2517
  )
2518
+
2519
+ if video_data:
2520
+ st.video(video_data)
2521
+ st.download_button(
2522
+ label="Download Preview",
2523
+ data=video_data,
2524
+ file_name=f"manim_preview_{int(time.time())}.mp4",
2525
+ mime="video/mp4"
2526
+ )
2527
+ else:
2528
+ st.error(f"Failed to generate preview: {status}")
2529
  else:
2530
  st.warning("AI models not initialized. Please use the Debug Connection section to test API connectivity.")
2531
  else:
 
3364
 
3365
  if __name__ == "__main__":
3366
  main()
3367
+
3368
+ if __name__ == "__main__":
3369
+ main()