Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -104,98 +104,51 @@ def detect_tools(message):
|
|
| 104 |
return tools
|
| 105 |
|
| 106 |
# --- Internet Search Feature ---
|
| 107 |
-
def
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
with DDGS(
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
for i in range(min(max_results, len(links))):
|
| 125 |
-
results.append({
|
| 126 |
-
"title": re.sub(r'<[^>]+>', '', titles[i]) if i < len(titles) else "No title",
|
| 127 |
-
"href": links[i],
|
| 128 |
-
"body": ""
|
| 129 |
-
})
|
| 130 |
-
return results
|
| 131 |
-
except:
|
| 132 |
-
return []
|
| 133 |
-
|
| 134 |
-
def wiki_search(query, max_results=3):
|
| 135 |
-
try:
|
| 136 |
-
url = "https://en.wikipedia.org/w/api.php"
|
| 137 |
-
params = {"action": "query", "list": "search", "srsearch": query, "format": "json", "srlimit": max_results}
|
| 138 |
-
r = requests.get(url, params=params, timeout=10)
|
| 139 |
-
data = r.json()
|
| 140 |
-
return [{"title": i["title"], "href": f"https://en.wikipedia.org/wiki/{i['title'].replace(' ', '_')}",
|
| 141 |
-
"body": i["snippet"].replace('<span class="searchmatch">', '').replace('</span>', '')}
|
| 142 |
-
for i in data["query"]["search"]]
|
| 143 |
-
except:
|
| 144 |
-
return []
|
| 145 |
-
|
| 146 |
-
def web_search(query, max_results=5):
|
| 147 |
-
# Try DDG
|
| 148 |
-
logger.info(f"๐ Searching DDG: {query}")
|
| 149 |
-
ddg = ddg_search(query, max_results)
|
| 150 |
-
if ddg:
|
| 151 |
-
return {"engine": "DuckDuckGo", "results": ddg}
|
| 152 |
-
|
| 153 |
-
logger.warning("โ ๏ธ DDG failed, trying Bing in 2s...")
|
| 154 |
-
time.sleep(2)
|
| 155 |
-
# Try Bing
|
| 156 |
-
bing = bing_search(query, max_results)
|
| 157 |
-
if bing:
|
| 158 |
-
return {"engine": "Bing", "results": bing}
|
| 159 |
-
|
| 160 |
-
logger.warning("โ ๏ธ Bing failed, trying Wikipedia in 2s...")
|
| 161 |
-
time.sleep(2)
|
| 162 |
-
# Try Wikipedia
|
| 163 |
-
wiki = wiki_search(query, max_results)
|
| 164 |
-
if wiki:
|
| 165 |
-
return {"engine": "Wikipedia", "results": wiki}
|
| 166 |
-
|
| 167 |
-
return {"engine": "Failed", "results": [{"error": "All engines failed"}]}
|
| 168 |
-
|
| 169 |
-
def format_results(data):
|
| 170 |
-
if not data or not data.get("results") or (isinstance(data["results"][0], dict) and "error" in data["results"][0]):
|
| 171 |
-
return "No results found."
|
| 172 |
|
| 173 |
-
|
| 174 |
-
for i, r in enumerate(
|
| 175 |
-
title = r.get("title", "No title")
|
| 176 |
-
url = r.get("href",
|
| 177 |
-
body = r.get("body",
|
| 178 |
-
|
| 179 |
-
return "\n\n".join(
|
| 180 |
|
| 181 |
def perform_search(query):
|
| 182 |
try:
|
| 183 |
# Clean query for better search results
|
| 184 |
search_query = query.lower().replace('search for', '').replace('find out about', '').replace('/search', '').strip()
|
|
|
|
| 185 |
|
| 186 |
-
|
| 187 |
|
| 188 |
-
if
|
| 189 |
-
logger.info(f"โ
Found {len(
|
| 190 |
-
return
|
| 191 |
else:
|
| 192 |
-
error_msg =
|
| 193 |
logger.warning(f"โ Search failed: {error_msg}")
|
| 194 |
-
return
|
| 195 |
|
| 196 |
except Exception as e:
|
| 197 |
logger.error(f"โ ๏ธ Global Search Error: {str(e)}")
|
| 198 |
-
return
|
| 199 |
|
| 200 |
# --- Image Generation Feature ---
|
| 201 |
@app.route('/api/image', methods=['POST'])
|
|
|
|
| 104 |
return tools
|
| 105 |
|
| 106 |
# --- Internet Search Feature ---
|
| 107 |
+
def web_search(query: str, max_results: int = 5) -> list:
|
| 108 |
+
"""Search the web using DuckDuckGo v7.5.0 syntax. No API key required."""
|
| 109 |
+
try:
|
| 110 |
+
from duckduckgo_search import DDGS
|
| 111 |
+
with DDGS() as ddgs:
|
| 112 |
+
results = list(ddgs.text(query, max_results=max_results))
|
| 113 |
+
return results
|
| 114 |
+
except Exception as e:
|
| 115 |
+
logger.error(f"Search failed: {str(e)}")
|
| 116 |
+
return [{"error": f"Search failed: {str(e)}"}]
|
| 117 |
+
|
| 118 |
+
def format_results(results: list) -> str:
|
| 119 |
+
"""Format search results with markdown citations."""
|
| 120 |
+
if not results:
|
| 121 |
+
return "No results found."
|
| 122 |
+
if isinstance(results[0], dict) and "error" in results[0]:
|
| 123 |
+
return results[0]["error"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
+
formatted = []
|
| 126 |
+
for i, r in enumerate(results, 1):
|
| 127 |
+
title = r.get("title", "No title")
|
| 128 |
+
url = r.get("href", "#")
|
| 129 |
+
body = r.get("body", "No description")[:300]
|
| 130 |
+
formatted.append(f"{i}. [{title}]({url})\n {body}")
|
| 131 |
+
return "\n\n".join(formatted)
|
| 132 |
|
| 133 |
def perform_search(query):
|
| 134 |
try:
|
| 135 |
# Clean query for better search results
|
| 136 |
search_query = query.lower().replace('search for', '').replace('find out about', '').replace('/search', '').strip()
|
| 137 |
+
logger.info(f"๐ Searching for: {search_query}")
|
| 138 |
|
| 139 |
+
results = web_search(search_query)
|
| 140 |
|
| 141 |
+
if results and not (isinstance(results[0], dict) and "error" in results[0]):
|
| 142 |
+
logger.info(f"โ
Found {len(results)} results")
|
| 143 |
+
return results, None
|
| 144 |
else:
|
| 145 |
+
error_msg = results[0]["error"] if results and "error" in results[0] else "No results found."
|
| 146 |
logger.warning(f"โ Search failed: {error_msg}")
|
| 147 |
+
return [], error_msg
|
| 148 |
|
| 149 |
except Exception as e:
|
| 150 |
logger.error(f"โ ๏ธ Global Search Error: {str(e)}")
|
| 151 |
+
return [], str(e)
|
| 152 |
|
| 153 |
# --- Image Generation Feature ---
|
| 154 |
@app.route('/api/image', methods=['POST'])
|