omarash2016 commited on
Commit
a8be61d
·
verified ·
1 Parent(s): bc3fe15

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -23
app.py CHANGED
@@ -11,7 +11,15 @@ from langchain_core.messages import HumanMessage, SystemMessage
11
  # --- Configuration ---
12
  NEBIUS_API_KEY = os.getenv("NEBIUS_API_KEY")
13
  NEBIUS_BASE_URL = "https://api.studio.nebius.ai/v1/"
14
- MODEL_NAME = "openai/gpt-oss-120b"
 
 
 
 
 
 
 
 
15
 
16
  # --- System Prompt ---
17
  SYSTEM_PROMPT = """You are a 'Vibe Coding' Python Tutor.
@@ -77,9 +85,9 @@ def parse_agent_response(full_text):
77
 
78
  return chat_content, videos, articles, quiz
79
 
80
- async def run_tutor_dashboard(user_message):
81
  """
82
- Main function to run the agent loop.
83
  """
84
  server_params = StdioServerParameters(
85
  command=sys.executable,
@@ -96,22 +104,33 @@ async def run_tutor_dashboard(user_message):
96
  api_key=NEBIUS_API_KEY,
97
  base_url=NEBIUS_BASE_URL,
98
  model=MODEL_NAME,
99
- temperature=0.7
 
100
  )
101
 
102
  agent_executor = create_react_agent(llm, tools)
103
 
104
- # Prepend the SystemMessage to ensure the agent follows instructions
105
  inputs = {
106
  "messages": [
107
  SystemMessage(content=SYSTEM_PROMPT),
108
  HumanMessage(content=user_message)
109
  ]
110
  }
111
- response = await agent_executor.ainvoke(inputs)
112
- final_text = response["messages"][-1].content
113
-
114
- return parse_agent_response(final_text)
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  # --- Gradio Dashboard UI ---
117
  # Professional "Slate" theme
@@ -144,7 +163,7 @@ with gr.Blocks(title="AI Python Tutor", theme=theme, fill_height=True) as demo:
144
 
145
  chatbot = gr.Chatbot(
146
  height=600,
147
- show_label=False, # Removed built-in label to match custom header
148
  type="messages",
149
  bubble_full_width=False,
150
  show_copy_button=True,
@@ -211,17 +230,26 @@ with gr.Blocks(title="AI Python Tutor", theme=theme, fill_height=True) as demo:
211
  # Placeholder for AI
212
  history.append({"role": "assistant", "content": "Thinking..."})
213
 
214
- # Yield placeholders to ALL output boxes (Side AND Bottom)
215
- # Structure: history, msg, 3x Side Boxes, 3x Bottom Boxes
216
  yield history, "", "", "", "", "", "", ""
217
 
218
- # Run Agent
219
- chat_text, video_text, article_text, quiz_text = await run_tutor_dashboard(user_message)
220
 
221
- # Update AI response
222
- history[-1]["content"] = chat_text
 
 
 
 
 
 
 
 
 
 
223
 
224
- # Yield final content to ALL output boxes
 
225
  yield history, "", video_text, article_text, quiz_text, video_text, article_text, quiz_text
226
 
227
  # --- Focus Mode Logic ---
@@ -229,14 +257,9 @@ with gr.Blocks(title="AI Python Tutor", theme=theme, fill_height=True) as demo:
229
 
230
  def toggle_fullscreen(current_state):
231
  new_state = not current_state
232
- # If new_state is True (Fullscreen): Hide side col, Show bottom row
233
- # If False (Normal): Show side col, Hide bottom row
234
-
235
  side_visible = not new_state
236
  bottom_visible = new_state
237
-
238
  btn_text = "↩ Exit Focus" if new_state else "⛶ Focus Mode"
239
-
240
  return new_state, gr.Column(visible=side_visible), gr.Row(visible=bottom_visible), btn_text
241
 
242
  fullscreen_btn.click(
@@ -245,7 +268,7 @@ with gr.Blocks(title="AI Python Tutor", theme=theme, fill_height=True) as demo:
245
  outputs=[is_fullscreen, right_col, bottom_dashboard, fullscreen_btn]
246
  )
247
 
248
- # Actions - We must map outputs to BOTH side and bottom components
249
  outputs_list = [
250
  chatbot, msg,
251
  video_box_side, article_box_side, quiz_box_side,
 
11
  # --- Configuration ---
12
  NEBIUS_API_KEY = os.getenv("NEBIUS_API_KEY")
13
  NEBIUS_BASE_URL = "https://api.studio.nebius.ai/v1/"
14
+
15
+ # OPTION 1: Best Balance (Speed + Intelligence) -> RECOMMENDED
16
+ MODEL_NAME = "Qwen/Qwen3-30B-A3B-Thinking-2507"
17
+
18
+ # OPTION 2: Maximum Speed (Good for simple tasks)
19
+ # MODEL_NAME = "Qwen/Qwen3-30B-A3B-Thinking-2507"
20
+
21
+ # OPTION 3: Maximum Intelligence (Slowest)
22
+ # MODEL_NAME = "openai/gpt-oss-120b"
23
 
24
  # --- System Prompt ---
25
  SYSTEM_PROMPT = """You are a 'Vibe Coding' Python Tutor.
 
