langchain-core 1.0.0a6__py3-none-any.whl → 1.0.0a8__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.

Potentially problematic release.


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

Files changed (131) hide show
  1. langchain_core/_api/__init__.py +3 -3
  2. langchain_core/_api/beta_decorator.py +6 -6
  3. langchain_core/_api/deprecation.py +21 -29
  4. langchain_core/_api/path.py +3 -6
  5. langchain_core/_import_utils.py +2 -3
  6. langchain_core/agents.py +10 -11
  7. langchain_core/caches.py +7 -7
  8. langchain_core/callbacks/base.py +91 -91
  9. langchain_core/callbacks/file.py +11 -11
  10. langchain_core/callbacks/manager.py +86 -89
  11. langchain_core/callbacks/stdout.py +8 -8
  12. langchain_core/callbacks/usage.py +4 -4
  13. langchain_core/chat_history.py +5 -5
  14. langchain_core/document_loaders/base.py +2 -2
  15. langchain_core/document_loaders/langsmith.py +15 -15
  16. langchain_core/documents/base.py +16 -16
  17. langchain_core/documents/compressor.py +4 -4
  18. langchain_core/example_selectors/length_based.py +1 -1
  19. langchain_core/example_selectors/semantic_similarity.py +17 -19
  20. langchain_core/exceptions.py +3 -3
  21. langchain_core/globals.py +3 -151
  22. langchain_core/indexing/api.py +44 -43
  23. langchain_core/indexing/base.py +30 -30
  24. langchain_core/indexing/in_memory.py +3 -3
  25. langchain_core/language_models/_utils.py +5 -7
  26. langchain_core/language_models/base.py +18 -132
  27. langchain_core/language_models/chat_models.py +118 -227
  28. langchain_core/language_models/fake.py +11 -11
  29. langchain_core/language_models/fake_chat_models.py +35 -29
  30. langchain_core/language_models/llms.py +91 -201
  31. langchain_core/load/dump.py +1 -1
  32. langchain_core/load/load.py +11 -12
  33. langchain_core/load/mapping.py +2 -4
  34. langchain_core/load/serializable.py +2 -4
  35. langchain_core/messages/ai.py +17 -20
  36. langchain_core/messages/base.py +23 -25
  37. langchain_core/messages/block_translators/__init__.py +2 -5
  38. langchain_core/messages/block_translators/anthropic.py +3 -3
  39. langchain_core/messages/block_translators/bedrock_converse.py +2 -2
  40. langchain_core/messages/block_translators/langchain_v0.py +2 -2
  41. langchain_core/messages/block_translators/openai.py +6 -6
  42. langchain_core/messages/content.py +120 -124
  43. langchain_core/messages/human.py +7 -7
  44. langchain_core/messages/system.py +7 -7
  45. langchain_core/messages/tool.py +24 -24
  46. langchain_core/messages/utils.py +67 -79
  47. langchain_core/output_parsers/base.py +12 -14
  48. langchain_core/output_parsers/json.py +4 -4
  49. langchain_core/output_parsers/list.py +3 -5
  50. langchain_core/output_parsers/openai_functions.py +3 -3
  51. langchain_core/output_parsers/openai_tools.py +3 -3
  52. langchain_core/output_parsers/pydantic.py +2 -2
  53. langchain_core/output_parsers/transform.py +13 -15
  54. langchain_core/output_parsers/xml.py +7 -9
  55. langchain_core/outputs/chat_generation.py +4 -4
  56. langchain_core/outputs/chat_result.py +1 -3
  57. langchain_core/outputs/generation.py +2 -2
  58. langchain_core/outputs/llm_result.py +5 -5
  59. langchain_core/prompts/__init__.py +1 -5
  60. langchain_core/prompts/base.py +10 -15
  61. langchain_core/prompts/chat.py +31 -82
  62. langchain_core/prompts/dict.py +2 -2
  63. langchain_core/prompts/few_shot.py +5 -5
  64. langchain_core/prompts/few_shot_with_templates.py +4 -4
  65. langchain_core/prompts/loading.py +3 -5
  66. langchain_core/prompts/prompt.py +4 -16
  67. langchain_core/prompts/string.py +2 -1
  68. langchain_core/prompts/structured.py +16 -23
  69. langchain_core/rate_limiters.py +3 -4
  70. langchain_core/retrievers.py +14 -14
  71. langchain_core/runnables/base.py +928 -1042
  72. langchain_core/runnables/branch.py +36 -40
  73. langchain_core/runnables/config.py +27 -35
  74. langchain_core/runnables/configurable.py +108 -124
  75. langchain_core/runnables/fallbacks.py +76 -72
  76. langchain_core/runnables/graph.py +39 -45
  77. langchain_core/runnables/graph_ascii.py +9 -11
  78. langchain_core/runnables/graph_mermaid.py +18 -19
  79. langchain_core/runnables/graph_png.py +8 -9
  80. langchain_core/runnables/history.py +114 -127
  81. langchain_core/runnables/passthrough.py +113 -139
  82. langchain_core/runnables/retry.py +43 -48
  83. langchain_core/runnables/router.py +23 -28
  84. langchain_core/runnables/schema.py +42 -44
  85. langchain_core/runnables/utils.py +28 -31
  86. langchain_core/stores.py +9 -13
  87. langchain_core/structured_query.py +8 -8
  88. langchain_core/tools/base.py +62 -115
  89. langchain_core/tools/convert.py +31 -35
  90. langchain_core/tools/render.py +1 -1
  91. langchain_core/tools/retriever.py +4 -4
  92. langchain_core/tools/simple.py +13 -17
  93. langchain_core/tools/structured.py +12 -15
  94. langchain_core/tracers/base.py +62 -64
  95. langchain_core/tracers/context.py +17 -35
  96. langchain_core/tracers/core.py +49 -53
  97. langchain_core/tracers/evaluation.py +11 -11
  98. langchain_core/tracers/event_stream.py +58 -60
  99. langchain_core/tracers/langchain.py +13 -13
  100. langchain_core/tracers/log_stream.py +22 -24
  101. langchain_core/tracers/root_listeners.py +14 -14
  102. langchain_core/tracers/run_collector.py +2 -4
  103. langchain_core/tracers/schemas.py +8 -8
  104. langchain_core/tracers/stdout.py +2 -1
  105. langchain_core/utils/__init__.py +0 -3
  106. langchain_core/utils/_merge.py +2 -2
  107. langchain_core/utils/aiter.py +24 -28
  108. langchain_core/utils/env.py +4 -4
  109. langchain_core/utils/function_calling.py +31 -41
  110. langchain_core/utils/html.py +3 -4
  111. langchain_core/utils/input.py +3 -3
  112. langchain_core/utils/iter.py +15 -19
  113. langchain_core/utils/json.py +3 -2
  114. langchain_core/utils/json_schema.py +6 -6
  115. langchain_core/utils/mustache.py +3 -5
  116. langchain_core/utils/pydantic.py +16 -18
  117. langchain_core/utils/usage.py +1 -1
  118. langchain_core/utils/utils.py +29 -29
  119. langchain_core/vectorstores/base.py +18 -21
  120. langchain_core/vectorstores/in_memory.py +14 -87
  121. langchain_core/vectorstores/utils.py +2 -2
  122. langchain_core/version.py +1 -1
  123. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.0a8.dist-info}/METADATA +10 -21
  124. langchain_core-1.0.0a8.dist-info/RECORD +176 -0
  125. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.0a8.dist-info}/WHEEL +1 -1
  126. langchain_core/messages/block_translators/ollama.py +0 -47
  127. langchain_core/prompts/pipeline.py +0 -138
  128. langchain_core/tracers/langchain_v1.py +0 -31
  129. langchain_core/utils/loading.py +0 -35
  130. langchain_core-1.0.0a6.dist-info/RECORD +0 -181
  131. langchain_core-1.0.0a6.dist-info/entry_points.txt +0 -4
