97e91a83f3
Ruff / Ruff (push) Waiting to run
Test / Core Tests (push) Waiting to run
Test / Offline Coverage Tests (Python 3.10) (push) Waiting to run
Test / Offline Coverage Tests (Python 3.11) (push) Waiting to run
Test / Offline Coverage Tests (Python 3.12) (push) Waiting to run
Test / Offline Coverage Tests (Python 3.13) (push) Waiting to run
Test / Offline Coverage Tests (Python 3.9) (push) Waiting to run
Test / Full Coverage (Python 3.11) (push) Waiting to run
Test / Core Provider Tests (OpenAI) (push) Blocked by required conditions
Test / Core Provider Tests (Anthropic) (push) Blocked by required conditions
Test / Core Provider Tests (Google) (push) Blocked by required conditions
Test / Core Provider Tests (Other) (push) Blocked by required conditions
Test / Anthropic Tests (push) Blocked by required conditions
Test / Gemini Tests (push) Blocked by required conditions
Test / Google GenAI Tests (push) Blocked by required conditions
Test / Vertex AI Tests (push) Blocked by required conditions
Test / OpenAI Tests (push) Blocked by required conditions
Test / Writer Tests (push) Blocked by required conditions
Test / Auto Client Tests (push) Blocked by required conditions
ty / type-check (push) Waiting to run
54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
"""Regression test for async streaming with Mode.GEMINI_TOOLS.
|
|
|
|
The sync paths in PartialBase.from_streaming_response and
|
|
IterableBase.from_streaming_response apply extract_json_from_stream
|
|
for both Mode.MD_JSON and Mode.GEMINI_TOOLS, but the async paths
|
|
were only applying it for Mode.MD_JSON.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from instructor.mode import Mode
|
|
from instructor.utils.core import (
|
|
extract_json_from_stream,
|
|
extract_json_from_stream_async,
|
|
)
|
|
|
|
|
|
def test_sync_extract_json_from_stream_handles_codeblock():
|
|
chunks = ["```json\n", '{"name": "Alice",', ' "age": 30}', "\n```"]
|
|
result = "".join(extract_json_from_stream(iter(chunks)))
|
|
assert result == '{"name": "Alice", "age": 30}'
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_extract_json_from_stream_handles_codeblock():
|
|
chunks = ["```json\n", '{"name": "Alice",', ' "age": 30}', "\n```"]
|
|
|
|
async def async_chunks():
|
|
for c in chunks:
|
|
yield c
|
|
|
|
result = "".join([c async for c in extract_json_from_stream_async(async_chunks())])
|
|
assert result == '{"name": "Alice", "age": 30}'
|
|
|
|
|
|
def test_sync_gemini_tools_mode_triggers_json_extraction():
|
|
"""Verify that GEMINI_TOOLS is in the set that triggers extract_json_from_stream
|
|
in the sync from_streaming_response path."""
|
|
# This tests the condition that was already correct in the sync path
|
|
assert Mode.GEMINI_TOOLS in {Mode.MD_JSON, Mode.GEMINI_TOOLS}
|
|
|
|
|
|
def test_async_gemini_tools_mode_triggers_json_extraction():
|
|
"""Verify the fix: GEMINI_TOOLS must be in the set that triggers
|
|
extract_json_from_stream_async in the async from_streaming_response_async path.
|
|
|
|
Before the fix, the async path only checked `mode == Mode.MD_JSON`,
|
|
so GEMINI_TOOLS streaming would skip JSON extraction from code blocks.
|
|
"""
|
|
# After the fix, both sync and async paths use the same set
|
|
mode = Mode.GEMINI_TOOLS
|
|
# This is the condition in the fixed async path
|
|
assert mode in {Mode.MD_JSON, Mode.GEMINI_TOOLS}
|