diff --git a/src/openrouter_agent/__init__.py b/src/openrouter_agent/__init__.py index 5df8a08..5036ce4 100644 --- a/src/openrouter_agent/__init__.py +++ b/src/openrouter_agent/__init__.py @@ -39,7 +39,6 @@ OpenResponsesResult, OutputFileSearchCallItem, OutputFunctionCallItem, - OutputImage, OutputImageGenerationCallItem, OutputItems, OutputMessage, @@ -235,6 +234,21 @@ class BeforeCreateRequestHook(Protocol): def before_create_request(self, hook_ctx: BeforeCreateRequestContext, request: Any) -> Any: ... +# openrouter 1.1.40 renamed OutputImage to CodeInterpreterImageOutput with no +# back-compat alias, and this package's constraint (openrouter>=1.1,<2) spans +# both. The two models are structurally identical (type, url) and this package +# only re-exports the type, so bind whichever name the installed SDK provides +# to keep OutputImage / OutputInputImage stable for consumers. +# Both ignores are load-bearing across the range, not just today: mypy resolves +# against the locked SDK, so exactly one of these two imports is unresolvable at +# any given pin, and which one flips when the lock crosses 1.1.40. +try: + from openrouter.components import OutputImage # type: ignore[attr-defined] +except ImportError: # openrouter >= 1.1.40 + from openrouter.components import ( # type: ignore[assignment, no-redef] + CodeInterpreterImageOutput as OutputImage, + ) + OutputInputImage = OutputImage __all__ = [ diff --git a/tests/unit/test_sdk_compat_exports.py b/tests/unit/test_sdk_compat_exports.py new file mode 100644 index 0000000..5631743 --- /dev/null +++ b/tests/unit/test_sdk_compat_exports.py @@ -0,0 +1,28 @@ +"""Guards the public re-exports that the generated SDK has renamed under us. + +The package constraint is ``openrouter>=1.1,<2``, so a plain install resolves +whatever 1.1.x is newest. A symbol this package re-exports by name can vanish +inside that range -- openrouter 1.1.40 renamed ``OutputImage`` -- and the +failure mode is an ImportError at ``import openrouter_agent``, i.e. the whole +package, not just the renamed type. +""" + +from __future__ import annotations + +import openrouter_agent + + +def test_output_image_is_exported_under_both_names() -> None: + assert openrouter_agent.OutputImage is openrouter_agent.OutputInputImage + + +def test_output_image_has_the_code_interpreter_image_shape() -> None: + fields = openrouter_agent.OutputImage.model_fields + + assert set(fields) == {"type", "url"} + + +def test_declared_public_api_is_fully_importable() -> None: + missing = [name for name in openrouter_agent.__all__ if not hasattr(openrouter_agent, name)] + + assert missing == []