@@ -5,13 +5,10 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import inspect
7
7
  import threading
8
- from collections.abc import Awaitable
8
+ from collections.abc import Awaitable, Callable
9
9
  from typing import (
10
10
  TYPE_CHECKING,
11
11
  Any,
12
- Callable,
13
- Optional,
14
- Union,
15
12
  cast,
16
13
  )
17
14
 
@@ -86,69 +83,66 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
86
83
  and experiment with.
87
84
 
88
85
  Examples:
86
+ ```python
87
+ from langchain_core.runnables import (
88
+ RunnableLambda,
89
+ RunnableParallel,
90
+ RunnablePassthrough,
91
+ )
89
92
 
90
- .. code-block:: python
91
-
92
- from langchain_core.runnables import (
93
- RunnableLambda,
94
- RunnableParallel,
95
- RunnablePassthrough,
96
- )
97
-
98
- runnable = RunnableParallel(
99
- origin=RunnablePassthrough(), modified=lambda x: x + 1
100
- )
93
+ runnable = RunnableParallel(
94
+ origin=RunnablePassthrough(), modified=lambda x: x + 1
95
+ )
101
96
 
102
- runnable.invoke(1) # {'origin': 1, 'modified': 2}
97
+ runnable.invoke(1) # {'origin': 1, 'modified': 2}
103
98
 
104
99
 
105
- def fake_llm(prompt: str) -> str: # Fake LLM for the example
106
- return "completion"
100
+ def fake_llm(prompt: str) -> str: # Fake LLM for the example
101
+ return "completion"
107
102
 
108
103
 
109
- chain = RunnableLambda(fake_llm) | {
110
- "original": RunnablePassthrough(), # Original LLM output
111
- "parsed": lambda text: text[::-1], # Parsing logic
112
- }
104
+ chain = RunnableLambda(fake_llm) | {
105
+ "original": RunnablePassthrough(), # Original LLM output
106
+ "parsed": lambda text: text[::-1], # Parsing logic
107
+ }
113
108
 
114
- chain.invoke("hello") # {'original': 'completion', 'parsed': 'noitelpmoc'}
109
+ chain.invoke("hello") # {'original': 'completion', 'parsed': 'noitelpmoc'}
110
+ ```
115
111
 
