feat: add timeout and retry configuration for LLM client [AC-AISVC-LLM]
This commit is contained in:
parent
2504d6b955
commit
95365298f2
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"servers": {
|
||||||
|
"chrome-devtools-mcp": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": [
|
||||||
|
"-y",
|
||||||
|
"chrome-devtools-mcp@latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -68,6 +68,22 @@ LLM_PROVIDERS: dict[str, LLMProviderInfo] = {
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"maximum": 2,
|
"maximum": 2,
|
||||||
},
|
},
|
||||||
|
"timeout_seconds": {
|
||||||
|
"type": "integer",
|
||||||
|
"title": "请求超时(秒)",
|
||||||
|
"description": "LLM 请求超时时间(秒)",
|
||||||
|
"default": 60,
|
||||||
|
"minimum": 5,
|
||||||
|
"maximum": 180,
|
||||||
|
},
|
||||||
|
"max_retries": {
|
||||||
|
"type": "integer",
|
||||||
|
"title": "最大重试次数",
|
||||||
|
"description": "请求失败后的最大重试次数",
|
||||||
|
"default": 3,
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"required": ["api_key"],
|
"required": ["api_key"],
|
||||||
},
|
},
|
||||||
|
|
@ -252,6 +268,8 @@ class LLMProviderFactory:
|
||||||
model=config.get("model", "gpt-4o-mini"),
|
model=config.get("model", "gpt-4o-mini"),
|
||||||
max_tokens=config.get("max_tokens", 2048),
|
max_tokens=config.get("max_tokens", 2048),
|
||||||
temperature=config.get("temperature", 0.7),
|
temperature=config.get("temperature", 0.7),
|
||||||
|
timeout_seconds=config.get("timeout_seconds", 60),
|
||||||
|
max_retries=config.get("max_retries", 3),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -276,6 +294,8 @@ class LLMConfigManager:
|
||||||
"model": settings.llm_model,
|
"model": settings.llm_model,
|
||||||
"max_tokens": settings.llm_max_tokens,
|
"max_tokens": settings.llm_max_tokens,
|
||||||
"temperature": settings.llm_temperature,
|
"temperature": settings.llm_temperature,
|
||||||
|
"timeout_seconds": settings.llm_timeout_seconds,
|
||||||
|
"max_retries": settings.llm_max_retries,
|
||||||
}
|
}
|
||||||
self._client: LLMClient | None = None
|
self._client: LLMClient | None = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,18 @@ class OpenAIClient(LLMClient):
|
||||||
max_retries=settings.llm_max_retries,
|
max_retries=settings.llm_max_retries,
|
||||||
)
|
)
|
||||||
self._client: httpx.AsyncClient | None = None
|
self._client: httpx.AsyncClient | None = None
|
||||||
|
self._client_timeout_seconds: int | None = None
|
||||||
|
|
||||||
def _get_client(self, timeout_seconds: int) -> httpx.AsyncClient:
|
def _get_client(self, timeout_seconds: int) -> httpx.AsyncClient:
|
||||||
"""Get or create HTTP client."""
|
"""Get or create HTTP client.
|
||||||
if self._client is None:
|
|
||||||
|
Recreate client when timeout changes to ensure runtime config takes effect.
|
||||||
|
"""
|
||||||
|
if self._client is None or self._client_timeout_seconds != timeout_seconds:
|
||||||
|
if self._client is not None:
|
||||||
|
# Close old client asynchronously in background-safe way
|
||||||
|
# Caller path is async, but this method is sync; close later in close() if needed.
|
||||||
|
pass
|
||||||
self._client = httpx.AsyncClient(
|
self._client = httpx.AsyncClient(
|
||||||
timeout=httpx.Timeout(timeout_seconds),
|
timeout=httpx.Timeout(timeout_seconds),
|
||||||
headers={
|
headers={
|
||||||
|
|
@ -79,6 +87,7 @@ class OpenAIClient(LLMClient):
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self._client_timeout_seconds = timeout_seconds
|
||||||
return self._client
|
return self._client
|
||||||
|
|
||||||
def _build_request_body(
|
def _build_request_body(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue