langchain-google-genai 2.1.7__tar.gz → 2.1.9__tar.gz

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.

Potentially problematic release.


This version of langchain-google-genai might be problematic. Click here for more details.

Files changed (16) hide show
  1. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/PKG-INFO +22 -21
  2. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/README.md +21 -20
  3. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/__init__.py +26 -24
  4. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/_common.py +10 -10
  5. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/_function_utils.py +9 -2
  6. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/_genai_extension.py +5 -5
  7. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/_image_utils.py +3 -3
  8. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/chat_models.py +186 -31
  9. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/embeddings.py +125 -21
  10. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/llms.py +13 -1
  11. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/pyproject.toml +1 -1
  12. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/LICENSE +0 -0
  13. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/_enums.py +0 -0
  14. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/genai_aqa.py +0 -0
  15. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/google_vector_store.py +0 -0
  16. {langchain_google_genai-2.1.7 → langchain_google_genai-2.1.9}/langchain_google_genai/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-google-genai
3
- Version: 2.1.7
3
+ Version: 2.1.9
4
4
  Summary: An integration package connecting Google's genai package and LangChain
5
5
  Home-page: https://github.com/langchain-ai/langchain-google
6
6
  License: MIT
@@ -29,16 +29,20 @@ This package enables seamless access to Google Gemini's chat, vision, embeddings
29
29
 
30
30
  ## Table of Contents
31
31
 