116
112
  In some cases, it may be useful to pass the input through while adding some
117
113
  keys to the output. In this case, you can use the `assign` method:
118
114
 
119
- .. code-block:: python
120
-
121
- from langchain_core.runnables import RunnablePassthrough
115
+ ```python
116
+ from langchain_core.runnables import RunnablePassthrough
122
117
 
123
118
 
124
- def fake_llm(prompt: str) -> str: # Fake LLM for the example
125
- return "completion"
119
+ def fake_llm(prompt: str) -> str: # Fake LLM for the example
120
+ return "completion"
126
121
 
127
122
 
128
- runnable = {
129
- "llm1": fake_llm,
130
- "llm2": fake_llm,
131
- } | RunnablePassthrough.assign(
132
- total_chars=lambda inputs: len(inputs["llm1"] + inputs["llm2"])
133
- )
134
-
135
- runnable.invoke("hello")
136
- # {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20}
123
+ runnable = {
124
+ "llm1": fake_llm,
125
+ "llm2": fake_llm,
126
+ } | RunnablePassthrough.assign(
127
+ total_chars=lambda inputs: len(inputs["llm1"] + inputs["llm2"])
128
+ )
137
129
 
130
+ runnable.invoke("hello")
131
+ # {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20}
132
+ ```
138
133
  """
139
134
 
140
- input_type: Optional[type[Other]] = None
135
+ input_type: type[Other] | None = None
141
136
 
142
- func: Optional[
143
- Union[Callable[[Other], None], Callable[[Other, RunnableConfig], None]]
144
- ] = None
137
+ func: Callable[[Other], None] | Callable[[Other, RunnableConfig], None] | None = (
138
+ None
139
+ )
145
140
 
146
- afunc: Optional[
147
- Union[
148
- Callable[[Other], Awaitable[None]],
149
- Callable[[Other, RunnableConfig], Awaitable[None]],
150
- ]
151
- ] = None
141
+ afunc: (
142
+ Callable[[Other], Awaitable[None]]
143
+ | Callable[[Other, RunnableConfig], Awaitable[None]]
144
+ | None
145
+ ) = None
152
146
 
153
147
  @override
154
148
  def __repr_args__(self) -> Any:
@@ -158,23 +152,16 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
158
152
 
159
153
  def __init__(
160
154
  self,
161
- func: Optional[
162
- Union[
163
- Union[Callable[[Other], None], Callable[[Other, RunnableConfig], None]],
164
- Union[
165
- Callable[[Other], Awaitable[None]],
166
- Callable[[Other, RunnableConfig], Awaitable[None]],
167
- ],
168
- ]
169
- ] = None,
170
- afunc: Optional[
171
- Union[
172
- Callable[[Other], Awaitable[None]],
173
- Callable[[Other, RunnableConfig], Awaitable[None]],
174
- ]
175
- ] = None,
155
+ func: Callable[[Other], None]
156
+ | Callable[[Other, RunnableConfig], None]
157
+ | Callable[[Other], Awaitable[None]]
158
+ | Callable[[Other, RunnableConfig], Awaitable[None]]
159
+ | None = None,
160
+ afunc: Callable[[Other], Awaitable[None]]
161
+ | Callable[[Other, RunnableConfig], Awaitable[None]]
162
+ | None = None,
176
163
  *,
177
- input_type: Optional[type[Other]] = None,
164
+ input_type: type[Other] | None = None,
178
165
  **kwargs: Any,
179
166
  ) -> None:
180
167
  """Create e RunnablePassthrough.
@@ -219,14 +206,9 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
219
206
  @override
220
207
  def assign(
221
208
  cls,
222
- **kwargs: Union[
223
- Runnable[dict[str, Any], Any],
224
- Callable[[dict[str, Any]], Any],
225
- Mapping[
226
- str,
227
- Union[Runnable[dict[str, Any], Any], Callable[[dict[str, Any]], Any]],
228
- ],
229
- ],
209
+ **kwargs: Runnable[dict[str, Any], Any]
210
+ | Callable[[dict[str, Any]], Any]
211
+ | Mapping[str, Runnable[dict[str, Any], Any] | Callable[[dict[str, Any]], Any]],
230
212
  ) -> RunnableAssign:
231
213
  """Merge the Dict input with the output produced by the mapping argument.
232
214
 
@@ -242,7 +224,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
242
224
 
243
225
  @override
244
226
  def invoke(
245
- self, input: Other, config: Optional[RunnableConfig] = None, **kwargs: Any
227
+ self, input: Other, config: RunnableConfig | None = None, **kwargs: Any
246
228
  ) -> Other:
247
229
  if self.func is not None:
248
230
  call_func_with_variable_args(
@@ -254,8 +236,8 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
254
236
  async def ainvoke(
255
237
  self,
256
238
  input: Other,
257
- config: Optional[RunnableConfig] = None,
258
- **kwargs: Optional[Any],
239
+ config: RunnableConfig | None = None,
240
+ **kwargs: Any | None,
259
241
  ) -> Other:
260
242
  if self.afunc is not None:
261
243
  await acall_func_with_variable_args(
@@ -271,7 +253,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
271
253
  def transform(
272
254
  self,
273
255
  input: Iterator[Other],
274
- config: Optional[RunnableConfig] = None,
256
+ config: RunnableConfig | None = None,
275
257
  **kwargs: Any,
276
258
  ) -> Iterator[Other]:
277
259
  if self.func is None:
@@ -302,7 +284,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
302
284
  async def atransform(
303
285
  self,
304
286
  input: AsyncIterator[Other],
305
- config: Optional[RunnableConfig] = None,
287
+ config: RunnableConfig | None = None,
306
288
  **kwargs: Any,
307
289
  ) -> AsyncIterator[Other]:
308
290
  if self.afunc is None and self.func is None:
@@ -345,7 +327,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
345
327
  def stream(
346
328
  self,
347
329
  input: Other,
348
- config: Optional[RunnableConfig] = None,
330
+ config: RunnableConfig | None = None,
349
331
  **kwargs: Any,
350
332
  ) -> Iterator[Other]:
351
333
  return self.transform(iter([input]), config, **kwargs)
@@ -354,7 +336,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
354
336
  async def astream(
355
337
  self,
356
338
  input: Other,
357
- config: Optional[RunnableConfig] = None,
339
+ config: RunnableConfig | None = None,
358
340
  **kwargs: Any,
359
341
  ) -> AsyncIterator[Other]:
360
342
  async def input_aiter() -> AsyncIterator[Other]:
@@ -376,36 +358,35 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
376
358
  on the mapper's logic.
377
359
 
378
360
  Examples:
379
- .. code-block:: python
380
-
381
- # This is a RunnableAssign
382
- from langchain_core.runnables.passthrough import (
383
- RunnableAssign,
384
- RunnableParallel,
385
- )
386
- from langchain_core.runnables.base import RunnableLambda
361
+ ```python
362
+ # This is a RunnableAssign
363
+ from langchain_core.runnables.passthrough import (
364
+ RunnableAssign,
365
+ RunnableParallel,
366
+ )
367
+ from langchain_core.runnables.base import RunnableLambda
387
368
 
388
369
 
389
- def add_ten(x: dict[str, int]) -> dict[str, int]:
390
- return {"added": x["input"] + 10}
370
+ def add_ten(x: dict[str, int]) -> dict[str, int]:
371
+ return {"added": x["input"] + 10}
391
372
 
392
373
 
393
- mapper = RunnableParallel(
394
- {
395
- "add_step": RunnableLambda(add_ten),
396
- }
397
- )
398
-
399
- runnable_assign = RunnableAssign(mapper)
374
+ mapper = RunnableParallel(
375
+ {
376
+ "add_step": RunnableLambda(add_ten),
377
+ }
378
+ )
400
379
 
401
- # Synchronous example
402
- runnable_assign.invoke({"input": 5})
403
- # returns {'input': 5, 'add_step': {'added': 15}}
380
+ runnable_assign = RunnableAssign(mapper)
404
381
 
405
- # Asynchronous example
406
- await runnable_assign.ainvoke({"input": 5})
407
- # returns {'input': 5, 'add_step': {'added': 15}}
382
+ # Synchronous example
383
+ runnable_assign.invoke({"input": 5})
384
+ # returns {'input': 5, 'add_step': {'added': 15}}
408
385
 
386
+ # Asynchronous example
387
+ await runnable_assign.ainvoke({"input": 5})
388
+ # returns {'input': 5, 'add_step': {'added': 15}}
389
+ ```
409
390
  """
410
391
 
411
392
  mapper: RunnableParallel
@@ -436,9 +417,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
436
417
  return ["langchain", "schema", "runnable"]
437
418
 
438
419
  @override
439
- def get_name(
440
- self, suffix: Optional[str] = None, *, name: Optional[str] = None
441
- ) -> str:
420
+ def get_name(self, suffix: str | None = None, *, name: str | None = None) -> str:
442
421
  name = (
443
422
  name
444
423
  or self.name
@@ -447,9 +426,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
447
426
  return super().get_name(suffix, name=name)
448
427
 
449
428
  @override
450
- def get_input_schema(
451
- self, config: Optional[RunnableConfig] = None
452
- ) -> type[BaseModel]:
429
+ def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
453
430
  map_input_schema = self.mapper.get_input_schema(config)
454
431
  if not issubclass(map_input_schema, RootModel):
455
432
  # ie. it's a dict
@@ -459,7 +436,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
459
436
 
460
437
  @override
461
438
  def get_output_schema(
462
- self, config: Optional[RunnableConfig] = None
439
+ self, config: RunnableConfig | None = None
463
440
  ) -> type[BaseModel]:
464
441
  map_input_schema = self.mapper.get_input_schema(config)
465
442
  map_output_schema = self.mapper.get_output_schema(config)
@@ -524,7 +501,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
524
501
  def invoke(
525
502
  self,
526
503
  input: dict[str, Any],
527
- config: Optional[RunnableConfig] = None,
504
+ config: RunnableConfig | None = None,
528
505
  **kwargs: Any,
529
506
  ) -> dict[str, Any]:
530
507
  return self._call_with_config(self._invoke, input, config, **kwargs)
@@ -553,7 +530,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
553
530
  async def ainvoke(
554
531
  self,
555
532
  input: dict[str, Any],
556
- config: Optional[RunnableConfig] = None,
533
+ config: RunnableConfig | None = None,
557
534
  **kwargs: Any,
558
535
  ) -> dict[str, Any]:
559
536
  return await self._acall_with_config(self._ainvoke, input, config, **kwargs)
@@ -608,7 +585,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
608
585
  def transform(
609
586
  self,
610
587
  input: Iterator[dict[str, Any]],
611
- config: Optional[RunnableConfig] = None,
588
+ config: RunnableConfig | None = None,
612
589
  **kwargs: Any | None,
613
590
  ) -> Iterator[dict[str, Any]]:
614
591
  yield from self._transform_stream_with_config(
@@ -660,7 +637,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
660
637
  async def atransform(
661
638
  self,
662
639
  input: AsyncIterator[dict[str, Any]],
663
- config: Optional[RunnableConfig] = None,
640
+ config: RunnableConfig | None = None,
664
641
  **kwargs: Any,
665
642
  ) -> AsyncIterator[dict[str, Any]]:
666
643
  async for chunk in self._atransform_stream_with_config(
@@ -672,7 +649,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
672
649
  def stream(
673
650
  self,
674
651
  input: dict[str, Any],
675
- config: Optional[RunnableConfig] = None,
652
+ config: RunnableConfig | None = None,
676
653
  **kwargs: Any,
677
654
  ) -> Iterator[dict[str, Any]]:
678
655
  return self.transform(iter([input]), config, **kwargs)
@@ -681,7 +658,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
681
658
  async def astream(
682
659
  self,
683
660
  input: dict[str, Any],
684
- config: Optional[RunnableConfig] = None,
661
+ config: RunnableConfig | None = None,
685
662
  **kwargs: Any,
686
663
  ) -> AsyncIterator[dict[str, Any]]:
687
664
  async def input_aiter() -> AsyncIterator[dict[str, Any]]:
@@ -700,28 +677,27 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
700
677
  the selected keys.
701
678
 
702
679
  Example:
703
- .. code-block:: python
704
-
705
- from langchain_core.runnables.passthrough import RunnablePick
706
-
707
- input_data = {
708
- "name": "John",
709
- "age": 30,
710
- "city": "New York",
711
- "country": "USA",
712
- }
713
-
714
- runnable = RunnablePick(keys=["name", "age"])
680
+ ```python
681
+ from langchain_core.runnables.passthrough import RunnablePick
682
+
683
+ input_data = {
684
+ "name": "John",
685
+ "age": 30,
686
+ "city": "New York",
687
+ "country": "USA",
688
+ }
715
689
 
716
- output_data = runnable.invoke(input_data)
690
+ runnable = RunnablePick(keys=["name", "age"])
717
691
 
718
- print(output_data) # Output: {'name': 'John', 'age': 30}
692
+ output_data = runnable.invoke(input_data)
719
693
 
694
+ print(output_data) # Output: {'name': 'John', 'age': 30}
695
+ ```
720
696
  """
721
697
 
722
- keys: Union[str, list[str]]
698
+ keys: str | list[str]
723
699
 
724
- def __init__(self, keys: Union[str, list[str]], **kwargs: Any) -> None:
700
+ def __init__(self, keys: str | list[str], **kwargs: Any) -> None:
725
701
  """Create a RunnablePick.
726
702
 
727
703
  Args:
@@ -746,9 +722,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
746
722
  return ["langchain", "schema", "runnable"]
747
723
 
748
724
  @override
749
- def get_name(
750
- self, suffix: Optional[str] = None, *, name: Optional[str] = None
751
- ) -> str:
725
+ def get_name(self, suffix: str | None = None, *, name: str | None = None) -> str:
752
726
  name = (
753
727
  name
754
728
  or self.name
@@ -779,7 +753,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
779
753
  def invoke(
780
754
  self,
781
755
  input: dict[str, Any],
782
- config: Optional[RunnableConfig] = None,
756
+ config: RunnableConfig | None = None,
783
757
  **kwargs: Any,
784
758
  ) -> dict[str, Any]:
785
759
  return self._call_with_config(self._invoke, input, config, **kwargs)
@@ -794,7 +768,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
794
768
  async def ainvoke(
795
769
  self,
796
770
  input: dict[str, Any],
797
- config: Optional[RunnableConfig] = None,
771
+ config: RunnableConfig | None = None,
798
772
  **kwargs: Any,
799
773
  ) -> dict[str, Any]:
800
774
  return await self._acall_with_config(self._ainvoke, input, config, **kwargs)
@@ -812,7 +786,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
812
786
  def transform(
813
787
  self,
814
788
  input: Iterator[dict[str, Any]],
815
- config: Optional[RunnableConfig] = None,
789
+ config: RunnableConfig | None = None,
816
790
  **kwargs: Any,
817
791
  ) -> Iterator[dict[str, Any]]:
818
792
  yield from self._transform_stream_with_config(
@@ -832,7 +806,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
832
806
  async def atransform(
833
807
  self,
834
808
  input: AsyncIterator[dict[str, Any]],
835
- config: Optional[RunnableConfig] = None,
809
+ config: RunnableConfig | None = None,
836
810
  **kwargs: Any,
837
811
  ) -> AsyncIterator[dict[str, Any]]:
838
812
  async for chunk in self._atransform_stream_with_config(
@@ -844,7 +818,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
844
818
  def stream(
845
819
  self,
846
820
  input: dict[str, Any],
847
- config: Optional[RunnableConfig] = None,
821
+ config: RunnableConfig | None = None,
848
822
  **kwargs: Any,
849
823
  ) -> Iterator[dict[str, Any]]:
850
824
  return self.transform(iter([input]), config, **kwargs)
@@ -853,7 +827,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
853
827
  async def astream(
854
828
  self,
855
829
  input: dict[str, Any],
856
- config: Optional[RunnableConfig] = None,
830
+ config: RunnableConfig | None = None,
857
831
  **kwargs: Any,
858
832
  ) -> AsyncIterator[dict[str, Any]]:
859
833
  async def input_aiter() -> AsyncIterator[dict[str, Any]]:
@@ -3,9 +3,7 @@
3
3
  from typing import (
4
4
  TYPE_CHECKING,
5
5
  Any,
6
- Optional,
7
6
  TypeVar,
8
- Union,
9
7
  cast,
10
8
  )
11
9
 
@@ -62,36 +60,34 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
62
60
  Example:
63
61
  Here's an example that uses a RunnableLambda to raise an exception
64
62
 
65
- .. code-block:: python
63
+ ```python
64
+ import time
66
65
 
67
- import time
68
66
 
67
+ def foo(input) -> None:
68
+ '''Fake function that raises an exception.'''
69
+ raise ValueError(f"Invoking foo failed. At time {time.time()}")
69
70
 
70
- def foo(input) -> None:
71
- '''Fake function that raises an exception.'''
72
- raise ValueError(f"Invoking foo failed. At time {time.time()}")
73
71
 
72
+ runnable = RunnableLambda(foo)
74
73
 
75
- runnable = RunnableLambda(foo)
76
-
77
- runnable_with_retries = runnable.with_retry(
78
- retry_if_exception_type=(ValueError,), # Retry only on ValueError
79
- wait_exponential_jitter=True, # Add jitter to the exponential backoff
80
- stop_after_attempt=2, # Try twice
81
- exponential_jitter_params={
82
- "initial": 2
83
- }, # if desired, customize backoff
84
- )
74
+ runnable_with_retries = runnable.with_retry(
75
+ retry_if_exception_type=(ValueError,), # Retry only on ValueError
76
+ wait_exponential_jitter=True, # Add jitter to the exponential backoff
77
+ stop_after_attempt=2, # Try twice
78
+ exponential_jitter_params={"initial": 2}, # if desired, customize backoff
79
+ )
85
80
 
86
- # The method invocation above is equivalent to the longer form below:
81
+ # The method invocation above is equivalent to the longer form below:
87
82
 
88
- runnable_with_retries = RunnableRetry(
89
- bound=runnable,
90
- retry_exception_types=(ValueError,),
91
- max_attempt_number=2,
92
- wait_exponential_jitter=True,
93
- exponential_jitter_params={"initial": 2},
94
- )
83
+ runnable_with_retries = RunnableRetry(
84
+ bound=runnable,
85
+ retry_exception_types=(ValueError,),
86
+ max_attempt_number=2,
87
+ wait_exponential_jitter=True,
88
+ exponential_jitter_params={"initial": 2},
89
+ )
90
+ ```
95
91
 
96
92
  This logic can be used to retry any Runnable, including a chain of Runnables,
97
93
  but in general it's best practice to keep the scope of the retry as small as
@@ -99,22 +95,20 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
99
95
  the Runnable that is likely to fail, not the entire chain.
100
96
 
101
97
  Example:
98
+ ```python
99
+ from langchain_core.chat_models import ChatOpenAI
100
+ from langchain_core.prompts import PromptTemplate
102
101
 
103
- .. code-block:: python
104
-
105
- from langchain_core.chat_models import ChatOpenAI
106
- from langchain_core.prompts import PromptTemplate
107
-
108
- template = PromptTemplate.from_template("tell me a joke about {topic}.")
109
- model = ChatOpenAI(temperature=0.5)
110
-
111
- # Good
112
- chain = template | model.with_retry()
102
+ template = PromptTemplate.from_template("tell me a joke about {topic}.")
103
+ model = ChatOpenAI(temperature=0.5)
113
104
 
114
- # Bad
115
- chain = template | model
116
- retryable_chain = chain.with_retry()
105
+ # Good
106
+ chain = template | model.with_retry()
117
107
 
108
+ # Bad
109
+ chain = template | model
110
+ retryable_chain = chain.with_retry()
111
+ ```
118
112
  """
119
113
 
120
114
  retry_exception_types: tuple[type[BaseException], ...] = (Exception,)
@@ -130,7 +124,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
130
124
  wait_exponential_jitter: bool = True
131
125
  """Whether to add jitter to the exponential backoff."""
132
126
 
133
- exponential_jitter_params: Optional[ExponentialJitterParams] = None
127
+ exponential_jitter_params: ExponentialJitterParams | None = None
134
128
  """Parameters for ``tenacity.wait_exponential_jitter``. Namely: ``initial``,
135
129
  ``max``, ``exp_base``, and ``jitter`` (all float values).
136
130
  """
@@ -178,7 +172,8 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
178
172
  retry_state: RetryCallState,
179
173
  ) -> list[RunnableConfig]:
180
174
  return [
181
- self._patch_config(c, rm, retry_state) for c, rm in zip(config, run_manager)
175
+ self._patch_config(c, rm, retry_state)
176
+ for c, rm in zip(config, run_manager, strict=False)
182
177
  ]
183
178
 
184
179
  def _invoke(
@@ -201,7 +196,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
201
196
 
202
197
  @override
203
198
  def invoke(
204
- self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any
199
+ self, input: Input, config: RunnableConfig | None = None, **kwargs: Any
205
200
  ) -> Output:
206
201
  return self._call_with_config(self._invoke, input, config, **kwargs)
207
202
 
@@ -225,7 +220,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
225
220
 
226
221
  @override
227
222
  async def ainvoke(
228
- self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any
223
+ self, input: Input, config: RunnableConfig | None = None, **kwargs: Any
229
224
  ) -> Output:
230
225
  return await self._acall_with_config(self._ainvoke, input, config, **kwargs)
231
226
 
@@ -235,7 +230,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
235
230
  run_manager: list["CallbackManagerForChainRun"],
236
231
  config: list[RunnableConfig],
237
232
  **kwargs: Any,
238
- ) -> list[Union[Output, Exception]]:
233
+ ) -> list[Output | Exception]:
239
234
  results_map: dict[int, Output] = {}
240
235
 
241
236
  not_set: list[Output] = []
@@ -284,7 +279,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
284
279
  if result is not_set:
285
280
  result = cast("list[Output]", [e] * len(inputs))
286
281
 
287
- outputs: list[Union[Output, Exception]] = []
282
+ outputs: list[Output | Exception] = []
288
283
  for idx in range(len(inputs)):
289
284
  if idx in results_map:
290
285
  outputs.append(results_map[idx])
@@ -296,7 +291,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
296
291
  def batch(
297
292
  self,
298
293
  inputs: list[Input],
299
- config: Optional[Union[RunnableConfig, list[RunnableConfig]]] = None,
294
+ config: RunnableConfig | list[RunnableConfig] | None = None,
300
295
  *,
301
296
  return_exceptions: bool = False,
302
297
  **kwargs: Any,
@@ -311,7 +306,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
311
306
  run_manager: list["AsyncCallbackManagerForChainRun"],
312
307
  config: list[RunnableConfig],
313
308
  **kwargs: Any,
314
- ) -> list[Union[Output, Exception]]:
309
+ ) -> list[Output | Exception]:
315
310
  results_map: dict[int, Output] = {}
316
311
 
317
312
  not_set: list[Output] = []
@@ -359,7 +354,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
359
354
  if result is not_set:
360
355
  result = cast("list[Output]", [e] * len(inputs))
361
356
 
362
- outputs: list[Union[Output, Exception]] = []
357
+ outputs: list[Output | Exception] = []
363
358
  for idx in range(len(inputs)):
364
359
  if idx in results_map:
365
360
  outputs.append(results_map[idx])
@@ -371,7 +366,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
371
366
  async def abatch(
372
367
  self,
373
368
  inputs: list[Input],
374
- config: Optional[Union[RunnableConfig, list[RunnableConfig]]] = None,
369
+ config: RunnableConfig | list[RunnableConfig] | None = None,
375
370
  *,
376
371
  return_exceptions: bool = False,
377
372
  **kwargs: Any,