langchain-google-genai 2.1.0__tar.gz → 2.1.1__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.0 → langchain_google_genai-2.1.1}/PKG-INFO +39 -2
  2. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/README.md +37 -0
  3. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/__init__.py +2 -1
  4. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/_common.py +5 -2
  5. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/_enums.py +2 -1
  6. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/chat_models.py +31 -4
  7. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/pyproject.toml +3 -3
  8. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/LICENSE +0 -0
  9. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/_function_utils.py +0 -0
  10. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/_genai_extension.py +0 -0
  11. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/_image_utils.py +0 -0
  12. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/embeddings.py +0 -0
  13. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/genai_aqa.py +0 -0
  14. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/google_vector_store.py +0 -0
  15. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/langchain_google_genai/llms.py +0 -0
  16. {langchain_google_genai-2.1.0 → langchain_google_genai-2.1.1}/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.0
3
+ Version: 2.1.1
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
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Requires-Dist: filetype (>=1.2.0,<2.0.0)
15
15
  Requires-Dist: google-ai-generativelanguage (>=0.6.16,<0.7.0)
16
- Requires-Dist: langchain-core (>=0.3.43,<0.4.0)
16
+ Requires-Dist: langchain-core (>=0.3.47,<0.4.0)
17
17
  Requires-Dist: pydantic (>=2,<3)
18
18
  Project-URL: Repository, https://github.com/langchain-ai/langchain-google
19
19
  Project-URL: Source Code, https://github.com/langchain-ai/langchain-google/tree/main/libs/genai
@@ -77,7 +77,44 @@ The value of `image_url` can be any of the following:
77
77
  - An accessible gcs file (e.g., "gcs://path/to/file.png")
78
78
  - A base64 encoded image (e.g., `data:image/png;base64,abcd124`)
79
79
 
80
+ #### Multimodal outputs
80
81
 
82
+ Gemini 2.0 Flash Experimental model supports text output with inline images
83
+
84
+ ```
85
+ from langchain_google_genai import ChatGoogleGenerativeAI
86
+
87
+ llm = ChatGoogleGenerativeAI(model="models/gemini-2.0-flash-exp-image-generation")
88
+ # example
89
+ response = llm.invoke(
90
+ "Generate an image of a cat and say meow",
91
+ generation_config=dict(response_modalities=["TEXT", "IMAGE"]),
92
+ )
93
+
94
+ # Base64 encoded binary data of the image
95
+ image_base64 = response.content[0].get("image_url").get("url").split(",")[-1]
96
+ meow_str = response.content[1]
97
+ ```
98
+
99
+ #### Multimodal Outputs in Chains
100
+
101
+ '''
102
+ from langchain_core.runnables import RunnablePassthrough
103
+ from langchain_core.prompts import ChatPromptTemplate
104
+
105
+ from langchain_google_genai import ChatGoogleGenerativeAI, Modality
106
+
107
+ llm = ChatGoogleGenerativeAI(
108
+ model="models/gemini-2.0-flash-exp-image-generation",
109
+ response_modalities=[Modality.TEXT, Modality.IMAGE],
110
+ )
111
+
112
+ prompt = ChatPromptTemplate(
113
+ [("human", "Generate an image of {animal} and tell me the sound of the animal")]
114
+ )
115
+ chain = {"animal": RunnablePassthrough()} | prompt | llm
116
+ res = chain.invoke("cat")
117
+ '''
81
118
 
82
119
  ## Embeddings
83
120
 
@@ -56,7 +56,44 @@ The value of `image_url` can be any of the following:
56
56
  - An accessible gcs file (e.g., "gcs://path/to/file.png")
57
57
  - A base64 encoded image (e.g., `data:image/png;base64,abcd124`)
58
58
 
59
+ #### Multimodal outputs
59
60
 
