mirror of
https://github.com/MervinPraison/PraisonAIUI.git
synced 2026-11-07 05:56:17 -10:00
fix(voice-agent): warn on slow MCP doctor probe instead of failing
Use a 2s timeout for GET /api/mcp/servers and downgrade timeout-style errors to warn so stdio MCP connect does not fail the whole doctor run. Follow-up to #273 (example-only; no core SDK changes). Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
e6a346aa22
commit
8ce13a9fec
2 files changed
+40
-1
No files matched your search
@@ -17,6 +17,25 @@ def _tcp_open(host: str, port: int, timeout: float = 2.0) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
_MCP_PROBE_TIMEOUT_SEC = 2.0
|
||||
|
||||
|
||||
def _is_slow_mcp_probe(detail: str) -> bool:
|
||||
lowered = detail.lower()
|
||||
return any(token in lowered for token in ("timed out", "timeout", "temporarily unavailable"))
|
||||
|
||||
|
||||
def _mcp_servers_probe(app_port: int) -> tuple[str, str]:
|
||||
"""Probe MCP list endpoint; slow stdio connect must not fail the whole doctor run."""
|
||||
status, detail = _http_status(
|
||||
f"http://127.0.0.1:{app_port}/api/mcp/servers",
|
||||
timeout=_MCP_PROBE_TIMEOUT_SEC,
|
||||
)
|
||||
if status == "fail" and _is_slow_mcp_probe(detail):
|
||||
return "warn", detail
|
||||
return status, detail
|
||||
|
||||
|
||||
def _http_status(url: str, timeout: float = 5.0) -> tuple[str, str]:
|
||||
try:
|
||||
req = Request(url, headers={"User-Agent": "praisonai-voice-doctor"})
|
||||
@@ -64,7 +83,7 @@ def run_voice_doctor(*, app_port: int = 8001, sidecar_port: int = 8002) -> dict[
|
||||
checks.append({"name": "Speech Engine config", "status": status, "detail": detail})
|
||||
status, detail = _http_status(f"http://127.0.0.1:{app_port}/api/voice/realtime/config")
|
||||
checks.append({"name": "GPT Realtime config", "status": status, "detail": detail})
|
||||
status, detail = _http_status(f"http://127.0.0.1:{app_port}/api/mcp/servers")
|
||||
status, detail = _mcp_servers_probe(app_port)
|
||||
checks.append({"name": "MCP servers API", "status": status, "detail": detail})
|
||||
else:
|
||||
checks.append(
|
||||
|
||||
@@ -478,6 +478,26 @@ def test_voice_doctor_report(monkeypatch):
|
||||
assert report["summary"]["failed"] >= 1
|
||||
|
||||
|
||||
def test_voice_doctor_mcp_probe_timeout_is_warn(monkeypatch):
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-key-12345678")
|
||||
|
||||
def fake_http_status(url: str, timeout: float = 5.0):
|
||||
if "/api/mcp/servers" in url:
|
||||
assert timeout == 2.0
|
||||
return "fail", "timed out"
|
||||
return "pass", "HTTP 200"
|
||||
|
||||
with _voice_modules() as imp:
|
||||
doctor = imp("integrations.voice.doctor")
|
||||
monkeypatch.setattr(doctor, "_tcp_open", lambda *args, **kwargs: True)
|
||||
monkeypatch.setattr(doctor, "_http_status", fake_http_status)
|
||||
report = doctor.run_voice_doctor(app_port=8001, sidecar_port=59998)
|
||||
|
||||
mcp = next(c for c in report["checks"] if c["name"] == "MCP servers API")
|
||||
assert mcp["status"] == "warn"
|
||||
assert mcp["detail"] == "timed out"
|
||||
|
||||
|
||||
def test_call_detail_ui_includes_analytics():
|
||||
with _voice_modules() as imp:
|
||||
ui = imp("integrations.voice.call_detail_ui")
|
||||
|
||||
Reference in new issue
Block a user