Skip to content

Commit 1ed8611

Browse files
LukasParkeclaude
andauthored
fix: bind the code-interpreter image type across the openrouter 1.1.40 rename (#27)
openrouter 1.1.40 renamed components.OutputImage to components.CodeInterpreterImageOutput with no back-compat alias. This package re-exports that symbol by name from __init__.py and declares `openrouter>=1.1,<2`, so any resolution at or above 1.1.40 raises ImportError on `import openrouter_agent` — the whole package, not just the renamed type. That is the state of the published 0.8.0 wheel today: a plain `pip install openrouter-agent-sdk` resolves the newest 1.1.x and cannot be imported. CI missed it because every job except `build` runs through uv.lock, which pins 1.1.22; `build` installs the wheel unpinned and is the one job that sees what users get. Bind whichever name the installed SDK provides. The two models are structurally identical (type, url) and this package only re-exports the type, so OutputImage and OutputInputImage stay stable for consumers on both sides of the boundary. Verified against 1.1.22, 1.1.39, 1.1.40 and 1.1.90; the full unit suite also passes against 1.1.90, so the rename was the only incompatibility in the range. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent f060a49 commit 1ed8611

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

‎src/openrouter_agent/__init__.py‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
OpenResponsesResult,
4040
OutputFileSearchCallItem,
4141
OutputFunctionCallItem,
42-
OutputImage,
4342
OutputImageGenerationCallItem,
4443
OutputItems,
4544
OutputMessage,
@@ -235,6 +234,21 @@ class BeforeCreateRequestHook(Protocol):
235234
def before_create_request(self, hook_ctx: BeforeCreateRequestContext, request: Any) -> Any: ...
236235

237236

237+
# openrouter 1.1.40 renamed OutputImage to CodeInterpreterImageOutput with no
238+
# back-compat alias, and this package's constraint (openrouter>=1.1,<2) spans
239+
# both. The two models are structurally identical (type, url) and this package
240+
# only re-exports the type, so bind whichever name the installed SDK provides
241+
# to keep OutputImage / OutputInputImage stable for consumers.
242+
# Both ignores are load-bearing across the range, not just today: mypy resolves
243+
# against the locked SDK, so exactly one of these two imports is unresolvable at
244+
# any given pin, and which one flips when the lock crosses 1.1.40.
245+
try:
246+
from openrouter.components import OutputImage # type: ignore[attr-defined]
247+
except ImportError: # openrouter >= 1.1.40
248+
from openrouter.components import ( # type: ignore[assignment, no-redef]
249+
CodeInterpreterImageOutput as OutputImage,
250+
)
251+
238252
OutputInputImage = OutputImage
239253

240254
__all__ = [
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Guards the public re-exports that the generated SDK has renamed under us.
2+
3+
The package constraint is ``openrouter>=1.1,<2``, so a plain install resolves
4+
whatever 1.1.x is newest. A symbol this package re-exports by name can vanish
5+
inside that range -- openrouter 1.1.40 renamed ``OutputImage`` -- and the
6+
failure mode is an ImportError at ``import openrouter_agent``, i.e. the whole
7+
package, not just the renamed type.
8+
"""
9+
10+
from __future__ import annotations
11+
12+
import openrouter_agent
13+
14+
15+
def test_output_image_is_exported_under_both_names() -> None:
16+
assert openrouter_agent.OutputImage is openrouter_agent.OutputInputImage
17+
18+
19+
def test_output_image_has_the_code_interpreter_image_shape() -> None:
20+
fields = openrouter_agent.OutputImage.model_fields
21+
22+
assert set(fields) == {"type", "url"}
23+
24+
25+
def test_declared_public_api_is_fully_importable() -> None:
26+
missing = [name for name in openrouter_agent.__all__ if not hasattr(openrouter_agent, name)]
27+
28+
assert missing == []

0 commit comments

Comments
 (0)