fix: add 570s total timeout to agent runner
Wraps the tool-calling loop in asyncio.wait_for so long-running tasks (e.g. consultation summary generation) return a clean Hebrew message instead of being abruptly cut when PHP closes the connection at 600s. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, Callable
|
||||
@@ -84,6 +85,7 @@ class AgentRunner:
|
||||
model: str = "sonnet",
|
||||
max_tokens: int = 4096,
|
||||
max_iterations: int = 10,
|
||||
total_timeout: float = 570.0,
|
||||
):
|
||||
self.client = AsyncOpenAI(
|
||||
base_url=f"{ai_gateway_url.rstrip('/')}/v1",
|
||||
@@ -92,6 +94,7 @@ class AgentRunner:
|
||||
self.model = model
|
||||
self.max_tokens = max_tokens
|
||||
self.max_iterations = max_iterations
|
||||
self.total_timeout = total_timeout
|
||||
|
||||
async def run(
|
||||
self,
|
||||
@@ -108,7 +111,45 @@ class AgentRunner:
|
||||
kb_topic_name: str | None = None,
|
||||
on_event: Callable[[dict], None] | None = None,
|
||||
) -> str:
|
||||
"""Run a conversation with tool-calling loop. Returns the final text response.
|
||||
"""Run a conversation with tool-calling loop, bounded by total_timeout seconds."""
|
||||
try:
|
||||
return await asyncio.wait_for(
|
||||
self._run_impl(
|
||||
system_prompt=system_prompt,
|
||||
messages=messages,
|
||||
context=context,
|
||||
espocrm_url=espocrm_url,
|
||||
espocrm_api_key=espocrm_api_key,
|
||||
depth=depth,
|
||||
blocked_tools=blocked_tools,
|
||||
allowed_toolsets=allowed_toolsets,
|
||||
kb_sources_used=kb_sources_used,
|
||||
kb_topic_id=kb_topic_id,
|
||||
kb_topic_name=kb_topic_name,
|
||||
on_event=on_event,
|
||||
),
|
||||
timeout=self.total_timeout,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning("[agent] total timeout (%.0fs) reached", self.total_timeout)
|
||||
return "⏱️ המשימה לקחה יותר זמן מהמותר. נסי לפצל אותה לחלקים קטנים — למשל: קודם בקשי לקרוא מסמך ספציפי, ואז לכתוב את הסיכום."
|
||||
|
||||
async def _run_impl(
|
||||
self,
|
||||
system_prompt: str,
|
||||
messages: list[dict[str, str]],
|
||||
context: dict,
|
||||
espocrm_url: str,
|
||||
espocrm_api_key: str,
|
||||
depth: int = 0,
|
||||
blocked_tools: set[str] | None = None,
|
||||
allowed_toolsets: list[str] | None = None,
|
||||
kb_sources_used: list[dict] | None = None,
|
||||
kb_topic_id: int | None = None,
|
||||
kb_topic_name: str | None = None,
|
||||
on_event: Callable[[dict], None] | None = None,
|
||||
) -> str:
|
||||
"""Internal tool-calling loop. Returns the final text response.
|
||||
|
||||
Args:
|
||||
depth: Current delegation depth. 0 = main conversation, 1 = child agent.
|
||||
|
||||
Reference in New Issue
Block a user