Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -26,24 +26,62 @@ 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,
|
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 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
class CreativeAgenticAI:
|
49 |
"""
|
@@ -102,9 +140,14 @@ class CreativeAgenticAI:
|
|
102 |
Returns:
|
103 |
AI response with metadata
|
104 |
"""
|
105 |
-
# Enhanced system prompt for better
|
106 |
if not system_prompt:
|
107 |
-
|
|
|
|
|
|
|
|
|
|
|
108 |
IMPORTANT: When you search the web and find information, you MUST:
|
109 |
1. Always cite your sources with clickable links in this format: [Source Title](URL)
|
110 |
2. Include multiple diverse sources when possible
|
@@ -112,39 +155,41 @@ IMPORTANT: When you search the web and find information, you MUST:
|
|
112 |
4. At the end of your response, provide a "Sources Used" section with all the links
|
113 |
5. Be transparent about which information comes from which source
|
114 |
"""
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
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 = []
|
149 |
if include_domains:
|
150 |
filter_context.append(f"ONLY search these domains: {', '.join(include_domains)}")
|
@@ -162,7 +207,7 @@ IMPORTANT: When you search the web and find information, you MUST:
|
|
162 |
"max_tokens": max_tokens,
|
163 |
}
|
164 |
|
165 |
-
# Add domain filtering for compound models
|
166 |
if self._supports_web_search():
|
167 |
if include_domains and include_domains[0].strip():
|
168 |
params["include_domains"] = [domain.strip() for domain in include_domains if domain.strip()]
|
@@ -184,11 +229,14 @@ IMPORTANT: When you search the web and find information, you MUST:
|
|
184 |
try:
|
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 =
|
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
|
@@ -301,7 +349,7 @@ IMPORTANT: When you search the web and find information, you MUST:
|
|
301 |
return content
|
302 |
|
303 |
if "Sources Used:" not in content and "sources:" not in content.lower():
|
304 |
-
sources_section = "\n\n---\n\n###
|
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"
|
@@ -462,7 +510,8 @@ async def chat_with_ai(message: str,
|
|
462 |
|
463 |
ai_response = response["content"]
|
464 |
|
465 |
-
|
|
|
466 |
tool_info = response["tool_usage"]
|
467 |
tool_summary = []
|
468 |
|
@@ -480,6 +529,7 @@ async def chat_with_ai(message: str,
|
|
480 |
if tool_summary:
|
481 |
ai_response += f"\n\n*{' | '.join(tool_summary)}*"
|
482 |
|
|
|
483 |
search_info = []
|
484 |
if response.get("search_type_used") and response["search_type_used"] != "none":
|
485 |
search_info.append(f"π Search type: {response['search_type_used']}")
|
@@ -495,7 +545,7 @@ async def chat_with_ai(message: str,
|
|
495 |
filter_info.append(f"β Excluded domains: {', '.join(exclude_list)}")
|
496 |
search_info.extend(filter_info)
|
497 |
|
498 |
-
if search_info:
|
499 |
ai_response += f"\n\n*π Search settings: {' | '.join(search_info)}*"
|
500 |
|
501 |
history.append([message, ai_response])
|
@@ -586,7 +636,7 @@ def create_gradio_app():
|
|
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) +
|
590 |
- π― **Model Flexibility**: Choose the right model for your task
|
591 |
""")
|
592 |
|
@@ -605,19 +655,20 @@ def create_gradio_app():
|
|
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
|
610 |
</ul>
|
611 |
</div>
|
612 |
|
613 |
<div class="citation-info">
|
614 |
<h3>π Enhanced Citation System</h3>
|
615 |
-
<p>
|
616 |
<ul>
|
617 |
-
<li><strong>Automatic Source Citations:</strong> Clickable links to sources
|
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 |
""")
|
623 |
|
|
|
26 |
"Content-Type": "application/json"
|
27 |
}
|
28 |
|
29 |
+
# Prepare the body for Chutes API
|
30 |
body = {
|
31 |
"model": kwargs.get("model", "openai/gpt-oss-20b"),
|
32 |
"messages": kwargs.get("messages", []),
|
33 |
+
"stream": kwargs.get("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 |
+
if body["stream"]:
|
40 |
+
# Handle streaming response
|
41 |
+
async with session.post(
|
42 |
+
f"{self.base_url}/chat/completions",
|
43 |
+
headers=headers,
|
44 |
+
json=body
|
45 |
+
) as response:
|
46 |
+
if response.status != 200:
|
47 |
+
raise Exception(f"Chutes API error: {await response.text()}")
|
48 |
+
|
49 |
+
content = ""
|
50 |
+
async for line in response.content:
|
51 |
+
line = line.decode("utf-8").strip()
|
52 |
+
if line.startswith("data: "):
|
53 |
+
data = line[6:]
|
54 |
+
if data == "[DONE]":
|
55 |
+
break
|
56 |
+
try:
|
57 |
+
if data.strip():
|
58 |
+
chunk_json = json.loads(data)
|
59 |
+
if "choices" in chunk_json and len(chunk_json["choices"]) > 0:
|
60 |
+
delta = chunk_json["choices"][0].get("delta", {})
|
61 |
+
if "content" in delta:
|
62 |
+
content += delta["content"]
|
63 |
+
except json.JSONDecodeError:
|
64 |
+
continue
|
65 |
+
|
66 |
+
# Return in OpenAI format for compatibility
|
67 |
+
return {
|
68 |
+
"choices": [{
|
69 |
+
"message": {
|
70 |
+
"content": content,
|
71 |
+
"role": "assistant"
|
72 |
+
}
|
73 |
+
}]
|
74 |
+
}
|
75 |
+
else:
|
76 |
+
# Handle non-streaming response
|
77 |
+
async with session.post(
|
78 |
+
f"{self.base_url}/chat/completions",
|
79 |
+
headers=headers,
|
80 |
+
json=body
|
81 |
+
) as response:
|
82 |
+
if response.status != 200:
|
83 |
+
raise Exception(f"Chutes API error: {await response.text()}")
|
84 |
+
return await response.json()
|
85 |
|
86 |
class CreativeAgenticAI:
|
87 |
"""
|
|
|
140 |
Returns:
|
141 |
AI response with metadata
|
142 |
"""
|
143 |
+
# Enhanced system prompt for better behavior
|
144 |
if not system_prompt:
|
145 |
+
if self.model == "openai/gpt-oss-20b":
|
146 |
+
# Simple, direct system prompt for Chutes model
|
147 |
+
system_prompt = """You are a helpful, knowledgeable AI assistant. Provide direct, clear, and informative responses to user questions. Be concise but thorough. Do not include internal reasoning or commentary - just give the answer the user is looking for."""
|
148 |
+
else:
|
149 |
+
# Enhanced system prompt for Groq models with search capabilities
|
150 |
+
citation_instruction = """
|
151 |
IMPORTANT: When you search the web and find information, you MUST:
|
152 |
1. Always cite your sources with clickable links in this format: [Source Title](URL)
|
153 |
2. Include multiple diverse sources when possible
|
|
|
155 |
4. At the end of your response, provide a "Sources Used" section with all the links
|
156 |
5. Be transparent about which information comes from which source
|
157 |
"""
|
158 |
+
|
159 |
+
domain_context = ""
|
160 |
+
if include_domains and self._supports_web_search():
|
161 |
+
domain_context = f"\nYou are restricted to searching ONLY these domains: {', '.join(include_domains)}. Make sure to find and cite sources specifically from these domains."
|
162 |
+
elif exclude_domains and self._supports_web_search():
|
163 |
+
domain_context = f"\nAvoid searching these domains: {', '.join(exclude_domains)}. Search everywhere else on the web."
|
164 |
+
|
165 |
+
search_instruction = ""
|
166 |
+
if search_type == "browser_search" and self._supports_browser_search():
|
167 |
+
search_instruction = "\nUse browser search tools to find the most current and relevant information from the web."
|
168 |
+
elif search_type == "web_search":
|
169 |
+
search_instruction = "\nUse web search capabilities to find relevant information."
|
170 |
+
elif force_search:
|
171 |
+
if self._supports_browser_search():
|
172 |
+
search_instruction = "\nYou MUST use search tools to find current information before responding."
|
173 |
+
elif self._supports_web_search():
|
174 |
+
search_instruction = "\nYou MUST use web search to find current information before responding."
|
175 |
+
|
176 |
+
system_prompt = f"""You are a creative and intelligent AI assistant with agentic capabilities.
|
177 |
+
You can search the web, analyze information, and provide comprehensive responses.
|
178 |
+
Be helpful, creative, and engaging while maintaining accuracy.
|
179 |
+
|
180 |
+
{citation_instruction}
|
181 |
+
{domain_context}
|
182 |
+
{search_instruction}
|
183 |
+
|
184 |
+
Your responses should be well-structured, informative, and properly cited with working links."""
|
185 |
|
186 |
# Build messages
|
187 |
messages = [{"role": "system", "content": system_prompt}]
|
188 |
messages.extend(self.conversation_history[-20:])
|
189 |
+
|
190 |
+
# Enhanced message for domain filtering (only for Groq models)
|
191 |
enhanced_message = message
|
192 |
+
if (include_domains or exclude_domains) and self._supports_web_search():
|
193 |
filter_context = []
|
194 |
if include_domains:
|
195 |
filter_context.append(f"ONLY search these domains: {', '.join(include_domains)}")
|
|
|
207 |
"max_tokens": max_tokens,
|
208 |
}
|
209 |
|
210 |
+
# Add domain filtering for compound models (Groq only)
|
211 |
if self._supports_web_search():
|
212 |
if include_domains and include_domains[0].strip():
|
213 |
params["include_domains"] = [domain.strip() for domain in include_domains if domain.strip()]
|
|
|
229 |
try:
|
230 |
# Make the API call based on model
|
231 |
if self.available_models[self.model]["api"] == "chutes":
|
232 |
+
# Use streaming for better response quality
|
233 |
+
params["stream"] = True
|
234 |
response = await self.chutes_client.chat_completions_create(**params)
|
235 |
# Handle Chutes response
|
236 |
content = response.get("choices", [{}])[0].get("message", {}).get("content", "No response content")
|
237 |
+
tool_calls = None
|
238 |
else:
|
239 |
+
# Groq API call
|
240 |
params["max_completion_tokens"] = params.pop("max_tokens", None)
|
241 |
response = self.groq_client.chat.completions.create(**params)
|
242 |
content = response.choices[0].message.content
|
|
|
349 |
return content
|
350 |
|
351 |
if "Sources Used:" not in content and "sources:" not in content.lower():
|
352 |
+
sources_section = "\n\n---\n\n### Sources Used:\n"
|
353 |
for i, url in enumerate(tool_info["sources_found"][:10], 1):
|
354 |
domain = self._extract_domain(url)
|
355 |
sources_section += f"{i}. [{domain}]({url})\n"
|
|
|
510 |
|
511 |
ai_response = response["content"]
|
512 |
|
513 |
+
# Add tool usage info for Groq models
|
514 |
+
if response.get("tool_usage") and ai_instance.model != "openai/gpt-oss-20b":
|
515 |
tool_info = response["tool_usage"]
|
516 |
tool_summary = []
|
517 |
|
|
|
529 |
if tool_summary:
|
530 |
ai_response += f"\n\n*{' | '.join(tool_summary)}*"
|
531 |
|
532 |
+
# Add search settings info
|
533 |
search_info = []
|
534 |
if response.get("search_type_used") and response["search_type_used"] != "none":
|
535 |
search_info.append(f"π Search type: {response['search_type_used']}")
|
|
|
545 |
filter_info.append(f"β Excluded domains: {', '.join(exclude_list)}")
|
546 |
search_info.extend(filter_info)
|
547 |
|
548 |
+
if search_info and ai_instance.model != "openai/gpt-oss-20b":
|
549 |
ai_response += f"\n\n*π Search settings: {' | '.join(search_info)}*"
|
550 |
|
551 |
history.append([message, ai_response])
|
|
|
636 |
- π§ **Intelligence** (Neuro): Advanced AI reasoning across multiple models
|
637 |
- π **Precision Search** (Scope): Domain filtering (Groq models)
|
638 |
- π€ **AI Capabilities** (AI): Agentic behavior with tool usage
|
639 |
+
- β‘ **Dual APIs**: Web search (Groq) + Streaming chat (Chutes)
|
640 |
- π― **Model Flexibility**: Choose the right model for your task
|
641 |
""")
|
642 |
|
|
|
655 |
|
656 |
<h4>π¬ Chat Model (Chutes API)</h4>
|
657 |
<ul>
|
658 |
+
<li><strong>openai/gpt-oss-20b:</strong> Fast conversational capabilities with streaming</li>
|
659 |
+
<li><strong>Features:</strong> General chat, streaming responses, no web search</li>
|
660 |
</ul>
|
661 |
</div>
|
662 |
|
663 |
<div class="citation-info">
|
664 |
<h3>π Enhanced Citation System</h3>
|
665 |
+
<p>Groq models include:</p>
|
666 |
<ul>
|
667 |
+
<li><strong>Automatic Source Citations:</strong> Clickable links to sources</li>
|
668 |
<li><strong>Sources Used Section:</strong> Dedicated section showing all websites</li>
|
669 |
<li><strong>Search Type Indication:</strong> Shows which search method was used</li>
|
670 |
</ul>
|
671 |
+
<p><strong>Chutes models:</strong> Direct conversational responses without web search</p>
|
672 |
</div>
|
673 |
""")
|
674 |
|