Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Commit ·
f4ebc8f
1
Parent(s): f03cbf4
fix: gracefully handle MCP and OpenAPI failures during startup
Browse files- Wrap MCP connection in try/except so a 401/timeout doesn't crash the
session — continue without MCP tools
- Wrap OpenAPI spec fetch in try/except so a 500 from
huggingface.co/.well-known/openapi.json doesn't kill the session
- Add assistant_chunk and assistant_stream_end handlers to CLI event
listener so streaming responses are printed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- agent/core/tools.py +20 -15
- agent/main.py +6 -0
agent/core/tools.py
CHANGED
|
@@ -177,17 +177,19 @@ class ToolRouter:
|
|
| 177 |
search_openapi_handler,
|
| 178 |
)
|
| 179 |
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
|
|
|
| 188 |
)
|
| 189 |
-
|
| 190 |
-
|
|
|
|
| 191 |
|
| 192 |
def get_tool_specs_for_llm(self) -> list[dict[str, Any]]:
|
| 193 |
"""Get tool specifications in OpenAI format"""
|
|
@@ -207,12 +209,15 @@ class ToolRouter:
|
|
| 207 |
|
| 208 |
async def __aenter__(self) -> "ToolRouter":
|
| 209 |
if self.mcp_client is not None:
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
|
| 215 |
-
# Register OpenAPI tool (requires async initialization)
|
| 216 |
await self.register_openapi_tool()
|
| 217 |
|
| 218 |
total_tools = len(self.tools)
|
|
|
|
| 177 |
search_openapi_handler,
|
| 178 |
)
|
| 179 |
|
| 180 |
+
try:
|
| 181 |
+
openapi_spec = await _get_api_search_tool_spec()
|
| 182 |
+
self.register_tool(
|
| 183 |
+
ToolSpec(
|
| 184 |
+
name=openapi_spec["name"],
|
| 185 |
+
description=openapi_spec["description"],
|
| 186 |
+
parameters=openapi_spec["parameters"],
|
| 187 |
+
handler=search_openapi_handler,
|
| 188 |
+
)
|
| 189 |
)
|
| 190 |
+
logger.info(f"Loaded OpenAPI search tool: {openapi_spec['name']}")
|
| 191 |
+
except Exception as e:
|
| 192 |
+
logger.warning("Failed to load OpenAPI search tool: %s", e)
|
| 193 |
|
| 194 |
def get_tool_specs_for_llm(self) -> list[dict[str, Any]]:
|
| 195 |
"""Get tool specifications in OpenAI format"""
|
|
|
|
| 209 |
|
| 210 |
async def __aenter__(self) -> "ToolRouter":
|
| 211 |
if self.mcp_client is not None:
|
| 212 |
+
try:
|
| 213 |
+
await self.mcp_client.__aenter__()
|
| 214 |
+
await self.mcp_client.initialize()
|
| 215 |
+
await self.register_mcp_tools()
|
| 216 |
+
self._mcp_initialized = True
|
| 217 |
+
except Exception as e:
|
| 218 |
+
logger.warning("MCP connection failed, continuing without MCP tools: %s", e)
|
| 219 |
+
self.mcp_client = None
|
| 220 |
|
|
|
|
| 221 |
await self.register_openapi_tool()
|
| 222 |
|
| 223 |
total_tools = len(self.tools)
|
agent/main.py
CHANGED
|
@@ -147,6 +147,12 @@ async def event_listener(
|
|
| 147 |
content = event.data.get("content", "") if event.data else ""
|
| 148 |
if content:
|
| 149 |
print(f"\nAssistant: {content}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
elif event.event_type == "tool_call":
|
| 151 |
tool_name = event.data.get("tool", "") if event.data else ""
|
| 152 |
arguments = event.data.get("arguments", {}) if event.data else {}
|
|
|
|
| 147 |
content = event.data.get("content", "") if event.data else ""
|
| 148 |
if content:
|
| 149 |
print(f"\nAssistant: {content}")
|
| 150 |
+
elif event.event_type == "assistant_chunk":
|
| 151 |
+
content = event.data.get("content", "") if event.data else ""
|
| 152 |
+
if content:
|
| 153 |
+
print(content, end="", flush=True)
|
| 154 |
+
elif event.event_type == "assistant_stream_end":
|
| 155 |
+
print() # newline after streaming
|
| 156 |
elif event.event_type == "tool_call":
|
| 157 |
tool_name = event.data.get("tool", "") if event.data else ""
|
| 158 |
arguments = event.data.get("arguments", {}) if event.data else {}
|