HAMMALE commited on
Commit
569b494
Β·
verified Β·
1 Parent(s): 286a919

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -53
app.py CHANGED
@@ -2,7 +2,7 @@ import os
2
  import re
3
  import json
4
  import gradio as gr
5
- from typing import List, Dict, Any
6
  import requests
7
  from datetime import datetime
8
  import ast
@@ -133,42 +133,76 @@ def download_and_load_model(progress=gr.Progress()):
133
  def get_tool_descriptions() -> str:
134
  return "\n".join([f"- {tool.name}: {tool.description}" for tool in TOOLS])
135
 
136
- THINK_ONLY_PROMPT = """You are a helpful AI assistant. Solve problems step-by-step.
137
 
138
- Format:
139
- Thought: your reasoning
140
- Answer: your final answer
 
 
 
 
 
 
 
 
141
 
142
  Question: {question}
143
 
144
- Think step by step:"""
 
 
145
 
146
- ACT_ONLY_PROMPT = """You are a helpful AI assistant with tools.
147
 
148
  Available tools:
149
  {tools}
150
 
 
 
 
 
 
 
 
 
151
  Format:
152
  Action: tool_name
153
- Action Input: input
 
 
 
 
 
 
 
154
 
155
  Question: {question}
156
 
157
  Action:"""
158
 
