langchain-b12 0.1.7__py3-none-any.whl → 0.1.9__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.
@@ -7,10 +7,6 @@ from typing import Any, Literal, cast
7
7
  from google import genai
8
8
  from google.genai import types
9
9
  from google.oauth2 import service_account
10
- from langchain_b12.genai.genai_utils import (
11
- convert_messages_to_contents,
12
- parse_response_candidate,
13
- )
14
10
  from langchain_core.callbacks import (
15
11
  AsyncCallbackManagerForLLMRun,
16
12
  CallbackManagerForLLMRun,
@@ -40,6 +36,18 @@ from langchain_core.utils.function_calling import (
40
36
  convert_to_openai_tool,
41
37
  )
42
38
  from pydantic import BaseModel, ConfigDict, Field
39
+ from tenacity import (
40
+ retry,
41
+ retry_if_exception_type,
42
+ stop_after_attempt,
43
+ stop_never,
44
+ wait_exponential_jitter,
45
+ )
46
+
47
+ from langchain_b12.genai.genai_utils import (
48
+ convert_messages_to_contents,
49
+ parse_response_candidate,
50
+ )
43
51
 
44
52
  logger = logging.getLogger(__name__)
45
53
 
@@ -75,6 +83,8 @@ class ChatGenAI(BaseChatModel):
75
83
  """How many completions to generate for each prompt."""
76
84
  seed: int | None = None
77
85
  """Random seed for the generation."""
86
+ max_retries: int | None = Field(default=3)
87
+ """Maximum number of retries when generation fails. None disables retries."""
78
88
  safety_settings: list[types.SafetySetting] | None = None
79
89
  """The default safety settings to use for all generations.
80
90
 
@@ -173,10 +183,29 @@ class ChatGenAI(BaseChatModel):
173
183
  run_manager: CallbackManagerForLLMRun | None = None,
174
184
  **kwargs: Any,
175
185
  ) -> ChatResult:
176
- stream_iter = self._stream(
177
- messages, stop=stop, run_manager=run_manager, **kwargs
186
+ @retry(
187
+ reraise=True,
188
+ stop=stop_after_attempt(self.max_retries + 1)
189
+ if self.max_retries is not None
190
+ else stop_never,
191
+ wait=wait_exponential_jitter(initial=1, max=60),
192
+ retry=retry_if_exception_type(Exception),
193
+ before_sleep=lambda retry_state: logger.warning(
194
+ "ChatGenAI._generate failed (attempt %d/%s). "
195
+ "Retrying in %.2fs... Error: %s",
196
+ retry_state.attempt_number,
197
+ self.max_retries + 1 if self.max_retries is not None else "∞",
198
+ retry_state.next_action.sleep,
199
+ retry_state.outcome.exception(),
200
+ ),
178
201
  )
179
- return generate_from_stream(stream_iter)
202
+ def _generate_with_retry() -> ChatResult:
203
+ stream_iter = self._stream(
204
+ messages, stop=stop, run_manager=run_manager, **kwargs
205
+ )
206
+ return generate_from_stream(stream_iter)
207
+
208
+ return _generate_with_retry()
180
209
 
181
210
  async def _agenerate(
182
211
  self,
@@ -185,10 +214,29 @@ class ChatGenAI(BaseChatModel):
185
214
  run_manager: AsyncCallbackManagerForLLMRun | None = None,
186
215
  **kwargs: Any,
187
216
  ) -> ChatResult:
188
- stream_iter = self._astream(
189
- messages, stop=stop, run_manager=run_manager, **kwargs
217
+ @retry(
218
+ reraise=True,
219
+ stop=stop_after_attempt(self.max_retries + 1)
220
+ if self.max_retries is not None
221
+ else stop_never,
222
+ wait=wait_exponential_jitter(initial=1, max=60),
223
+ retry=retry_if_exception_type(Exception),
224
+ before_sleep=lambda retry_state: logger.warning(
225
+ "ChatGenAI._agenerate failed (attempt %d/%s). "
226
+ "Retrying in %.2fs... Error: %s",
227
+ retry_state.attempt_number,
228
+ self.max_retries + 1 if self.max_retries is not None else "∞",
229
+ retry_state.next_action.sleep,
230
+ retry_state.outcome.exception(),
231
+ ),
190
232
  )
191
- return await agenerate_from_stream(stream_iter)
233
+ async def _agenerate_with_retry() -> ChatResult:
234
+ stream_iter = self._astream(
235
+ messages, stop=stop, run_manager=run_manager, **kwargs
236
+ )
237
+ return await agenerate_from_stream(stream_iter)
238
+
239
+ return await _agenerate_with_retry()
192
240
 
193
241
  def _stream(
194
242
  self,
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-b12
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: A reusable collection of tools and implementations for Langchain
5
5
  Author-email: Vincent Min <vincent.min@b12-consulting.com>
6
6
  Requires-Python: >=3.11
7
7
  Requires-Dist: langchain-core>=0.3.60
8
+ Requires-Dist: tenacity>=9.1.2
8
9
  Description-Content-Type: text/markdown
9
10
 
10
11
  # Langchain B12
@@ -2,8 +2,8 @@ langchain_b12/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  langchain_b12/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  langchain_b12/citations/citations.py,sha256=ZQvYayjQXIUaRosJ0qwL3Nc7kC8sBzmaIkE-BOslaVI,12261
4
4
  langchain_b12/genai/embeddings.py,sha256=h0Z-5PltDW9q79AjSrLemsz-_QKMB-043XXDvYSRQds,3483
5
- langchain_b12/genai/genai.py,sha256=Nsbwe0nlMW2p5bDtKRunDzamRcWM62zHqUNDBlbNFSg,16936
5
+ langchain_b12/genai/genai.py,sha256=zZdGwkkaxobnA1jT07MvWHaIHKeBis4X1zJ8o5KrnHk,18841
6
6
  langchain_b12/genai/genai_utils.py,sha256=tA6UiJURK25-11vtaX4768UV47jDCYwVKIIWydD4Egw,10736
7
- langchain_b12-0.1.7.dist-info/METADATA,sha256=_wBqxchZ-bO6Ol5cw2IbRLgB0BgF8fa_-XqjlKLsvVU,1204
8
- langchain_b12-0.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
- langchain_b12-0.1.7.dist-info/RECORD,,
7
+ langchain_b12-0.1.9.dist-info/METADATA,sha256=CpmYdZwkej43d-DvTOR8FU65QSHAZ4iiFu7Ale8Gy0I,1235
8
+ langchain_b12-0.1.9.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
9
+ langchain_b12-0.1.9.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any