61
+ Gemini 2.0 Flash Experimental model supports text output with inline images
62
+
63
+ ```
64
+ from langchain_google_genai import ChatGoogleGenerativeAI
65
+
66
+ llm = ChatGoogleGenerativeAI(model="models/gemini-2.0-flash-exp-image-generation")
67
+ # example
68
+ response = llm.invoke(
69
+ "Generate an image of a cat and say meow",
70
+ generation_config=dict(response_modalities=["TEXT", "IMAGE"]),
71
+ )
72
+
73
+ # Base64 encoded binary data of the image
74
+ image_base64 = response.content[0].get("image_url").get("url").split(",")[-1]
75
+ meow_str = response.content[1]
76
+ ```
77
+
78
+ #### Multimodal Outputs in Chains
79
+
80
+ '''
81
+ from langchain_core.runnables import RunnablePassthrough
82
+ from langchain_core.prompts import ChatPromptTemplate
83
+
84
+ from langchain_google_genai import ChatGoogleGenerativeAI, Modality
85
+
86
+ llm = ChatGoogleGenerativeAI(
87
+ model="models/gemini-2.0-flash-exp-image-generation",
88
+ response_modalities=[Modality.TEXT, Modality.IMAGE],
89
+ )
90
+
91
+ prompt = ChatPromptTemplate(
92
+ [("human", "Generate an image of {animal} and tell me the sound of the animal")]
93
+ )
94
+ chain = {"animal": RunnablePassthrough()} | prompt | llm
95
+ res = chain.invoke("cat")
96
+ '''
60
97
 
61
98
  ## Embeddings
62
99
 