159
- REACT_PROMPT = """You are a helpful AI assistant with tools.
160
 
161
  Available tools:
162
  {tools}
163
 
164
- Pattern:
165
- Thought: what to do next
166
- Action: tool_name
167
- Action Input: input
168
- Observation: [result]
169
- ... repeat as needed
170
- Thought: I know the answer
171
- Answer: final answer
 
 
 
 
 
 
 
 
 
172
 
173
  Question: {question}
174
 
@@ -211,90 +245,115 @@ def call_llm(prompt: str, max_tokens: int = 500) -> str:
211
  except Exception as e:
212
  return f"Error during generation: {str(e)}"
213
 
214
- def think_only_mode(question: str) -> str:
215
  if not model_loaded:
216
- return "Error: Model not loaded."
 
 
 
 
217
 
218
- output = "**Mode: Think-Only**\n\n"
219
  response = call_llm(THINK_ONLY_PROMPT.format(question=question), max_tokens=800)
220
 
221
  if response.startswith("Error"):
222
- return output + response
 
223
 
224
  for line in response.split('\n'):
225
  if line.strip():
226
- output += f"**{line.strip()}**\n\n" if line.strip().startswith(('Thought:', 'Answer:')) else f"{line}\n\n"
 
 
 
 
 
227
 
228
- return output + "\n---\n"
229
 
230
- def act_only_mode(question: str, max_iterations: int = 5) -> str:
231
  if not model_loaded:
232
- return "Error: Model not loaded."
 
233
 
234
- output = "**Mode: Act-Only**\n\n"
235
  conversation = ACT_ONLY_PROMPT.format(question=question, tools=get_tool_descriptions())
236
 
237
  for iteration in range(max_iterations):
 
 
238
  response = call_llm(conversation, max_tokens=300)
239
 
240
  if response.startswith("Error"):
241
- return output + response
242
-
243
- output += f"**Iteration {iteration + 1}:**\n{response}\n\n"
244
 
245
  if 'Answer:' in response:
246
  match = re.search(r'Answer:\s*(.+)', response, re.IGNORECASE | re.DOTALL)
247
  if match:
248
- output += f"**Final Answer:** {match.group(1).strip()}\n\n"
249
  break
250
 
251
  action_name, action_input = parse_action(response)
252
  if action_name and action_input:
253
- output += f"**Action:** {action_name}\n**Input:** {action_input}\n\n"
 
 
 
254
  observation = call_tool(action_name, action_input)
255
- output += f"**Observation:** {observation}\n\n"
 
256
  conversation += f"\n{response}\nObservation: {observation}\n\n"
257
  else:
258
- output += f"No valid action found in iteration {iteration + 1}.\n\n"
259
  break
260
 
261
- return output + "\n---\n"
262
 
263
- def react_mode(question: str, max_iterations: int = 5) -> str:
264
  if not model_loaded:
265
- return "Error: Model not loaded."
 
266
 
267
- output = "**Mode: ReAct**\n\n"
268
  conversation = REACT_PROMPT.format(question=question, tools=get_tool_descriptions())
269
 
270
  for iteration in range(max_iterations):
 
 
271
  response = call_llm(conversation, max_tokens=400)
272
 
273
  if response.startswith("Error"):
274
- return output + response
275
-
276
- output += f"**Iteration {iteration + 1}:**\n"
277
 
 
278
  for thought in re.findall(r'Thought:\s*(.+?)(?=\n(?:Action:|Answer:|$))', response, re.IGNORECASE | re.DOTALL):
279
- output += f"**Thought:** {thought.strip()}\n\n"
280
 
 
281
  if 'Answer:' in response:
282
  match = re.search(r'Answer:\s*(.+)', response, re.IGNORECASE | re.DOTALL)
283
  if match:
284
- output += f"**Answer:** {match.group(1).strip()}\n\n"
285
  break
286
 
 
287
  action_name, action_input = parse_action(response)
288
  if action_name and action_input:
289
- output += f"**Action:** {action_name}\n**Input:** {action_input}\n\n"
 
 
 
290
  observation = call_tool(action_name, action_input)
291
- output += f"**Observation:** {observation}\n\n"
 
292
  conversation += f"\n{response}\nObservation: {observation}\n\nThought:"
293
  else:
294
- output += f"No action found in iteration {iteration + 1}.\n{response}\n\n"
 
295
  break
296
 
297
- return output + "\n---\n"
298
 
299
  EXAMPLES = [
300
  "What is 25 * 47?",
@@ -304,15 +363,31 @@ EXAMPLES = [
304
  ]
305
 
306
  def run_comparison(question: str, mode: str):
 
 
 
 
 
307
  if mode == "Think-Only":
308
- return think_only_mode(question), "", ""
 
 
 
 
309
  elif mode == "Act-Only":
310
- return "", act_only_mode(question), ""
 
 
 
 
311
  elif mode == "ReAct":
312
- return "", "", react_mode(question)
313
- elif mode == "All (Compare)":
314
- return think_only_mode(question), act_only_mode(question), react_mode(question)
315
- return "Invalid mode.", "", ""
 
 
 
316
 
317
  with gr.Blocks(title="LLM Reasoning Modes") as demo:
318
  gr.Markdown("# LLM Reasoning Modes Comparison\n\n**Model:** openai/gpt-oss-20b\n\n**Tools:** DuckDuckGo | Wikipedia | Weather | Calculator | Python")
@@ -324,7 +399,7 @@ with gr.Blocks(title="LLM Reasoning Modes") as demo:
324
  with gr.Row():
325
  with gr.Column(scale=3):
326
  question_input = gr.Textbox(label="Question", lines=3)
327
- mode_dropdown = gr.Dropdown(choices=["Think-Only", "Act-Only", "ReAct", "All (Compare)"], value="Think-Only", label="Mode")
328
  submit_btn = gr.Button("Run", variant="primary", size="lg")
329
  with gr.Column(scale=1):
330
  gr.Markdown("**Examples**")
 
2
  import re
3
  import json
4
  import gradio as gr
5
+ from typing import List, Dict, Any, Generator
6
  import requests
7
  from datetime import datetime
8
  import ast
 
133
  def get_tool_descriptions() -> str:
134
  return "\n".join([f"- {tool.name}: {tool.description}" for tool in TOOLS])
135
 
136
+ THINK_ONLY_PROMPT = """You are an expert problem solver. Use your knowledge and reasoning to answer questions.
137
 
