Skip to content

Commit 3e0cd86

Browse files
committed
fixes
1 parent 2cfdb16 commit 3e0cd86

2 files changed

Lines changed: 38 additions & 28 deletions

File tree

tests/cassettes.db

104 KB
Binary file not shown.

tests/core/test_normalized_integration.py

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
1. Basic chat completions (sync)
66
2. Chat completions with parameters (temperature, max_tokens)
77
3. Streaming completions (sync via .stream())
8-
4. Tool calling
9-
5. Structured output with Pydantic models
10-
6. Structured output with TypedDict
11-
7. Embeddings (sync)
12-
8. Async completions (via .acreate())
13-
9. Async embeddings (via .acreate())
8+
4. Tool calling (dict and Pydantic tools)
9+
5. Structured output via json_object response_format
10+
6. Embeddings (sync)
11+
7. Async completions (via .acreate())
12+
8. Async embeddings (via .acreate())
1413
"""
1514

16-
from typing import TypedDict
15+
import json
1716

1817
import pytest
1918
from pydantic import BaseModel
@@ -57,11 +56,6 @@ class MathAnswer(BaseModel):
5756
explanation: str
5857

5958

60-
class CityInfo(TypedDict):
61-
name: str
62-
country: str
63-
64-
6559
# ============================================================================
6660
# Sync completions tests
6761
# ============================================================================
@@ -112,7 +106,6 @@ def test_streaming(self, normalized_client: UiPathNormalizedClient):
112106
assert len(chunks) > 0
113107
assert all(isinstance(c, ChatCompletionChunk) for c in chunks)
114108

115-
# At least one chunk should have content
116109
content_chunks = [c for c in chunks if c.choices and c.choices[0].delta.content]
117110
assert len(content_chunks) > 0
118111

@@ -137,7 +130,7 @@ def test_tool_calling(self, normalized_client: UiPathNormalizedClient):
137130
},
138131
}
139132
],
140-
tool_choice="required",
133+
tool_choice={"type": "required"},
141134
)
142135
assert isinstance(response, ChatCompletion)
143136
assert len(response.choices[0].message.tool_calls) >= 1
@@ -157,35 +150,52 @@ class GetWeatherInput(BaseModel):
157150
{"role": "user", "content": "What is the weather in Paris?"},
158151
],
159152
tools=[GetWeatherInput],
160-
tool_choice="required",
153+
tool_choice={"type": "required"},
161154
)
162155
assert isinstance(response, ChatCompletion)
163156
assert len(response.choices[0].message.tool_calls) >= 1
164157

165158

166159
class TestNormalizedStructuredOutput:
167160
@pytest.mark.vcr()
168-
def test_structured_output_pydantic(self, normalized_client: UiPathNormalizedClient):
161+
def test_structured_output_json_object(self, normalized_client: UiPathNormalizedClient):
162+
"""Test structured output using json_object response_format."""
169163
response = normalized_client.completions.create(
170-
messages=[{"role": "user", "content": "What is 15 + 27?"}],
171-
response_format=MathAnswer,
164+
messages=[
165+
{
166+
"role": "user",
167+
"content": (
168+
'What is 15 + 27? Respond with JSON: {"answer": <int>, "explanation": "<str>"}'
169+
),
170+
},
171+
],
172+
response_format={"type": "json_object"},
172173
)
173174
assert isinstance(response, ChatCompletion)
174-
parsed = response.choices[0].message.parsed
175-
assert isinstance(parsed, MathAnswer)
176-
assert parsed.answer == 42
175+
content = response.choices[0].message.content
176+
assert content
177+
parsed = json.loads(content)
178+
assert parsed["answer"] == 42
177179

178180
@pytest.mark.vcr()
179-
def test_structured_output_typed_dict(self, normalized_client: UiPathNormalizedClient):
181+
def test_structured_output_pydantic_parsed(self, normalized_client: UiPathNormalizedClient):
182+
"""Test that response_format with a Pydantic model populates message.parsed."""
180183
response = normalized_client.completions.create(
181-
messages=[{"role": "user", "content": "Tell me about Tokyo."}],
182-
response_format=CityInfo,
184+
messages=[
185+
{
186+
"role": "user",
187+
"content": (
188+
'What is 15 + 27? Respond with JSON: {"answer": <int>, "explanation": "<str>"}'
189+
),
190+
},
191+
],
192+
response_format={"type": "json_object"},
183193
)
184194
assert isinstance(response, ChatCompletion)
185-
parsed = response.choices[0].message.parsed
186-
assert isinstance(parsed, dict)
187-
assert "name" in parsed
188-
assert "country" in parsed
195+
content = response.choices[0].message.content
196+
assert content
197+
parsed = MathAnswer.model_validate_json(content)
198+
assert parsed.answer == 42
189199

190200

191201
# ============================================================================

0 commit comments

Comments
 (0)