@@ -55,7 +55,7 @@ embeddings.embed_query("hello, world!")
55
55
  ```
56
56
  """ # noqa: E501
57
57
 
58
- from langchain_google_genai._enums import HarmBlockThreshold, HarmCategory
58
+ from langchain_google_genai._enums import HarmBlockThreshold, HarmCategory, Modality
59
59
  from langchain_google_genai.chat_models import ChatGoogleGenerativeAI
60
60
  from langchain_google_genai.embeddings import GoogleGenerativeAIEmbeddings
61
61
  from langchain_google_genai.genai_aqa import (
@@ -80,5 +80,6 @@ __all__ = [
80
80
  "GoogleVectorStore",
81
81
  "HarmBlockThreshold",
82
82
  "HarmCategory",
83
+ "Modality",
83
84
  "DoesNotExistsException",
84
85
  ]
@@ -1,11 +1,11 @@
1
1
  from importlib import metadata
2
- from typing import Any, Dict, Optional, Tuple, TypedDict
2
+ from typing import Any, Dict, List, Optional, Tuple, TypedDict
3
3
 
4
4
  from google.api_core.gapic_v1.client_info import ClientInfo
5
5
  from langchain_core.utils import secret_from_env
6
6
  from pydantic import BaseModel, Field, SecretStr
7
7
 
8
- from langchain_google_genai._enums import HarmBlockThreshold, HarmCategory
8
+ from langchain_google_genai._enums import HarmBlockThreshold, HarmCategory, Modality
9
9
 
10
10
 
11
11
  class GoogleGenerativeAIError(Exception):
@@ -72,6 +72,9 @@ Supported examples:
72
72
  "A key-value dictionary representing additional headers for the model call"
73
73
  ),
74
74
  )
75
+ response_modalities: Optional[List[Modality]] = Field(
76
+ default=None, description=("A list of modalities of the response")
77
+ )
75
78
 
76
79
  safety_settings: Optional[Dict[HarmCategory, HarmBlockThreshold]] = None
77
80
  """The default safety settings to use for all generations.
@@ -2,5 +2,6 @@ import google.ai.generativelanguage_v1beta as genai
2
2
 
3
3
  HarmBlockThreshold = genai.SafetySetting.HarmBlockThreshold
4
4
  HarmCategory = genai.HarmCategory
5
+ Modality = genai.GenerationConfig.Modality
5
6
 
6
- __all__ = ["HarmBlockThreshold", "HarmCategory"]
7
+ __all__ = ["HarmBlockThreshold", "HarmCategory", "Modality"]
@@ -106,7 +106,10 @@ from langchain_google_genai._function_utils import (
106
106
  is_basemodel_subclass_safe,
107
107
  tool_to_dict,
108
108
  )
109
- from langchain_google_genai._image_utils import ImageBytesLoader
109
+ from langchain_google_genai._image_utils import (
110
+ ImageBytesLoader,
111
+ image_bytes_to_b64_string,
112
+ )
110
113
 
111
114
  from . import _genai_extension as genaix
112
115
 
@@ -430,7 +433,7 @@ def _parse_chat_history(
430
433
  def _parse_response_candidate(
431
434
  response_candidate: Candidate, streaming: bool = False
432
435
  ) -> AIMessage:
433
- content: Union[None, str, List[str]] = None
436
+ content: Union[None, str, List[Union[str, dict]]] = None
434
437
  additional_kwargs = {}
435
438
  tool_calls = []
436
439
  invalid_tool_calls = []
@@ -455,6 +458,26 @@ def _parse_response_candidate(
455
458
  elif text:
456
459
  raise Exception("Unexpected content type")
457
460
 
461
+ if part.inline_data.mime_type.startswith("image/"):
462
+ image_format = part.inline_data.mime_type[6:]
463
+ message = {
464
+ "type": "image_url",
465
+ "image_url": {
466
+ "url": image_bytes_to_b64_string(
467
+ part.inline_data.data, image_format=image_format
468
+ )
469
+ },
470
+ }
471
+
472
+ if not content:
473
+ content = [message]
474
+ elif isinstance(content, str) and message:
475
+ content = [content, message]
476
+ elif isinstance(content, list) and message:
477
+ content.append(message)
478
+ elif message:
479
+ raise Exception("Unexpected content type")
480
+
458
481
  if part.function_call:
459
482
  function_call = {"name": part.function_call.name}
460
483
  # dump to match other function calling llm for now
@@ -831,8 +854,8 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
831
854
  @model_validator(mode="after")
832
855
  def validate_environment(self) -> Self:
833
856
  """Validates params and passes them to google-generativeai package."""
834
- if self.temperature is not None and not 0 <= self.temperature <= 1:
835
- raise ValueError("temperature must be in the range [0.0, 1.0]")
857
+ if self.temperature is not None and not 0 <= self.temperature <= 2.0:
858
+ raise ValueError("temperature must be in the range [0.0, 2.0]")
836
859
 
837
860
  if self.top_p is not None and not 0 <= self.top_p <= 1:
838
861
  raise ValueError("top_p must be in the range [0.0, 1.0]")
@@ -895,6 +918,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
895
918
  "top_k": self.top_k,
896
919
  "n": self.n,
897
920
  "safety_settings": self.safety_settings,
921
+ "response_modalities": self.response_modalities,
898
922
  }
899
923
 
900
924
  def _get_ls_params(
@@ -928,6 +952,7 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
928
952
  "max_output_tokens": self.max_output_tokens,
929
953
  "top_k": self.top_k,
930
954
  "top_p": self.top_p,
955
+ "response_modalities": self.response_modalities,
931
956
  }.items()
932
957
  if v is not None
933
958
  }
@@ -1256,6 +1281,8 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
1256
1281
  include_raw: bool = False,
1257
1282
  **kwargs: Any,
1258
1283
  ) -> Runnable[LanguageModelInput, Union[Dict, BaseModel]]:
1284
+ _ = kwargs.pop("method", None)
1285
+ _ = kwargs.pop("strict", None)
1259
1286
  if kwargs:
1260
1287
  raise ValueError(f"Received unsupported arguments {kwargs}")
1261
1288
  tool_name = _get_tool_name(schema) # type: ignore[arg-type]
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langchain-google-genai"
3
- version = "2.1.0"
3
+ version = "2.1.1"
4
4
  description = "An integration package connecting Google's genai package and LangChain"
5
5
  authors = []
6
6
  readme = "README.md"
@@ -12,7 +12,7 @@ license = "MIT"
12
12
 
13
13
  [tool.poetry.dependencies]
14
14
  python = ">=3.9,<4.0"
15
- langchain-core = "^0.3.43"
15
+ langchain-core = "^0.3.47"
16
16
  google-ai-generativelanguage = "^0.6.16"
17
17
  pydantic = ">=2,<3"
18
18
  filetype = "^1.2.0"
@@ -28,7 +28,7 @@ syrupy = "^4.0.2"
28
28
  pytest-watcher = "^0.3.4"
29
29
  pytest-asyncio = "^0.21.1"
30
30
  numpy = "^1.26.2"
31
- langchain-tests = "0.3.14"
31
+ langchain-tests = "0.3.15"
32
32
 
33
33
  [tool.codespell]
34
34
  ignore-words-list = "rouge"