langchain-google-genai 1.0.5__tar.gz → 1.0.6__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.
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/PKG-INFO +2 -2
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/chat_models.py +38 -2
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/embeddings.py +98 -20
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/pyproject.toml +5 -2
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/LICENSE +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/README.md +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/__init__.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_common.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_enums.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_function_utils.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_genai_extension.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_image_utils.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/genai_aqa.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/google_vector_store.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/llms.py +0 -0
- {langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/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: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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
|
Provides-Extra: images
|
|
15
15
|
Requires-Dist: google-generativeai (>=0.5.2,<0.6.0)
|
|
16
|
-
Requires-Dist: langchain-core (>=0.2.
|
|
16
|
+
Requires-Dist: langchain-core (>=0.2.2,<0.3)
|
|
17
17
|
Requires-Dist: pillow (>=10.1.0,<11.0.0) ; extra == "images"
|
|
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
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/chat_models.py
RENAMED
|
@@ -51,7 +51,7 @@ from langchain_core.callbacks.manager import (
|
|
|
51
51
|
CallbackManagerForLLMRun,
|
|
52
52
|
)
|
|
53
53
|
from langchain_core.language_models import LanguageModelInput
|
|
54
|
-
from langchain_core.language_models.chat_models import BaseChatModel
|
|
54
|
+
from langchain_core.language_models.chat_models import BaseChatModel, LangSmithParams
|
|
55
55
|
from langchain_core.messages import (
|
|
56
56
|
AIMessage,
|
|
57
57
|
AIMessageChunk,
|
|
@@ -64,6 +64,7 @@ from langchain_core.messages import (
|
|
|
64
64
|
ToolCallChunk,
|
|
65
65
|
ToolMessage,
|
|
66
66
|
)
|
|
67
|
+
from langchain_core.messages.ai import UsageMetadata
|
|
67
68
|
from langchain_core.output_parsers.openai_tools import parse_tool_calls
|
|
68
69
|
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult
|
|
69
70
|
from langchain_core.pydantic_v1 import Field, SecretStr, root_validator
|
|
@@ -526,6 +527,22 @@ def _response_to_result(
|
|
|
526
527
|
"""Converts a PaLM API response into a LangChain ChatResult."""
|
|
527
528
|
llm_output = {"prompt_feedback": proto.Message.to_dict(response.prompt_feedback)}
|
|
528
529
|
|
|
530
|
+
# Get usage metadata
|
|
531
|
+
try:
|
|
532
|
+
input_tokens = response.usage_metadata.prompt_token_count
|
|
533
|
+
output_tokens = response.usage_metadata.candidates_token_count
|
|
534
|
+
total_tokens = response.usage_metadata.total_token_count
|
|
535
|
+
if input_tokens + output_tokens + total_tokens > 0:
|
|
536
|
+
lc_usage = UsageMetadata(
|
|
537
|
+
input_tokens=input_tokens,
|
|
538
|
+
output_tokens=output_tokens,
|
|
539
|
+
total_tokens=total_tokens,
|
|
540
|
+
)
|
|
541
|
+
else:
|
|
542
|
+
lc_usage = None
|
|
543
|
+
except AttributeError:
|
|
544
|
+
lc_usage = None
|
|
545
|
+
|
|
529
546
|
generations: List[ChatGeneration] = []
|
|
530
547
|
|
|
531
548
|
for candidate in response.candidates:
|
|
@@ -536,9 +553,11 @@ def _response_to_result(
|
|
|
536
553
|
proto.Message.to_dict(safety_rating, use_integers_for_enums=False)
|
|
537
554
|
for safety_rating in candidate.safety_ratings
|
|
538
555
|
]
|
|
556
|
+
message = _parse_response_candidate(candidate, streaming=stream)
|
|
557
|
+
message.usage_metadata = lc_usage
|
|
539
558
|
generations.append(
|
|
540
559
|
(ChatGenerationChunk if stream else ChatGeneration)(
|
|
541
|
-
message=
|
|
560
|
+
message=message,
|
|
542
561
|
generation_info=generation_info,
|
|
543
562
|
)
|
|
544
563
|
)
|
|
@@ -678,6 +697,23 @@ class ChatGoogleGenerativeAI(_BaseGoogleGenerativeAI, BaseChatModel):
|
|
|
678
697
|
"safety_settings": self.safety_settings,
|
|
679
698
|
}
|
|
680
699
|
|
|
700
|
+
def _get_ls_params(
|
|
701
|
+
self, stop: Optional[List[str]] = None, **kwargs: Any
|
|
702
|
+
) -> LangSmithParams:
|
|
703
|
+
"""Get standard params for tracing."""
|
|
704
|
+
params = self._get_invocation_params(stop=stop, **kwargs)
|
|
705
|
+
ls_params = LangSmithParams(
|
|
706
|
+
ls_provider="google_genai",
|
|
707
|
+
ls_model_name=self.model,
|
|
708
|
+
ls_model_type="chat",
|
|
709
|
+
ls_temperature=params.get("temperature", self.temperature),
|
|
710
|
+
)
|
|
711
|
+
if ls_max_tokens := params.get("max_output_tokens", self.max_output_tokens):
|
|
712
|
+
ls_params["ls_max_tokens"] = ls_max_tokens
|
|
713
|
+
if ls_stop := stop or params.get("stop", None):
|
|
714
|
+
ls_params["ls_stop"] = ls_stop
|
|
715
|
+
return ls_params
|
|
716
|
+
|
|
681
717
|
def _prepare_params(
|
|
682
718
|
self,
|
|
683
719
|
stop: Optional[List[str]],
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/embeddings.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import string
|
|
1
3
|
from typing import Any, Dict, List, Optional
|
|
2
4
|
|
|
3
5
|
# TODO: remove ignore once the google package is published with types
|
|
@@ -15,6 +17,9 @@ from langchain_google_genai._common import (
|
|
|
15
17
|
)
|
|
16
18
|
from langchain_google_genai._genai_extension import build_generative_service
|
|
17
19
|
|
|
20
|
+
_MAX_TOKENS_PER_BATCH = 20000
|
|
21
|
+
_DEFAULT_BATCH_SIZE = 100
|
|
22
|
+
|
|
18
23
|
|
|
19
24
|
class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
|
|
20
25
|
"""`Google Generative AI Embeddings`.
|
|
@@ -91,6 +96,67 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
|
|
|
91
96
|
)
|
|
92
97
|
return values
|
|
93
98
|
|
|
99
|
+
@staticmethod
|
|
100
|
+
def _split_by_punctuation(text: str) -> List[str]:
|
|
101
|
+
"""Splits a string by punctuation and whitespace characters."""
|
|
102
|
+
split_by = string.punctuation + "\t\n "
|
|
103
|
+
pattern = f"([{split_by}])"
|
|
104
|
+
# Using re.split to split the text based on the pattern
|
|
105
|
+
return [segment for segment in re.split(pattern, text) if segment]
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def _prepare_batches(texts: List[str], batch_size: int) -> List[List[str]]:
|
|
109
|
+
"""Splits texts in batches based on current maximum batch size
|
|
110
|
+
and maximum tokens per request.
|
|
111
|
+
"""
|
|
112
|
+
text_index = 0
|
|
113
|
+
texts_len = len(texts)
|
|
114
|
+
batch_token_len = 0
|
|
115
|
+
batches: List[List[str]] = []
|
|
116
|
+
current_batch: List[str] = []
|
|
117
|
+
if texts_len == 0:
|
|
118
|
+
return []
|
|
119
|
+
while text_index < texts_len:
|
|
120
|
+
current_text = texts[text_index]
|
|
121
|
+
# Number of tokens per a text is conservatively estimated
|
|
122
|
+
# as 2 times number of words, punctuation and whitespace characters.
|
|
123
|
+
# Using `count_tokens` API will make batching too expensive.
|
|
124
|
+
# Utilizing a tokenizer, would add a dependency that would not
|
|
125
|
+
# necessarily be reused by the application using this class.
|
|
126
|
+
current_text_token_cnt = (
|
|
127
|
+
len(GoogleGenerativeAIEmbeddings._split_by_punctuation(current_text))
|
|
128
|
+
* 2
|
|
129
|
+
)
|
|
130
|
+
end_of_batch = False
|
|
131
|
+
if current_text_token_cnt > _MAX_TOKENS_PER_BATCH:
|
|
132
|
+
# Current text is too big even for a single batch.
|
|
133
|
+
# Such request will fail, but we still make a batch
|
|
134
|
+
# so that the app can get the error from the API.
|
|
135
|
+
if len(current_batch) > 0:
|
|
136
|
+
# Adding current batch if not empty.
|
|
137
|
+
batches.append(current_batch)
|
|
138
|
+
current_batch = [current_text]
|
|
139
|
+
text_index += 1
|
|
140
|
+
end_of_batch = True
|
|
141
|
+
elif (
|
|
142
|
+
batch_token_len + current_text_token_cnt > _MAX_TOKENS_PER_BATCH
|
|
143
|
+
or len(current_batch) == batch_size
|
|
144
|
+
):
|
|
145
|
+
end_of_batch = True
|
|
146
|
+
else:
|
|
147
|
+
if text_index == texts_len - 1:
|
|
148
|
+
# Last element - even though the batch may be not big,
|
|
149
|
+
# we still need to make it.
|
|
150
|
+
end_of_batch = True
|
|
151
|
+
batch_token_len += current_text_token_cnt
|
|
152
|
+
current_batch.append(current_text)
|
|
153
|
+
text_index += 1
|
|
154
|
+
if end_of_batch:
|
|
155
|
+
batches.append(current_batch)
|
|
156
|
+
current_batch = []
|
|
157
|
+
batch_token_len = 0
|
|
158
|
+
return batches
|
|
159
|
+
|
|
94
160
|
def _prepare_request(
|
|
95
161
|
self,
|
|
96
162
|
text: str,
|
|
@@ -112,12 +178,14 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
|
|
|
112
178
|
def embed_documents(
|
|
113
179
|
self,
|
|
114
180
|
texts: List[str],
|
|
181
|
+
*,
|
|
182
|
+
batch_size: int = _DEFAULT_BATCH_SIZE,
|
|
115
183
|
task_type: Optional[str] = None,
|
|
116
184
|
titles: Optional[List[str]] = None,
|
|
117
185
|
output_dimensionality: Optional[int] = None,
|
|
118
186
|
) -> List[List[float]]:
|
|
119
|
-
"""Embed a list of strings.
|
|
120
|
-
sets a max batch size of
|
|
187
|
+
"""Embed a list of strings. Google Generative AI currently
|
|
188
|
+
sets a max batch size of 100 strings.
|
|
121
189
|
|
|
122
190
|
Args:
|
|
123
191
|
texts: List[str] The list of strings to embed.
|
|
@@ -127,28 +195,38 @@ class GoogleGenerativeAIEmbeddings(BaseModel, Embeddings):
|
|
|
127
195
|
Only applicable when TaskType is RETRIEVAL_DOCUMENT.
|
|
128
196
|
output_dimensionality: Optional reduced dimension for the output embedding.
|
|
129
197
|
https://ai.google.dev/api/rest/v1/models/batchEmbedContents#EmbedContentRequest
|
|
130
|
-
|
|
131
198
|
Returns:
|
|
132
199
|
List of embeddings, one for each text.
|
|
133
200
|
"""
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
201
|
+
embeddings: List[List[float]] = []
|
|
202
|
+
batch_start_index = 0
|
|
203
|
+
for batch in GoogleGenerativeAIEmbeddings._prepare_batches(texts, batch_size):
|
|
204
|
+
if titles:
|
|
205
|
+
titles_batch = titles[
|
|
206
|
+
batch_start_index : batch_start_index + len(batch)
|
|
207
|
+
]
|
|
208
|
+
batch_start_index += len(batch)
|
|
209
|
+
else:
|
|
210
|
+
titles_batch = [None] * len(batch) # type: ignore[list-item]
|
|
144
211
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
212
|
+
requests = [
|
|
213
|
+
self._prepare_request(
|
|
214
|
+
text=text,
|
|
215
|
+
task_type=task_type,
|
|
216
|
+
title=title,
|
|
217
|
+
output_dimensionality=output_dimensionality,
|
|
218
|
+
)
|
|
219
|
+
for text, title in zip(batch, titles_batch)
|
|
220
|
+
]
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
result = self.client.batch_embed_contents(
|
|
224
|
+
BatchEmbedContentsRequest(requests=requests, model=self.model)
|
|
225
|
+
)
|
|
226
|
+
except Exception as e:
|
|
227
|
+
raise GoogleGenerativeAIError(f"Error embedding content: {e}") from e
|
|
228
|
+
embeddings.extend([list(e.values) for e in result.embeddings])
|
|
229
|
+
return embeddings
|
|
152
230
|
|
|
153
231
|
def embed_query(
|
|
154
232
|
self,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "langchain-google-genai"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.6"
|
|
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.2.
|
|
15
|
+
langchain-core = ">=0.2.2,<0.3"
|
|
16
16
|
google-generativeai = "^0.5.2"
|
|
17
17
|
pillow = { version = "^10.1.0", optional = true }
|
|
18
18
|
|
|
@@ -32,6 +32,9 @@ pytest-asyncio = "^0.21.1"
|
|
|
32
32
|
numpy = "^1.26.2"
|
|
33
33
|
langchain-core = { git = "https://github.com/langchain-ai/langchain.git", subdirectory = "libs/core" }
|
|
34
34
|
|
|
35
|
+
[tool.codespell]
|
|
36
|
+
ignore-words-list = "rouge"
|
|
37
|
+
|
|
35
38
|
[tool.poetry.group.codespell]
|
|
36
39
|
optional = true
|
|
37
40
|
|
|
File without changes
|
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/__init__.py
RENAMED
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_common.py
RENAMED
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_enums.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/_image_utils.py
RENAMED
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/genai_aqa.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/llms.py
RENAMED
|
File without changes
|
{langchain_google_genai-1.0.5 → langchain_google_genai-1.0.6}/langchain_google_genai/py.typed
RENAMED
|
File without changes
|