32
- - [Overview](#overview)
33
- - [Installation](#installation)
34
- - [Quickstart](#quickstart)
35
- - [Chat Models](#chat-models)
36
- - [Multimodal Inputs](#multimodal-inputs)
37
- - [Multimodal Outputs](#multimodal-outputs)
38
- - [Multimodal Outputs in Chains](#multimodal-outputs-in-chains)
39
- - [Thinking Support](#thinking-support)
40
- - [Embeddings](#embeddings)
41
- - [Semantic Retrieval (RAG)](#semantic-retrieval-rag)
32
+ - [langchain-google-genai](#langchain-google-genai)
33
+ - [Table of Contents](#table-of-contents)
34
+ - [Overview](#overview)
35
+ - [Installation](#installation)
36
+ - [Quickstart](#quickstart)
37
+ - [Chat Models](#chat-models)
38
+ - [Multimodal Inputs](#multimodal-inputs)
39
+ - [Multimodal Outputs](#multimodal-outputs)
40
+ - [Audio Output](#audio-output)
41
+ - [Multimodal Outputs in Chains](#multimodal-outputs-in-chains)
42
+ - [Thinking Support](#thinking-support)
43
+ - [Embeddings](#embeddings)
44
+ - [Semantic Retrieval (RAG)](#semantic-retrieval-rag)
45
+ - [Resources](#resources)
42
46
 
43
47
  ---
44
48
 
@@ -109,9 +113,9 @@ print(response.content)
109
113
 
110
114
  ✅ `image_url` can be:
111
115
 
112
- * A public image URL
113
- * A Google Cloud Storage path (`gcs://...`)
114
- * A base64-encoded image (e.g., `data:image/png;base64,...`)
116
+ - A public image URL
117
+ - A Google Cloud Storage path (`gcs://...`)
118
+ - A base64-encoded image (e.g., `data:image/png;base64,...`)
115
119
 
116
120
  ---
117
121
 
@@ -208,7 +212,7 @@ You can use Gemini embeddings in LangChain:
208
212
  ```python
209
213
  from langchain_google_genai import GoogleGenerativeAIEmbeddings
210
214
 
211
- embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
215
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
212
216
  vector = embeddings.embed_query("hello, world!")
213
217
  print(vector)
214
218
  ```
@@ -249,12 +253,9 @@ print("Answerable probability:", response.answerable_probability)
249
253
 
250
254
  ---
251
255
 
252
-
253
256
  ## Resources
254
257
 
255
- * [LangChain Documentation](https://docs.langchain.com/)
256
- * [Google Generative AI SDK](https://googleapis.github.io/python-genai/)
257
- * [Gemini Model Documentation](https://ai.google.dev/)
258
-
259
-
258
+ - [LangChain Documentation](https://docs.langchain.com/)
259
+ - [Google Generative AI SDK](https://googleapis.github.io/python-genai/)
260
+ - [Gemini Model Documentation](https://ai.google.dev/)
260
261
 
@@ -8,16 +8,20 @@ This package enables seamless access to Google Gemini's chat, vision, embeddings
8
8
 
9
9
  ## Table of Contents
10
10
 
11
- - [Overview](#overview)
12
- - [Installation](#installation)
13
- - [Quickstart](#quickstart)
14
- - [Chat Models](#chat-models)
15
- - [Multimodal Inputs](#multimodal-inputs)
16
- - [Multimodal Outputs](#multimodal-outputs)
17
- - [Multimodal Outputs in Chains](#multimodal-outputs-in-chains)
18
- - [Thinking Support](#thinking-support)
19
- - [Embeddings](#embeddings)
20
- - [Semantic Retrieval (RAG)](#semantic-retrieval-rag)
11
+ - [langchain-google-genai](#langchain-google-genai)
12
+ - [Table of Contents](#table-of-contents)
13
+ - [Overview](#overview)
14
+ - [Installation](#installation)
15
+ - [Quickstart](#quickstart)
16
+ - [Chat Models](#chat-models)
17
+ - [Multimodal Inputs](#multimodal-inputs)
18
+ - [Multimodal Outputs](#multimodal-outputs)
19
+ - [Audio Output](#audio-output)
20
+ - [Multimodal Outputs in Chains](#multimodal-outputs-in-chains)
21
+ - [Thinking Support](#thinking-support)
22
+ - [Embeddings](#embeddings)
23
+ - [Semantic Retrieval (RAG)](#semantic-retrieval-rag)
24
+ - [Resources](#resources)
21
25
 
22
26
  ---
23
27
 
@@ -88,9 +92,9 @@ print(response.content)
88
92
 
89
93
  ✅ `image_url` can be:
90
94
 
91
- * A public image URL
92
- * A Google Cloud Storage path (`gcs://...`)
93
- * A base64-encoded image (e.g., `data:image/png;base64,...`)
95
+ - A public image URL
96
+ - A Google Cloud Storage path (`gcs://...`)
97
+ - A base64-encoded image (e.g., `data:image/png;base64,...`)
94
98
 
95
99
  ---
96
100
 
@@ -187,7 +191,7 @@ You can use Gemini embeddings in LangChain:
187
191
  ```python
188
192
  from langchain_google_genai import GoogleGenerativeAIEmbeddings
189
193
 
190
- embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
194
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
191
195
  vector = embeddings.embed_query("hello, world!")
192
196
  print(vector)
193
197
  ```
@@ -228,11 +232,8 @@ print("Answerable probability:", response.answerable_probability)
228
232
 
229
233
  ---
230
234
 
231
-
232
235
  ## Resources
233
236
 
234
- * [LangChain Documentation](https://docs.langchain.com/)
235
- * [Google Generative AI SDK](https://googleapis.github.io/python-genai/)
236
- * [Gemini Model Documentation](https://ai.google.dev/)
237
-
238
-
237
+ - [LangChain Documentation](https://docs.langchain.com/)
238
+ - [Google Generative AI SDK](https://googleapis.github.io/python-genai/)
239
+ - [Gemini Model Documentation](https://ai.google.dev/)
@@ -4,55 +4,57 @@ This module integrates Google's Generative AI models, specifically the Gemini se
4
4
 
5
5
  **Chat Models**
6
6
 
7
- The `ChatGoogleGenerativeAI` class is the primary interface for interacting with Google's Gemini chat models. It allows users to send and receive messages using a specified Gemini model, suitable for various conversational AI applications.
7
+ The ``ChatGoogleGenerativeAI`` class is the primary interface for interacting with Google's Gemini chat models. It allows users to send and receive messages using a specified Gemini model, suitable for various conversational AI applications.
8
8
 
9
9
  **LLMs**
10
10
 
11
- The `GoogleGenerativeAI` class is the primary interface for interacting with Google's Gemini LLMs. It allows users to generate text using a specified Gemini model.
11
+ The ``GoogleGenerativeAI`` class is the primary interface for interacting with Google's Gemini LLMs. It allows users to generate text using a specified Gemini model.
12
12
 
13
13
  **Embeddings**
14
14
 
15
- The `GoogleGenerativeAIEmbeddings` class provides functionalities to generate embeddings using Google's models.
15
+ The ``GoogleGenerativeAIEmbeddings`` class provides functionalities to generate embeddings using Google's models.
16
16
  These embeddings can be used for a range of NLP tasks, including semantic analysis, similarity comparisons, and more.
17
+
17
18
  **Installation**
18
19
 
19
20
  To install the package, use pip:
20
21
 
21
- ```python
22
- pip install -U langchain-google-genai
23
- ```
24
- ## Using Chat Models
22
+ .. code-block:: python
23
+ pip install -U langchain-google-genai
24
+
25
+ **Using Chat Models**
25
26
 
26
27
  After setting up your environment with the required API key, you can interact with the Google Gemini models.
27
28
 
28
- ```python
29
- from langchain_google_genai import ChatGoogleGenerativeAI
29
+ .. code-block:: python
30
+
31
+ from langchain_google_genai import ChatGoogleGenerativeAI
30
32
 
31
- llm = ChatGoogleGenerativeAI(model="gemini-pro")
32
- llm.invoke("Sing a ballad of LangChain.")
33
- ```
33
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro")
34
+ llm.invoke("Sing a ballad of LangChain.")
34
35
 
35
- ## Using LLMs
36
+ **Using LLMs**
36
37
 
37
38
  The package also supports generating text with Google's models.
38
39
 
39
- ```python
40
- from langchain_google_genai import GoogleGenerativeAI
40
+ .. code-block:: python
41
41
 
42
- llm = GoogleGenerativeAI(model="gemini-pro")
43
- llm.invoke("Once upon a time, a library called LangChain")
44
- ```
42
+ from langchain_google_genai import GoogleGenerativeAI
45
43
 
46
- ## Embedding Generation
44
+ llm = GoogleGenerativeAI(model="gemini-2.5-pro")
45
+ llm.invoke("Once upon a time, a library called LangChain")
46
+
47
+ **Embedding Generation**
47
48
 
48
49
  The package also supports creating embeddings with Google's models, useful for textual similarity and other NLP applications.
49
50
 
50
- ```python
51
- from langchain_google_genai import GoogleGenerativeAIEmbeddings
51
+ .. code-block:: python
52
+
53
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
54
+
55
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
56
+ embeddings.embed_query("hello, world!")
52
57
 
53
- embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
54
- embeddings.embed_query("hello, world!")
55
- ```
56
58
  """ # noqa: E501
57
59
 
58
60
  from langchain_google_genai._enums import HarmBlockThreshold, HarmCategory, Modality
@@ -24,8 +24,8 @@ class _BaseGoogleGenerativeAI(BaseModel):
24
24
  model: str = Field(
25
25
  ...,
26
26
  description="""The name of the model to use.
27
- Supported examples:
28
- - gemini-pro
27
+ Examples:
28
+ - gemini-2.5-pro
29
29
  - models/text-bison-001""",
30
30
  )
31
31
  """Model name to use."""
@@ -39,20 +39,19 @@ Supported examples:
39
39
  "when making API calls. If not provided, credentials will be ascertained from "
40
40
  "the GOOGLE_API_KEY envvar"
41
41
  temperature: float = 0.7
42
- """Run inference with this temperature. Must by in the closed interval
43
- [0.0, 2.0]."""
42
+ """Run inference with this temperature. Must be within ``[0.0, 2.0]``."""
44
43
  top_p: Optional[float] = None
45
44
  """Decode using nucleus sampling: consider the smallest set of tokens whose
46
- probability sum is at least top_p. Must be in the closed interval [0.0, 1.0]."""
45
+ probability sum is at least ``top_p``. Must be within ``[0.0, 1.0]``."""
47
46
  top_k: Optional[int] = None
48
- """Decode using top-k sampling: consider the set of top_k most probable tokens.
47
+ """Decode using top-k sampling: consider the set of ``top_k`` most probable tokens.
49
48
  Must be positive."""
50
49
  max_output_tokens: Optional[int] = Field(default=None, alias="max_tokens")
51
50
  """Maximum number of tokens to include in a candidate. Must be greater than zero.
52
- If unset, will default to 64."""
51
+ If unset, will default to ``64``."""
53
52
  n: int = 1
54
53
  """Number of chat completions to generate for each prompt. Note that the API may
55
- not return the full n completions if duplicates are generated."""
54
+ not return the full ``n`` completions if duplicates are generated."""
56
55
  max_retries: int = 6
57
56
  """The maximum number of retries to make when generating."""
58
57
 
@@ -94,6 +93,7 @@ Supported examples:
94
93
 
95
94
  For example:
96
95
 
96
+ .. code-block:: python
97
97
  from google.generativeai.types.safety_types import HarmBlockThreshold, HarmCategory
98
98
 
99
99
  safety_settings = {
@@ -102,7 +102,7 @@ Supported examples:
102
102
  HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
103
103
  HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
104
104
  }
105
- """ # noqa: E501
105
+ """ # noqa: E501
106
106
 
107
107
  @property
108
108
  def lc_secrets(self) -> Dict[str, str]:
@@ -149,7 +149,7 @@ def get_client_info(module: Optional[str] = None) -> "ClientInfo":
149
149
  module (Optional[str]):
150
150
  Optional. The module for a custom user agent header.
151
151
  Returns:
152
- google.api_core.gapic_v1.client_info.ClientInfo
152
+ ``google.api_core.gapic_v1.client_info.ClientInfo``
153
153
  """
154
154
  client_library_version, user_agent = get_user_agent(module)
155
155
  return ClientInfo(
@@ -322,7 +322,7 @@ def _get_properties_from_schema_any(schema: Any) -> Dict[str, Any]:
322
322
 
323
323
 
324
324
  def _get_properties_from_schema(schema: Dict) -> Dict[str, Any]:
325
- properties = {}
325
+ properties: Dict[str, Dict[str, Union[str, int, Dict, List]]] = {}
326
326
  for k, v in schema.items():
327
327
  if not isinstance(k, str):
328
328
  logger.warning(f"Key '{k}' is not supported in schema, type={type(k)}")
@@ -331,7 +331,14 @@ def _get_properties_from_schema(schema: Dict) -> Dict[str, Any]:
331
331
  logger.warning(f"Value '{v}' is not supported in schema, ignoring v={v}")
332
332
  continue
333
333
  properties_item: Dict[str, Union[str, int, Dict, List]] = {}
334
- if v.get("type") or v.get("anyOf") or v.get("type_"):
334
+ if v.get("anyOf") and all(
335
+ anyOf_type.get("type") != "null" for anyOf_type in v.get("anyOf", [])
336
+ ):
337
+ properties_item["anyOf"] = [
338
+ _format_json_schema_to_gapic(anyOf_type)
339
+ for anyOf_type in v.get("anyOf", [])
340
+ ]
341
+ elif v.get("type") or v.get("anyOf") or v.get("type_"):
335
342
  item_type_ = _get_type_from_schema(v)
336
343
  properties_item["type_"] = item_type_
337
344
  if _is_nullable_schema(v):
@@ -174,12 +174,12 @@ class TestCredentials(credentials.Credentials):
174
174
 
175
175
  @property
176
176
  def expired(self) -> bool:
177
- """Returns `False`, test credentials never expire."""
177
+ """Returns ``False``, test credentials never expire."""
178
178
  return False
179
179
 
180
180
  @property
181
181
  def valid(self) -> bool:
182
- """Returns `True`, test credentials are always valid."""
182
+ """Returns ``True``, test credentials are always valid."""
183
183
  return True
184
184
 
185
185
  def refresh(self, request: Any) -> None:
@@ -206,11 +206,11 @@ class TestCredentials(credentials.Credentials):
206
206
  def _get_credentials() -> Optional[credentials.Credentials]:
207
207
  """Returns credential from config if set or fake credentials for unit testing.
208
208
 
209
- If _config.testing is True, a fake credential is returned.
209
+ If ``_config.testing`` is ``True``, a fake credential is returned.
210
210
  Otherwise, we are in a real environment and will use credentials if provided
211
- or None is returned.
211
+ or ``None`` is returned.
212
212
 
213
- If None is passed to the clients later on, the actual credentials will be
213
+ If ``None`` is passed to the clients later on, the actual credentials will be
214
214
  inferred by the rules specified in google.auth package.
215
215
  """
216
216
  if _config.testing:
@@ -30,7 +30,7 @@ class ImageBytesLoader:
30
30
  """
31
31
 
32
32
  def load_bytes(self, image_string: str) -> bytes:
33
- """Routes to the correct loader based on the image_string.
33
+ """Routes to the correct loader based on the ``'image_string'``.
34
34
 
35
35
  Args:
36
36
  image_string: Can be either:
@@ -178,8 +178,8 @@ def image_bytes_to_b64_string(
178
178
 
179
179
  Args:
180
180
  image_bytes: Bytes of the image.
181
- encoding: Type of encoding in the string. 'ascii' by default.
182
- image_format: Format of the image. 'png' by default.
181
+ encoding: Type of encoding in the string. ``'ascii'`` by default.
182
+ image_format: Format of the image. ``'png'`` by default.
183
183
 
184
184
  Returns:
185
185
  B64 image encoded string.
@@ -6,6 +6,7 @@ import io
6
6
  import json
7
7
  import logging
8
8
  import mimetypes
9
+ import time
9
10
  import uuid
10
11
  import warnings
11
12
  import wave
@@ -31,7 +32,7 @@ from typing import (
31
32
  import filetype # type: ignore[import]
32
33
  import google.api_core
33
34
 
34
- # TODO: remove ignore once the google package is published with types
35
+ # TODO: remove ignore once the Google package is published with types
35
36
  import proto # type: ignore[import]
36
37
  from google.ai.generativelanguage_v1beta import (
37
38
  GenerativeServiceAsyncClient as v1betaGenerativeServiceAsyncClient,
@@ -153,7 +154,12 @@ class ChatGoogleGenerativeAIError(GoogleGenerativeAIError):
153
154
  """
154
155
 
155
156
 
156
- def _create_retry_decorator() -> Callable[[Any], Any]:
157
+ def _create_retry_decorator(
158
+ max_retries: int = 6,
159
+ wait_exponential_multiplier: float = 2.0,
160
+ wait_exponential_min: float = 1.0,
161
+ wait_exponential_max: float = 60.0,
162
+ ) -> Callable[[Any], Any]:
157
163
  """
158
164
  Creates and returns a preconfigured tenacity retry decorator.
159
165
 
@@ -165,15 +171,14 @@ def _create_retry_decorator() -> Callable[[Any], Any]:
165
171
  Callable[[Any], Any]: A retry decorator configured for handling specific
166
172
  Google API exceptions.
167
173
  """
168
- multiplier = 2
169
- min_seconds = 1
170
- max_seconds = 60
171
- max_retries = 2
172
-
173
174
  return retry(
174
175
  reraise=True,
175
176
  stop=stop_after_attempt(max_retries),
176
- wait=wait_exponential(multiplier=multiplier, min=min_seconds, max=max_seconds),
177
+ wait=wait_exponential(
178
+ multiplier=wait_exponential_multiplier,
179
+ min=wait_exponential_min,
180
+ max=wait_exponential_max,
181
+ ),
177
182
  retry=(
178
183
  retry_if_exception_type(google.api_core.exceptions.ResourceExhausted)
179
184
  | retry_if_exception_type(google.api_core.exceptions.ServiceUnavailable)
@@ -198,13 +203,17 @@ def _chat_with_retry(generation_method: Callable, **kwargs: Any) -> Any:
198
203
  Returns:
199
204
  Any: The result from the chat generation method.
200
205
  """
201
- retry_decorator = _create_retry_decorator()
206
+ retry_decorator = _create_retry_decorator(
207
+ max_retries=kwargs.get("max_retries", 6),
208
+ wait_exponential_multiplier=kwargs.get("wait_exponential_multiplier", 2.0),
209
+ wait_exponential_min=kwargs.get("wait_exponential_min", 1.0),
210
+ wait_exponential_max=kwargs.get("wait_exponential_max", 60.0),
211
+ )
202
212
 
203
213
  @retry_decorator
204
214
  def _chat_with_retry(**kwargs: Any) -> Any:
205
215
  try:
206
216
  return generation_method(**kwargs)
207
- # Do not retry for these errors.
208
217
  except google.api_core.exceptions.FailedPrecondition as exc:
209
218
  if "location is not supported" in exc.message:
210
219
  error_msg = (
@@ -218,6 +227,13 @@ def _chat_with_retry(generation_method: Callable, **kwargs: Any) -> Any:
218
227
  raise ChatGoogleGenerativeAIError(
219
228
  f"Invalid argument provided to Gemini: {e}"
220
229
  ) from e
230
+ except google.api_core.exceptions.ResourceExhausted as e:
231
+ # Handle quota-exceeded error with recommended retry delay
232
+ if hasattr(e, "retry_after") and e.retry_after < kwargs.get(
233
+ "wait_exponential_max", 60.0
234
+ ):
235
+ time.sleep(e.retry_after)
236
+ raise e
221
237
  except Exception as e:
222
238
  raise e
223
239
 
@@ -295,7 +311,7 @@ def _is_openai_image_block(block: dict) -> bool:
295
311
  def _convert_to_parts(
296
312
  raw_content: Union[str, Sequence[Union[str, dict]]],
297
313
  ) -> List[Part]:
298
- """Converts a list of LangChain messages into a google parts."""
314
+ """Converts a list of LangChain messages into a Google parts."""
299
315
  parts = []
300
316
  content = [raw_content] if isinstance(raw_content, str) else raw_content
301
317
  image_loader = ImageBytesLoader()
@@ -413,7 +429,7 @@ def _convert_to_parts(
413
429
  def _convert_tool_message_to_parts(
414
430
  message: ToolMessage | FunctionMessage, name: Optional[str] = None
415
431
  ) -> list[Part]:
416
- """Converts a tool or function message to a google part."""
432
+ """Converts a tool or function message to a Google part."""
417
433
  # Legacy agent stores tool name in message.additional_kwargs instead of message.name
418
434
  name = message.name or name or message.additional_kwargs.get("name")
419
435
  response: Any
@@ -824,14 +840,13 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
824
840
  To use, you must have either:
825
841
 
826
842
  1. The ``GOOGLE_API_KEY`` environment variable set with your API key, or
827
- 2. Pass your API key using the google_api_key kwarg
828
- to the ChatGoogleGenerativeAI constructor.
843
+ 2. Pass your API key using the ``google_api_key`` kwarg to the ChatGoogleGenerativeAI constructor.
829
844
 
830
845
  .. code-block:: python
831
846
 
832
847
  from langchain_google_genai import ChatGoogleGenerativeAI
833
848
 
834
- llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash-001")
849
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash")
835
850
  llm.invoke("Write me a ballad about LangChain")
836
851
 
837
852
  Invoke:
@@ -893,8 +908,8 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
893
908
 
894
909
  Context Caching:
895
910
  Context caching allows you to store and reuse content (e.g., PDFs, images) for faster processing.
896
- The `cached_content` parameter accepts a cache name created via the Google Generative AI API.
897
- Below are two examples: caching a single file directly and caching multiple files using `Part`.
911
+ The ``cached_content`` parameter accepts a cache name created via the Google Generative AI API.
912
+ Below are two examples: caching a single file directly and caching multiple files using ``Part``.
898
913
 
899
914
  Single File Example:
900
915
  This caches a single file and queries it.
@@ -1041,7 +1056,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1041
1056
  .. code-block:: python
1042
1057
 
1043
1058
  from google.ai.generativelanguage_v1beta.types import Tool as GenAITool
1044
- llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash-exp")
1059
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash")
1045
1060
  resp = llm.invoke(
1046
1061
  "When is the next total solar eclipse in US?",
1047
1062
  tools=[GenAITool(google_search={})],
@@ -1099,6 +1114,144 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1099
1114
 
1100
1115
  'The weather in this image appears to be sunny and pleasant. The sky is a bright blue with scattered white clouds, suggesting fair weather. The lush green grass and trees indicate a warm and possibly slightly breezy day. There are no signs of rain or storms.'
1101
1116
 
1117
+ PDF input:
1118
+ .. code-block:: python
1119
+
1120
+ import base64
1121
+ from langchain_core.messages import HumanMessage
1122
+
1123
+ pdf_bytes = open("/path/to/your/test.pdf", 'rb').read()
1124
+ pdf_base64 = base64.b64encode(pdf_bytes).decode('utf-8')
1125
+
1126
+ message = HumanMessage(
1127
+ content=[
1128
+ {"type": "text", "text": "describe the document in a sentence"},
1129
+ {
1130
+ "type": "file",
1131
+ "source_type": "base64",
1132
+ "mime_type":"application/pdf",
1133
+ "data": pdf_base64
1134
+ }
1135
+ ]
1136
+ )
1137
+ ai_msg = llm.invoke([message])
1138
+ ai_msg.content
1139
+
1140
+ .. code-block:: python
1141
+
1142
+ 'This research paper describes a system developed for SemEval-2025 Task 9, which aims to automate the detection of food hazards from recall reports, addressing the class imbalance problem by leveraging LLM-based data augmentation techniques and transformer-based models to improve performance.'
1143
+
1144
+ Video input:
1145
+ .. code-block:: python
1146
+
1147
+ import base64
1148
+ from langchain_core.messages import HumanMessage
1149
+
1150
+ video_bytes = open("/path/to/your/video.mp4", 'rb').read()
1151
+ video_base64 = base64.b64encode(video_bytes).decode('utf-8')
1152
+
1153
+ message = HumanMessage(
1154
+ content=[
1155
+ {"type": "text", "text": "describe what's in this video in a sentence"},
1156
+ {
1157
+ "type": "file",
1158
+ "source_type": "base64",
1159
+ "mime_type": "video/mp4",
1160
+ "data": video_base64
1161
+ }
1162
+ ]
1163
+ )
1164
+ ai_msg = llm.invoke([message])
1165
+ ai_msg.content
1166
+
1167
+ .. code-block:: python
1168
+
1169
+ 'Tom and Jerry, along with a turkey, engage in a chaotic Thanksgiving-themed adventure involving a corn-on-the-cob chase, maze antics, and a disastrous attempt to prepare a turkey dinner.'
1170
+
1171
+ You can also pass YouTube URLs directly:
1172
+
1173
+ .. code-block:: python
1174
+
1175
+ from langchain_core.messages import HumanMessage
1176
+
1177
+ message = HumanMessage(
1178
+ content=[
1179
+ {"type": "text", "text": "summarize the video in 3 sentences."},
1180
+ {
1181
+ "type": "media",
1182
+ "file_uri": "https://www.youtube.com/watch?v=9hE5-98ZeCg",
1183
+ "mime_type": "video/mp4",
1184
+ }
1185
+ ]
1186
+ )
1187
+ ai_msg = llm.invoke([message])
1188
+ ai_msg.content
1189
+
1190
+ .. code-block:: python
1191
+
1192
+ 'The video is a demo of multimodal live streaming in Gemini 2.0. The narrator is sharing his screen in AI Studio and asks if the AI can see it. The AI then reads text that is highlighted on the screen, defines the word “multimodal,” and summarizes everything that was seen and heard.'
1193
+
1194
+ Audio input:
1195
+ .. code-block:: python
1196
+
1197
+ import base64
1198
+ from langchain_core.messages import HumanMessage
1199
+
1200
+ audio_bytes = open("/path/to/your/audio.mp3", 'rb').read()
1201
+ audio_base64 = base64.b64encode(audio_bytes).decode('utf-8')
1202
+
1203
+ message = HumanMessage(
1204
+ content=[
1205
+ {"type": "text", "text": "summarize this audio in a sentence"},
1206
+ {
1207
+ "type": "file",
1208
+ "source_type": "base64",
1209
+ "mime_type":"audio/mp3",
1210
+ "data": audio_base64
1211
+ }
1212
+ ]
1213
+ )
1214
+ ai_msg = llm.invoke([message])
1215
+ ai_msg.content
1216
+
1217
+ .. code-block:: python
1218
+
1219
+ "In this episode of the Made by Google podcast, Stephen Johnson and Simon Tokumine discuss NotebookLM, a tool designed to help users understand complex material in various modalities, with a focus on its unexpected uses, the development of audio overviews, and the implementation of new features like mind maps and source discovery."
1220
+
1221
+ File upload (URI-based):
1222
+ You can also upload files to Google's servers and reference them by URI.
1223
+ This works for PDFs, images, videos, and audio files.
1224
+
1225
+ .. code-block:: python
1226
+
1227
+ import time
1228
+ from google import genai
1229
+ from langchain_core.messages import HumanMessage
1230
+
1231
+ client = genai.Client()
1232
+
1233
+ myfile = client.files.upload(file="/path/to/your/sample.pdf")
1234
+ while myfile.state.name == "PROCESSING":
1235
+ time.sleep(2)
1236
+ myfile = client.files.get(name=myfile.name)
1237
+
1238
+ message = HumanMessage(
1239
+ content=[
1240
+ {"type": "text", "text": "What is in the document?"},
1241
+ {
1242
+ "type": "media",
1243
+ "file_uri": myfile.uri,
1244
+ "mime_type": "application/pdf",
1245
+ },
1246
+ ]
1247
+ )
1248
+ ai_msg = llm.invoke([message])
1249
+ ai_msg.content
1250
+
1251
+ .. code-block:: python
1252
+
1253
+ "This research paper assesses and mitigates multi-turn jailbreak vulnerabilities in large language models using the Crescendo attack study, evaluating attack success rates and mitigation strategies like prompt hardening and LLM-as-guardrail."
1254
+
1102
1255
  Token usage:
1103
1256
  .. code-block:: python
1104
1257
 
@@ -1140,12 +1293,15 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1140
1293
 
1141
1294
  response_mime_type: Optional[str] = None
1142
1295
  """Optional. Output response mimetype of the generated candidate text. Only
1143
- supported in Gemini 1.5 and later models. Supported mimetype:
1144
- * "text/plain": (default) Text output.
1145
- * "application/json": JSON response in the candidates.
1146
- * "text/x.enum": Enum in plain text.
1147
- The model also needs to be prompted to output the appropriate response
1148
- type, otherwise the behavior is undefined. This is a preview feature.
1296
+ supported in Gemini 1.5 and later models.
1297
+
1298
+ Supported mimetype:
1299
+ * ``'text/plain'``: (default) Text output.
1300
+ * ``'application/json'``: JSON response in the candidates.
1301
+ * ``'text/x.enum'``: Enum in plain text.
1302
+
1303
+ The model also needs to be prompted to output the appropriate response
1304
+ type, otherwise the behavior is undefined. This is a preview feature.
1149
1305
  """
1150
1306
 
1151
1307
  response_schema: Optional[Dict[str, Any]] = None
@@ -1230,9 +1386,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1230
1386
  if self.top_k is not None and self.top_k <= 0:
1231
1387
  raise ValueError("top_k must be positive")
1232
1388
 
1233
- if not any(
1234
- self.model.startswith(prefix) for prefix in ("models/", "tunedModels/")
1235
- ):
1389
+ if not any(self.model.startswith(prefix) for prefix in ("models/",)):
1236
1390
  self.model = f"models/{self.model}"
1237
1391
 
1238
1392
  additional_headers = self.additional_headers or {}
@@ -1328,7 +1482,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1328
1482
 
1329
1483
  else:
1330
1484
  raise ValueError(
1331
- "Tools are already defined." "code_execution tool can't be defined"
1485
+ "Tools are already defined.code_execution tool can't be defined"
1332
1486
  )
1333
1487
 
1334
1488
  return super().invoke(input, config, stop=stop, **kwargs)
@@ -1545,7 +1699,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1545
1699
  )
1546
1700
 
1547
1701
  if run_manager:
1548
- run_manager.on_llm_new_token(gen.text)
1702
+ run_manager.on_llm_new_token(gen.text, chunk=gen)
1549
1703
  yield gen
1550
1704
 
1551
1705
  async def _astream(
@@ -1611,7 +1765,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1611
1765
  )
1612
1766
 
1613
1767
  if run_manager:
1614
- await run_manager.on_llm_new_token(gen.text)
1768
+ await run_manager.on_llm_new_token(gen.text, chunk=gen)
1615
1769
  yield gen
1616
1770
 
1617
1771
  def _prepare_request(
@@ -1816,7 +1970,8 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1816
1970
  tools: A list of tool definitions to bind to this chat model.
1817
1971
  Can be a pydantic model, callable, or BaseTool. Pydantic
1818
1972
  models, callables, and BaseTools will be automatically converted to
1819
- their schema dictionary representation.
1973
+ their schema dictionary representation. Tools with Union types in
1974
+ their arguments are now supported and converted to `anyOf` schemas.
1820
1975
  **kwargs: Any additional parameters to pass to the
1821
1976
  :class:`~langchain.runnable.Runnable` constructor.
1822
1977
  """
@@ -17,7 +17,10 @@ from langchain_google_genai._common import (
17
17
  GoogleGenerativeAIError,
18
18
  get_client_info,
19
19
  )
20
- from langchain_google_genai._genai_extension import build_generative_service
20
+ from langchain_google_genai._genai_extension import (
21
+ build_generative_async_service,
22
+ build_generative_service,
23
+ )
21
24
 
22
25
  _MAX_TOKENS_PER_BATCH = 20000
23
26
  _DEFAULT_BATCH_SIZE = 100
@@ -29,29 +32,30 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
29
32
  To use, you must have either:
30
33
 
31
34
  1. The ``GOOGLE_API_KEY`` environment variable set with your API key, or
32
- 2. Pass your API key using the google_api_key kwarg
33
- to the GoogleGenerativeAIEmbeddings constructor.
35
+ 2. Pass your API key using the google_api_key kwarg to the
36
+ GoogleGenerativeAIEmbeddings constructor.
34
37
 
35
38
  Example:
36
39
  .. code-block:: python
37
40
 
38
41
  from langchain_google_genai import GoogleGenerativeAIEmbeddings
39
42
 
40
- embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
43
+ embeddings = GoogleGenerativeAIEmbeddings(model="gemini-embedding-001")
41
44
  embeddings.embed_query("What's our Q1 revenue?")
42
45
  """
43
46
 
44
47
  client: Any = None #: :meta private:
48
+ async_client: Any = None #: :meta private:
45
49
  model: str = Field(
46
50
  ...,
47
51
  description="The name of the embedding model to use. "
48
- "Example: models/embedding-001",
52
+ "Example: ``'models/gemini-embedding-001'``",
49
53
  )
50
54
  task_type: Optional[str] = Field(
51
55
  default=None,
52
56
  description="The task type. Valid options include: "
53
- "task_type_unspecified, retrieval_query, retrieval_document, "
54
- "semantic_similarity, classification, and clustering",
57
+ "``'task_type_unspecified'``, ``'retrieval_query'``, ``'retrieval_document'``, "
58
+ "``'semantic_similarity'``, ``'classification'``, and ``'clustering'``",
55
59
  )
56
60
  google_api_key: Optional[SecretStr] = Field(
57
61
  default_factory=secret_from_env("GOOGLE_API_KEY", default=None),
@@ -76,7 +80,7 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
76
80
  )
77
81
  transport: Optional[str] = Field(
78
82
  default=None,
79
- description="A string, one of: [`rest`, `grpc`, `grpc_asyncio`].",
83
+ description="A string, one of: [``'rest'``, ``'grpc'``, ``'grpc_asyncio'``].",
80
84
  )
81
85
  request_options: Optional[Dict] = Field(
82
86
  default=None,
@@ -93,6 +97,9 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
93
97
  google_api_key = self.google_api_key
94
98
  client_info = get_client_info("GoogleGenerativeAIEmbeddings")
95
99
 
100
+ if not any(self.model.startswith(prefix) for prefix in ("models/",)):
101
+ self.model = f"models/{self.model}"
102
+
96
103
  self.client = build_generative_service(
97
104
  credentials=self.credentials,
98
105
  api_key=google_api_key,
@@ -100,6 +107,13 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
100
107
  client_options=self.client_options,
101
108
  transport=self.transport,
102
109
  )
110
+ self.async_client = build_generative_async_service(
111
+ credentials=self.credentials,
112
+ api_key=google_api_key,
113
+ client_info=client_info,
114
+ client_options=self.client_options,
115
+ transport=self.transport,
116
+ )
103
117
  return self
104
118
 
105
119
  @staticmethod
@@ -166,12 +180,12 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
166
180
  def _prepare_request(
167
181
  self,
168
182
  text: str,
183
+ *,
169
184
  task_type: Optional[str] = None,
170
185
  title: Optional[str] = None,
171
186
  output_dimensionality: Optional[int] = None,
172
187
  ) -> EmbedContentRequest:
173
188
  task_type = self.task_type or task_type or "RETRIEVAL_DOCUMENT"
174
- # https://ai.google.dev/api/rest/v1/models/batchEmbedContents#EmbedContentRequest
175
189
  request = EmbedContentRequest(
176
190
  content={"parts": [{"text": text}]},
177
191
  model=self.model,
@@ -190,17 +204,17 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
190
204
  titles: Optional[List[str]] = None,
191
205
  output_dimensionality: Optional[int] = None,
192
206
  ) -> List[List[float]]:
193
- """Embed a list of strings. Google Generative AI currently
194
- sets a max batch size of 100 strings.
207
+ """Embed a list of strings using the `batch endpoint <https://ai.google.dev/api/embeddings#method:-models.batchembedcontents>`__.
208
+
209
+ Google Generative AI currently sets a max batch size of 100 strings.
195
210
 
196
211
  Args:
197
212
  texts: List[str] The list of strings to embed.
198
213
  batch_size: [int] The batch size of embeddings to send to the model
199
- task_type: task_type (https://ai.google.dev/api/rest/v1/TaskType)
214
+ task_type: `task_type <https://ai.google.dev/api/embeddings#tasktype>`__
200
215
  titles: An optional list of titles for texts provided.
201
- Only applicable when TaskType is RETRIEVAL_DOCUMENT.
202
- output_dimensionality: Optional reduced dimension for the output embedding.
203
- https://ai.google.dev/api/rest/v1/models/batchEmbedContents#EmbedContentRequest
216
+ Only applicable when TaskType is ``'RETRIEVAL_DOCUMENT'``.
217
+ output_dimensionality: Optional `reduced dimension for the output embedding <https://ai.google.dev/api/embeddings#EmbedContentRequest>`__.
204
218
  Returns:
205
219
  List of embeddings, one for each text.
206
220
  """
@@ -237,26 +251,26 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
237
251
  def embed_query(
238
252
  self,
239
253
  text: str,
254
+ *,
240
255
  task_type: Optional[str] = None,
241
256
  title: Optional[str] = None,
242
257
  output_dimensionality: Optional[int] = None,
243
258
  ) -> List[float]:
244
- """Embed a text, using the non-batch endpoint:
245
- https://ai.google.dev/api/rest/v1/models/embedContent#EmbedContentRequest
259
+ """Embed a text, using the `non-batch endpoint <https://ai.google.dev/api/embeddings#method:-models.embedcontent>`__.
246
260
 
247
261
  Args:
248
262
  text: The text to embed.
249
- task_type: task_type (https://ai.google.dev/api/rest/v1/TaskType)
263
+ task_type: `task_type <https://ai.google.dev/api/embeddings#tasktype>`__
250
264
  title: An optional title for the text.
251
- Only applicable when TaskType is RETRIEVAL_DOCUMENT.
252
- output_dimensionality: Optional reduced dimension for the output embedding.
265
+ Only applicable when TaskType is ``'RETRIEVAL_DOCUMENT'``.
266
+ output_dimensionality: Optional `reduced dimension for the output embedding <https://ai.google.dev/api/embeddings#EmbedContentRequest>`__.
253
267
 
254
268
  Returns:
255
269
  Embedding for the text.
256
270
  """
257
271
  task_type_to_use = task_type if task_type else self.task_type
258
272
  if task_type_to_use is None:
259
- task_type_to_use = "RETRIEVAL_QUERY" # Default to RETRIEVAL_QUERY
273
+ task_type_to_use = "RETRIEVAL_QUERY"
260
274
  try:
261
275
  request: EmbedContentRequest = self._prepare_request(
262
276
  text=text,
@@ -268,3 +282,93 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
268
282
  except Exception as e:
269
283
  raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e
270
284
  return list(result.embedding.values)
285
+
286
+ async def aembed_documents(
287
+ self,
288
+ texts: List[str],
289
+ *,
290
+ batch_size: int = _DEFAULT_BATCH_SIZE,
291
+ task_type: Optional[str] = None,
292
+ titles: Optional[List[str]] = None,
293
+ output_dimensionality: Optional[int] = None,
294
+ ) -> List[List[float]]:
295
+ """Embed a list of strings using the `batch endpoint <https://ai.google.dev/api/embeddings#method:-models.batchembedcontents>`__.
296
+
297
+ Google Generative AI currently sets a max batch size of 100 strings.
298
+
299
+ Args:
300
+ texts: List[str] The list of strings to embed.
301
+ batch_size: [int] The batch size of embeddings to send to the model
302
+ task_type: `task_type <https://ai.google.dev/api/embeddings#tasktype>`__
303
+ titles: An optional list of titles for texts provided.
304
+ Only applicable when TaskType is ``'RETRIEVAL_DOCUMENT'``.
305
+ output_dimensionality: Optional `reduced dimension for the output embedding <https://ai.google.dev/api/embeddings#EmbedContentRequest>`__.
306
+ Returns:
307
+ List of embeddings, one for each text.
308
+ """
309
+ embeddings: List[List[float]] = []
310
+ batch_start_index = 0
311
+ for batch in GoogleGenerativeAIEmbeddings._prepare_batches(texts, batch_size):
312
+ if titles:
313
+ titles_batch = titles[
314
+ batch_start_index : batch_start_index + len(batch)
315
+ ]
316
+ batch_start_index += len(batch)
317
+ else:
318
+ titles_batch = [None] * len(batch) # type: ignore[list-item]
319
+
320
+ requests = [
321
+ self._prepare_request(
322
+ text=text,
323
+ task_type=task_type,
324
+ title=title,
325
+ output_dimensionality=output_dimensionality,
326
+ )
327
+ for text, title in zip(batch, titles_batch)
328
+ ]
329
+
330
+ try:
331
+ result = await self.async_client.batch_embed_contents(
332
+ BatchEmbedContentsRequest(requests=requests, model=self.model)
333
+ )
334
+ except Exception as e:
335
+ raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e
336
+ embeddings.extend([list(e.values) for e in result.embeddings])
337
+ return embeddings
338
+
339
+ async def aembed_query(
340
+ self,
341
+ text: str,
342
+ *,
343
+ task_type: Optional[str] = None,
344
+ title: Optional[str] = None,
345
+ output_dimensionality: Optional[int] = None,
346
+ ) -> List[float]:
347
+ """Embed a text, using the `non-batch endpoint <https://ai.google.dev/api/embeddings#method:-models.embedcontent>`__.
348
+
349
+ Args:
350
+ text: The text to embed.
351
+ task_type: `task_type <https://ai.google.dev/api/embeddings#tasktype>`__
352
+ title: An optional title for the text.
353
+ Only applicable when TaskType is ``'RETRIEVAL_DOCUMENT'``.
354
+ output_dimensionality: Optional `reduced dimension for the output embedding <https://ai.google.dev/api/embeddings#EmbedContentRequest>`__.
355
+
356
+ Returns:
357
+ Embedding for the text.
358
+ """
359
+ task_type_to_use = task_type if task_type else self.task_type
360
+ if task_type_to_use is None:
361
+ task_type_to_use = "RETRIEVAL_QUERY"
362
+ try:
363
+ request: EmbedContentRequest = self._prepare_request(
364
+ text=text,
365
+ task_type=task_type,
366
+ title=title,
367
+ output_dimensionality=output_dimensionality,
368
+ )
369
+ result: EmbedContentResponse = await self.async_client.embed_content(
370
+ request
371
+ )
372
+ except Exception as e:
373
+ raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e
374
+ return list(result.embedding.values)
@@ -29,7 +29,7 @@ class GoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseLLM):
29
29
  .. code-block:: python
30
30
 
31
31
  from langchain_google_genai import GoogleGenerativeAI
32
- llm = GoogleGenerativeAI(model="gemini-pro")
32
+ llm = GoogleGenerativeAI(model="gemini-2.5-pro")
33
33
  """
34
34
 
35
35
  client: Any = None #: :meta private:
@@ -63,6 +63,9 @@ class GoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseLLM):
63
63
  def validate_environment(self) -> Self:
64
64
  """Validates params and passes them to google-generativeai package."""
65
65
 
66
+ if not any(self.model.startswith(prefix) for prefix in ("models/",)):
67
+ self.model = f"models/{self.model}"
68
+
66
69
  self.client = ChatGoogleGenerativeAI(
67
70
  api_key=self.google_api_key,
68
71
  credentials=self.credentials,
@@ -86,6 +89,15 @@ class GoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseLLM):
86
89
  """Get standard params for tracing."""
87
90
  ls_params = super()._get_ls_params(stop=stop, **kwargs)
88
91
  ls_params["ls_provider"] = "google_genai"
92
+
93
+ models_prefix = "models/"
94
+ ls_model_name = (
95
+ self.model[len(models_prefix) :]
96
+ if self.model and self.model.startswith(models_prefix)
97
+ else self.model
98
+ )
99
+ ls_params["ls_model_name"] = ls_model_name
100
+
89
101
  if ls_max_tokens := kwargs.get("max_output_tokens", self.max_output_tokens):
90
102
  ls_params["ls_max_tokens"] = ls_max_tokens
91
103
  return ls_params
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langchain-google-genai"
3
- version = "2.1.7"
3
+ version = "2.1.9"
4
4
  description = "An integration package connecting Google's genai package and LangChain"
5
5
  authors = []
6
6
  readme = "README.md"