shukdevdattaEX commited on
Commit
598b26d
Β·
verified Β·
1 Parent(s): 4bd696b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -129
app.py CHANGED
@@ -26,20 +26,15 @@ class ChutesClient:
26
  "Content-Type": "application/json"
27
  }
28
 
29
- # Prepare the body
30
  body = {
31
  "model": kwargs.get("model", "openai/gpt-oss-20b"),
32
  "messages": kwargs.get("messages", []),
33
- "stream": False, # Non-streaming for simplicity
34
  "max_tokens": kwargs.get("max_tokens", 1024),
35
  "temperature": kwargs.get("temperature", 0.7)
36
  }
37
 
38
- # Add tool calls if present
39
- if "tools" in kwargs and kwargs["tools"]:
40
- body["tools"] = kwargs["tools"]
41
- body["tool_choice"] = kwargs.get("tool_choice", "auto")
42
-
43
  async with aiohttp.ClientSession() as session:
44
  async with session.post(
45
  f"{self.base_url}/chat/completions",
@@ -80,7 +75,7 @@ class CreativeAgenticAI:
80
  self.available_models = {
81
  "compound-beta": {"supports_web_search": True, "supports_browser_search": False, "api": "groq"},
82
  "compound-beta-mini": {"supports_web_search": True, "supports_browser_search": False, "api": "groq"},
83
- "openai/gpt-oss-20b": {"supports_web_search": False, "supports_browser_search": True, "api": "chutes"},
84
  }
85
 
86
  async def chat(self, message: str,
@@ -125,7 +120,7 @@ IMPORTANT: When you search the web and find information, you MUST:
125
  domain_context = f"\nAvoid searching these domains: {', '.join(exclude_domains)}. Search everywhere else on the web."
126
 
127
  search_instruction = ""
128
- if search_type == "browser_search":
129
  search_instruction = "\nUse browser search tools to find the most current and relevant information from the web."
130
  elif search_type == "web_search":
131
  search_instruction = "\nUse web search capabilities to find relevant information."
@@ -147,11 +142,7 @@ IMPORTANT: When you search the web and find information, you MUST:
147
 
148
  # Build messages
149
  messages = [{"role": "system", "content": system_prompt}]
150
-
151
- # Add conversation history (last 10 exchanges)
152
- messages.extend(self.conversation_history[-20:]) # Last 10 user-assistant pairs
153
-
154
- # Add current message with context
155
  enhanced_message = message
156
  if include_domains or exclude_domains:
157
  filter_context = []
@@ -178,20 +169,13 @@ IMPORTANT: When you search the web and find information, you MUST:
178
  if exclude_domains and exclude_domains[0].strip():
179
  params["exclude_domains"] = [domain.strip() for domain in exclude_domains if domain.strip()]
180
 
181
- # Add tools based on search type and model capabilities
182
  tools = []
183
  tool_choice = None
184
-
185
- if search_type == "browser_search" and self._supports_browser_search():
186
- tools = [{"type": "browser_search"}]
187
- tool_choice = "required" if force_search else "auto"
188
- elif search_type == "auto":
189
- if self._supports_browser_search():
190
- tools = [{"type": "browser_search"}]
191
  tool_choice = "required" if force_search else "auto"
192
- elif force_search and self._supports_browser_search():
193
- tools = [{"type": "browser_search"}]
194
- tool_choice = "required"
195
 
196
  if tools:
197
  params["tools"] = tools
@@ -201,14 +185,17 @@ IMPORTANT: When you search the web and find information, you MUST:
201
  # Make the API call based on model
202
  if self.available_models[self.model]["api"] == "chutes":
203
  response = await self.chutes_client.chat_completions_create(**params)
 
 
 
204
  else:
205
  params["max_completion_tokens"] = params.pop("max_tokens", None)
206
  response = self.groq_client.chat.completions.create(**params)
 
 
207
 
208
- content = response["choices"][0]["message"]["content"]
209
-
210
- # Extract tool usage information and enhance it
211
- tool_info = self._extract_tool_info(response)
212
 
213
  # Process content to enhance citations
214
  processed_content = self._enhance_citations(content, tool_info)
@@ -217,8 +204,7 @@ IMPORTANT: When you search the web and find information, you MUST:
217
  self.conversation_history.append({"role": "user", "content": message})
218
  self.conversation_history.append({"role": "assistant", "content": processed_content})
219
 
220
- # Create response object
221
- response_data = {
222
  "content": processed_content,
223
  "timestamp": datetime.now().isoformat(),
224
  "model": self.model,
@@ -233,8 +219,6 @@ IMPORTANT: When you search the web and find information, you MUST:
233
  }
234
  }
235
 
236
- return response_data
237
-
238
  except Exception as e:
239
  error_msg = f"Error: {str(e)}"
240
  self.conversation_history.append({"role": "user", "content": message})
@@ -256,7 +240,7 @@ IMPORTANT: When you search the web and find information, you MUST:
256
  """Check if current model supports browser search tools"""
257
  return self.available_models.get(self.model, {}).get("supports_browser_search", False)
258
 
259
- def _extract_tool_info(self, response) -> Dict:
260
  """Extract tool usage information in a JSON serializable format"""
261
  tool_info = {
262
  "tools_used": [],
@@ -264,8 +248,8 @@ IMPORTANT: When you search the web and find information, you MUST:
264
  "sources_found": []
265
  }
266
 
267
- # Check for executed_tools attribute (compound models)
268
- if hasattr(response.choices[0].message, 'executed_tools'):
269
  tools = response.choices[0].message.executed_tools
270
  if tools:
271
  for tool in tools:
@@ -273,31 +257,27 @@ IMPORTANT: When you search the web and find information, you MUST:
273
  "tool_type": getattr(tool, "type", "unknown"),
274
  "tool_name": getattr(tool, "name", "unknown"),
275
  }
276
-
277
  if hasattr(tool, "input"):
278
  tool_input = str(tool.input)
279
  tool_dict["input"] = tool_input
280
  if "search" in tool_dict["tool_name"].lower():
281
  tool_info["search_queries"].append(tool_input)
282
-
283
  if hasattr(tool, "output"):
284
  tool_output = str(tool.output)
285
  tool_dict["output"] = tool_output
286
  urls = self._extract_urls(tool_output)
287
  tool_info["sources_found"].extend(urls)
288
-
289
  tool_info["tools_used"].append(tool_dict)
290
 
291
- # Check for tool_calls attribute (browser search models)
292
- if hasattr(response.choices[0].message, 'tool_calls') and response.choices[0].message.tool_calls:
293
- for tool_call in response.choices[0].message.tool_calls:
294
  tool_dict = {
295
- "tool_type": tool_call.type if hasattr(tool_call, 'type') else "browser_search",
296
- "tool_name": tool_call.function.name if hasattr(tool_call, 'function') else "browser_search",
297
- "tool_id": tool_call.id if hasattr(tool_call, 'id') else None
298
  }
299
-
300
- if hasattr(tool_call, 'function') and hasattr(tool_call.function, 'arguments'):
301
  try:
302
  args = json.loads(tool_call.function.arguments) if isinstance(tool_call.function.arguments, str) else tool_call.function.arguments
303
  tool_dict["arguments"] = args
@@ -305,7 +285,6 @@ IMPORTANT: When you search the web and find information, you MUST:
305
  tool_info["search_queries"].append(args["query"])
306
  except:
307
  tool_dict["arguments"] = str(tool_call.function.arguments)
308
-
309
  tool_info["tools_used"].append(tool_dict)
310
 
311
  return tool_info
@@ -326,7 +305,6 @@ IMPORTANT: When you search the web and find information, you MUST:
326
  for i, url in enumerate(tool_info["sources_found"][:10], 1):
327
  domain = self._extract_domain(url)
328
  sources_section += f"{i}. [{domain}]({url})\n"
329
-
330
  content += sources_section
331
 
332
  return content
@@ -378,7 +356,6 @@ async def validate_api_keys(groq_api_key: str, chutes_api_key: str, model: str)
378
  return "❌ Please enter a valid Groq API key for the selected model"
379
 
380
  try:
381
- # Test API keys based on model
382
  if model == "openai/gpt-oss-20b":
383
  chutes_client = ChutesClient(api_key=chutes_api_key)
384
  await chutes_client.chat_completions_create(
@@ -394,7 +371,6 @@ async def validate_api_keys(groq_api_key: str, chutes_api_key: str, model: str)
394
  max_tokens=10
395
  )
396
 
397
- # Create AI instance
398
  ai_instance = CreativeAgenticAI(groq_api_key=groq_api_key, chutes_api_key=chutes_api_key, model=model)
399
  api_key_status = "Valid βœ…"
400
 
