Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Commit ·
89b1b00
1
Parent(s): 54196ee
removing extra prints
Browse files- agent/core/tools.py +17 -10
- agent/tools/docs_tools.py +0 -49
agent/core/tools.py
CHANGED
|
@@ -132,11 +132,13 @@ class ToolRouter:
|
|
| 132 |
|
| 133 |
async def register_mcp_tools(self) -> None:
|
| 134 |
tools = await self.mcp_client.list_tools()
|
|
|
|
|
|
|
| 135 |
for tool in tools:
|
| 136 |
if tool.name in NOT_ALLOWED_TOOL_NAMES:
|
| 137 |
-
|
| 138 |
continue
|
| 139 |
-
|
| 140 |
self.register_tool(
|
| 141 |
ToolSpec(
|
| 142 |
name=tool.name,
|
|
@@ -145,6 +147,9 @@ class ToolRouter:
|
|
| 145 |
handler=None,
|
| 146 |
)
|
| 147 |
)
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
async def register_openapi_tool(self) -> None:
|
| 150 |
"""Register the OpenAPI search tool (requires async initialization)"""
|
|
@@ -153,8 +158,6 @@ class ToolRouter:
|
|
| 153 |
search_openapi_handler,
|
| 154 |
)
|
| 155 |
|
| 156 |
-
print("Registering OpenAPI search tool...")
|
| 157 |
-
|
| 158 |
# Register search_hf_api_endpoints with dynamic spec
|
| 159 |
openapi_spec = await _get_api_search_tool_spec()
|
| 160 |
self.register_tool(
|
|
@@ -165,7 +168,7 @@ class ToolRouter:
|
|
| 165 |
handler=search_openapi_handler,
|
| 166 |
)
|
| 167 |
)
|
| 168 |
-
print(f"
|
| 169 |
|
| 170 |
def get_tool_specs_for_llm(self) -> list[dict[str, Any]]:
|
| 171 |
"""Get tool specifications in OpenAI format"""
|
|
@@ -189,11 +192,13 @@ class ToolRouter:
|
|
| 189 |
await self.mcp_client.initialize()
|
| 190 |
await self.register_mcp_tools()
|
| 191 |
self._mcp_initialized = True
|
| 192 |
-
print(f"MCP initialized: {self._mcp_initialized}")
|
| 193 |
|
| 194 |
# Register OpenAPI tool (requires async initialization)
|
| 195 |
await self.register_openapi_tool()
|
| 196 |
|
|
|
|
|
|
|
|
|
|
| 197 |
return self
|
| 198 |
|
| 199 |
async def __aexit__(self, exc_type, exc, tb) -> None:
|
|
@@ -237,11 +242,8 @@ class ToolRouter:
|
|
| 237 |
|
| 238 |
def create_builtin_tools() -> list[ToolSpec]:
|
| 239 |
"""Create built-in tool specifications"""
|
| 240 |
-
print(
|
| 241 |
-
f"Creating built-in tools: {EXPLORE_HF_DOCS_TOOL_SPEC['name']}, {HF_DOCS_FETCH_TOOL_SPEC['name']}, {PLAN_TOOL_SPEC['name']}, {HF_JOBS_TOOL_SPEC['name']}, {PRIVATE_HF_REPO_TOOL_SPEC['name']}, {GITHUB_FIND_EXAMPLES_TOOL_SPEC['name']}, {GITHUB_LIST_REPOS_TOOL_SPEC['name']}, {GITHUB_READ_FILE_TOOL_SPEC['name']}"
|
| 242 |
-
)
|
| 243 |
# in order of importance
|
| 244 |
-
|
| 245 |
# Documentation search tools
|
| 246 |
ToolSpec(
|
| 247 |
name=EXPLORE_HF_DOCS_TOOL_SPEC["name"],
|
|
@@ -308,3 +310,8 @@ def create_builtin_tools() -> list[ToolSpec]:
|
|
| 308 |
handler=github_read_file_handler,
|
| 309 |
),
|
| 310 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
async def register_mcp_tools(self) -> None:
|
| 134 |
tools = await self.mcp_client.list_tools()
|
| 135 |
+
registered_names = []
|
| 136 |
+
skipped_count = 0
|
| 137 |
for tool in tools:
|
| 138 |
if tool.name in NOT_ALLOWED_TOOL_NAMES:
|
| 139 |
+
skipped_count += 1
|
| 140 |
continue
|
| 141 |
+
registered_names.append(tool.name)
|
| 142 |
self.register_tool(
|
| 143 |
ToolSpec(
|
| 144 |
name=tool.name,
|
|
|
|
| 147 |
handler=None,
|
| 148 |
)
|
| 149 |
)
|
| 150 |
+
print(
|
| 151 |
+
f"Loaded {len(registered_names)} MCP tools: {', '.join(registered_names)} ({skipped_count} disabled)"
|
| 152 |
+
)
|
| 153 |
|
| 154 |
async def register_openapi_tool(self) -> None:
|
| 155 |
"""Register the OpenAPI search tool (requires async initialization)"""
|
|
|
|
| 158 |
search_openapi_handler,
|
| 159 |
)
|
| 160 |
|
|
|
|
|
|
|
| 161 |
# Register search_hf_api_endpoints with dynamic spec
|
| 162 |
openapi_spec = await _get_api_search_tool_spec()
|
| 163 |
self.register_tool(
|
|
|
|
| 168 |
handler=search_openapi_handler,
|
| 169 |
)
|
| 170 |
)
|
| 171 |
+
print(f"Loaded OpenAPI search tool: {openapi_spec['name']}")
|
| 172 |
|
| 173 |
def get_tool_specs_for_llm(self) -> list[dict[str, Any]]:
|
| 174 |
"""Get tool specifications in OpenAI format"""
|
|
|
|
| 192 |
await self.mcp_client.initialize()
|
| 193 |
await self.register_mcp_tools()
|
| 194 |
self._mcp_initialized = True
|
|
|
|
| 195 |
|
| 196 |
# Register OpenAPI tool (requires async initialization)
|
| 197 |
await self.register_openapi_tool()
|
| 198 |
|
| 199 |
+
total_tools = len(self.tools)
|
| 200 |
+
print(f"\nAgent ready with {total_tools} tools total\n")
|
| 201 |
+
|
| 202 |
return self
|
| 203 |
|
| 204 |
async def __aexit__(self, exc_type, exc, tb) -> None:
|
|
|
|
| 242 |
|
| 243 |
def create_builtin_tools() -> list[ToolSpec]:
|
| 244 |
"""Create built-in tool specifications"""
|
|
|
|
|
|
|
|
|
|
| 245 |
# in order of importance
|
| 246 |
+
tools = [
|
| 247 |
# Documentation search tools
|
| 248 |
ToolSpec(
|
| 249 |
name=EXPLORE_HF_DOCS_TOOL_SPEC["name"],
|
|
|
|
| 310 |
handler=github_read_file_handler,
|
| 311 |
),
|
| 312 |
]
|
| 313 |
+
|
| 314 |
+
tool_names = ", ".join([t.name for t in tools])
|
| 315 |
+
print(f"Loaded {len(tools)} built-in tools: {tool_names}")
|
| 316 |
+
|
| 317 |
+
return tools
|
agent/tools/docs_tools.py
CHANGED
|
@@ -5,7 +5,6 @@ Tools for exploring and fetching HuggingFace documentation and API specification
|
|
| 5 |
|
| 6 |
import asyncio
|
| 7 |
import os
|
| 8 |
-
import time
|
| 9 |
from typing import Any
|
| 10 |
|
| 11 |
import httpx
|
|
@@ -21,21 +20,15 @@ async def _fetch_html_page(hf_token: str, endpoint: str) -> str:
|
|
| 21 |
url = f"{base_url}/{endpoint}"
|
| 22 |
headers = {"Authorization": f"Bearer {hf_token}"}
|
| 23 |
|
| 24 |
-
fetch_start = time.perf_counter()
|
| 25 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 26 |
response = await client.get(url, headers=headers)
|
| 27 |
response.raise_for_status()
|
| 28 |
|
| 29 |
-
fetch_time = time.perf_counter() - fetch_start
|
| 30 |
-
print(f"[DEBUG] _fetch_html_page: Fetched in {fetch_time:.2f}s")
|
| 31 |
-
|
| 32 |
return response.text
|
| 33 |
|
| 34 |
|
| 35 |
def _parse_sidebar_navigation(html_content: str) -> list[dict[str, str]]:
|
| 36 |
"""Parse the sidebar navigation and extract all links"""
|
| 37 |
-
parse_start = time.perf_counter()
|
| 38 |
-
|
| 39 |
soup = BeautifulSoup(html_content, "html.parser")
|
| 40 |
sidebar = soup.find("nav", class_=lambda x: x and "flex-auto" in x)
|
| 41 |
|
|
@@ -53,11 +46,6 @@ def _parse_sidebar_navigation(html_content: str) -> list[dict[str, str]]:
|
|
| 53 |
page_url = f"https://huggingface.co{href}" if href.startswith("/") else href
|
| 54 |
nav_data.append({"title": title, "url": page_url})
|
| 55 |
|
| 56 |
-
parse_time = time.perf_counter() - parse_start
|
| 57 |
-
print(
|
| 58 |
-
f"[DEBUG] _parse_sidebar_navigation: Parsed in {parse_time:.2f}s, found {len(nav_data)} links"
|
| 59 |
-
)
|
| 60 |
-
|
| 61 |
return nav_data
|
| 62 |
|
| 63 |
|
|
@@ -96,18 +84,11 @@ async def _fetch_all_glimpses(
|
|
| 96 |
hf_token: str, nav_data: list[dict[str, str]]
|
| 97 |
) -> list[dict[str, str]]:
|
| 98 |
"""Fetch glimpses for all pages in parallel"""
|
| 99 |
-
glimpse_start = time.perf_counter()
|
| 100 |
-
|
| 101 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 102 |
result_items = await asyncio.gather(
|
| 103 |
*[_fetch_single_glimpse(client, hf_token, item) for item in nav_data]
|
| 104 |
)
|
| 105 |
|
| 106 |
-
glimpse_time = time.perf_counter() - glimpse_start
|
| 107 |
-
print(
|
| 108 |
-
f"[DEBUG] _fetch_all_glimpses: Fetched {len(result_items)} glimpses in {glimpse_time:.2f}s"
|
| 109 |
-
)
|
| 110 |
-
|
| 111 |
return list(result_items)
|
| 112 |
|
| 113 |
|
|
@@ -130,9 +111,6 @@ def _format_exploration_results(
|
|
| 130 |
|
| 131 |
async def explore_hf_docs(hf_token: str, endpoint: str) -> str:
|
| 132 |
"""Main function to explore documentation structure"""
|
| 133 |
-
start_time = time.perf_counter()
|
| 134 |
-
print(f"[DEBUG] explore_hf_docs: Starting for endpoint '{endpoint}'")
|
| 135 |
-
|
| 136 |
# Fetch HTML page
|
| 137 |
html_content = await _fetch_html_page(hf_token, endpoint)
|
| 138 |
|
|
@@ -148,9 +126,6 @@ async def explore_hf_docs(hf_token: str, endpoint: str) -> str:
|
|
| 148 |
# Format results
|
| 149 |
result = _format_exploration_results(endpoint, result_items)
|
| 150 |
|
| 151 |
-
total_time = time.perf_counter() - start_time
|
| 152 |
-
print(f"[DEBUG] explore_hf_docs: Total time {total_time:.2f}s")
|
| 153 |
-
|
| 154 |
return result
|
| 155 |
|
| 156 |
|
|
@@ -199,12 +174,8 @@ async def _fetch_openapi_spec() -> dict[str, Any]:
|
|
| 199 |
global _openapi_spec_cache
|
| 200 |
|
| 201 |
if _openapi_spec_cache is not None:
|
| 202 |
-
print("[DEBUG] _fetch_openapi_spec: Using cached spec")
|
| 203 |
return _openapi_spec_cache
|
| 204 |
|
| 205 |
-
start_time = time.perf_counter()
|
| 206 |
-
print("[DEBUG] _fetch_openapi_spec: Fetching from API")
|
| 207 |
-
|
| 208 |
url = "https://huggingface.co/.well-known/openapi.json"
|
| 209 |
|
| 210 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
|
@@ -214,9 +185,6 @@ async def _fetch_openapi_spec() -> dict[str, Any]:
|
|
| 214 |
spec = response.json()
|
| 215 |
_openapi_spec_cache = spec
|
| 216 |
|
| 217 |
-
fetch_time = time.perf_counter() - start_time
|
| 218 |
-
print(f"[DEBUG] _fetch_openapi_spec: Fetched and cached in {fetch_time:.2f}s")
|
| 219 |
-
|
| 220 |
return spec
|
| 221 |
|
| 222 |
|
|
@@ -457,9 +425,7 @@ async def search_openapi_handler(arguments: dict[str, Any]) -> tuple[str, bool]:
|
|
| 457 |
Returns:
|
| 458 |
Tuple of (search_results, success)
|
| 459 |
"""
|
| 460 |
-
start_time = time.perf_counter()
|
| 461 |
tag = arguments.get("tag", "")
|
| 462 |
-
print(f"[DEBUG] search_openapi: Starting for tag '{tag}'")
|
| 463 |
|
| 464 |
if not tag:
|
| 465 |
return "Error: No tag provided", False
|
|
@@ -474,9 +440,6 @@ async def search_openapi_handler(arguments: dict[str, Any]) -> tuple[str, bool]:
|
|
| 474 |
# Format results
|
| 475 |
formatted = _format_openapi_results(results, tag)
|
| 476 |
|
| 477 |
-
total_time = time.perf_counter() - start_time
|
| 478 |
-
print(f"[DEBUG] search_openapi: Total time {total_time:.2f}s")
|
| 479 |
-
|
| 480 |
return formatted, True
|
| 481 |
|
| 482 |
except httpx.HTTPStatusError as e:
|
|
@@ -497,9 +460,7 @@ async def hf_docs_fetch_handler(arguments: dict[str, Any]) -> tuple[str, bool]:
|
|
| 497 |
Returns:
|
| 498 |
Tuple of (full_markdown_content, success)
|
| 499 |
"""
|
| 500 |
-
start_time = time.perf_counter()
|
| 501 |
url = arguments.get("url", "")
|
| 502 |
-
print(f"[DEBUG] fetch_hf_docs: Starting for URL '{url}'")
|
| 503 |
|
| 504 |
if not url:
|
| 505 |
return "Error: No URL provided", False
|
|
@@ -521,25 +482,15 @@ async def hf_docs_fetch_handler(arguments: dict[str, Any]) -> tuple[str, bool]:
|
|
| 521 |
# Make request with auth
|
| 522 |
headers = {"Authorization": f"Bearer {hf_token}"}
|
| 523 |
|
| 524 |
-
fetch_start = time.perf_counter()
|
| 525 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 526 |
response = await client.get(url, headers=headers)
|
| 527 |
response.raise_for_status()
|
| 528 |
|
| 529 |
-
fetch_time = time.perf_counter() - fetch_start
|
| 530 |
content = response.text
|
| 531 |
-
content_size_kb = len(content) / 1024
|
| 532 |
-
|
| 533 |
-
print(
|
| 534 |
-
f"[DEBUG] fetch_hf_docs: Fetched {content_size_kb:.1f}KB in {fetch_time:.2f}s"
|
| 535 |
-
)
|
| 536 |
|
| 537 |
# Return the markdown content directly
|
| 538 |
result = f"Documentation from: {url}\n\n{content}"
|
| 539 |
|
| 540 |
-
total_time = time.perf_counter() - start_time
|
| 541 |
-
print(f"[DEBUG] fetch_hf_docs: Total time {total_time:.2f}s")
|
| 542 |
-
|
| 543 |
return result, True
|
| 544 |
|
| 545 |
except httpx.HTTPStatusError as e:
|
|
|
|
| 5 |
|
| 6 |
import asyncio
|
| 7 |
import os
|
|
|
|
| 8 |
from typing import Any
|
| 9 |
|
| 10 |
import httpx
|
|
|
|
| 20 |
url = f"{base_url}/{endpoint}"
|
| 21 |
headers = {"Authorization": f"Bearer {hf_token}"}
|
| 22 |
|
|
|
|
| 23 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 24 |
response = await client.get(url, headers=headers)
|
| 25 |
response.raise_for_status()
|
| 26 |
|
|
|
|
|
|
|
|
|
|
| 27 |
return response.text
|
| 28 |
|
| 29 |
|
| 30 |
def _parse_sidebar_navigation(html_content: str) -> list[dict[str, str]]:
|
| 31 |
"""Parse the sidebar navigation and extract all links"""
|
|
|
|
|
|
|
| 32 |
soup = BeautifulSoup(html_content, "html.parser")
|
| 33 |
sidebar = soup.find("nav", class_=lambda x: x and "flex-auto" in x)
|
| 34 |
|
|
|
|
| 46 |
page_url = f"https://huggingface.co{href}" if href.startswith("/") else href
|
| 47 |
nav_data.append({"title": title, "url": page_url})
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
return nav_data
|
| 50 |
|
| 51 |
|
|
|
|
| 84 |
hf_token: str, nav_data: list[dict[str, str]]
|
| 85 |
) -> list[dict[str, str]]:
|
| 86 |
"""Fetch glimpses for all pages in parallel"""
|
|
|
|
|
|
|
| 87 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 88 |
result_items = await asyncio.gather(
|
| 89 |
*[_fetch_single_glimpse(client, hf_token, item) for item in nav_data]
|
| 90 |
)
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
return list(result_items)
|
| 93 |
|
| 94 |
|
|
|
|
| 111 |
|
| 112 |
async def explore_hf_docs(hf_token: str, endpoint: str) -> str:
|
| 113 |
"""Main function to explore documentation structure"""
|
|
|
|
|
|
|
|
|
|
| 114 |
# Fetch HTML page
|
| 115 |
html_content = await _fetch_html_page(hf_token, endpoint)
|
| 116 |
|
|
|
|
| 126 |
# Format results
|
| 127 |
result = _format_exploration_results(endpoint, result_items)
|
| 128 |
|
|
|
|
|
|
|
|
|
|
| 129 |
return result
|
| 130 |
|
| 131 |
|
|
|
|
| 174 |
global _openapi_spec_cache
|
| 175 |
|
| 176 |
if _openapi_spec_cache is not None:
|
|
|
|
| 177 |
return _openapi_spec_cache
|
| 178 |
|
|
|
|
|
|
|
|
|
|
| 179 |
url = "https://huggingface.co/.well-known/openapi.json"
|
| 180 |
|
| 181 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
|
|
|
| 185 |
spec = response.json()
|
| 186 |
_openapi_spec_cache = spec
|
| 187 |
|
|
|
|
|
|
|
|
|
|
| 188 |
return spec
|
| 189 |
|
| 190 |
|
|
|
|
| 425 |
Returns:
|
| 426 |
Tuple of (search_results, success)
|
| 427 |
"""
|
|
|
|
| 428 |
tag = arguments.get("tag", "")
|
|
|
|
| 429 |
|
| 430 |
if not tag:
|
| 431 |
return "Error: No tag provided", False
|
|
|
|
| 440 |
# Format results
|
| 441 |
formatted = _format_openapi_results(results, tag)
|
| 442 |
|
|
|
|
|
|
|
|
|
|
| 443 |
return formatted, True
|
| 444 |
|
| 445 |
except httpx.HTTPStatusError as e:
|
|
|
|
| 460 |
Returns:
|
| 461 |
Tuple of (full_markdown_content, success)
|
| 462 |
"""
|
|
|
|
| 463 |
url = arguments.get("url", "")
|
|
|
|
| 464 |
|
| 465 |
if not url:
|
| 466 |
return "Error: No URL provided", False
|
|
|
|
| 482 |
# Make request with auth
|
| 483 |
headers = {"Authorization": f"Bearer {hf_token}"}
|
| 484 |
|
|
|
|
| 485 |
async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
|
| 486 |
response = await client.get(url, headers=headers)
|
| 487 |
response.raise_for_status()
|
| 488 |
|
|
|
|
| 489 |
content = response.text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 490 |
|
| 491 |
# Return the markdown content directly
|
| 492 |
result = f"Documentation from: {url}\n\n{content}"
|
| 493 |
|
|
|
|
|
|
|
|
|
|
| 494 |
return result, True
|
| 495 |
|
| 496 |
except httpx.HTTPStatusError as e:
|