85
 
86
  return chat_content, videos, articles, quiz
87
 
88
+ async def run_tutor_dashboard_stream(user_message):
89
  """
90
+ Runs the agent loop and yields streaming text updates.
91
  """
92
  server_params = StdioServerParameters(
93
  command=sys.executable,
 
104
  api_key=NEBIUS_API_KEY,
105
  base_url=NEBIUS_BASE_URL,
106
  model=MODEL_NAME,
107
+ temperature=0.7,
108
+ streaming=True # Critical for speed
109
  )
110
 
111
  agent_executor = create_react_agent(llm, tools)
112
 
 
113
  inputs = {
114
  "messages": [
115
  SystemMessage(content=SYSTEM_PROMPT),
116
  HumanMessage(content=user_message)
117
  ]
118
  }
119
+
120
+ # Stream the response token by token
121
+ final_text = ""
122
+ async for event in agent_executor.astream_events(inputs, version="v1"):
123
+ kind = event["event"]
124
+
125
+ # Stream actual tokens from the LLM
126
+ if kind == "on_chat_model_stream":
127
+ content = event["data"]["chunk"].content
128
+ if content:
129
+ final_text += content
130
+ yield final_text
131
+
132
+ # Once done, yield the final text one last time to ensure completeness
133
+ yield final_text
134
 
135
  # --- Gradio Dashboard UI ---
136
  # Professional "Slate" theme
 
163
 
164
  chatbot = gr.Chatbot(
165
  height=600,
166
+ show_label=False,
167
  type="messages",
168
  bubble_full_width=False,
169
  show_copy_button=True,
 
230
  # Placeholder for AI
231
  history.append({"role": "assistant", "content": "Thinking..."})
232
 
233
+ # Initial yield
 
234
  yield history, "", "", "", "", "", "", ""
235
 
236
+ full_response = ""
 
237
 
238
+ # STREAMING LOOP
239
+ async for chunk in run_tutor_dashboard_stream(user_message):
240
+ full_response = chunk
241
+
242
+ # Update chat history LIVE
243
+ history[-1]["content"] = full_response
244
+
245
+ # Yield update just for chat, keeping others blank for now
246
+ yield history, "", "", "", "", "", "", ""
247
+
248
+ # Final Parse (Split into 4 components)
249
+ chat_text, video_text, article_text, quiz_text = parse_agent_response(full_response)
250
 
251
+ # Update everything one last time
252
+ history[-1]["content"] = chat_text
253
  yield history, "", video_text, article_text, quiz_text, video_text, article_text, quiz_text
254
 
255
  # --- Focus Mode Logic ---
 
257
 
258
  def toggle_fullscreen(current_state):
259
  new_state = not current_state
 
 
 
260
  side_visible = not new_state
261
  bottom_visible = new_state
 
262
  btn_text = "↩ Exit Focus" if new_state else "⛶ Focus Mode"
 
263
  return new_state, gr.Column(visible=side_visible), gr.Row(visible=bottom_visible), btn_text
264
 
265
  fullscreen_btn.click(
 
268
  outputs=[is_fullscreen, right_col, bottom_dashboard, fullscreen_btn]
269
  )
270
 
271
+ # Actions
272
  outputs_list = [
273
  chatbot, msg,
274
  video_box_side, article_box_side, quiz_box_side,