@@ -599,7 +575,7 @@ def create_gradio_app():
599
  gr.HTML("""
600
  <div class="header">
601
  <h1>πŸ€– NeuroScope-AI Enhanced</h1>
602
- <p>Powered by Groq and Chutes Models with Web Search, Browser Search & Agentic Capabilities</p>
603
  </div>
604
  """)
605
 
@@ -608,9 +584,9 @@ def create_gradio_app():
608
  gr.Markdown("""
609
  **Enhanced with Multiple Search Capabilities:**
610
  - 🧠 **Intelligence** (Neuro): Advanced AI reasoning across multiple models
611
- - πŸ” **Precision Search** (Scope): Domain filtering + Browser search tools
612
  - πŸ€– **AI Capabilities** (AI): Agentic behavior with tool usage
613
- - ⚑ **Dual Search**: Web search (compound models) + Browser search (other models)
614
  - 🎯 **Model Flexibility**: Choose the right model for your task
615
  """)
616
 
@@ -627,10 +603,10 @@ def create_gradio_app():
627
  <li><strong>Features:</strong> Include/exclude domains, autonomous web search</li>
628
  </ul>
629
 
630
- <h4>πŸ” Browser Search Models (Chutes API)</h4>
631
  <ul>
632
- <li><strong>openai/gpt-oss-20b:</strong> Fast browser search capabilities</li>
633
- <li><strong>Features:</strong> Real-time browser search, current information</li>
634
  </ul>
635
  </div>
636
 
@@ -638,10 +614,9 @@ def create_gradio_app():
638
  <h3>πŸ”— Enhanced Citation System</h3>
639
  <p>All models now include:</p>
640
  <ul>
641
- <li><strong>Automatic Source Citations:</strong> Clickable links to sources</li>
642
  <li><strong>Sources Used Section:</strong> Dedicated section showing all websites</li>
643
  <li><strong>Search Type Indication:</strong> Shows which search method was used</li>
644
- <li><strong>Tool Usage Display:</strong> Transparent about AI's research process</li>
645
  </ul>
646
  </div>
647
  """)
@@ -669,7 +644,7 @@ def create_gradio_app():
669
  ],
670
  label="🧠 Model Selection",
671
  value="compound-beta",
672
- info="Choose based on your search needs"
673
  )
674
  with gr.Column(scale=1):
675
  connect_btn = gr.Button("πŸ”— Connect", variant="primary", size="lg")
@@ -710,7 +685,7 @@ def create_gradio_app():
710
  with gr.Accordion("πŸ” Search Settings", open=False, elem_id="neuroscope-accordion"):
711
  with gr.Row():
712
  search_type = gr.Radio(
713
- choices=["auto", "web_search", "browser_search", "none"],
714
  label="🎯 Search Type",
715
  value="auto",
716
  info="Choose search method (auto = model decides)"
@@ -718,7 +693,7 @@ def create_gradio_app():
718
  force_search = gr.Checkbox(
719
  label="⚑ Force Search",
720
  value=False,
721
- info="Force AI to search even for general questions"
722
  )
723
 
724
  model_selection.change(
@@ -788,18 +763,15 @@ def create_gradio_app():
788
  - Best for: Research papers, academic sources, filtered searches
789
  - API: Groq
790
 
791
- **For Current Events & Real-Time Information:**
792
- - `openai/gpt-oss-20b` with browser search
793
- - Best for: News, current events, real-time data
794
- - API: Chutes
795
-
796
  **For General Knowledge & Creative Tasks:**
797
- - Any model with search type = "auto" or "none"
798
- - Best for: Creative writing, general questions, analysis
 
799
 
800
  **For Programming & Technical Documentation:**
801
- - `openai/gpt-oss-20b` with browser search, or compound models with tech domains
802
  - Best for: Code help, documentation, technical guides
 
803
  """)
804
 
805
  with gr.Accordion("πŸ”— Common Domain Examples", open=False, elem_id="neuroscope-accordion"):
