Skip to content

Commit 386fd3d

Browse files
authored
Add stop_sequences to Google models (#1935)
1 parent dab34b7 commit 386fd3d

12 files changed

+141
-72
lines changed

pydantic_ai_slim/pydantic_ai/models/gemini.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ def _settings_to_generation_config(model_settings: GeminiModelSettings) -> _Gemi
366366
config: _GeminiGenerationConfig = {}
367367
if (max_tokens := model_settings.get('max_tokens')) is not None:
368368
config['max_output_tokens'] = max_tokens
369+
if (stop_sequences := model_settings.get('stop_sequences')) is not None:
370+
config['stop_sequences'] = stop_sequences # pragma: no cover
369371
if (temperature := model_settings.get('temperature')) is not None:
370372
config['temperature'] = temperature
371373
if (top_p := model_settings.get('top_p')) is not None:

pydantic_ai_slim/pydantic_ai/models/google.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ async def _generate_content(
260260
temperature=model_settings.get('temperature'),
261261
top_p=model_settings.get('top_p'),
262262
max_output_tokens=model_settings.get('max_tokens'),
263+
stop_sequences=model_settings.get('stop_sequences'),
263264
presence_penalty=model_settings.get('presence_penalty'),
264265
frequency_penalty=model_settings.get('frequency_penalty'),
265266
safety_settings=model_settings.get('google_safety_settings'),

pydantic_ai_slim/pydantic_ai/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class ModelSettings(TypedDict, total=False):
139139
* Mistral
140140
* Groq
141141
* Cohere
142+
* Google
142143
"""
143144

144145
extra_headers: dict[str, str]

tests/cassettes/test_settings/test_stop_settings[anthropic].yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interactions:
88
connection:
99
- keep-alive
1010
content-length:
11-
- '193'
11+
- '272'
1212
content-type:
1313
- application/json
1414
host:
@@ -18,7 +18,7 @@ interactions:
1818
max_tokens: 1024
1919
messages:
2020
- content:
21-
- text: What is the capital of France?
21+
- text: What is the capital of France? Give me an answer that contains the word "Paris", but is not the first word.
2222
type: text
2323
role: user
2424
model: claude-3-5-sonnet-latest
@@ -31,7 +31,7 @@ interactions:
3131
connection:
3232
- keep-alive
3333
content-length:
34-
- '359'
34+
- '356'
3535
content-type:
3636
- application/json
3737
strict-transport-security:
@@ -40,9 +40,9 @@ interactions:
4040
- chunked
4141
parsed_body:
4242
content:
43-
- text: 'The capital of France is '
43+
- text: 'The beautiful city of '
4444
type: text
45-
id: msg_01SVFZqkSLhUPkAA4w6rhzFD
45+
id: msg_01376yZQxHcw9pER2Ab2SvQb
4646
model: claude-3-5-sonnet-20241022
4747
role: assistant
4848
stop_reason: stop_sequence
@@ -51,8 +51,8 @@ interactions:
5151
usage:
5252
cache_creation_input_tokens: 0
5353
cache_read_input_tokens: 0
54-
input_tokens: 14
55-
output_tokens: 6
54+
input_tokens: 32
55+
output_tokens: 5
5656
service_tier: standard
5757
status:
5858
code: 200

tests/cassettes/test_settings/test_stop_settings[bedrock].yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
interactions:
22
- request:
3-
body: '{"messages": [{"role": "user", "content": [{"text": "What is the capital of France?"}]}], "system": [], "inferenceConfig":
4-
{"stopSequences": ["Paris"]}}'
3+
body: '{"messages": [{"role": "user", "content": [{"text": "What is the capital of France? Give me an answer that contains
4+
the word \"Paris\", but is not the first word."}]}], "system": [], "inferenceConfig": {"stopSequences": ["Paris"]}}'
55
headers:
66
amz-sdk-invocation-id:
77
- !!binary |
8-
YzVkZjljOTMtMDQ1Zi00NWE0LWJhY2YtMDAwMjdjYTg1NmRl
8+
YWEyMWExMDYtNjJjMy00MmNiLTlkNjUtYTEwYzYzYTIxNGFk
99
amz-sdk-request:
1010
- !!binary |
1111
YXR0ZW1wdD0x
1212
content-length:
13-
- '152'
13+
- '231'
1414
content-type:
1515
- !!binary |
1616
YXBwbGljYXRpb24vanNvbg==
@@ -21,22 +21,22 @@ interactions:
2121
connection:
2222
- keep-alive
2323
content-length:
24-
- '209'
24+
- '197'
2525
content-type:
2626
- application/json
2727
parsed_body:
2828
metrics:
29-
latencyMs: 179
29+
latencyMs: 189
3030
output:
3131
message:
3232
content:
33-
- text: The capital of France is Paris
33+
- text: The city of Paris
3434
role: assistant
3535
stopReason: end_turn
3636
usage:
37-
inputTokens: 7
38-
outputTokens: 6
39-
totalTokens: 13
37+
inputTokens: 25
38+
outputTokens: 4
39+
totalTokens: 29
4040
status:
4141
code: 200
4242
message: OK

tests/cassettes/test_settings/test_stop_settings[cohere].yaml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ interactions:
88
connection:
99
- keep-alive
1010
content-length:
11-
- '140'
11+
- '219'
1212
content-type:
1313
- application/json
1414
host:
1515
- api.cohere.com
1616
method: POST
1717
parsed_body:
1818
messages:
19-
- content: What is the capital of France?
19+
- content: What is the capital of France? Give me an answer that contains the word "Paris", but is not the first word.
2020
role: user
2121
model: command-r-plus
2222
stop_sequences:
@@ -32,34 +32,34 @@ interactions:
3232
cache-control:
3333
- no-cache, no-store, no-transform, must-revalidate, private, max-age=0
3434
content-length:
35-
- '280'
35+
- '297'
3636
content-type:
3737
- application/json
3838
expires:
3939
- Thu, 01 Jan 1970 00:00:00 UTC
4040
num_chars:
41-
- '1200'
41+
- '521'
4242
num_tokens:
43-
- '12'
43+
- '34'
4444
pragma:
4545
- no-cache
4646
vary:
4747
- Origin
4848
parsed_body:
4949
finish_reason: STOP_SEQUENCE
50-
id: 2ed6908c-e5cb-4063-b2a3-0ac4990d1b85
50+
id: 02069ccc-65d6-4286-ba8c-097e317431c5
5151
message:
5252
content:
53-
- text: The capital of France is
53+
- text: The capital of France is a city known as
5454
type: text
5555
role: assistant
5656
usage:
5757
billed_units:
58-
input_tokens: 7
59-
output_tokens: 5
58+
input_tokens: 25
59+
output_tokens: 9
6060
tokens:
61-
input_tokens: 200
62-
output_tokens: 7
61+
input_tokens: 91
62+
output_tokens: 11
6363
status:
6464
code: 200
6565
message: OK
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
interactions:
2+
- request:
3+
headers:
4+
accept:
5+
- '*/*'
6+
accept-encoding:
7+
- gzip, deflate
8+
connection:
9+
- keep-alive
10+
content-length:
11+
- '216'
12+
content-type:
13+
- application/json
14+
host:
15+
- generativelanguage.googleapis.com
16+
method: POST
17+
parsed_body:
18+
contents:
19+
- parts:
20+
- text: What is the capital of France? Give me an answer that contains the word "Paris", but is not the first word.
21+
role: user
22+
generationConfig:
23+
stopSequences:
24+
- Paris
25+
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent
26+
response:
27+
headers:
28+
alt-svc:
29+
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
30+
content-length:
31+
- '677'
32+
content-type:
33+
- application/json; charset=UTF-8
34+
server-timing:
35+
- gfet4t7; dur=362
36+
transfer-encoding:
37+
- chunked
38+
vary:
39+
- Origin
40+
- X-Origin
41+
- Referer
42+
parsed_body:
43+
candidates:
44+
- avgLogprobs: -0.5998413562774658
45+
content:
46+
parts:
47+
- text: 'The most iconic city in France is '
48+
role: model
49+
finishReason: STOP
50+
modelVersion: gemini-1.5-flash
51+
responseId: UB5DaMfEN7jFnvgPocrJaA
52+
usageMetadata:
53+
candidatesTokenCount: 8
54+
candidatesTokensDetails:
55+
- modality: TEXT
56+
tokenCount: 8
57+
promptTokenCount: 25
58+
promptTokensDetails:
59+
- modality: TEXT
60+
tokenCount: 25
61+
totalTokenCount: 33
62+
status:
63+
code: 200
64+
message: OK
65+
version: 1

tests/cassettes/test_settings/test_stop_settings[groq].yaml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ interactions:
88
connection:
99
- keep-alive
1010
content-length:
11-
- '136'
11+
- '215'
1212
content-type:
1313
- application/json
1414
host:
1515
- api.groq.com
1616
method: POST
1717
parsed_body:
1818
messages:
19-
- content: What is the capital of France?
19+
- content: What is the capital of France? Give me an answer that contains the word "Paris", but is not the first word.
2020
role: user
2121
model: llama3-8b-8192
2222
n: 1
@@ -33,38 +33,38 @@ interactions:
3333
connection:
3434
- keep-alive
3535
content-length:
36-
- '562'
36+
- '603'
3737
content-type:
3838
- application/json
3939
transfer-encoding:
4040
- chunked
4141
vary:
42-
- Origin, Accept-Encoding
42+
- Origin
4343
parsed_body:
4444
choices:
4545
- finish_reason: stop
4646
index: 0
4747
logprobs: null
4848
message:
49-
content: 'The capital of France is '
49+
content: "Bien sûr!\n\nThe lovely city that is the capital of France is "
5050
role: assistant
51-
created: 1744190899
52-
id: chatcmpl-9de98446-dccf-439b-bcb8-996ee77471d8
51+
created: 1749229135
52+
id: chatcmpl-69930f13-fe23-4584-9d09-c1e1612a2183
5353
model: llama3-8b-8192
5454
object: chat.completion
55-
system_fingerprint: fp_dadc9d6142
55+
system_fingerprint: fp_179b0f92c9
5656
usage:
57-
completion_time: 0.006666667
58-
completion_tokens: 8
59-
prompt_time: 0.003914844
60-
prompt_tokens: 17
61-
queue_time: 0.5322581550000001
62-
total_time: 0.010581511
63-
total_tokens: 25
57+
completion_time: 0.020833333
58+
completion_tokens: 25
59+
prompt_time: 0.004837532
60+
prompt_tokens: 35
61+
queue_time: 0.022124504000000003
62+
total_time: 0.025670865
63+
total_tokens: 60
6464
usage_breakdown:
6565
models: null
6666
x_groq:
67-
id: req_01jrcy20hceg1t9cpsg7cmj7f9
67+
id: req_01jx32wsk4fwf98jtfjm1agphs
6868
status:
6969
code: 200
7070
message: OK

tests/cassettes/test_settings/test_stop_settings[mistral].yaml

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ interactions:
88
connection:
99
- keep-alive
1010
content-length:
11-
- '153'
11+
- '232'
1212
content-type:
1313
- application/json
1414
host:
1515
- api.mistral.ai
1616
method: POST
1717
parsed_body:
1818
messages:
19-
- content: What is the capital of France?
19+
- content: What is the capital of France? Give me an answer that contains the word "Paris", but is not the first word.
2020
role: user
2121
model: ministral-8b-latest
2222
n: 1
@@ -37,14 +37,6 @@ interactions:
3737
- '322'
3838
content-type:
3939
- application/json
40-
ratelimitbysize-limit:
41-
- '500000'
42-
ratelimitbysize-query-cost:
43-
- '32008'
44-
ratelimitbysize-remaining:
45-
- '467992'
46-
ratelimitbysize-reset:
47-
- '42'
4840
transfer-encoding:
4941
- chunked
5042
parsed_body:
@@ -55,14 +47,14 @@ interactions:
5547
content: 'The capital of France is '
5648
role: assistant
5749
tool_calls: null
58-
created: 1744190898
59-
id: 0bbc8cf8fc76455fae759fb9109f8547
50+
created: 1749229172
51+
id: 59bee455a928496eb22bbf8b8b817252
6052
model: ministral-8b-latest
6153
object: chat.completion
6254
usage:
6355
completion_tokens: 6
64-
prompt_tokens: 10
65-
total_tokens: 16
56+
prompt_tokens: 28
57+
total_tokens: 34
6658
status:
6759
code: 200
6860
message: OK

0 commit comments

Comments
 (0)