Spaces:
Running
on
Zero
Running
on
Zero
Y Phung Nguyen
commited on
Commit
Β·
7a7ea02
1
Parent(s):
e6bba1f
Upd MCP Gemini timeout bufer
Browse files
agent.py
CHANGED
|
@@ -288,19 +288,29 @@ async def call_tool(name: str, arguments: dict) -> Sequence[TextContent | ImageC
|
|
| 288 |
"max_output_tokens": GEMINI_MAX_OUTPUT_TOKENS
|
| 289 |
}
|
| 290 |
|
| 291 |
-
# Convert timeout from milliseconds to seconds
|
| 292 |
-
|
|
|
|
|
|
|
| 293 |
logger.info(f"π΅ Calling Gemini API with model={model}, timeout={timeout_seconds}s...")
|
| 294 |
|
| 295 |
# Use asyncio.to_thread to make the blocking call async
|
| 296 |
# The API accepts contents as a list and config as a separate parameter
|
| 297 |
def generate_sync():
|
| 298 |
-
|
| 299 |
-
model=model
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
|
|
|
|
| 304 |
response = await asyncio.wait_for(
|
| 305 |
asyncio.to_thread(generate_sync),
|
| 306 |
timeout=timeout_seconds
|
|
@@ -329,10 +339,11 @@ async def call_tool(name: str, arguments: dict) -> Sequence[TextContent | ImageC
|
|
| 329 |
return [TextContent(type="text", text="Error: No response from Gemini")]
|
| 330 |
|
| 331 |
except asyncio.TimeoutError:
|
| 332 |
-
timeout_seconds = min(GEMINI_TIMEOUT / 1000.0, 100.0)
|
| 333 |
error_msg = f"Gemini API call timed out after {timeout_seconds}s"
|
| 334 |
logger.error(f"β {error_msg}")
|
| 335 |
-
|
|
|
|
|
|
|
| 336 |
except Exception as e:
|
| 337 |
logger.error(f"β Error generating content: {type(e).__name__}: {e}")
|
| 338 |
import traceback
|
|
|
|
| 288 |
"max_output_tokens": GEMINI_MAX_OUTPUT_TOKENS
|
| 289 |
}
|
| 290 |
|
| 291 |
+
# Convert timeout from milliseconds to seconds
|
| 292 |
+
# Cap at 18s to leave buffer for client timeout (25s) and communication overhead
|
| 293 |
+
# This ensures server completes before client times out
|
| 294 |
+
timeout_seconds = min(GEMINI_TIMEOUT / 1000.0, 18.0)
|
| 295 |
logger.info(f"π΅ Calling Gemini API with model={model}, timeout={timeout_seconds}s...")
|
| 296 |
|
| 297 |
# Use asyncio.to_thread to make the blocking call async
|
| 298 |
# The API accepts contents as a list and config as a separate parameter
|
| 299 |
def generate_sync():
|
| 300 |
+
try:
|
| 301 |
+
logger.debug(f"Calling Gemini API synchronously (model={model})...")
|
| 302 |
+
result = gemini_client.models.generate_content(
|
| 303 |
+
model=model,
|
| 304 |
+
contents=gemini_contents,
|
| 305 |
+
config=generation_config,
|
| 306 |
+
)
|
| 307 |
+
logger.debug("Gemini API synchronous call completed")
|
| 308 |
+
return result
|
| 309 |
+
except Exception as sync_error:
|
| 310 |
+
logger.error(f"Error in synchronous Gemini API call: {type(sync_error).__name__}: {sync_error}")
|
| 311 |
+
raise
|
| 312 |
|
| 313 |
+
logger.debug(f"Starting async wrapper for Gemini API call (timeout={timeout_seconds}s)...")
|
| 314 |
response = await asyncio.wait_for(
|
| 315 |
asyncio.to_thread(generate_sync),
|
| 316 |
timeout=timeout_seconds
|
|
|
|
| 339 |
return [TextContent(type="text", text="Error: No response from Gemini")]
|
| 340 |
|
| 341 |
except asyncio.TimeoutError:
|
|
|
|
| 342 |
error_msg = f"Gemini API call timed out after {timeout_seconds}s"
|
| 343 |
logger.error(f"β {error_msg}")
|
| 344 |
+
logger.error(f" Model: {model}, Prompt length: {len(user_prompt)} chars")
|
| 345 |
+
logger.error(f" This may indicate network issues, API rate limiting, or the request is too complex")
|
| 346 |
+
return [TextContent(type="text", text=f"Error: {error_msg}. The request may be too complex or there may be network issues.")]
|
| 347 |
except Exception as e:
|
| 348 |
logger.error(f"β Error generating content: {type(e).__name__}: {e}")
|
| 349 |
import traceback
|
client.py
CHANGED
|
@@ -375,18 +375,23 @@ async def call_agent(user_prompt: str, system_prompt: str = None, files: list =
|
|
| 375 |
logger.debug(f"MCP tool arguments keys: {list(arguments.keys())}")
|
| 376 |
logger.debug(f"User prompt length: {len(user_prompt)} chars")
|
| 377 |
|
| 378 |
-
# Add timeout to prevent hanging
|
|
|
|
|
|
|
|
|
|
| 379 |
try:
|
| 380 |
-
logger.debug("Starting MCP tool call with
|
| 381 |
result = await asyncio.wait_for(
|
| 382 |
session.call_tool(generate_tool.name, arguments=arguments),
|
| 383 |
-
timeout=
|
| 384 |
)
|
| 385 |
logger.info(f"β
MCP tool call completed successfully")
|
| 386 |
except asyncio.TimeoutError:
|
| 387 |
-
logger.error(f"β MCP tool call timed out after
|
| 388 |
-
logger.error(f"
|
|
|
|
| 389 |
logger.error(f" Check if agent.py process is still running and responsive")
|
|
|
|
| 390 |
# Invalidate session on timeout to force retry
|
| 391 |
config.global_mcp_session = None
|
| 392 |
# Properly cleanup stdio context
|
|
|
|
| 375 |
logger.debug(f"MCP tool arguments keys: {list(arguments.keys())}")
|
| 376 |
logger.debug(f"User prompt length: {len(user_prompt)} chars")
|
| 377 |
|
| 378 |
+
# Add timeout to prevent hanging
|
| 379 |
+
# Client timeout should be longer than server timeout to account for communication overhead
|
| 380 |
+
# Server timeout is ~18s, so client should wait ~25s to allow for processing + communication
|
| 381 |
+
client_timeout = 25.0
|
| 382 |
try:
|
| 383 |
+
logger.debug(f"Starting MCP tool call with {client_timeout}s timeout...")
|
| 384 |
result = await asyncio.wait_for(
|
| 385 |
session.call_tool(generate_tool.name, arguments=arguments),
|
| 386 |
+
timeout=client_timeout
|
| 387 |
)
|
| 388 |
logger.info(f"β
MCP tool call completed successfully")
|
| 389 |
except asyncio.TimeoutError:
|
| 390 |
+
logger.error(f"β MCP tool call timed out after {client_timeout}s")
|
| 391 |
+
logger.error(f" Tool: {generate_tool.name}, Model: {model or 'default'}")
|
| 392 |
+
logger.error(f" This suggests the MCP server (agent.py) is not responding or the Gemini API call is taking too long")
|
| 393 |
logger.error(f" Check if agent.py process is still running and responsive")
|
| 394 |
+
logger.error(f" Consider increasing GEMINI_TIMEOUT or checking network connectivity")
|
| 395 |
# Invalidate session on timeout to force retry
|
| 396 |
config.global_mcp_session = None
|
| 397 |
# Properly cleanup stdio context
|