Skip to content

Commit 1bfaad9

Browse files
conradleeclaude
andcommitted
Add tests for enhanced JSON Schema features and remove enum conversion
- Remove enum-to-string conversion workaround (no longer needed) - Add 6 comprehensive tests for enhanced features: * Discriminated unions (oneOf with $ref) * Recursive schemas ($ref and $defs) * Dicts with additionalProperties * Optional/nullable fields (type: 'null') * Integer enums (native support) * Recursive schema with gemini-2.5-flash (FAILING) All tests use google_provider with GLA API and recorded cassettes. Tests use gemini-2.5-flash except recursive schema which uses gemini-2.0-flash. NOTE: test_google_recursive_schema_native_output_gemini_2_5 consistently fails with 500 Internal Server Error. This needs investigation before merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2d9ea0d commit 1bfaad9

8 files changed

+734
-6
lines changed

pydantic_ai_slim/pydantic_ai/profiles/google.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ def transform(self, schema: JsonSchema) -> JsonSchema:
3636
schema.pop('discriminator', None)
3737
schema.pop('examples', None)
3838

39-
# Gemini only supports string enums, so we need to convert any enum values to strings.
40-
# Pydantic will take care of transforming the transformed string values to the correct type.
41-
if enum := schema.get('enum'):
42-
schema['type'] = 'string'
43-
schema['enum'] = [str(val) for val in enum]
44-
4539
type_ = schema.get('type')
4640
if type_ == 'string' and (fmt := schema.pop('format', None)):
4741
description = schema.get('description')
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
interactions:
2+
- request:
3+
headers:
4+
accept:
5+
- '*/*'
6+
accept-encoding:
7+
- gzip, deflate
8+
connection:
9+
- keep-alive
10+
content-length:
11+
- '519'
12+
content-type:
13+
- application/json
14+
host:
15+
- generativelanguage.googleapis.com
16+
method: POST
17+
parsed_body:
18+
contents:
19+
- parts:
20+
- text: Create a config named "api-config" with metadata author="Alice" and version="1.0"
21+
role: user
22+
generationConfig:
23+
responseJsonSchema:
24+
description: A response with configuration metadata.
25+
properties:
26+
metadata:
27+
additionalProperties:
28+
type: string
29+
type: object
30+
name:
31+
type: string
32+
required:
33+
- name
34+
- metadata
35+
title: ConfigResponse
36+
type: object
37+
responseMimeType: application/json
38+
responseModalities:
39+
- TEXT
40+
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
41+
response:
42+
headers:
43+
alt-svc:
44+
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
45+
content-length:
46+
- '631'
47+
content-type:
48+
- application/json; charset=UTF-8
49+
server-timing:
50+
- gfet4t7; dur=1379
51+
transfer-encoding:
52+
- chunked
53+
vary:
54+
- Origin
55+
- X-Origin
56+
- Referer
57+
parsed_body:
58+
candidates:
59+
- content:
60+
parts:
61+
- text: '{"name": "api-config", "metadata": {"author": "Alice", "version": "1.0"}}'
62+
role: model
63+
finishReason: STOP
64+
index: 0
65+
modelVersion: gemini-2.5-flash
66+
responseId: CZMUacOtKv2SxN8Pi7TrsAs
67+
usageMetadata:
68+
candidatesTokenCount: 25
69+
promptTokenCount: 23
70+
promptTokensDetails:
71+
- modality: TEXT
72+
tokenCount: 23
73+
thoughtsTokenCount: 158
74+
totalTokenCount: 206
75+
status:
76+
code: 200
77+
message: OK
78+
version: 1
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
interactions:
2+
- request:
3+
headers:
4+
accept:
5+
- '*/*'
6+
accept-encoding:
7+
- gzip, deflate
8+
connection:
9+
- keep-alive
10+
content-length:
11+
- '807'
12+
content-type:
13+
- application/json
14+
host:
15+
- generativelanguage.googleapis.com
16+
method: POST
17+
parsed_body:
18+
contents:
19+
- parts:
20+
- text: Tell me about a cat with a meow volume of 5
21+
role: user
22+
generationConfig:
23+
responseJsonSchema:
24+
$defs:
25+
Cat:
26+
properties:
27+
meow_volume:
28+
type: integer
29+
pet_type:
30+
default: cat
31+
enum:
32+
- cat
33+
type: string
34+
required:
35+
- meow_volume
36+
title: Cat
37+
type: object
38+
Dog:
39+
properties:
40+
bark_volume:
41+
type: integer
42+
pet_type:
43+
default: dog
44+
enum:
45+
- dog
46+
type: string
47+
required:
48+
- bark_volume
49+
title: Dog
50+
type: object
51+
description: A response containing a pet.
52+
properties:
53+
pet:
54+
oneOf:
55+
- $ref: '#/$defs/Cat'
56+
- $ref: '#/$defs/Dog'
57+
required:
58+
- pet
59+
title: PetResponse
60+
type: object
61+
responseMimeType: application/json
62+
responseModalities:
63+
- TEXT
64+
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
65+
response:
66+
headers:
67+
alt-svc:
68+
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
69+
content-length:
70+
- '594'
71+
content-type:
72+
- application/json; charset=UTF-8
73+
server-timing:
74+
- gfet4t7; dur=1682
75+
transfer-encoding:
76+
- chunked
77+
vary:
78+
- Origin
79+
- X-Origin
80+
- Referer
81+
parsed_body:
82+
candidates:
83+
- content:
84+
parts:
85+
- text: '{"pet":{"pet_type":"cat","meow_volume":5}}'
86+
role: model
87+
finishReason: STOP
88+
index: 0
89+
modelVersion: gemini-2.5-flash
90+
responseId: B5MUaePHJLHd7M8PqfX5qAQ
91+
usageMetadata:
92+
candidatesTokenCount: 16
93+
promptTokenCount: 14
94+
promptTokensDetails:
95+
- modality: TEXT
96+
tokenCount: 14
97+
thoughtsTokenCount: 181
98+
totalTokenCount: 211
99+
status:
100+
code: 200
101+
message: OK
102+
version: 1
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
interactions:
2+
- request:
3+
headers:
4+
accept:
5+
- '*/*'
6+
accept-encoding:
7+
- gzip, deflate
8+
connection:
9+
- keep-alive
10+
content-length:
11+
- '509'
12+
content-type:
13+
- application/json
14+
host:
15+
- generativelanguage.googleapis.com
16+
method: POST
17+
parsed_body:
18+
contents:
19+
- parts:
20+
- text: Create a task named "Fix bug" with a priority
21+
role: user
22+
generationConfig:
23+
responseJsonSchema:
24+
$defs:
25+
Priority:
26+
enum:
27+
- 1
28+
- 2
29+
- 3
30+
title: Priority
31+
type: integer
32+
description: A task with a priority level.
33+
properties:
34+
name:
35+
type: string
36+
priority:
37+
$ref: '#/$defs/Priority'
38+
required:
39+
- name
40+
- priority
41+
title: Task
42+
type: object
43+
responseMimeType: application/json
44+
responseModalities:
45+
- TEXT
46+
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
47+
response:
48+
headers:
49+
alt-svc:
50+
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
51+
content-length:
52+
- '584'
53+
content-type:
54+
- application/json; charset=UTF-8
55+
server-timing:
56+
- gfet4t7; dur=2911
57+
transfer-encoding:
58+
- chunked
59+
vary:
60+
- Origin
61+
- X-Origin
62+
- Referer
63+
parsed_body:
64+
candidates:
65+
- content:
66+
parts:
67+
- text: '{"name": "Fix bug", "priority": 1}'
68+
role: model
69+
finishReason: STOP
70+
index: 0
71+
modelVersion: gemini-2.5-flash
72+
responseId: D5MUaYKeH9PjnsEPron42AQ
73+
usageMetadata:
74+
candidatesTokenCount: 13
75+
promptTokenCount: 12
76+
promptTokensDetails:
77+
- modality: TEXT
78+
tokenCount: 12
79+
thoughtsTokenCount: 448
80+
totalTokenCount: 473
81+
status:
82+
code: 200
83+
message: OK
84+
version: 1

0 commit comments

Comments
 (0)