@@ -827,20 +799,19 @@ def create_gradio_app():
827
  gr.Markdown("""
828
  ### πŸš€ Getting Started
829
  1. **Enter your API Keys** - Groq from [console.groq.com](https://console.groq.com/), Chutes for openai/gpt-oss-20b
830
- 2. **Select a model** - Choose based on your search needs:
831
  - **Compound models** (Groq): For web search with domain filtering
832
- - **openai/gpt-oss-20b** (Chutes): For browser search with real-time data
833
- 3. **Configure search settings** - Choose search type and options
834
  4. **Click Connect** - Validate your keys and connect to the AI
835
  5. **Start chatting!** - Type your message and get intelligent responses with citations
836
 
837
  ### 🎯 Key Features
838
- - **Dual Search Capabilities**: Web search (compound) + Browser search (Chutes)
839
- - **Smart Citations**: Automatic source linking and citation formatting
840
- - **Domain Filtering**: Control which websites the AI searches (compound models)
841
- - **Real-time Search**: Get current information with browser search tools
842
  - **Model Flexibility**: Choose the right model and API for your task
843
- - **Enhanced Tool Visibility**: See exactly what search tools were used
844
 
845
  ### πŸ’‘ Tips for Best Results
846
 
@@ -849,13 +820,8 @@ def create_gradio_app():
849
  - Include academic domains (*.edu, arxiv.org) for scholarly sources
850
  - Use "Force Search" for the most current information
851
 
852
- **For Current Events:**
853
- - Use openai/gpt-oss-20b (Chutes)
854
- - Set search type to "browser_search"
855
- - Enable "Force Search" for real-time data
856
-
857
  **For Creative Tasks:**
858
- - Any model works well
859
  - Set search type to "none" for purely creative responses
860
  - Use higher temperature (0.8-1.0) for more creativity
861
  """)
@@ -863,7 +829,7 @@ def create_gradio_app():
863
  with gr.Accordion("🎯 Sample Examples to Test Enhanced Search", open=False, elem_id="neuroscope-accordion"):
864
  gr.Markdown("""
865
  <div class="example-box">
866
- <h4>πŸ”¬ Research & Analysis (Test Different Models)</h4>
867
 
868
  **Compound Model + Domain Filtering (Groq):**
869
  - Query: "What are the latest breakthroughs in quantum computing?"
@@ -871,48 +837,35 @@ def create_gradio_app():
871
  - Include domains: "arxiv.org, *.edu, nature.com"
872
  - Search type: web_search
873
 
874
- **Browser Search Model (Chutes):**
875
- - Same query with openai/gpt-oss-20b
876
- - Search type: browser_search
877
- - Force search: enabled
878
-
879
- <h4>πŸ“° Current Events (Browser Search Excellence)</h4>
880
 
881
- **Real-time News:**
882
- - Query: "What happened in AI industry this week?"
883
- - Model: openai/gpt-oss-20b (Chutes)
884
- - Search type: browser_search
885
- - Force search: enabled
886
 
887
- **Compare with Web Search:**
888
- - Same query with compound-beta (Groq)
889
- - Include domains: "reuters.com, bbc.com, techcrunch.com"
890
-
891
- <h4>πŸ’» Programming & Tech (Model Comparison)</h4>
892
-
893
- **Technical Documentation:**
894
  - Query: "How to implement OAuth 2.0 in Python Flask?"
895
- - Try with both model types:
896
- - compound-beta with "github.com, docs.python.org, stackoverflow.com"
897
- - openai/gpt-oss-20b (Chutes) with browser_search
 
 
 
 
898
 
899
- <h4>🎨 Creative Tasks (No Search Needed)</h4>
900
  - Query: "Write a short story about AI and humans working together"
901
  - Any model with search_type: "none"
902
  - Higher temperature (0.8-1.0)
903
 
904
- <h4>πŸ“Š Business Analysis (Filtered vs Real-time)</h4>
905
 
906
- **Financial Data (Real-time):**
907
- - Query: "Current cryptocurrency market trends"
908
- - Model: openai/gpt-oss-20b (Chutes)
909
- - Search type: browser_search
910
- - Force search: enabled
911
-
912
- **Business Analysis (Filtered):**
913
  - Query: "Cryptocurrency adoption in enterprise"
914
- - Model: compound-beta (Groq)
915
  - Include domains: "bloomberg.com, wsj.com, harvard.edu"
 
916
  </div>
917
  """)
918
 
@@ -935,29 +888,28 @@ def create_gradio_app():
935
 
936
  with gr.Accordion("πŸš€ About This Enhanced NeuroScope AI", open=True, elem_id="neuroscope-accordion"):
