fix(deps): pin openrouter below 0.11 to avoid SSE stream regressions (#373)

* fix(openrouter): address SSE stream leak by closing response iterator

* refactor(openrouter): pass through SDK args in SSE leak patch

* test(openrouter): make SSE leak tests version-agnostic across SDK generations

* fix(openrouter): remove SSE stream leak patch and update dependencies
This commit is contained in:
Xi Zhang
2026-07-22 15:03:57 +01:00
committed by GitHub
parent 1abfc8236d
commit e9857dde22
4 changed files with 29 additions and 3 deletions
+5
View File
@@ -79,6 +79,11 @@ def main():
warnings.filterwarnings(
"ignore", message=".*type is unknown and inference may fail.*"
)
# v3 streaming is a deliberate choice (#268), so its beta notice is noise.
# Matched by message, not category, to keep other beta warnings visible.
warnings.filterwarnings(
"ignore", message=".*v3 streaming protocol on Pregel is experimental.*"
)
from ..config import load_config
from .commands import _configure_logging
+2
View File
@@ -25,6 +25,8 @@ dependencies = [
"langchain-google-genai>=4.2",
"langchain-ollama>=1.1",
"langchain-openrouter>=0.2.5",
# 0.11.0+ SSE regressions: teardown noise + mid-turn ReadTimeout
"openrouter>=0.10.8,<0.11.0",
"tavily-python>=0.7",
"pyyaml>=6.0",
"rich>=15.0",
+17
View File
@@ -381,6 +381,13 @@ class TestSlashModelIdFallback:
# =============================================================================
def _sdk_retry_supports_status_codes_override() -> bool:
"""openrouter>=0.11 only; the 429 override degrades to a no-op below that."""
from openrouter.utils.retries import RetryConfig
return "status_codes_override" in getattr(RetryConfig, "__annotations__", {})
class TestThirdPartyRouting:
@patch("EvoScientist.llm.models.init_chat_model")
def test_siliconflow_routes_through_openai(self, mock_init, monkeypatch):
@@ -471,6 +478,11 @@ class TestThirdPartyRouting:
# --- OpenRouter upstream 429 retry ---
@pytest.mark.skipif(
not _sdk_retry_supports_status_codes_override(),
reason="openrouter<0.11 RetryConfig lacks status_codes_override; "
"the 429 override no-ops there by design (models.py hasattr guard)",
)
def test_openrouter_429_added_to_retryable_status_codes(self, monkeypatch):
"""Upstream 429s must become retryable on the real SDK client.
@@ -501,6 +513,11 @@ class TestThirdPartyRouting:
retry_config = model.client.sdk_configuration.retry_config
assert getattr(retry_config, "status_codes_override", None) is None
@pytest.mark.skipif(
not _sdk_retry_supports_status_codes_override(),
reason="openrouter<0.11 RetryConfig lacks status_codes_override; "
"the 429 override no-ops there by design (models.py hasattr guard)",
)
def test_openrouter_429_retried_on_the_wire(self, monkeypatch):
"""End-to-end: a 429 with Retry-After is retried and the retry succeeds."""
import httpx
Generated
+5 -3
View File
@@ -973,6 +973,7 @@ dependencies = [
{ name = "lazy-loader" },
{ name = "markdownify" },
{ name = "nest-asyncio" },
{ name = "openrouter" },
{ name = "prompt-toolkit" },
{ name = "psutil" },
{ name = "python-dotenv" },
@@ -1083,6 +1084,7 @@ requires-dist = [
{ name = "lazy-loader", specifier = ">=0.5" },
{ name = "markdownify", specifier = ">=1.2" },
{ name = "nest-asyncio", specifier = ">=1.6" },
{ name = "openrouter", specifier = ">=0.10.8,<0.11.0" },
{ name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.5.0" },
{ name = "prompt-toolkit", specifier = ">=3.0" },
{ name = "psutil", specifier = ">=6.0" },
@@ -2920,7 +2922,7 @@ wheels = [
[[package]]
name = "openrouter"
version = "0.11.44"
version = "0.10.8"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "httpcore" },
@@ -2928,9 +2930,9 @@ dependencies = [
{ name = "jsonpath-python" },
{ name = "pydantic" },
]
sdist = { url = "https://files.pythonhosted.org/packages/38/66/1c239f07abd22c7eb505e664deb31eee7b9d1451a4f7e7249e60711b42b7/openrouter-0.11.44.tar.gz", hash = "sha256:7a61c42949a96a6c2da2bb7810f7ba99581271c2344deecff34d2bbae9b83157", size = 380246, upload-time = "2026-07-17T20:59:07.669Z" }
sdist = { url = "https://files.pythonhosted.org/packages/38/4c/1fed3f4cbcf0962d8117b54f1740696c98d0dc2e3d5c34459d46effe8a3b/openrouter-0.10.8.tar.gz", hash = "sha256:ac7f4cea1ec1c2a063b0ad9792a8f64dde68ed053279b6c42bee849a50afc47c", size = 340259, upload-time = "2026-06-28T15:33:38.067Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/08/c4/1572fff0d9169c0aa849ebaa7d492508eb2d4d583b8b5caf9a5a97760123/openrouter-0.11.44-py3-none-any.whl", hash = "sha256:b787f132a00fe058d8772985d5ec25dfa446b2ad00309be03143f8d8f5b5371b", size = 837128, upload-time = "2026-07-17T20:59:06.287Z" },
{ url = "https://files.pythonhosted.org/packages/15/ae/76fc8ad57f6717e9231fbd7313e5623733d86f1a2149baa458772164f456/openrouter-0.10.8-py3-none-any.whl", hash = "sha256:ff9b3cd2f55a3f905d21f56517344da9f9556ffbd2cb9d31ddc388c4b930aab6", size = 748497, upload-time = "2026-06-28T15:33:36.627Z" },
]
[[package]]