Skip to content

feat(vision): ModelRouterVisionProvider + multimodal ChatMessage — bump nullain-sdk to 0.7.0 - #82

Merged
netty-linux merged 1 commit into
masterfrom
release/nullain-sdk-0.7.0
Aug 12, 2026
Merged

feat(vision): ModelRouterVisionProvider + multimodal ChatMessage — bump nullain-sdk to 0.7.0#82
netty-linux merged 1 commit into
masterfrom
release/nullain-sdk-0.7.0

Conversation

@netty-linux

Copy link
Copy Markdown
Owner

Summary

  • VisionProvider (nullain.ports.vision) gains its first adapter, ModelRouterVisionProvider: routes an image + prompt through an injected ModelRouter/LLMProvider as a plain multimodal chat completion (PLAN.md Fase 2, rescoped — no heavy OCR/CV package needed).
  • ChatMessage.content (nullain.llm.types) now also accepts list[TextPart | ImagePart] (new ContentPart union). Existing str | None path is byte-for-byte unchanged in to_api_dict().
  • VisionError added to the error hierarchy, mirroring SearchError.
  • Version: nullain-sdk 0.6.0 → 0.7.0 (MINOR). Neither ChatMessage nor VisionProvider/ModelRouterVisionProvider/SearchProvider are in nullain/__init__.py::__all__ (not covered by the formal SemVer policy per docs/api-stability.md), but the change is additive/non-breaking regardless — exactly a MINOR case in practice.
  • CHANGELOG.md's [Unreleased] block (search + vision work) moved to a dated [0.7.0] section.

Test plan

  • make check (ruff + pyright strict + pytest) green — 726 passed, 7 skipped
  • test_vision_provider_contract.py runs against ModelRouterVisionProvider via an offline fake LLMProvider
  • Manual diff of nullain-sdk/src/nullain/__init__.py — zero lines changed

Notes

🤖 Generated with Claude Code

…bump nullain-sdk to 0.7.0

VisionProvider (nullain.ports.vision) gains its first adapter,
ModelRouterVisionProvider: routes an image + prompt through an injected
ModelRouter/LLMProvider as a plain multimodal chat completion. PLAN.md
Fase 2 rescoped for this — the vision path actually used in production
needs no heavy OCR/CV dependency, so it ships as a module here instead of
the separate nullain-vision package originally planned.

ChatMessage.content (nullain.llm.types) now also accepts a list of
TextPart/ImagePart content blocks (new ContentPart union). The existing
str | None path is unchanged — to_api_dict() emits the exact same payload
as before for every text-only message.

VisionError added to the error hierarchy, mirroring SearchError's shape.
test_vision_provider_contract.py now runs against ModelRouterVisionProvider
via an offline fake LLMProvider.

Version: nullain-sdk 0.6.0 -> 0.7.0 (MINOR). Per docs/api-stability.md,
none of ChatMessage/VisionProvider/ModelRouterVisionProvider/SearchProvider
are in nullain/__init__.py's __all__, so this technically wouldn't require
any bump under the formal policy — but the change is additive and
non-breaking regardless (str | list[ContentPart] | None is a superset of
str | None; to_api_dict() is byte-for-byte unchanged for existing str | None
callers), which is exactly a MINOR bump in practice. CHANGELOG's
[Unreleased] block (search + vision work) moved to a dated [0.7.0] section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@netty-linux
netty-linux merged commit 4ed0621 into master Aug 12, 2026
11 checks passed
@netty-linux
netty-linux deleted the release/nullain-sdk-0.7.0 branch August 12, 2026 11:22
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