937
  gr.Markdown("""
938
- **Enhanced Creative Agentic AI Chat Tool** with dual search capabilities:
939
 
940
  ### πŸ†• **New in This Version:**
941
- - πŸ” **Browser Search Integration**: Real-time search with Chutes API
942
- - 🌐 **Dual Search System**: Web search (Groq) + Browser search (Chutes)
943
  - 🎯 **Model Flexibility**: Multiple models across two APIs
944
- - ⚑ **Force Search Option**: Make AI search even for general questions
945
- - πŸ”§ **Enhanced Tool Visibility**: See exactly what search tools were used
946
- - πŸ“Š **Model Comparison Guide**: Choose the right model and API for your task
947
 
948
  ### πŸ† **Core Features:**
949
- - πŸ”— **Automatic Source Citations**: Every response includes clickable links to sources
950
- - πŸ“š **Sources Used Section**: Dedicated section showing all websites referenced
951
- - 🌐 **Smart Domain Filtering**: Control search scope (compound models)
952
- - πŸ” **Real-time Browser Search**: Current information (Chutes model)
953
  - πŸ’¬ **Conversational Memory**: Maintains context throughout the session
954
  - βš™οΈ **Full Customization**: Adjust all parameters and prompts
955
  - 🎨 **Creative & Analytical**: Optimized for both creative and research tasks
956
 
957
  ### πŸ› οΈ **Technical Details:**
958
  - **Compound Models (Groq)**: compound-beta, compound-beta-mini (web search + domain filtering)
959
- - **Tool-based Model (Chutes)**: openai/gpt-oss-20b (browser search tools)
960
- - **Automatic Search Type Detection**: AI chooses best search method
961
  - **Enhanced Error Handling**: Robust error management and user feedback
962
  - **Real-time Status Updates**: Live feedback on model capabilities and search settings
963
  """)
@@ -968,5 +920,7 @@ def create_gradio_app():
968
  if __name__ == "__main__":
969
  app = create_gradio_app()
970
  app.launch(
971
- share=True
 
 
972
  )
 
26
  "Content-Type": "application/json"
27
  }
28
 
29
+ # Prepare the body, excluding tools since Chutes doesn't support the same format
30
  body = {
31
  "model": kwargs.get("model", "openai/gpt-oss-20b"),
32
  "messages": kwargs.get("messages", []),
33
+ "stream": False,
34
  "max_tokens": kwargs.get("max_tokens", 1024),
35
  "temperature": kwargs.get("temperature", 0.7)
36
  }
37
 
 
 
 
 
 
38
  async with aiohttp.ClientSession() as session:
39
  async with session.post(
40
  f"{self.base_url}/chat/completions",
 
75
  self.available_models = {
76
  "compound-beta": {"supports_web_search": True, "supports_browser_search": False, "api": "groq"},
77
  "compound-beta-mini": {"supports_web_search": True, "supports_browser_search": False, "api": "groq"},
78
+ "openai/gpt-oss-20b": {"supports_web_search": False, "supports_browser_search": False, "api": "chutes"},
79
  }
80
 
81
  async def chat(self, message: str,
 
120
  domain_context = f"\nAvoid searching these domains: {', '.join(exclude_domains)}. Search everywhere else on the web."
121
 
122
  search_instruction = ""
123
+ if search_type == "browser_search" and self._supports_browser_search():
124
  search_instruction = "\nUse browser search tools to find the most current and relevant information from the web."
125
  elif search_type == "web_search":
126
  search_instruction = "\nUse web search capabilities to find relevant information."
 
142
 
143
  # Build messages
144
  messages = [{"role": "system", "content": system_prompt}]
145
+ messages.extend(self.conversation_history[-20:])
 
 
 
 
146
  enhanced_message = message
147
  if include_domains or exclude_domains:
148
  filter_context = []
 
169
  if exclude_domains and exclude_domains[0].strip():
170
  params["exclude_domains"] = [domain.strip() for domain in exclude_domains if domain.strip()]
171
 
172
+ # Add tools only for Groq models that support browser search
173
  tools = []
174
  tool_choice = None
175
+ if self._supports_browser_search():
176
+ if search_type in ["browser_search", "auto"] or force_search:
177
+ tools = [{"type": "browser_search", "function": {"name": "browser_search"}}]
 
 
 
 
178
  tool_choice = "required" if force_search else "auto"
 
 
 
179
 
180
  if tools:
181
  params["tools"] = tools
 
185
  # Make the API call based on model
186
  if self.available_models[self.model]["api"] == "chutes":
187
  response = await self.chutes_client.chat_completions_create(**params)
188
+ # Handle Chutes response
189
+ content = response.get("choices", [{}])[0].get("message", {}).get("content", "No response content")
190
+ tool_calls = response.get("choices", [{}])[0].get("message", {}).get("tool_calls", None)
191
  else:
192
  params["max_completion_tokens"] = params.pop("max_tokens", None)
193
  response = self.groq_client.chat.completions.create(**params)
194
+ content = response.choices[0].message.content
195
+ tool_calls = response.choices[0].message.tool_calls if hasattr(response.choices[0].message, "tool_calls") else None
196
 
197
+ # Extract tool usage information
198
+ tool_info = self._extract_tool_info(response, tool_calls)
 
 
199
 
200
  # Process content to enhance citations
201
  processed_content = self._enhance_citations(content, tool_info)
 
204
  self.conversation_history.append({"role": "user", "content": message})
205
  self.conversation_history.append({"role": "assistant", "content": processed_content})
206
 
207
+ return {
 
208
  "content": processed_content,
209
  "timestamp": datetime.now().isoformat(),
210
  "model": self.model,
 
219
  }
220
  }
221
 
 
 
222
  except Exception as e:
223
  error_msg = f"Error: {str(e)}"
224
  self.conversation_history.append({"role": "user", "content": message})
 
240
  """Check if current model supports browser search tools"""
241
  return self.available_models.get(self.model, {}).get("supports_browser_search", False)
242
 
243
+ def _extract_tool_info(self, response, tool_calls) -> Dict:
244
  """Extract tool usage information in a JSON serializable format"""
245
  tool_info = {
246
  "tools_used": [],
 
248
  "sources_found": []
249
  }
250
 
251
+ # Handle Groq executed_tools
252
+ if hasattr(response, 'choices') and hasattr(response.choices[0].message, 'executed_tools'):
253
  tools = response.choices[0].message.executed_tools
254
  if tools:
255
  for tool in tools:
 
257
  "tool_type": getattr(tool, "type", "unknown"),
258
  "tool_name": getattr(tool, "name", "unknown"),
259
  }
 
260
  if hasattr(tool, "input"):
261
  tool_input = str(tool.input)
262
  tool_dict["input"] = tool_input
263
  if "search" in tool_dict["tool_name"].lower():
264
  tool_info["search_queries"].append(tool_input)
 
265
  if hasattr(tool, "output"):
266
  tool_output = str(tool.output)
267
  tool_dict["output"] = tool_output
268
  urls = self._extract_urls(tool_output)
269
  tool_info["sources_found"].extend(urls)
 
270
  tool_info["tools_used"].append(tool_dict)
271
 
272
+ # Handle tool_calls for both APIs
273
+ if tool_calls:
274
+ for tool_call in tool_calls:
275
  tool_dict = {
276
+ "tool_type": getattr(tool_call, "type", "browser_search"),
277
+ "tool_name": getattr(tool_call, "function", {}).get("name", "browser_search"),
278
+ "tool_id": getattr(tool_call, "id", None)
279
  }
280
+ if hasattr(tool_call, "function") and hasattr(tool_call.function, "arguments"):
 
281
  try:
282
  args = json.loads(tool_call.function.arguments) if isinstance(tool_call.function.arguments, str) else tool_call.function.arguments
283
  tool_dict["arguments"] = args
 
285
  tool_info["search_queries"].append(args["query"])
286
  except:
287
  tool_dict["arguments"] = str(tool_call.function.arguments)
 
288
  tool_info["tools_used"].append(tool_dict)
289
 
290
  return tool_info
 
305
  for i, url in enumerate(tool_info["sources_found"][:10], 1):
306
  domain = self._extract_domain(url)
307
  sources_section += f"{i}. [{domain}]({url})\n"
 
308
  content += sources_section
309
 
310
  return content
 
356
  return "❌ Please enter a valid Groq API key for the selected model"
357
 
358
  try:
 
359
  if model == "openai/gpt-oss-20b":
360
  chutes_client = ChutesClient(api_key=chutes_api_key)
361
  await chutes_client.chat_completions_create(
 
371
  max_tokens=10
372
  )
373
 
 
374
  ai_instance = CreativeAgenticAI(groq_api_key=groq_api_key, chutes_api_key=chutes_api_key, model=model)
375
  api_key_status = "Valid βœ…"
376
 
 
575
  gr.HTML("""
576
  <div class="header">
577
  <h1>πŸ€– NeuroScope-AI Enhanced</h1>
578
+ <p>Powered by Groq and Chutes Models with Web Search and Agentic Capabilities</p>
579
  </div>
580
  """)
581
 
 
584
  gr.Markdown("""
585
  **Enhanced with Multiple Search Capabilities:**
586
  - 🧠 **Intelligence** (Neuro): Advanced AI reasoning across multiple models
587
+ - πŸ” **Precision Search** (Scope): Domain filtering (Groq models)
588
  - πŸ€– **AI Capabilities** (AI): Agentic behavior with tool usage
589
+ - ⚑ **Dual APIs**: Web search (Groq) + Basic chat (Chutes)
590
  - 🎯 **Model Flexibility**: Choose the right model for your task
591
  """)
592
 
 
603
  <li><strong>Features:</strong> Include/exclude domains, autonomous web search</li>
604
  </ul>
605
 
606
+ <h4>πŸ’¬ Chat Model (Chutes API)</h4>
607
  <ul>
608
+ <li><strong>openai/gpt-oss-20b:</strong> Fast conversational capabilities</li>
609
+ <li><strong>Features:</strong> General chat, no browser search</li>
610
  </ul>
611
  </div>
612
 
 
614
  <h3>πŸ”— Enhanced Citation System</h3>
615
  <p>All models now include:</p>
616
  <ul>
617
+ <li><strong>Automatic Source Citations:</strong> Clickable links to sources (Groq models)</li>
618
  <li><strong>Sources Used Section:</strong> Dedicated section showing all websites</li>
619
  <li><strong>Search Type Indication:</strong> Shows which search method was used</li>
 
620
  </ul>
621
  </div>
622
  """)
 
644
  ],
645
  label="🧠 Model Selection",
646
  value="compound-beta",
647
+ info="Choose based on your needs"
648
  )
649
  with gr.Column(scale=1):
650
  connect_btn = gr.Button("πŸ”— Connect", variant="primary", size="lg")
 
685
  with gr.Accordion("πŸ” Search Settings", open=False, elem_id="neuroscope-accordion"):
686
  with gr.Row():
687
  search_type = gr.Radio(
688
+ choices=["auto", "web_search", "none"],
689
  label="🎯 Search Type",
690
  value="auto",
691
  info="Choose search method (auto = model decides)"
 
693
  force_search = gr.Checkbox(
694
  label="⚑ Force Search",
695
  value=False,
696
+ info="Force AI to search even for general questions (Groq models only)"
697
  )
698
 
699
  model_selection.change(
 
763
  - Best for: Research papers, academic sources, filtered searches
764
  - API: Groq
765
 
 
 
 
 
 
766
  **For General Knowledge & Creative Tasks:**
767
+ - `openai/gpt-oss-20b` for fast conversational responses
768
+ - Best for: Creative writing, general questions
769
+ - API: Chutes
770
 
771
  **For Programming & Technical Documentation:**
772
+ - `compound-beta` with tech domains
773
  - Best for: Code help, documentation, technical guides
774
+ - API: Groq
775
  """)
776
 
777
  with gr.Accordion("πŸ”— Common Domain Examples", open=False, elem_id="neuroscope-accordion"):
 
799
  gr.Markdown("""
800
  ### πŸš€ Getting Started
801
  1. **Enter your API Keys** - Groq from [console.groq.com](https://console.groq.com/), Chutes for openai/gpt-oss-20b
802
+ 2. **Select a model** - Choose based on your needs:
803
  - **Compound models** (Groq): For web search with domain filtering
804
+ - **openai/gpt-oss-20b** (Chutes): For general conversational tasks
805
+ 3. **Configure search settings** - Choose search type and options (Groq models only)
806
  4. **Click Connect** - Validate your keys and connect to the AI
807
  5. **Start chatting!** - Type your message and get intelligent responses with citations
808
 
809
  ### 🎯 Key Features
810
+ - **Dual APIs**: Web search (Groq) + Basic chat (Chutes)
811
+ - **Smart Citations**: Automatic source linking and citation formatting (Groq models)
812
+ - **Domain Filtering**: Control which websites the AI searches (Groq models)
 
813
  - **Model Flexibility**: Choose the right model and API for your task
814
+ - **Enhanced Tool Visibility**: See search tools used (Groq models)
815
 
816
  ### πŸ’‘ Tips for Best Results
817
 
 
820
  - Include academic domains (*.edu, arxiv.org) for scholarly sources
821
  - Use "Force Search" for the most current information
822
 
 
 
 
 
 
823
  **For Creative Tasks:**
824
+ - Use openai/gpt-oss-20b (Chutes) or any model
825
  - Set search type to "none" for purely creative responses
826
  - Use higher temperature (0.8-1.0) for more creativity
827
  """)
 
