google-genai 1.53.0__py3-none-any.whl → 1.55.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/__init__.py +1 -0
- google/genai/_api_client.py +6 -6
- google/genai/_interactions/__init__.py +117 -0
- google/genai/_interactions/_base_client.py +2019 -0
- google/genai/_interactions/_client.py +511 -0
- google/genai/_interactions/_compat.py +234 -0
- google/genai/_interactions/_constants.py +29 -0
- google/genai/_interactions/_exceptions.py +122 -0
- google/genai/_interactions/_files.py +139 -0
- google/genai/_interactions/_models.py +873 -0
- google/genai/_interactions/_qs.py +165 -0
- google/genai/_interactions/_resource.py +58 -0
- google/genai/_interactions/_response.py +847 -0
- google/genai/_interactions/_streaming.py +354 -0
- google/genai/_interactions/_types.py +276 -0
- google/genai/_interactions/_utils/__init__.py +79 -0
- google/genai/_interactions/_utils/_compat.py +61 -0
- google/genai/_interactions/_utils/_datetime_parse.py +151 -0
- google/genai/_interactions/_utils/_logs.py +40 -0
- google/genai/_interactions/_utils/_proxy.py +80 -0
- google/genai/_interactions/_utils/_reflection.py +57 -0
- google/genai/_interactions/_utils/_resources_proxy.py +39 -0
- google/genai/_interactions/_utils/_streams.py +27 -0
- google/genai/_interactions/_utils/_sync.py +73 -0
- google/genai/_interactions/_utils/_transform.py +472 -0
- google/genai/_interactions/_utils/_typing.py +172 -0
- google/genai/_interactions/_utils/_utils.py +437 -0
- google/genai/_interactions/_version.py +18 -0
- google/genai/_interactions/resources/__init__.py +34 -0
- google/genai/_interactions/resources/interactions.py +1350 -0
- google/genai/_interactions/types/__init__.py +107 -0
- google/genai/_interactions/types/allowed_tools.py +33 -0
- google/genai/_interactions/types/allowed_tools_param.py +35 -0
- google/genai/_interactions/types/annotation.py +42 -0
- google/genai/_interactions/types/annotation_param.py +42 -0
- google/genai/_interactions/types/audio_content.py +38 -0
- google/genai/_interactions/types/audio_content_param.py +45 -0
- google/genai/_interactions/types/audio_mime_type.py +25 -0
- google/genai/_interactions/types/audio_mime_type_param.py +27 -0
- google/genai/_interactions/types/code_execution_call_arguments.py +33 -0
- google/genai/_interactions/types/code_execution_call_arguments_param.py +32 -0
- google/genai/_interactions/types/code_execution_call_content.py +37 -0
- google/genai/_interactions/types/code_execution_call_content_param.py +37 -0
- google/genai/_interactions/types/code_execution_result_content.py +42 -0
- google/genai/_interactions/types/code_execution_result_content_param.py +41 -0
- google/genai/_interactions/types/content_delta.py +358 -0
- google/genai/_interactions/types/content_start.py +79 -0
- google/genai/_interactions/types/content_stop.py +35 -0
- google/genai/_interactions/types/deep_research_agent_config.py +33 -0
- google/genai/_interactions/types/deep_research_agent_config_param.py +32 -0
- google/genai/_interactions/types/document_content.py +36 -0
- google/genai/_interactions/types/document_content_param.py +43 -0
- google/genai/_interactions/types/dynamic_agent_config.py +44 -0
- google/genai/_interactions/types/dynamic_agent_config_param.py +33 -0
- google/genai/_interactions/types/error_event.py +46 -0
- google/genai/_interactions/types/file_search_result_content.py +46 -0
- google/genai/_interactions/types/file_search_result_content_param.py +46 -0
- google/genai/_interactions/types/function.py +38 -0
- google/genai/_interactions/types/function_call_content.py +39 -0
- google/genai/_interactions/types/function_call_content_param.py +39 -0
- google/genai/_interactions/types/function_param.py +37 -0
- google/genai/_interactions/types/function_result_content.py +52 -0
- google/genai/_interactions/types/function_result_content_param.py +54 -0
- google/genai/_interactions/types/generation_config.py +57 -0
- google/genai/_interactions/types/generation_config_param.py +59 -0
- google/genai/_interactions/types/google_search_call_arguments.py +29 -0
- google/genai/_interactions/types/google_search_call_arguments_param.py +31 -0
- google/genai/_interactions/types/google_search_call_content.py +37 -0
- google/genai/_interactions/types/google_search_call_content_param.py +37 -0
- google/genai/_interactions/types/google_search_result.py +35 -0
- google/genai/_interactions/types/google_search_result_content.py +43 -0
- google/genai/_interactions/types/google_search_result_content_param.py +44 -0
- google/genai/_interactions/types/google_search_result_param.py +35 -0
- google/genai/_interactions/types/image_content.py +41 -0
- google/genai/_interactions/types/image_content_param.py +48 -0
- google/genai/_interactions/types/image_mime_type.py +23 -0
- google/genai/_interactions/types/image_mime_type_param.py +25 -0
- google/genai/_interactions/types/interaction.py +165 -0
- google/genai/_interactions/types/interaction_create_params.py +212 -0
- google/genai/_interactions/types/interaction_event.py +37 -0
- google/genai/_interactions/types/interaction_get_params.py +46 -0
- google/genai/_interactions/types/interaction_sse_event.py +32 -0
- google/genai/_interactions/types/interaction_status_update.py +37 -0
- google/genai/_interactions/types/mcp_server_tool_call_content.py +42 -0
- google/genai/_interactions/types/mcp_server_tool_call_content_param.py +42 -0
- google/genai/_interactions/types/mcp_server_tool_result_content.py +52 -0
- google/genai/_interactions/types/mcp_server_tool_result_content_param.py +54 -0
- google/genai/_interactions/types/model.py +36 -0
- google/genai/_interactions/types/model_param.py +38 -0
- google/genai/_interactions/types/speech_config.py +35 -0
- google/genai/_interactions/types/speech_config_param.py +35 -0
- google/genai/_interactions/types/text_content.py +37 -0
- google/genai/_interactions/types/text_content_param.py +38 -0
- google/genai/_interactions/types/thinking_level.py +22 -0
- google/genai/_interactions/types/thought_content.py +41 -0
- google/genai/_interactions/types/thought_content_param.py +47 -0
- google/genai/_interactions/types/tool.py +100 -0
- google/genai/_interactions/types/tool_choice.py +26 -0
- google/genai/_interactions/types/tool_choice_config.py +28 -0
- google/genai/_interactions/types/tool_choice_config_param.py +29 -0
- google/genai/_interactions/types/tool_choice_param.py +28 -0
- google/genai/_interactions/types/tool_choice_type.py +22 -0
- google/genai/_interactions/types/tool_param.py +97 -0
- google/genai/_interactions/types/turn.py +76 -0
- google/genai/_interactions/types/turn_param.py +73 -0
- google/genai/_interactions/types/url_context_call_arguments.py +29 -0
- google/genai/_interactions/types/url_context_call_arguments_param.py +31 -0
- google/genai/_interactions/types/url_context_call_content.py +37 -0
- google/genai/_interactions/types/url_context_call_content_param.py +37 -0
- google/genai/_interactions/types/url_context_result.py +33 -0
- google/genai/_interactions/types/url_context_result_content.py +43 -0
- google/genai/_interactions/types/url_context_result_content_param.py +44 -0
- google/genai/_interactions/types/url_context_result_param.py +32 -0
- google/genai/_interactions/types/usage.py +106 -0
- google/genai/_interactions/types/usage_param.py +106 -0
- google/genai/_interactions/types/video_content.py +41 -0
- google/genai/_interactions/types/video_content_param.py +48 -0
- google/genai/_interactions/types/video_mime_type.py +36 -0
- google/genai/_interactions/types/video_mime_type_param.py +38 -0
- google/genai/_live_converters.py +34 -3
- google/genai/_tokens_converters.py +5 -0
- google/genai/batches.py +62 -55
- google/genai/client.py +223 -0
- google/genai/errors.py +16 -1
- google/genai/file_search_stores.py +60 -60
- google/genai/files.py +56 -56
- google/genai/interactions.py +17 -0
- google/genai/live.py +4 -3
- google/genai/models.py +15 -3
- google/genai/tests/__init__.py +21 -0
- google/genai/tests/afc/__init__.py +21 -0
- google/genai/tests/afc/test_convert_if_exist_pydantic_model.py +309 -0
- google/genai/tests/afc/test_convert_number_values_for_function_call_args.py +63 -0
- google/genai/tests/afc/test_find_afc_incompatible_tool_indexes.py +240 -0
- google/genai/tests/afc/test_generate_content_stream_afc.py +530 -0
- google/genai/tests/afc/test_generate_content_stream_afc_thoughts.py +77 -0
- google/genai/tests/afc/test_get_function_map.py +176 -0
- google/genai/tests/afc/test_get_function_response_parts.py +277 -0
- google/genai/tests/afc/test_get_max_remote_calls_for_afc.py +130 -0
- google/genai/tests/afc/test_invoke_function_from_dict_args.py +241 -0
- google/genai/tests/afc/test_raise_error_for_afc_incompatible_config.py +159 -0
- google/genai/tests/afc/test_should_append_afc_history.py +53 -0
- google/genai/tests/afc/test_should_disable_afc.py +214 -0
- google/genai/tests/batches/__init__.py +17 -0
- google/genai/tests/batches/test_cancel.py +77 -0
- google/genai/tests/batches/test_create.py +78 -0
- google/genai/tests/batches/test_create_with_bigquery.py +113 -0
- google/genai/tests/batches/test_create_with_file.py +82 -0
- google/genai/tests/batches/test_create_with_gcs.py +125 -0
- google/genai/tests/batches/test_create_with_inlined_requests.py +255 -0
- google/genai/tests/batches/test_delete.py +86 -0
- google/genai/tests/batches/test_embedding.py +157 -0
- google/genai/tests/batches/test_get.py +78 -0
- google/genai/tests/batches/test_list.py +79 -0
- google/genai/tests/caches/__init__.py +17 -0
- google/genai/tests/caches/constants.py +29 -0
- google/genai/tests/caches/test_create.py +210 -0
- google/genai/tests/caches/test_create_custom_url.py +105 -0
- google/genai/tests/caches/test_delete.py +54 -0
- google/genai/tests/caches/test_delete_custom_url.py +52 -0
- google/genai/tests/caches/test_get.py +94 -0
- google/genai/tests/caches/test_get_custom_url.py +52 -0
- google/genai/tests/caches/test_list.py +68 -0
- google/genai/tests/caches/test_update.py +70 -0
- google/genai/tests/caches/test_update_custom_url.py +58 -0
- google/genai/tests/chats/__init__.py +1 -0
- google/genai/tests/chats/test_get_history.py +597 -0
- google/genai/tests/chats/test_send_message.py +844 -0
- google/genai/tests/chats/test_validate_response.py +90 -0
- google/genai/tests/client/__init__.py +17 -0
- google/genai/tests/client/test_async_stream.py +427 -0
- google/genai/tests/client/test_client_close.py +197 -0
- google/genai/tests/client/test_client_initialization.py +1687 -0
- google/genai/tests/client/test_client_requests.py +355 -0
- google/genai/tests/client/test_custom_client.py +77 -0
- google/genai/tests/client/test_http_options.py +178 -0
- google/genai/tests/client/test_replay_client_equality.py +168 -0
- google/genai/tests/client/test_retries.py +846 -0
- google/genai/tests/client/test_upload_errors.py +136 -0
- google/genai/tests/common/__init__.py +17 -0
- google/genai/tests/common/test_common.py +954 -0
- google/genai/tests/conftest.py +162 -0
- google/genai/tests/documents/__init__.py +17 -0
- google/genai/tests/documents/test_delete.py +51 -0
- google/genai/tests/documents/test_get.py +85 -0
- google/genai/tests/documents/test_list.py +72 -0
- google/genai/tests/errors/__init__.py +1 -0
- google/genai/tests/errors/test_api_error.py +417 -0
- google/genai/tests/file_search_stores/__init__.py +17 -0
- google/genai/tests/file_search_stores/test_create.py +66 -0
- google/genai/tests/file_search_stores/test_delete.py +64 -0
- google/genai/tests/file_search_stores/test_get.py +94 -0
- google/genai/tests/file_search_stores/test_import_file.py +112 -0
- google/genai/tests/file_search_stores/test_list.py +57 -0
- google/genai/tests/file_search_stores/test_upload_to_file_search_store.py +141 -0
- google/genai/tests/files/__init__.py +17 -0
- google/genai/tests/files/test_delete.py +46 -0
- google/genai/tests/files/test_download.py +85 -0
- google/genai/tests/files/test_get.py +46 -0
- google/genai/tests/files/test_list.py +72 -0
- google/genai/tests/files/test_upload.py +255 -0
- google/genai/tests/imports/test_no_optional_imports.py +28 -0
- google/genai/tests/interactions/__init__.py +0 -0
- google/genai/tests/interactions/test_integration.py +80 -0
- google/genai/tests/live/__init__.py +16 -0
- google/genai/tests/live/test_live.py +2177 -0
- google/genai/tests/live/test_live_music.py +362 -0
- google/genai/tests/live/test_live_response.py +163 -0
- google/genai/tests/live/test_send_client_content.py +147 -0
- google/genai/tests/live/test_send_realtime_input.py +268 -0
- google/genai/tests/live/test_send_tool_response.py +222 -0
- google/genai/tests/local_tokenizer/__init__.py +17 -0
- google/genai/tests/local_tokenizer/test_local_tokenizer.py +343 -0
- google/genai/tests/local_tokenizer/test_local_tokenizer_loader.py +235 -0
- google/genai/tests/mcp/__init__.py +17 -0
- google/genai/tests/mcp/test_has_mcp_tool_usage.py +89 -0
- google/genai/tests/mcp/test_mcp_to_gemini_tools.py +191 -0
- google/genai/tests/mcp/test_parse_config_for_mcp_sessions.py +201 -0
- google/genai/tests/mcp/test_parse_config_for_mcp_usage.py +130 -0
- google/genai/tests/mcp/test_set_mcp_usage_header.py +72 -0
- google/genai/tests/models/__init__.py +17 -0
- google/genai/tests/models/constants.py +8 -0
- google/genai/tests/models/test_compute_tokens.py +120 -0
- google/genai/tests/models/test_count_tokens.py +159 -0
- google/genai/tests/models/test_delete.py +107 -0
- google/genai/tests/models/test_edit_image.py +264 -0
- google/genai/tests/models/test_embed_content.py +94 -0
- google/genai/tests/models/test_function_call_streaming.py +442 -0
- google/genai/tests/models/test_generate_content.py +2502 -0
- google/genai/tests/models/test_generate_content_cached_content.py +132 -0
- google/genai/tests/models/test_generate_content_config_zero_value.py +103 -0
- google/genai/tests/models/test_generate_content_from_apikey.py +44 -0
- google/genai/tests/models/test_generate_content_http_options.py +40 -0
- google/genai/tests/models/test_generate_content_image_generation.py +143 -0
- google/genai/tests/models/test_generate_content_mcp.py +343 -0
- google/genai/tests/models/test_generate_content_media_resolution.py +97 -0
- google/genai/tests/models/test_generate_content_model.py +139 -0
- google/genai/tests/models/test_generate_content_part.py +821 -0
- google/genai/tests/models/test_generate_content_thought.py +76 -0
- google/genai/tests/models/test_generate_content_tools.py +1761 -0
- google/genai/tests/models/test_generate_images.py +191 -0
- google/genai/tests/models/test_generate_videos.py +759 -0
- google/genai/tests/models/test_get.py +104 -0
- google/genai/tests/models/test_list.py +233 -0
- google/genai/tests/models/test_recontext_image.py +189 -0
- google/genai/tests/models/test_segment_image.py +148 -0
- google/genai/tests/models/test_update.py +95 -0
- google/genai/tests/models/test_upscale_image.py +157 -0
- google/genai/tests/operations/__init__.py +17 -0
- google/genai/tests/operations/test_get.py +38 -0
- google/genai/tests/public_samples/__init__.py +17 -0
- google/genai/tests/public_samples/test_gemini_text_only.py +34 -0
- google/genai/tests/pytest_helper.py +229 -0
- google/genai/tests/shared/__init__.py +16 -0
- google/genai/tests/shared/batches/__init__.py +14 -0
- google/genai/tests/shared/batches/test_create_delete.py +57 -0
- google/genai/tests/shared/batches/test_create_get_cancel.py +56 -0
- google/genai/tests/shared/batches/test_list.py +40 -0
- google/genai/tests/shared/caches/__init__.py +14 -0
- google/genai/tests/shared/caches/test_create_get_delete.py +67 -0
- google/genai/tests/shared/caches/test_create_update_get.py +71 -0
- google/genai/tests/shared/caches/test_list.py +40 -0
- google/genai/tests/shared/chats/__init__.py +14 -0
- google/genai/tests/shared/chats/test_send_message.py +48 -0
- google/genai/tests/shared/chats/test_send_message_stream.py +50 -0
- google/genai/tests/shared/files/__init__.py +14 -0
- google/genai/tests/shared/files/test_list.py +41 -0
- google/genai/tests/shared/files/test_upload_get_delete.py +54 -0
- google/genai/tests/shared/models/__init__.py +14 -0
- google/genai/tests/shared/models/test_compute_tokens.py +41 -0
- google/genai/tests/shared/models/test_count_tokens.py +40 -0
- google/genai/tests/shared/models/test_edit_image.py +67 -0
- google/genai/tests/shared/models/test_embed.py +40 -0
- google/genai/tests/shared/models/test_generate_content.py +39 -0
- google/genai/tests/shared/models/test_generate_content_stream.py +54 -0
- google/genai/tests/shared/models/test_generate_images.py +40 -0
- google/genai/tests/shared/models/test_generate_videos.py +38 -0
- google/genai/tests/shared/models/test_list.py +37 -0
- google/genai/tests/shared/models/test_recontext_image.py +55 -0
- google/genai/tests/shared/models/test_segment_image.py +52 -0
- google/genai/tests/shared/models/test_upscale_image.py +52 -0
- google/genai/tests/shared/tunings/__init__.py +16 -0
- google/genai/tests/shared/tunings/test_create.py +46 -0
- google/genai/tests/shared/tunings/test_create_get_cancel.py +56 -0
- google/genai/tests/shared/tunings/test_list.py +39 -0
- google/genai/tests/tokens/__init__.py +16 -0
- google/genai/tests/tokens/test_create.py +154 -0
- google/genai/tests/transformers/__init__.py +17 -0
- google/genai/tests/transformers/test_blobs.py +71 -0
- google/genai/tests/transformers/test_bytes.py +15 -0
- google/genai/tests/transformers/test_duck_type.py +96 -0
- google/genai/tests/transformers/test_function_responses.py +72 -0
- google/genai/tests/transformers/test_schema.py +653 -0
- google/genai/tests/transformers/test_t_batch.py +286 -0
- google/genai/tests/transformers/test_t_content.py +160 -0
- google/genai/tests/transformers/test_t_contents.py +398 -0
- google/genai/tests/transformers/test_t_part.py +85 -0
- google/genai/tests/transformers/test_t_parts.py +87 -0
- google/genai/tests/transformers/test_t_tool.py +157 -0
- google/genai/tests/transformers/test_t_tools.py +195 -0
- google/genai/tests/tunings/__init__.py +16 -0
- google/genai/tests/tunings/test_cancel.py +39 -0
- google/genai/tests/tunings/test_end_to_end.py +106 -0
- google/genai/tests/tunings/test_get.py +67 -0
- google/genai/tests/tunings/test_list.py +75 -0
- google/genai/tests/tunings/test_tune.py +268 -0
- google/genai/tests/types/__init__.py +16 -0
- google/genai/tests/types/test_bytes_internal.py +271 -0
- google/genai/tests/types/test_bytes_type.py +152 -0
- google/genai/tests/types/test_future.py +101 -0
- google/genai/tests/types/test_optional_types.py +36 -0
- google/genai/tests/types/test_part_type.py +616 -0
- google/genai/tests/types/test_schema_from_json_schema.py +417 -0
- google/genai/tests/types/test_schema_json_schema.py +468 -0
- google/genai/tests/types/test_types.py +2903 -0
- google/genai/tunings.py +57 -57
- google/genai/types.py +229 -121
- google/genai/version.py +1 -1
- {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/METADATA +4 -2
- google_genai-1.55.0.dist-info/RECORD +345 -0
- google_genai-1.53.0.dist-info/RECORD +0 -41
- {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/WHEEL +0 -0
- {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
from ... import _mcp_utils
|
|
17
|
+
from ... import types
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from mcp import types as mcp_types
|
|
21
|
+
except ImportError as e:
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
if sys.version_info < (3, 10):
|
|
25
|
+
raise ImportError(
|
|
26
|
+
'MCP Tool requires Python 3.10 or above. Please upgrade your Python'
|
|
27
|
+
' version.'
|
|
28
|
+
) from e
|
|
29
|
+
else:
|
|
30
|
+
raise e
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_empty_mcp_tools_list():
|
|
34
|
+
"""Test conversion of empty MCP tools list to Gemini tools list."""
|
|
35
|
+
result = _mcp_utils.mcp_to_gemini_tools([])
|
|
36
|
+
|
|
37
|
+
assert result == []
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_unknown_field_conversion():
|
|
41
|
+
"""Test conversion of MCP tools with unknown fields to Gemini tools."""
|
|
42
|
+
mcp_tools = [
|
|
43
|
+
mcp_types.Tool(
|
|
44
|
+
name='tool',
|
|
45
|
+
description='tool-description',
|
|
46
|
+
inputSchema={
|
|
47
|
+
'type': 'object',
|
|
48
|
+
'properties': {},
|
|
49
|
+
'unknown_field': 'unknownField',
|
|
50
|
+
'unknown_object': {},
|
|
51
|
+
},
|
|
52
|
+
),
|
|
53
|
+
]
|
|
54
|
+
result = _mcp_utils.mcp_to_gemini_tools(mcp_tools)
|
|
55
|
+
assert result == [
|
|
56
|
+
types.Tool(
|
|
57
|
+
function_declarations=[
|
|
58
|
+
types.FunctionDeclaration(
|
|
59
|
+
name='tool',
|
|
60
|
+
description='tool-description',
|
|
61
|
+
parameters=types.Schema(
|
|
62
|
+
type='OBJECT',
|
|
63
|
+
properties={},
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
],
|
|
67
|
+
),
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_items_conversion():
|
|
72
|
+
"""Test conversion of MCP tools with items to Gemini tools."""
|
|
73
|
+
mcp_tools = [
|
|
74
|
+
mcp_types.Tool(
|
|
75
|
+
name='tool',
|
|
76
|
+
description='tool-description',
|
|
77
|
+
inputSchema={
|
|
78
|
+
'type': 'array',
|
|
79
|
+
'items': {
|
|
80
|
+
'type': 'object',
|
|
81
|
+
'properties': {
|
|
82
|
+
'key1': {
|
|
83
|
+
'type': 'string',
|
|
84
|
+
},
|
|
85
|
+
'key2': {
|
|
86
|
+
'type': 'number',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
),
|
|
92
|
+
]
|
|
93
|
+
result = _mcp_utils.mcp_to_gemini_tools(mcp_tools)
|
|
94
|
+
assert result == [
|
|
95
|
+
types.Tool(
|
|
96
|
+
function_declarations=[
|
|
97
|
+
types.FunctionDeclaration(
|
|
98
|
+
name='tool',
|
|
99
|
+
description='tool-description',
|
|
100
|
+
parameters=types.Schema(
|
|
101
|
+
type='ARRAY',
|
|
102
|
+
items=types.Schema(
|
|
103
|
+
type='OBJECT',
|
|
104
|
+
properties={
|
|
105
|
+
'key1': types.Schema(type='STRING'),
|
|
106
|
+
'key2': types.Schema(type='NUMBER'),
|
|
107
|
+
},
|
|
108
|
+
),
|
|
109
|
+
),
|
|
110
|
+
),
|
|
111
|
+
],
|
|
112
|
+
),
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_any_of_conversion():
|
|
117
|
+
"""Test conversion of MCP tools with any_of to Gemini tools."""
|
|
118
|
+
mcp_tools = [
|
|
119
|
+
mcp_types.Tool(
|
|
120
|
+
name='tool',
|
|
121
|
+
description='tool-description',
|
|
122
|
+
inputSchema={
|
|
123
|
+
'type': 'object',
|
|
124
|
+
'any_of': [
|
|
125
|
+
{
|
|
126
|
+
'type': 'string',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
'type': 'number',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
),
|
|
134
|
+
]
|
|
135
|
+
result = _mcp_utils.mcp_to_gemini_tools(mcp_tools)
|
|
136
|
+
assert result == [
|
|
137
|
+
types.Tool(
|
|
138
|
+
function_declarations=[
|
|
139
|
+
types.FunctionDeclaration(
|
|
140
|
+
name='tool',
|
|
141
|
+
description='tool-description',
|
|
142
|
+
parameters=types.Schema(
|
|
143
|
+
type='OBJECT',
|
|
144
|
+
any_of=[
|
|
145
|
+
types.Schema(type='STRING'),
|
|
146
|
+
types.Schema(type='NUMBER'),
|
|
147
|
+
],
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
],
|
|
151
|
+
),
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_properties_conversion():
|
|
156
|
+
"""Test conversion of MCP tools with properties to Gemini tools."""
|
|
157
|
+
mcp_tools = [
|
|
158
|
+
mcp_types.Tool(
|
|
159
|
+
name='tool',
|
|
160
|
+
description='tool-description',
|
|
161
|
+
inputSchema={
|
|
162
|
+
'type': 'object',
|
|
163
|
+
'properties': {
|
|
164
|
+
'key1': {
|
|
165
|
+
'type': 'string',
|
|
166
|
+
},
|
|
167
|
+
'key2': {
|
|
168
|
+
'type': 'number',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
),
|
|
173
|
+
]
|
|
174
|
+
result = _mcp_utils.mcp_to_gemini_tools(mcp_tools)
|
|
175
|
+
assert result == [
|
|
176
|
+
types.Tool(
|
|
177
|
+
function_declarations=[
|
|
178
|
+
types.FunctionDeclaration(
|
|
179
|
+
name='tool',
|
|
180
|
+
description='tool-description',
|
|
181
|
+
parameters=types.Schema(
|
|
182
|
+
type='OBJECT',
|
|
183
|
+
properties={
|
|
184
|
+
'key1': types.Schema(type='STRING'),
|
|
185
|
+
'key2': types.Schema(type='NUMBER'),
|
|
186
|
+
},
|
|
187
|
+
),
|
|
188
|
+
),
|
|
189
|
+
],
|
|
190
|
+
),
|
|
191
|
+
]
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
import _asyncio
|
|
17
|
+
import pytest
|
|
18
|
+
from ... import _extra_utils
|
|
19
|
+
from ... import types
|
|
20
|
+
from ..._adapters import McpToGenAiToolAdapter
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from mcp import types as mcp_types
|
|
24
|
+
from mcp import ClientSession as McpClientSession
|
|
25
|
+
except ImportError as e:
|
|
26
|
+
import sys
|
|
27
|
+
|
|
28
|
+
if sys.version_info < (3, 10):
|
|
29
|
+
raise ImportError(
|
|
30
|
+
'MCP Tool requires Python 3.10 or above. Please upgrade your Python'
|
|
31
|
+
' version.'
|
|
32
|
+
) from e
|
|
33
|
+
else:
|
|
34
|
+
raise e
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.asyncio
|
|
38
|
+
async def test_parse_empty_config_dict():
|
|
39
|
+
"""Test conversion of empty GenerateContentConfigDict to parsed config."""
|
|
40
|
+
config = {}
|
|
41
|
+
parsed_config, mcp_to_genai_tool_adapters = (
|
|
42
|
+
await _extra_utils.parse_config_for_mcp_sessions(config)
|
|
43
|
+
)
|
|
44
|
+
assert parsed_config == None
|
|
45
|
+
assert not mcp_to_genai_tool_adapters
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.mark.asyncio
|
|
49
|
+
async def test_parse_empty_config_object():
|
|
50
|
+
"""Test conversion of empty GenerateContentConfig to parsed config."""
|
|
51
|
+
config = types.GenerateContentConfig()
|
|
52
|
+
parsed_config, mcp_to_genai_tool_adapters = (
|
|
53
|
+
await _extra_utils.parse_config_for_mcp_sessions(config)
|
|
54
|
+
)
|
|
55
|
+
assert config is not parsed_config # config is not modified
|
|
56
|
+
assert not mcp_to_genai_tool_adapters
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.mark.asyncio
|
|
60
|
+
async def test_parse_config_object_with_tools():
|
|
61
|
+
"""Test conversion of GenerateContentConfig with tools to parsed config."""
|
|
62
|
+
|
|
63
|
+
class MockMcpClientSession(McpClientSession):
|
|
64
|
+
|
|
65
|
+
def __init__(self):
|
|
66
|
+
self._read_stream = None
|
|
67
|
+
self._write_stream = None
|
|
68
|
+
|
|
69
|
+
async def list_tools(self):
|
|
70
|
+
return mcp_types.ListToolsResult(
|
|
71
|
+
tools=[
|
|
72
|
+
mcp_types.Tool(
|
|
73
|
+
name='get_weather',
|
|
74
|
+
description='Get the weather in a city.',
|
|
75
|
+
inputSchema={
|
|
76
|
+
'type': 'object',
|
|
77
|
+
'properties': {'location': {'type': 'string'}},
|
|
78
|
+
},
|
|
79
|
+
),
|
|
80
|
+
mcp_types.Tool(
|
|
81
|
+
name='get_weather_2',
|
|
82
|
+
description='Different tool to get the weather.',
|
|
83
|
+
inputSchema={
|
|
84
|
+
'type': 'object',
|
|
85
|
+
'properties': {'location': {'type': 'string'}},
|
|
86
|
+
},
|
|
87
|
+
),
|
|
88
|
+
]
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
mock_session_instance = MockMcpClientSession()
|
|
92
|
+
config = types.GenerateContentConfig(tools=[mock_session_instance])
|
|
93
|
+
parsed_config, mcp_to_genai_tool_adapters = (
|
|
94
|
+
await _extra_utils.parse_config_for_mcp_sessions(config)
|
|
95
|
+
)
|
|
96
|
+
assert len(config.tools) == 1
|
|
97
|
+
assert config.tools[0] is mock_session_instance
|
|
98
|
+
assert config is not parsed_config # config is not modified
|
|
99
|
+
assert len(mcp_to_genai_tool_adapters) == 2
|
|
100
|
+
assert mcp_to_genai_tool_adapters.keys() == {
|
|
101
|
+
'get_weather',
|
|
102
|
+
'get_weather_2',
|
|
103
|
+
}
|
|
104
|
+
assert isinstance(
|
|
105
|
+
mcp_to_genai_tool_adapters['get_weather'], McpToGenAiToolAdapter
|
|
106
|
+
)
|
|
107
|
+
assert isinstance(
|
|
108
|
+
mcp_to_genai_tool_adapters['get_weather_2'], McpToGenAiToolAdapter
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@pytest.mark.asyncio
|
|
113
|
+
async def test_parse_config_object_with_tools_complex_type():
|
|
114
|
+
"""Test conversion of GenerateContentConfig with tools to parsed config."""
|
|
115
|
+
|
|
116
|
+
class MockMcpClientSession(McpClientSession):
|
|
117
|
+
|
|
118
|
+
def __init__(self):
|
|
119
|
+
self._read_stream = None
|
|
120
|
+
self._write_stream = None
|
|
121
|
+
self._future = _asyncio.Future() # This object cannot be pickled.
|
|
122
|
+
|
|
123
|
+
async def list_tools(self):
|
|
124
|
+
return mcp_types.ListToolsResult(
|
|
125
|
+
tools=[
|
|
126
|
+
mcp_types.Tool(
|
|
127
|
+
name='get_weather',
|
|
128
|
+
description='Get the weather in a city.',
|
|
129
|
+
inputSchema={
|
|
130
|
+
'type': 'object',
|
|
131
|
+
'properties': {'location': {'type': 'string'}},
|
|
132
|
+
},
|
|
133
|
+
),
|
|
134
|
+
mcp_types.Tool(
|
|
135
|
+
name='get_weather_2',
|
|
136
|
+
description='Different tool to get the weather.',
|
|
137
|
+
inputSchema={
|
|
138
|
+
'type': 'object',
|
|
139
|
+
'properties': {'location': {'type': 'string'}},
|
|
140
|
+
},
|
|
141
|
+
),
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
mock_session_instance = MockMcpClientSession()
|
|
146
|
+
config = types.GenerateContentConfig(tools=[mock_session_instance])
|
|
147
|
+
parsed_config, mcp_to_genai_tool_adapters = (
|
|
148
|
+
await _extra_utils.parse_config_for_mcp_sessions(config)
|
|
149
|
+
)
|
|
150
|
+
assert len(config.tools) == 1
|
|
151
|
+
assert config.tools[0] is mock_session_instance
|
|
152
|
+
assert config is not parsed_config # config is not modified
|
|
153
|
+
assert len(mcp_to_genai_tool_adapters) == 2
|
|
154
|
+
assert mcp_to_genai_tool_adapters.keys() == {
|
|
155
|
+
'get_weather',
|
|
156
|
+
'get_weather_2',
|
|
157
|
+
}
|
|
158
|
+
assert isinstance(
|
|
159
|
+
mcp_to_genai_tool_adapters['get_weather'], McpToGenAiToolAdapter
|
|
160
|
+
)
|
|
161
|
+
assert isinstance(
|
|
162
|
+
mcp_to_genai_tool_adapters['get_weather_2'], McpToGenAiToolAdapter
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@pytest.mark.asyncio
|
|
167
|
+
async def test_parse_config_object_with_non_mcp_tools():
|
|
168
|
+
"""Test conversion of GenerateContentConfig with regular tools to parsed config."""
|
|
169
|
+
|
|
170
|
+
config = types.GenerateContentConfig(
|
|
171
|
+
tools=[
|
|
172
|
+
types.Tool(
|
|
173
|
+
function_declarations=[
|
|
174
|
+
{'name': 'tool-1', 'description': 'tool-1-description'}
|
|
175
|
+
]
|
|
176
|
+
),
|
|
177
|
+
types.Tool(
|
|
178
|
+
function_declarations=[
|
|
179
|
+
{'name': 'tool-2', 'description': 'tool-2-description'}
|
|
180
|
+
]
|
|
181
|
+
),
|
|
182
|
+
]
|
|
183
|
+
)
|
|
184
|
+
parsed_config, mcp_to_genai_tool_adapters = (
|
|
185
|
+
await _extra_utils.parse_config_for_mcp_sessions(config)
|
|
186
|
+
)
|
|
187
|
+
assert len(config.tools) == 2
|
|
188
|
+
assert config is not parsed_config # config is not modified
|
|
189
|
+
assert mcp_to_genai_tool_adapters == {}
|
|
190
|
+
assert parsed_config.tools == [
|
|
191
|
+
types.Tool(
|
|
192
|
+
function_declarations=[
|
|
193
|
+
{'name': 'tool-1', 'description': 'tool-1-description'}
|
|
194
|
+
]
|
|
195
|
+
),
|
|
196
|
+
types.Tool(
|
|
197
|
+
function_declarations=[
|
|
198
|
+
{'name': 'tool-2', 'description': 'tool-2-description'}
|
|
199
|
+
]
|
|
200
|
+
),
|
|
201
|
+
]
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
import pytest
|
|
18
|
+
from ... import _extra_utils
|
|
19
|
+
from ... import types
|
|
20
|
+
from ..._adapters import McpToGenAiToolAdapter
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from mcp import types as mcp_types
|
|
24
|
+
from mcp import ClientSession as McpClientSession
|
|
25
|
+
except ImportError as e:
|
|
26
|
+
import sys
|
|
27
|
+
|
|
28
|
+
if sys.version_info < (3, 10):
|
|
29
|
+
raise ImportError(
|
|
30
|
+
'MCP Tool requires Python 3.10 or above. Please upgrade your Python'
|
|
31
|
+
' version.'
|
|
32
|
+
) from e
|
|
33
|
+
else:
|
|
34
|
+
raise e
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_parse_empty_config_dict():
|
|
38
|
+
"""Test conversion of empty GenerateContentConfigDict to parsed config."""
|
|
39
|
+
config = {}
|
|
40
|
+
parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
|
|
41
|
+
assert parsed_config == None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_parse_empty_config_object():
|
|
45
|
+
"""Test conversion of empty GenerateContentConfig to parsed config."""
|
|
46
|
+
config = types.GenerateContentConfig()
|
|
47
|
+
parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
|
|
48
|
+
assert config is not parsed_config # config is not modified
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_parse_config_object_with_tools():
|
|
52
|
+
"""Test conversion of GenerateContentConfig with tools to parsed config."""
|
|
53
|
+
|
|
54
|
+
class MockMcpClientSession(McpClientSession):
|
|
55
|
+
|
|
56
|
+
def __init__(self):
|
|
57
|
+
self._read_stream = None
|
|
58
|
+
self._write_stream = None
|
|
59
|
+
|
|
60
|
+
async def list_tools(self):
|
|
61
|
+
return mcp_types.ListToolsResult(
|
|
62
|
+
tools=[
|
|
63
|
+
mcp_types.Tool(
|
|
64
|
+
name='get_weather',
|
|
65
|
+
description='Get the weather in a city.',
|
|
66
|
+
inputSchema={
|
|
67
|
+
'type': 'object',
|
|
68
|
+
'properties': {'location': {'type': 'string'}},
|
|
69
|
+
},
|
|
70
|
+
),
|
|
71
|
+
mcp_types.Tool(
|
|
72
|
+
name='get_weather_2',
|
|
73
|
+
description='Different tool to get the weather.',
|
|
74
|
+
inputSchema={
|
|
75
|
+
'type': 'object',
|
|
76
|
+
'properties': {'location': {'type': 'string'}},
|
|
77
|
+
},
|
|
78
|
+
),
|
|
79
|
+
]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
mock_session_instance = MockMcpClientSession()
|
|
83
|
+
config = types.GenerateContentConfig(tools=[mock_session_instance])
|
|
84
|
+
parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
|
|
85
|
+
assert config.http_options is None
|
|
86
|
+
assert config is not parsed_config # config is not modified
|
|
87
|
+
assert re.match(
|
|
88
|
+
r'mcp_used/\d+\.\d+\.\d+',
|
|
89
|
+
parsed_config.http_options.headers['x-goog-api-client'],
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_parse_config_object_with_tools_and_existing_headers():
|
|
94
|
+
"""Test conversion of GenerateContentConfig with tools and existing headers to parsed config."""
|
|
95
|
+
|
|
96
|
+
config = types.GenerateContentConfig(
|
|
97
|
+
tools=[
|
|
98
|
+
mcp_types.Tool(
|
|
99
|
+
name='get_weather',
|
|
100
|
+
description='Get the weather in a city.',
|
|
101
|
+
inputSchema={
|
|
102
|
+
'type': 'object',
|
|
103
|
+
'properties': {'location': {'type': 'string'}},
|
|
104
|
+
},
|
|
105
|
+
),
|
|
106
|
+
mcp_types.Tool(
|
|
107
|
+
name='get_weather_2',
|
|
108
|
+
description='Different tool to get the weather.',
|
|
109
|
+
inputSchema={
|
|
110
|
+
'type': 'object',
|
|
111
|
+
'properties': {'location': {'type': 'string'}},
|
|
112
|
+
},
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
http_options=types.HttpOptions(
|
|
116
|
+
headers={
|
|
117
|
+
'x-goog-api-client': 'google-genai-sdk/1.0.0 gl-python/1.0.0'
|
|
118
|
+
}
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
|
|
122
|
+
assert not re.match(
|
|
123
|
+
r'mcp_used/\d+\.\d+\.\d+',
|
|
124
|
+
config.http_options.headers['x-goog-api-client'],
|
|
125
|
+
)
|
|
126
|
+
assert config is not parsed_config # config is not modified
|
|
127
|
+
assert re.match(
|
|
128
|
+
r'google-genai-sdk/1.0.0 gl-python/1.0.0 mcp_used/\d+\.\d+\.\d+',
|
|
129
|
+
parsed_config.http_options.headers['x-goog-api-client'],
|
|
130
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
from importlib.metadata import version
|
|
17
|
+
import re
|
|
18
|
+
import typing
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from ... import _mcp_utils
|
|
22
|
+
from ... import types
|
|
23
|
+
|
|
24
|
+
_is_mcp_imported = False
|
|
25
|
+
if typing.TYPE_CHECKING:
|
|
26
|
+
import mcp
|
|
27
|
+
|
|
28
|
+
_is_mcp_imported = True
|
|
29
|
+
else:
|
|
30
|
+
try:
|
|
31
|
+
import mcp
|
|
32
|
+
|
|
33
|
+
_is_mcp_imported = True
|
|
34
|
+
except ImportError:
|
|
35
|
+
_is_mcp_imported = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_set_mcp_usage_header_from_empty_dict():
|
|
39
|
+
if not _is_mcp_imported:
|
|
40
|
+
return
|
|
41
|
+
"""Test whether the MCP usage header is set correctly from an empty dict."""
|
|
42
|
+
headers = {}
|
|
43
|
+
_mcp_utils.set_mcp_usage_header(headers)
|
|
44
|
+
assert re.match(r'mcp_used/\d+\.\d+\.\d+', headers['x-goog-api-client'])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_set_mcp_usage_header_with_existing_header():
|
|
48
|
+
if not _is_mcp_imported:
|
|
49
|
+
return
|
|
50
|
+
"""Test whether the MCP usage header is set correctly from an existing header."""
|
|
51
|
+
headers = {'x-goog-api-client': 'google-genai-sdk/1.0.0 gl-python/1.0.0'}
|
|
52
|
+
_mcp_utils.set_mcp_usage_header(headers)
|
|
53
|
+
assert re.match(
|
|
54
|
+
r'google-genai-sdk/1.0.0 gl-python/1.0.0 mcp_used/\d+\.\d+\.\d+',
|
|
55
|
+
headers['x-goog-api-client'],
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_set_mcp_usage_header_with_existing_mcp_header():
|
|
60
|
+
if not _is_mcp_imported:
|
|
61
|
+
return
|
|
62
|
+
"""Test whether the MCP usage header is set correctly from an existing MCP header."""
|
|
63
|
+
headers = {
|
|
64
|
+
'x-goog-api-client': (
|
|
65
|
+
'google-genai-sdk/1.0.0 gl-python/1.0.0 mcp_used/1.0.0'
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
_mcp_utils.set_mcp_usage_header(headers)
|
|
69
|
+
assert re.match(
|
|
70
|
+
r'google-genai-sdk/1.0.0 gl-python/1.0.0 mcp_used/\d+\.\d+\.\d+',
|
|
71
|
+
headers['x-goog-api-client'],
|
|
72
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright 2025 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
"""Tests for the Google GenAI SDK's models module."""
|