google-genai 1.60.0__py3-none-any.whl → 1.62.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/genai/_interactions/_base_client.py +5 -2
- google/genai/_interactions/_compat.py +3 -3
- google/genai/_interactions/_utils/_json.py +50 -0
- google/genai/_interactions/resources/interactions.py +50 -28
- google/genai/_interactions/types/__init__.py +2 -1
- google/genai/_interactions/types/content_delta.py +1 -1
- google/genai/_interactions/types/function_result_content.py +2 -1
- google/genai/_interactions/types/function_result_content_param.py +4 -4
- google/genai/_interactions/types/{interaction_event.py → interaction_complete_event.py} +3 -3
- google/genai/_interactions/types/interaction_create_params.py +4 -4
- google/genai/_interactions/types/interaction_get_params.py +3 -0
- google/genai/_interactions/types/interaction_sse_event.py +11 -2
- google/genai/_interactions/types/interaction_start_event.py +36 -0
- google/genai/batches.py +3 -0
- google/genai/errors.py +19 -6
- google/genai/files.py +15 -15
- google/genai/live.py +22 -2
- google/genai/live_music.py +14 -1
- google/genai/models.py +486 -197
- google/genai/tests/batches/test_create_with_inlined_requests.py +31 -15
- google/genai/tests/batches/test_get.py +1 -1
- google/genai/tests/client/test_client_close.py +0 -1
- google/genai/tests/errors/test_api_error.py +38 -0
- google/genai/tests/files/test_register_table.py +1 -1
- google/genai/tests/transformers/test_schema.py +10 -1
- google/genai/tests/tunings/test_tune.py +87 -0
- google/genai/tunings.py +211 -20
- google/genai/types.py +178 -14
- google/genai/version.py +1 -1
- {google_genai-1.60.0.dist-info → google_genai-1.62.0.dist-info}/METADATA +1 -1
- {google_genai-1.60.0.dist-info → google_genai-1.62.0.dist-info}/RECORD +34 -32
- {google_genai-1.60.0.dist-info → google_genai-1.62.0.dist-info}/WHEEL +1 -1
- {google_genai-1.60.0.dist-info → google_genai-1.62.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.60.0.dist-info → google_genai-1.62.0.dist-info}/top_level.txt +0 -0
|
@@ -42,20 +42,36 @@ _SAFETY_SETTINGS = [
|
|
|
42
42
|
},
|
|
43
43
|
]
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
'
|
|
48
|
-
'
|
|
45
|
+
_INLINED_REQUESTS = [
|
|
46
|
+
{
|
|
47
|
+
'contents': [{
|
|
48
|
+
'parts': [{
|
|
49
|
+
'text': 'what is the number after 1? return just the number.',
|
|
50
|
+
}],
|
|
51
|
+
'role': 'user',
|
|
49
52
|
}],
|
|
50
|
-
'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'
|
|
53
|
+
'metadata': {
|
|
54
|
+
'key': 'request-1',
|
|
55
|
+
},
|
|
56
|
+
'config': {
|
|
57
|
+
'safety_settings': _SAFETY_SETTINGS,
|
|
58
|
+
},
|
|
54
59
|
},
|
|
55
|
-
|
|
56
|
-
'
|
|
60
|
+
{
|
|
61
|
+
'contents': [{
|
|
62
|
+
'parts': [{
|
|
63
|
+
'text': 'what is the number after 2? return just the number.',
|
|
64
|
+
}],
|
|
65
|
+
'role': 'user',
|
|
66
|
+
}],
|
|
67
|
+
'metadata': {
|
|
68
|
+
'key': 'request-2',
|
|
69
|
+
},
|
|
70
|
+
'config': {
|
|
71
|
+
'safety_settings': _SAFETY_SETTINGS,
|
|
72
|
+
},
|
|
57
73
|
},
|
|
58
|
-
|
|
74
|
+
]
|
|
59
75
|
_INLINED_TEXT_REQUEST_UNION = {
|
|
60
76
|
'contents': [{
|
|
61
77
|
'parts': [{
|
|
@@ -154,7 +170,7 @@ test_table: list[pytest_helper.TestTableItem] = [
|
|
|
154
170
|
name='test_union_with_inlined_request',
|
|
155
171
|
parameters=types._CreateBatchJobParameters(
|
|
156
172
|
model=_MLDEV_GEMINI_MODEL,
|
|
157
|
-
src=
|
|
173
|
+
src=_INLINED_REQUESTS,
|
|
158
174
|
config={
|
|
159
175
|
'display_name': _DISPLAY_NAME,
|
|
160
176
|
},
|
|
@@ -166,7 +182,7 @@ test_table: list[pytest_helper.TestTableItem] = [
|
|
|
166
182
|
name='test_with_inlined_request',
|
|
167
183
|
parameters=types._CreateBatchJobParameters(
|
|
168
184
|
model=_MLDEV_GEMINI_MODEL,
|
|
169
|
-
src={'inlined_requests':
|
|
185
|
+
src={'inlined_requests': _INLINED_REQUESTS},
|
|
170
186
|
config={
|
|
171
187
|
'display_name': _DISPLAY_NAME,
|
|
172
188
|
},
|
|
@@ -177,7 +193,7 @@ test_table: list[pytest_helper.TestTableItem] = [
|
|
|
177
193
|
name='test_with_inlined_request_config',
|
|
178
194
|
parameters=types._CreateBatchJobParameters(
|
|
179
195
|
model=_MLDEV_GEMINI_MODEL,
|
|
180
|
-
src={'inlined_requests':
|
|
196
|
+
src={'inlined_requests': _INLINED_REQUESTS},
|
|
181
197
|
config={
|
|
182
198
|
'display_name': _DISPLAY_NAME,
|
|
183
199
|
},
|
|
@@ -247,7 +263,7 @@ async def test_async_create(client):
|
|
|
247
263
|
with pytest_helper.exception_if_vertex(client, ValueError):
|
|
248
264
|
batch_job = await client.aio.batches.create(
|
|
249
265
|
model=_GEMINI_MODEL,
|
|
250
|
-
src=
|
|
266
|
+
src=_INLINED_REQUESTS,
|
|
251
267
|
)
|
|
252
268
|
assert batch_job.name.startswith('batches/')
|
|
253
269
|
assert (
|
|
@@ -29,7 +29,7 @@ _BATCH_JOB_FULL_RESOURCE_NAME = (
|
|
|
29
29
|
f'batchPredictionJobs/{_BATCH_JOB_NAME}'
|
|
30
30
|
)
|
|
31
31
|
# MLDev batch operation name.
|
|
32
|
-
_MLDEV_BATCH_OPERATION_NAME = 'batches/
|
|
32
|
+
_MLDEV_BATCH_OPERATION_NAME = 'batches/z2p8ksus4lyxt25rntl3fpd67p2niw4hfij5'
|
|
33
33
|
_INVALID_BATCH_JOB_NAME = 'invalid_name'
|
|
34
34
|
|
|
35
35
|
|
|
@@ -23,6 +23,7 @@ import pickle
|
|
|
23
23
|
|
|
24
24
|
import httpx
|
|
25
25
|
import pytest
|
|
26
|
+
import websockets
|
|
26
27
|
|
|
27
28
|
from ... import errors
|
|
28
29
|
|
|
@@ -257,6 +258,43 @@ def test_constructor_message_not_present():
|
|
|
257
258
|
}
|
|
258
259
|
|
|
259
260
|
|
|
261
|
+
def test_constructor_with_websocket_connection_closed_error():
|
|
262
|
+
actual_error = errors.APIError(
|
|
263
|
+
1007,
|
|
264
|
+
'At most one response modality can be specified in the setup request.'
|
|
265
|
+
' To enable simultaneous transcription and audio output,',
|
|
266
|
+
None,
|
|
267
|
+
)
|
|
268
|
+
assert actual_error.code == 1007
|
|
269
|
+
assert (
|
|
270
|
+
actual_error.details
|
|
271
|
+
== 'At most one response modality can be specified in the setup request.'
|
|
272
|
+
' To enable simultaneous transcription and audio output,',
|
|
273
|
+
)
|
|
274
|
+
assert actual_error.status == None
|
|
275
|
+
assert actual_error.message == None
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def test_raise_for_websocket_connection_closed_error():
|
|
279
|
+
try:
|
|
280
|
+
errors.APIError.raise_error(
|
|
281
|
+
1007,
|
|
282
|
+
'At most one response modality can be specified in the setup request.'
|
|
283
|
+
' To enable simultaneous transcription and audio output,',
|
|
284
|
+
None,
|
|
285
|
+
)
|
|
286
|
+
except errors.APIError as actual_error:
|
|
287
|
+
assert actual_error.code == 1007
|
|
288
|
+
assert (
|
|
289
|
+
actual_error.details
|
|
290
|
+
== 'At most one response modality can be specified in the setup'
|
|
291
|
+
' request.'
|
|
292
|
+
' To enable simultaneous transcription and audio output,'
|
|
293
|
+
)
|
|
294
|
+
assert actual_error.status == None
|
|
295
|
+
assert actual_error.message == None
|
|
296
|
+
|
|
297
|
+
|
|
260
298
|
def test_raise_for_response_code_exist_json_decoder_error():
|
|
261
299
|
class FakeResponse(httpx.Response):
|
|
262
300
|
|
|
@@ -42,7 +42,7 @@ def get_headers():
|
|
|
42
42
|
test_table: list[pytest_helper.TestTableItem] = [
|
|
43
43
|
pytest_helper.TestTableItem(
|
|
44
44
|
name='test_register',
|
|
45
|
-
parameters=types.
|
|
45
|
+
parameters=types._InternalRegisterFilesParameters(uris=['gs://unified-genai-dev/image.jpg']),
|
|
46
46
|
exception_if_vertex='only supported in the Gemini Developer client',
|
|
47
47
|
skip_in_api_mode=(
|
|
48
48
|
'The files have a TTL, they cannot be reliably retrieved for a long'
|
|
@@ -79,7 +79,6 @@ class CountryInfoWithAnyOf(pydantic.BaseModel):
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
@pytest.fixture
|
|
82
|
-
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
83
82
|
def client(use_vertex):
|
|
84
83
|
if use_vertex:
|
|
85
84
|
yield google_genai_client_module.Client(
|
|
@@ -91,6 +90,7 @@ def client(use_vertex):
|
|
|
91
90
|
)
|
|
92
91
|
|
|
93
92
|
|
|
93
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
94
94
|
def test_build_schema_for_list_of_pydantic_schema(client):
|
|
95
95
|
"""Tests _build_schema() when list[pydantic.BaseModel] is provided to response_schema."""
|
|
96
96
|
|
|
@@ -112,6 +112,7 @@ def test_build_schema_for_list_of_pydantic_schema(client):
|
|
|
112
112
|
assert list_schema['required'] == list(country_info_fields.keys())
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
115
116
|
def test_build_schema_for_list_of_nested_pydantic_schema(client):
|
|
116
117
|
"""Tests _build_schema() when list[pydantic.BaseModel] is provided to response_schema and the pydantic.BaseModel has nested pydantic fields."""
|
|
117
118
|
list_schema = _transformers.t_schema(
|
|
@@ -132,6 +133,7 @@ def test_build_schema_for_list_of_nested_pydantic_schema(client):
|
|
|
132
133
|
assert field_name in currency_info_fields
|
|
133
134
|
|
|
134
135
|
|
|
136
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
135
137
|
def test_t_schema_for_pydantic_schema(client):
|
|
136
138
|
"""Tests t_schema when pydantic.BaseModel is passed to response_schema."""
|
|
137
139
|
transformed_schema = _transformers.t_schema(client, CountryInfo)
|
|
@@ -143,6 +145,7 @@ def test_t_schema_for_pydantic_schema(client):
|
|
|
143
145
|
)
|
|
144
146
|
|
|
145
147
|
|
|
148
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
146
149
|
def test_t_schema_for_list_of_pydantic_schema(client):
|
|
147
150
|
"""Tests t_schema when list[pydantic.BaseModel] is passed to response_schema."""
|
|
148
151
|
transformed_schema = _transformers.t_schema(client, list[CountryInfo])
|
|
@@ -156,6 +159,7 @@ def test_t_schema_for_list_of_pydantic_schema(client):
|
|
|
156
159
|
)
|
|
157
160
|
|
|
158
161
|
|
|
162
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
159
163
|
def test_t_schema_for_null_fields(client):
|
|
160
164
|
"""Tests t_schema when null fields are present."""
|
|
161
165
|
transformed_schema = _transformers.t_schema(client, CountryInfoWithNullFields)
|
|
@@ -163,6 +167,7 @@ def test_t_schema_for_null_fields(client):
|
|
|
163
167
|
assert transformed_schema.properties['population'].nullable
|
|
164
168
|
|
|
165
169
|
|
|
170
|
+
#@pytest.mark.parametrize('use_vertex', [True, False])
|
|
166
171
|
def test_schema_with_no_null_fields_is_unchanged():
|
|
167
172
|
"""Tests handle_null_fields() doesn't change anything when no null fields are present."""
|
|
168
173
|
test_properties = {
|
|
@@ -207,6 +212,7 @@ def test_schema_with_default_value(client):
|
|
|
207
212
|
assert transformed_schema == expected_schema
|
|
208
213
|
|
|
209
214
|
|
|
215
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
210
216
|
def test_schema_with_any_of(client):
|
|
211
217
|
transformed_schema = _transformers.t_schema(client, CountryInfoWithAnyOf)
|
|
212
218
|
expected_schema = types.Schema(
|
|
@@ -601,6 +607,7 @@ def test_process_schema_order_properties_propagates_into_any_of(
|
|
|
601
607
|
assert schema == schema_without_property_ordering
|
|
602
608
|
|
|
603
609
|
|
|
610
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
604
611
|
def test_t_schema_does_not_change_property_ordering_if_set(client):
|
|
605
612
|
"""Tests t_schema doesn't overwrite the property_ordering field if already set."""
|
|
606
613
|
|
|
@@ -612,6 +619,7 @@ def test_t_schema_does_not_change_property_ordering_if_set(client):
|
|
|
612
619
|
assert transformed_schema.property_ordering == custom_property_ordering
|
|
613
620
|
|
|
614
621
|
|
|
622
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
615
623
|
def test_t_schema_sets_property_ordering_for_json_schema(client):
|
|
616
624
|
"""Tests t_schema sets the property_ordering field for json schemas."""
|
|
617
625
|
|
|
@@ -629,6 +637,7 @@ def test_t_schema_sets_property_ordering_for_json_schema(client):
|
|
|
629
637
|
]
|
|
630
638
|
|
|
631
639
|
|
|
640
|
+
@pytest.mark.parametrize('use_vertex', [True, False])
|
|
632
641
|
def test_t_schema_sets_property_ordering_for_schema_type(client):
|
|
633
642
|
"""Tests t_schema sets the property_ordering field for Schema types."""
|
|
634
643
|
|
|
@@ -20,6 +20,12 @@ from ... import types as genai_types
|
|
|
20
20
|
from .. import pytest_helper
|
|
21
21
|
import pytest
|
|
22
22
|
|
|
23
|
+
|
|
24
|
+
VERTEX_HTTP_OPTIONS = {
|
|
25
|
+
'api_version': 'v1beta1',
|
|
26
|
+
'base_url': 'https://us-central1-autopush-aiplatform.sandbox.googleapis.com/',
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
evaluation_config=genai_types.EvaluationConfig(
|
|
24
30
|
metrics=[
|
|
25
31
|
genai_types.Metric(name="bleu", prompt_template="test prompt template")
|
|
@@ -158,6 +164,87 @@ test_table: list[pytest_helper.TestTableItem] = [
|
|
|
158
164
|
),
|
|
159
165
|
exception_if_mldev="vertex_dataset_resource parameter is not supported in Gemini API.",
|
|
160
166
|
),
|
|
167
|
+
pytest_helper.TestTableItem(
|
|
168
|
+
name="test_tune_distillation",
|
|
169
|
+
parameters=genai_types.CreateTuningJobParameters(
|
|
170
|
+
base_model="meta/llama3_1@llama-3.1-8b-instruct",
|
|
171
|
+
training_dataset=genai_types.TuningDataset(
|
|
172
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-openai-opposites.jsonl",
|
|
173
|
+
),
|
|
174
|
+
config=genai_types.CreateTuningJobConfig(
|
|
175
|
+
method="DISTILLATION",
|
|
176
|
+
base_teacher_model="deepseek-ai/deepseek-v3.1-maas",
|
|
177
|
+
epoch_count=20,
|
|
178
|
+
validation_dataset=genai_types.TuningValidationDataset(
|
|
179
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-val-openai-opposites.jsonl",
|
|
180
|
+
),
|
|
181
|
+
output_uri="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test-folder",
|
|
182
|
+
http_options=VERTEX_HTTP_OPTIONS,
|
|
183
|
+
),
|
|
184
|
+
),
|
|
185
|
+
exception_if_mldev="parameter is not supported in Gemini API.",
|
|
186
|
+
),
|
|
187
|
+
pytest_helper.TestTableItem(
|
|
188
|
+
name="test_tune_oss_sft",
|
|
189
|
+
parameters=genai_types.CreateTuningJobParameters(
|
|
190
|
+
base_model="meta/llama3_1@llama-3.1-8b-instruct",
|
|
191
|
+
training_dataset=genai_types.TuningDataset(
|
|
192
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-openai-opposites.jsonl",
|
|
193
|
+
),
|
|
194
|
+
config=genai_types.CreateTuningJobConfig(
|
|
195
|
+
epoch_count=20,
|
|
196
|
+
validation_dataset=genai_types.TuningValidationDataset(
|
|
197
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-val-openai-opposites.jsonl",
|
|
198
|
+
),
|
|
199
|
+
custom_base_model="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test-folder/postprocess/node-0/checkpoints/final",
|
|
200
|
+
output_uri="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test",
|
|
201
|
+
http_options=VERTEX_HTTP_OPTIONS,
|
|
202
|
+
),
|
|
203
|
+
),
|
|
204
|
+
exception_if_mldev="not supported in Gemini API",
|
|
205
|
+
),
|
|
206
|
+
pytest_helper.TestTableItem(
|
|
207
|
+
name="test_tune_oss_sft_hyperparams",
|
|
208
|
+
parameters=genai_types.CreateTuningJobParameters(
|
|
209
|
+
base_model="meta/llama3_1@llama-3.1-8b-instruct",
|
|
210
|
+
training_dataset=genai_types.TuningDataset(
|
|
211
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-openai-opposites.jsonl",
|
|
212
|
+
),
|
|
213
|
+
config=genai_types.CreateTuningJobConfig(
|
|
214
|
+
epoch_count=20,
|
|
215
|
+
validation_dataset=genai_types.TuningValidationDataset(
|
|
216
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-val-openai-opposites.jsonl",
|
|
217
|
+
),
|
|
218
|
+
learning_rate=2.5e-4,
|
|
219
|
+
tuning_mode="TUNING_MODE_FULL",
|
|
220
|
+
custom_base_model="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test-folder/postprocess/node-0/checkpoints/final",
|
|
221
|
+
output_uri="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test",
|
|
222
|
+
http_options=VERTEX_HTTP_OPTIONS,
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
exception_if_mldev="not supported in Gemini API",
|
|
226
|
+
),
|
|
227
|
+
pytest_helper.TestTableItem(
|
|
228
|
+
name="test_tune_oss_distillation",
|
|
229
|
+
parameters=genai_types.CreateTuningJobParameters(
|
|
230
|
+
base_model="meta/llama3_1@llama-3.1-8b-instruct",
|
|
231
|
+
training_dataset=genai_types.TuningDataset(
|
|
232
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-openai-opposites.jsonl",
|
|
233
|
+
),
|
|
234
|
+
config=genai_types.CreateTuningJobConfig(
|
|
235
|
+
method="DISTILLATION",
|
|
236
|
+
base_teacher_model="deepseek-ai/deepseek-v3.1-maas",
|
|
237
|
+
epoch_count=20,
|
|
238
|
+
validation_dataset=genai_types.TuningValidationDataset(
|
|
239
|
+
gcs_uri="gs://nathreya-oss-tuning-sdk-test/distillation-val-openai-opposites.jsonl",
|
|
240
|
+
),
|
|
241
|
+
custom_base_model="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test-folder/postprocess/node-0/checkpoints/final",
|
|
242
|
+
output_uri="gs://nathreya-oss-tuning-sdk-test/ayushagra-distillation-test",
|
|
243
|
+
http_options=VERTEX_HTTP_OPTIONS,
|
|
244
|
+
),
|
|
245
|
+
),
|
|
246
|
+
exception_if_mldev="not supported in Gemini API",
|
|
247
|
+
),
|
|
161
248
|
]
|
|
162
249
|
|
|
163
250
|
pytestmark = pytest_helper.setup(
|