138
+ You must show your complete reasoning process using this format:
139
+ Thought: [Explain what you're thinking and why]
140
+ Thought: [Continue your reasoning, breaking down the problem]
141
+ Thought: [Build toward the solution step by step]
142
+ Answer: [Your final, complete answer]
143
+
144
+ Important:
145
+ - Show multiple thought steps
146
+ - Break down complex problems
147
+ - Explain your reasoning clearly
148
+ - Only provide the Answer when you're certain
149
 
150
  Question: {question}
151
 
152
+ Let me think through this step by step:
153
+
154
+ Thought:"""
155
 
156
+ ACT_ONLY_PROMPT = """You are an AI agent with access to external tools. You MUST use tools to find information.
157
 
158
  Available tools:
159
  {tools}
160
 
161
+ You MUST respond ONLY with actions - no thinking out loud:
162
+ Action: [exact tool name]
163
+ Action Input: [specific input for the tool]
164
+
165
+ After receiving the Observation, you can:
166
+ - Call another tool if you need more information
167
+ - Provide the final Answer when you have enough information
168
+
169
  Format:
170
  Action: tool_name
171
+ Action Input: input_string
172
+
173
+ Then after observation:
174
+ Action: another_tool
175
+ Action Input: another_input
176
+
177
+ OR
178
+ Answer: [final answer based on observations]
179
 
180
  Question: {question}
181
 
182
  Action:"""
183
 
184
+ REACT_PROMPT = """You are an expert AI agent that combines reasoning with tool usage (ReAct paradigm).
185
 
186
  Available tools:
187
  {tools}
188
 
189
+ You MUST alternate between thinking and acting:
190
+
191
+ 1. Thought: [Reason about what information you need and which tool to use]
192
+ 2. Action: [exact tool name]
193
+ 3. Action Input: [specific input]
194
+ 4. Observation: [tool result - will be provided to you]
195
+ 5. Thought: [Analyze the observation and decide next steps]
196
+ 6. Repeat 2-5 until you have enough information
197
+ 7. Thought: [Final reasoning with all gathered information]
198
+ 8. Answer: [Complete final answer]
199
+
200
+ Rules:
201
+ - ALWAYS start with a Thought explaining your strategy
202
+ - After each Observation, think about what you learned
203
+ - Use multiple tools if needed
204
+ - Only give Answer when you have sufficient information
205
+ - Be specific in your Action Inputs
206
 
207
  Question: {question}
208
 
 
245
  except Exception as e:
246
  return f"Error during generation: {str(e)}"
247
 
248
+ def think_only_mode(question: str) -> Generator[str, None, None]:
249
  if not model_loaded:
250
+ yield "❌ **Error: Model not loaded. Click 'Download & Load Model' first.**\n\n"
251
+ return
252
+
253
+ yield "🧠 **Mode: Think-Only (Chain-of-Thought)**\n\n"
254
+ yield "πŸ’­ Generating reasoning steps...\n\n"
255
 
 
256
  response = call_llm(THINK_ONLY_PROMPT.format(question=question), max_tokens=800)
257
 
258
  if response.startswith("Error"):
259
+ yield f"❌ {response}\n\n"
260
+ return
261
 
262
  for line in response.split('\n'):
263
  if line.strip():
264
+ if line.strip().startswith('Thought:'):
265
+ yield f"πŸ’­ **{line.strip()}**\n\n"
266
+ elif line.strip().startswith('Answer:'):
267
+ yield f"βœ… **{line.strip()}**\n\n"
268
+ else:
269
+ yield f"{line}\n\n"
270
 
271
+ yield "\n---\nβœ“ **Completed**\n"
272
 
273
+ def act_only_mode(question: str, max_iterations: int = 5) -> Generator[str, None, None]:
274
  if not model_loaded:
275
+ yield "❌ **Error: Model not loaded. Click 'Download & Load Model' first.**\n\n"
276
+ return
277
 
278
+ yield "πŸ”§ **Mode: Act-Only (Tool Use Only)**\n\n"
279
  conversation = ACT_ONLY_PROMPT.format(question=question, tools=get_tool_descriptions())
280
 
281
  for iteration in range(max_iterations):
282
+ yield f"πŸ”„ **Iteration {iteration + 1}**\n\n"
283
+
284
  response = call_llm(conversation, max_tokens=300)
285
 
286
  if response.startswith("Error"):
287
+ yield f"❌ {response}\n\n"
288
+ return
 
289
 
290
  if 'Answer:' in response:
291
  match = re.search(r'Answer:\s*(.+)', response, re.IGNORECASE | re.DOTALL)
292
  if match:
293
+ yield f"βœ… **Answer:** {match.group(1).strip()}\n\n"
294
  break
295
 
296
  action_name, action_input = parse_action(response)
297
  if action_name and action_input:
298
+ yield f"πŸ”§ **Action:** `{action_name}`\n"
299
+ yield f"πŸ“ **Action Input:** {action_input}\n\n"
300
+
301
+ yield f"⏳ Executing tool...\n\n"
302
  observation = call_tool(action_name, action_input)
303
+
304
+ yield f"πŸ‘οΈ **Observation:** {observation}\n\n"
305
  conversation += f"\n{response}\nObservation: {observation}\n\n"
306
  else:
307
+ yield f"⚠️ No valid action found. Response: {response}\n\n"
308
  break
309
 
310
+ yield "\n---\nβœ“ **Completed**\n"
311
 
312
+ def react_mode(question: str, max_iterations: int = 5) -> Generator[str, None, None]:
313
  if not model_loaded:
314
+ yield "❌ **Error: Model not loaded. Click 'Download & Load Model' first.**\n\n"
315
+ return
316
 
317
+ yield "πŸ€– **Mode: ReAct (Reasoning + Acting)**\n\n"
318
  conversation = REACT_PROMPT.format(question=question, tools=get_tool_descriptions())
319
 
320
  for iteration in range(max_iterations):
321
+ yield f"πŸ”„ **Step {iteration + 1}**\n\n"
322
+
323
  response = call_llm(conversation, max_tokens=400)
324
 
325
  if response.startswith("Error"):
326
+ yield f"❌ {response}\n\n"
327
+ return
 
328
 
329
+ # Extract and display thoughts
330
  for thought in re.findall(r'Thought:\s*(.+?)(?=\n(?:Action:|Answer:|$))', response, re.IGNORECASE | re.DOTALL):
331
+ yield f"πŸ’­ **Thought:** {thought.strip()}\n\n"
332
 
333
+ # Check for final answer
334
  if 'Answer:' in response:
335
  match = re.search(r'Answer:\s*(.+)', response, re.IGNORECASE | re.DOTALL)
336
  if match:
337
+ yield f"βœ… **Answer:** {match.group(1).strip()}\n\n"
338
  break
339
 
340
+ # Parse and execute action
341
  action_name, action_input = parse_action(response)
342
  if action_name and action_input:
343
+ yield f"πŸ”§ **Action:** `{action_name}`\n"
344
+ yield f"πŸ“ **Action Input:** {action_input}\n\n"
345
+
346
+ yield f"⏳ Executing tool...\n\n"
347
  observation = call_tool(action_name, action_input)
348
+
349
+ yield f"πŸ‘οΈ **Observation:** {observation}\n\n"
350
  conversation += f"\n{response}\nObservation: {observation}\n\nThought:"
351
  else:
352
+ if 'Answer:' not in response:
353
+ yield f"⚠️ No action found. Response: {response}\n\n"
354
  break
355
 
356
+ yield "\n---\nβœ“ **Completed**\n"
357
 
358
  EXAMPLES = [
359
  "What is 25 * 47?",
 
363
  ]
364
 
365
  def run_comparison(question: str, mode: str):
366
+ """Run selected mode with real-time streaming."""
367
+ if not question.strip():
368
+ yield "Please enter a question.", "", ""
369
+ return
370
+
371
  if mode == "Think-Only":
372
+ think_out = ""
373
+ for chunk in think_only_mode(question):
374
+ think_out += chunk
375
+ yield think_out, "", ""
376
+
377
  elif mode == "Act-Only":
378
+ act_out = ""
379
+ for chunk in act_only_mode(question):
380
+ act_out += chunk
381
+ yield "", act_out, ""
382
+
383
  elif mode == "ReAct":
384
+ react_out = ""
385
+ for chunk in react_mode(question):
386
+ react_out += chunk
387
+ yield "", "", react_out
388
+
389
+ else:
390
+ yield "Invalid mode selected.", "", ""
391
 
392
  with gr.Blocks(title="LLM Reasoning Modes") as demo:
393
  gr.Markdown("# LLM Reasoning Modes Comparison\n\n**Model:** openai/gpt-oss-20b\n\n**Tools:** DuckDuckGo | Wikipedia | Weather | Calculator | Python")
 
399
  with gr.Row():
400
  with gr.Column(scale=3):
401
  question_input = gr.Textbox(label="Question", lines=3)
402
+ mode_dropdown = gr.Dropdown(choices=["Think-Only", "Act-Only", "ReAct"], value="ReAct", label="Mode")
403
  submit_btn = gr.Button("Run", variant="primary", size="lg")
404
  with gr.Column(scale=1):
405
  gr.Markdown("**Examples**")