829
  with gr.Accordion("🎯 Sample Examples to Test Enhanced Search", open=False, elem_id="neuroscope-accordion"):
830
  gr.Markdown("""
831
  <div class="example-box">
832
+ <h4>πŸ”¬ Research & Analysis</h4>
833
 
834
  **Compound Model + Domain Filtering (Groq):**
835
  - Query: "What are the latest breakthroughs in quantum computing?"
 
837
  - Include domains: "arxiv.org, *.edu, nature.com"
838
  - Search type: web_search
839
 
840
+ <h4>πŸ’¬ General Knowledge (Chutes):**
841
+ - Query: "Tell me about quantum computing"
842
+ - Model: openai/gpt-oss-20b
843
+ - Search type: none
 
 
844
 
845
+ <h4>πŸ’» Programming & Tech</h4>
 
 
 
 
846
 
847
+ **Technical Documentation (Groq):**
 
 
 
 
 
 
848
  - Query: "How to implement OAuth 2.0 in Python Flask?"
849
+ - Model: compound-beta
850
+ - Include domains: "github.com, docs.python.org, stackoverflow.com"
851
+ - Search type: web_search
852
+
853
+ **Code Help (Chutes):**
854
+ - Same query with openai/gpt-oss-20b
855
+ - Search type: none
856
 
857
+ <h4>🎨 Creative Tasks</h4>
858
  - Query: "Write a short story about AI and humans working together"
859
  - Any model with search_type: "none"
860
  - Higher temperature (0.8-1.0)
861
 
862
+ <h4>πŸ“Š Business Analysis</h4>
863
 
864
+ **Business Analysis (Filtered, Groq):**
 
 
 
 
 
 
865
  - Query: "Cryptocurrency adoption in enterprise"
866
+ - Model: compound-beta
867
  - Include domains: "bloomberg.com, wsj.com, harvard.edu"
868
+ - Search type: web_search
869
  </div>
870
  """)
871
 
 
888
 
889
  with gr.Accordion("πŸš€ About This Enhanced NeuroScope AI", open=True, elem_id="neuroscope-accordion"):
890
  gr.Markdown("""
891
+ **Enhanced Creative Agentic AI Chat Tool** with dual API support:
892
 
893
  ### πŸ†• **New in This Version:**
894
+ - πŸ’¬ **Chutes API Integration**: For openai/gpt-oss-20b model
895
+ - 🌐 **Dual API System**: Web search (Groq) + Basic chat (Chutes)
896
  - 🎯 **Model Flexibility**: Multiple models across two APIs
897
+ - ⚑ **Force Search Option**: Make AI search for Groq models
898
+ - πŸ”§ **Enhanced Tool Visibility**: See search tools used (Groq models)
899
+ - πŸ“Š **Model Comparison Guide**: Choose the right model and API
900
 
901
  ### πŸ† **Core Features:**
902
+ - πŸ”— **Automatic Source Citations**: Clickable links to sources (Groq models)
903
+ - πŸ“š **Sources Used Section**: Dedicated section for websites (Groq models)
904
+ - 🌐 **Smart Domain Filtering**: Control search scope (Groq models)
 
905
  - πŸ’¬ **Conversational Memory**: Maintains context throughout the session
906
  - βš™οΈ **Full Customization**: Adjust all parameters and prompts
907
  - 🎨 **Creative & Analytical**: Optimized for both creative and research tasks
908
 
909
  ### πŸ› οΈ **Technical Details:**
910
  - **Compound Models (Groq)**: compound-beta, compound-beta-mini (web search + domain filtering)
911
+ - **Chat Model (Chutes)**: openai/gpt-oss-20b (basic conversational capabilities)
912
+ - **Automatic Search Type Detection**: AI chooses best search method (Groq models)
913
  - **Enhanced Error Handling**: Robust error management and user feedback
914
  - **Real-time Status Updates**: Live feedback on model capabilities and search settings
915
  """)
 
920
  if __name__ == "__main__":
921
  app = create_gradio_app()
922
  app.launch(
923
+ share=True,
924
+ server_name="0.0.0.0",
925
+ server_port=7860
926
  )