fix(genai): add automatic Partial wrapping for streaming requests#1695
fix(genai): add automatic Partial wrapping for streaming requests#1695
Conversation
- Automatically wrap regular models with Partial when stream=True is used - Prevents AssertionError in function_calls.py when streaming Gemini responses - Add comprehensive tests for sync and async streaming with regular models - Maintains backward compatibility with existing Partial usage Fixes #1691 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
instructor | 634428a | Commit Preview URL Branch Preview URL |
Jul 11 2025, 10:11 PM |
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: ✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Error Handling: 3. Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if kwargs.get("stream", False) and not issubclass(response_model, PartialBase):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewExcellent test additions:
Test quality:
📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with the minor suggestions above for future consideration. |
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to aafb781 in 1 minute and 19 seconds. Click for details.
- Reviewed
94lines of code in2files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. instructor/process_response.py:629
- Draft comment:
Ensure response_model is a class before using issubclass to avoid potential runtime errors if a non-class type is passed. - Reason this comment was not posted:
Confidence changes required:80%<= threshold85%None
2. tests/llm/test_genai/test_stream.py:106
- Draft comment:
New tests for regular model streaming (with implicit Partial wrapping) look comprehensive and validate both sync and async scenarios. - Reason this comment was not posted:
Confidence changes required:0%<= threshold85%None
Workflow ID: wflow_XdADUzaMWCKLAxSC
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
| ) -> tuple[type[T], dict[str, Any]]: | ||
| from google.genai import types | ||
|
|
||
| # Automatically wrap regular models with Partial when streaming is enabled |
There was a problem hiding this comment.
Duplicate partial wrapping logic in both handle_genai_structured_outputs and handle_genai_tools. Consider extracting a helper to DRY this pattern.
- Changed provider format from 'genai/gemini-2.5-flash' to 'google/gemini-2.5-flash' - Added comprehensive streaming examples with create_partial and create_iterable - Updated template variables examples to match test structure - Added async streaming examples for both partial and iterable methods
- Removed outdated mkdocs and mkdocs-material dependencies from the main dependencies list. - Added pre-commit back to the development dependencies. - Updated GenAI client initialization to use "genai/gemini-2.5-flash" across multiple documentation examples. - Clarified streaming limitations in the documentation regarding GenAI models. This update ensures the integration is aligned with the latest model version and improves the clarity of the documentation.
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: ✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Error Handling: 3. Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if kwargs.get("stream", False) and not issubclass(response_model, PartialBase):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewExcellent test additions:
Test quality:
📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with the minor suggestions above for future consideration. |
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: Todo List:
✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (
inspect.isclass(response_model)
and issubclass(response_model, (IterableBase, PartialBase))
and stream
):Consider adding the safety check to match existing patterns: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Code Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if (kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewExcellent test additions:
Test quality:
📚 Documentation UpdatesWell-executed documentation changes:
📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with the minor type safety suggestion above for future consideration. |
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed 97646b4 in 51 seconds. Click for details.
- Reviewed
32lines of code in2files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. pyproject.toml:116
- Draft comment:
Added pre-commit dependency. Ensure any required pre-commit configuration (like .pre-commit-config.yaml) is updated. - Reason this comment was not posted:
Confidence changes required:33%<= threshold85%None
2. uv.lock:1835
- Draft comment:
Pre-commit added in dev dependencies without a specifier. Verify consistency with pyproject.toml version constraints. - Reason this comment was not posted:
Confidence changes required:33%<= threshold85%None
3. uv.lock:1993
- Draft comment:
Pre-commit added with explicit version specifier. Confirm it matches the pyproject.toml requirement and overall dependency management. - Reason this comment was not posted:
Confidence changes required:33%<= threshold85%None
Workflow ID: wflow_cOj0QwaQPH8ngrZF
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed a5363f9 in 2 minutes and 14 seconds. Click for details.
- Reviewed
406lines of code in3files - Skipped
0files when reviewing. - Skipped posting
11draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. docs/integrations/genai.md:54
- Draft comment:
Updated provider from 'genai/gemini-1.5-flash' to 'google/gemini-2.5-flash'. Ensure all examples consistently use the new provider name. - Reason this comment was not posted:
Comment looked like it was already resolved.
2. docs/integrations/genai.md:180
- Draft comment:
Reformatted the 'messages' parameter from a plain string to a structured dict with 'role' and 'content'. Confirm that users are aware of the new message schema. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%The comment is asking for confirmation that users are aware of a change, which violates the rule against asking the PR author to confirm intentions or ensure behavior is intended. It doesn't provide a specific code suggestion or point out a clear issue with the code itself.
3. docs/integrations/genai.md:484
- Draft comment:
Updated the file upload example to wrap the prompt and file object inside a dict with 'role' and a list in 'content'. Verify that this structured format is correctly handled by the API. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is asking the PR author to verify that the structured format is correctly handled by the API. This falls under the rule of not asking the author to ensure behavior is intended or to double-check things. Therefore, this comment should be removed.
4. docs/integrations/genai.md:511
- Draft comment:
Added a warning block for streaming limitations. The warning clearly outlines that streaming isn’t supported for regular models unless using Partial explicitly. This improves docs clarity. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is purely informative, explaining what was done in the code. It doesn't provide any actionable feedback or suggestions for improvement. According to the rules, purely informative comments should be removed.
5. docs/integrations/genai.md:541
- Draft comment:
Streaming example now uses create_partial to leverage automatic Partial wrapping. Ensure this behavior is well-documented and that users understand when to use create_partial. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
6. docs/integrations/genai.md:567
- Draft comment:
Removed the redundant 'from google import genai' import in the async support snippet, cleaning up the example. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is purely informative, stating that a redundant import was removed. It does not provide any actionable feedback or suggestions for improvement.
7. tests/llm/test_genai/test_stream.py:17
- Draft comment:
Removed the explicit import and usage of Partial; test now uses create_partial with response_model=UserExtract to validate automatic Partial wrapping. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is purely informative, describing what was changed in the code without providing any actionable feedback or suggestions. It does not align with the rules for good comments, as it does not ask for confirmation of intention, suggest improvements, or highlight potential issues.
8. tests/llm/test_genai/test_stream.py:101
- Draft comment:
Removed redundant tests for regular model streaming (both sync and async). Ensure that the automatic Partial wrapping is sufficiently covered by the remaining create_partial tests. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =30%<= threshold85%The comment is suggesting that redundant tests were removed and is asking to ensure that the remaining tests cover the necessary functionality. This is indirectly asking for confirmation, which violates the rule against asking the PR author to ensure behavior is intended or tested. However, it does mention a specific area (create_partial tests) that should be covered, which could be seen as a specific suggestion. Overall, it leans more towards asking for confirmation rather than providing a specific suggestion or improvement.
9. uv.lock:1712
- Draft comment:
Lockfile update: Pre-commit, mkdocs, and mkdocs-material dependencies have been rearranged. Verify that these changes align with the intended dependency management (e.g., pre-commit moved to dev dependencies). - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%The comment is asking the PR author to verify changes related to dependencies, which is against the rules. It doesn't provide a specific suggestion or point out a clear issue with the code. Therefore, it should be removed.
10. docs/integrations/genai.md:252
- Draft comment:
Typo: In the message content, "jason" is likely meant to be "Jason" if referring to a name. - Reason this comment was not posted:
Comment was on unchanged code.
11. docs/integrations/genai.md:398
- Draft comment:
Typo: In the comment, "Multiple ways to load an PDF:" should be "Multiple ways to load a PDF:" since PDF is pronounced with a consonant sound (pee-dee-eff). - Reason this comment was not posted:
Comment was on unchanged code.
Workflow ID: wflow_AqVZa5FSWGLOfO6r
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: Todo List:
✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (
inspect.isclass(response_model)
and issubclass(response_model, (IterableBase, PartialBase))
and stream
):Consider adding the safety check to match existing patterns: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Code Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if (kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewTest strategy observation:
Recommendation: Consider adding at least one test that explicitly uses 📚 Documentation UpdatesWell-executed documentation changes:
Documentation gap: The automatic wrapping behavior introduced by this PR is not explicitly documented. Users may not realize they can now use regular models with streaming. 📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with the minor type safety suggestion above for future consideration. |
…response model test This change cleans up the test file by removing unnecessary imports and the parameterization of the mode argument, which is no longer needed. This helps maintain code clarity and adheres to linter requirements.
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: Todo List:
✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (
inspect.isclass(response_model)
and issubclass(response_model, (IterableBase, PartialBase))
and stream
):Consider adding the safety check to match existing patterns: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Code Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if (kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewCurrent test status:
Missing test coverage:
Recommendation: Add tests specifically for the automatic wrapping feature: def test_regular_model_auto_wrapping_with_streaming(client):
# Test that regular models are automatically wrapped with Partial when streaming
client = instructor.from_provider("google/gemini-2.5-flash", mode=mode)
stream = client.chat.completions.create(
model="gemini-2.5-flash",
response_model=UserExtract, # Regular model, not Partial[UserExtract]
stream=True,
messages=[{"role": "user", "content": "Jason is 25 years old"}],
)
# Verify streaming works and returns expected results
for result in stream:
assert isinstance(result, UserExtract)📚 Documentation UpdatesWell-executed documentation changes:
📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with suggestions for additional test coverage and type safety improvements for future consideration. |
|
Claude finished @jxnl's task —— View job PR Review Complete ✅I've thoroughly reviewed this PR that fixes the Gemini streaming issue by automatically wrapping regular models with Partial when streaming is enabled. Here's my comprehensive feedback: Todo List:
✅ Code Quality & ImplementationExcellent implementation approach:
Code placement:
🔍 Potential Issues & Edge Cases1. Type Safety Consideration: if (
inspect.isclass(response_model)
and issubclass(response_model, (IterableBase, PartialBase))
and stream
):Consider adding the safety check to match existing patterns: if (new_kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
response_model = Partial[response_model]2. Code Duplication: def auto_wrap_with_partial_if_streaming(response_model, kwargs):
if (kwargs.get("stream", False) and
inspect.isclass(response_model) and
not issubclass(response_model, PartialBase)):
return Partial[response_model]
return response_model⚡ Performance Considerations
🔒 Security Assessment
🧪 Test Coverage ReviewCurrent test status:
The PR description mentions "comprehensive tests for sync and async streaming with regular models" but the current test file only shows tests using explicit 📚 Documentation UpdatesWell-executed documentation changes:
📋 Minor Suggestions
🎯 Overall AssessmentThis is a high-quality fix that:
The implementation correctly identifies that streaming requires Partial models and automatically applies this requirement, which greatly improves the developer experience by removing the need for users to manually wrap models. Recommendation: ✅ Approve with the minor suggestions above for future consideration. |
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed c9b1a74 in 1 minute and 5 seconds. Click for details.
- Reviewed
16lines of code in1files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. tests/llm/test_genai/test_response_model_none.py:8
- Draft comment:
Removed unused 'import pytest'. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is purely informative, as it simply states that an unused import was removed. It does not provide any actionable feedback or suggestions for improvement.
2. tests/llm/test_genai/test_response_model_none.py:9
- Draft comment:
Removed unused 'from instructor.mode import Mode' import. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold85%This comment is purely informative, stating that an unused import was removed. It does not provide any actionable feedback or suggestions for improvement. According to the rules, purely informative comments should be removed.
3. tests/llm/test_genai/test_response_model_none.py:11
- Draft comment:
Removed unnecessary parameterized decorator; test doesn't require mode parameterization. - Reason this comment was not posted:
Comment looked like it was already resolved.
Workflow ID: wflow_DONUgapNGChELWvX
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
This PR fixes the Gemini streaming issue reported in #.
Summary
Test plan
Generated with Claude Code
Important
Fixes Gemini streaming issue by auto-wrapping models with Partial for streaming, updates docs and tests.
Partialinhandle_genai_structured_outputs()andhandle_genai_tools()whenstream=True.AssertionErrorinfunction_calls.pyfor streaming Gemini responses.Partialusage.genai.mdto reflect changes in streaming support and provider version.test_stream.py.test_response_model_none.py.pyproject.tomlanduv.lockto includepre-commitdependency.This description was created by
for c9b1a74. You can customize this summary. It will automatically update as commits are pushed.