Skip to content

fix: bind the code-interpreter image type across the openrouter 1.1.40 rename - #27

Merged
LukasParke merged 1 commit into
mainfrom
fix/openrouter-1.1.40-outputimage-rename
Aug 26, 2026
Merged

fix: bind the code-interpreter image type across the openrouter 1.1.40 rename#27
LukasParke merged 1 commit into
mainfrom
fix/openrouter-1.1.40-outputimage-rename

Conversation

@LukasParke

Copy link
Copy Markdown
Contributor

Fixes the build job, which is red on main and on every open PR.

The bug

openrouter 1.1.40 renamed components.OutputImagecomponents.CodeInterpreterImageOutput with no back-compat alias. __init__.py imports that symbol by name, and this package declares openrouter>=1.1,<2 — so any resolution at or above 1.1.40 raises:

ImportError: cannot import name 'OutputImage' from 'openrouter.components'
  src/openrouter_agent/__init__.py, line 20

That is an import failure on import openrouter_agentthe entire package, not just the renamed type.

This is the state of the published 0.8.0 wheel right now. A plain pip install openrouter-agent-sdk resolves the newest 1.1.x and produces an uninstallable-in-practice package. This PR is therefore worth landing ahead of the release train, not just to unstick CI.

Why CI only just caught it

Every job except build runs through uv.lock, which pins openrouter 1.1.22 — comfortably below the boundary. build installs the wheel unpinned (uv run --isolated --no-project --with "$wheel"), so it is the only job that sees what a user actually gets. It went red on its own as soon as a run happened after the SDK release; the last green main run predates it.

The fix

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 — both in __all__ — stay stable for consumers on both sides of the boundary.

Both type: ignore codes are load-bearing across the range rather than redundant: mypy resolves against the locked SDK, so exactly one of the two imports is unresolvable at any given pin, and which one flips when the lock crosses 1.1.40. warn_unused_ignores is already false.

Scope check

I checked every SDK symbol this package imports against the newest release: OutputImage is the only one missing. The full 117-test unit suite also passes against 1.1.90, so the rename was the sole incompatibility in the range — no cascade, and no reason to move the substrate pin.

Tests

tests/unit/test_sdk_compat_exports.py — the alias identity, the {type, url} shape, and a sweep asserting every name in __all__ is actually importable (the general form of this failure).

Mutation-checked: with the shim reverted, the CI build step reproduces the original ImportError verbatim and the new tests fail at collection under the newest SDK.

Verification

.upstreamer/scripts/verify.sh                        PASS: 0 failures
  (uv sync --frozen, uv lock --check, ruff check,
   ruff format --check, mypy src tests,
   pytest --cov-fail-under=83, 31 required symbols)

import openrouter_agent against openrouter:
  1.1.22  OK -> OutputImage
  1.1.39  OK -> OutputImage                  (last release before the rename)
  1.1.40  OK -> CodeInterpreterImageOutput   (first release with it)
  1.1.90  OK -> CodeInterpreterImageOutput   (newest)

full unit suite against 1.1.90               117 passed
CI build step verbatim, unpinned             imports cleanly (resolves 1.1.90)

…0 rename

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>
@LukasParke
LukasParke merged commit 1ed8611 into main Aug 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant