langchain-core 1.0.0a6__py3-none-any.whl → 1.0.4__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.
Files changed (165) hide show
  1. langchain_core/__init__.py +1 -1
  2. langchain_core/_api/__init__.py +3 -4
  3. langchain_core/_api/beta_decorator.py +23 -26
  4. langchain_core/_api/deprecation.py +51 -64
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +55 -48
  8. langchain_core/caches.py +65 -66
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +321 -336
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +454 -514
  13. langchain_core/callbacks/stdout.py +29 -30
  14. langchain_core/callbacks/streaming_stdout.py +32 -32
  15. langchain_core/callbacks/usage.py +60 -57
  16. langchain_core/chat_history.py +53 -68
  17. langchain_core/document_loaders/base.py +27 -25
  18. langchain_core/document_loaders/blob_loaders.py +1 -1
  19. langchain_core/document_loaders/langsmith.py +44 -48
  20. langchain_core/documents/__init__.py +23 -3
  21. langchain_core/documents/base.py +102 -94
  22. langchain_core/documents/compressor.py +10 -10
  23. langchain_core/documents/transformers.py +34 -35
  24. langchain_core/embeddings/fake.py +50 -54
  25. langchain_core/example_selectors/length_based.py +2 -2
  26. langchain_core/example_selectors/semantic_similarity.py +28 -32
  27. langchain_core/exceptions.py +21 -20
  28. langchain_core/globals.py +3 -151
  29. langchain_core/indexing/__init__.py +1 -1
  30. langchain_core/indexing/api.py +121 -126
  31. langchain_core/indexing/base.py +73 -75
  32. langchain_core/indexing/in_memory.py +4 -6
  33. langchain_core/language_models/__init__.py +14 -29
  34. langchain_core/language_models/_utils.py +58 -61
  35. langchain_core/language_models/base.py +82 -172
  36. langchain_core/language_models/chat_models.py +329 -402
  37. langchain_core/language_models/fake.py +11 -11
  38. langchain_core/language_models/fake_chat_models.py +42 -36
  39. langchain_core/language_models/llms.py +189 -269
  40. langchain_core/load/dump.py +9 -12
  41. langchain_core/load/load.py +18 -28
  42. langchain_core/load/mapping.py +2 -4
  43. langchain_core/load/serializable.py +42 -40
  44. langchain_core/messages/__init__.py +10 -16
  45. langchain_core/messages/ai.py +148 -148
  46. langchain_core/messages/base.py +53 -51
  47. langchain_core/messages/block_translators/__init__.py +19 -22
  48. langchain_core/messages/block_translators/anthropic.py +6 -6
  49. langchain_core/messages/block_translators/bedrock_converse.py +5 -5
  50. langchain_core/messages/block_translators/google_genai.py +10 -7
  51. langchain_core/messages/block_translators/google_vertexai.py +4 -32
  52. langchain_core/messages/block_translators/groq.py +117 -21
  53. langchain_core/messages/block_translators/langchain_v0.py +5 -5
  54. langchain_core/messages/block_translators/openai.py +11 -11
  55. langchain_core/messages/chat.py +2 -6
  56. langchain_core/messages/content.py +339 -330
  57. langchain_core/messages/function.py +6 -10
  58. langchain_core/messages/human.py +24 -31
  59. langchain_core/messages/modifier.py +2 -2
  60. langchain_core/messages/system.py +19 -29
  61. langchain_core/messages/tool.py +74 -90
  62. langchain_core/messages/utils.py +484 -510
  63. langchain_core/output_parsers/__init__.py +13 -10
  64. langchain_core/output_parsers/base.py +61 -61
  65. langchain_core/output_parsers/format_instructions.py +9 -4
  66. langchain_core/output_parsers/json.py +12 -10
  67. langchain_core/output_parsers/list.py +21 -23
  68. langchain_core/output_parsers/openai_functions.py +49 -47
  69. langchain_core/output_parsers/openai_tools.py +30 -23
  70. langchain_core/output_parsers/pydantic.py +13 -14
  71. langchain_core/output_parsers/string.py +5 -5
  72. langchain_core/output_parsers/transform.py +15 -17
  73. langchain_core/output_parsers/xml.py +35 -34
  74. langchain_core/outputs/__init__.py +1 -1
  75. langchain_core/outputs/chat_generation.py +18 -18
  76. langchain_core/outputs/chat_result.py +1 -3
  77. langchain_core/outputs/generation.py +16 -16
  78. langchain_core/outputs/llm_result.py +10 -10
  79. langchain_core/prompt_values.py +13 -19
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +81 -86
  82. langchain_core/prompts/chat.py +308 -351
  83. langchain_core/prompts/dict.py +6 -6
  84. langchain_core/prompts/few_shot.py +81 -88
  85. langchain_core/prompts/few_shot_with_templates.py +11 -13
  86. langchain_core/prompts/image.py +12 -14
  87. langchain_core/prompts/loading.py +4 -6
  88. langchain_core/prompts/message.py +7 -7
  89. langchain_core/prompts/prompt.py +24 -39
  90. langchain_core/prompts/string.py +26 -10
  91. langchain_core/prompts/structured.py +49 -53
  92. langchain_core/rate_limiters.py +51 -60
  93. langchain_core/retrievers.py +61 -198
  94. langchain_core/runnables/base.py +1551 -1656
  95. langchain_core/runnables/branch.py +68 -70
  96. langchain_core/runnables/config.py +72 -89
  97. langchain_core/runnables/configurable.py +145 -161
  98. langchain_core/runnables/fallbacks.py +102 -96
  99. langchain_core/runnables/graph.py +91 -97
  100. langchain_core/runnables/graph_ascii.py +27 -28
  101. langchain_core/runnables/graph_mermaid.py +42 -51
  102. langchain_core/runnables/graph_png.py +43 -16
  103. langchain_core/runnables/history.py +175 -177
  104. langchain_core/runnables/passthrough.py +151 -167
  105. langchain_core/runnables/retry.py +46 -51
  106. langchain_core/runnables/router.py +30 -35
  107. langchain_core/runnables/schema.py +75 -80
  108. langchain_core/runnables/utils.py +60 -67
  109. langchain_core/stores.py +85 -121
  110. langchain_core/structured_query.py +8 -8
  111. langchain_core/sys_info.py +29 -29
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +306 -245
  114. langchain_core/tools/convert.py +160 -155
  115. langchain_core/tools/render.py +10 -10
  116. langchain_core/tools/retriever.py +12 -11
  117. langchain_core/tools/simple.py +19 -24
  118. langchain_core/tools/structured.py +32 -39
  119. langchain_core/tracers/__init__.py +1 -9
  120. langchain_core/tracers/base.py +97 -99
  121. langchain_core/tracers/context.py +29 -52
  122. langchain_core/tracers/core.py +49 -53
  123. langchain_core/tracers/evaluation.py +11 -11
  124. langchain_core/tracers/event_stream.py +65 -64
  125. langchain_core/tracers/langchain.py +21 -21
  126. langchain_core/tracers/log_stream.py +45 -45
  127. langchain_core/tracers/memory_stream.py +3 -3
  128. langchain_core/tracers/root_listeners.py +16 -16
  129. langchain_core/tracers/run_collector.py +2 -4
  130. langchain_core/tracers/schemas.py +0 -129
  131. langchain_core/tracers/stdout.py +3 -3
  132. langchain_core/utils/__init__.py +1 -4
  133. langchain_core/utils/_merge.py +2 -2
  134. langchain_core/utils/aiter.py +57 -61
  135. langchain_core/utils/env.py +9 -9
  136. langchain_core/utils/function_calling.py +94 -188
  137. langchain_core/utils/html.py +7 -8
  138. langchain_core/utils/input.py +9 -6
  139. langchain_core/utils/interactive_env.py +1 -1
  140. langchain_core/utils/iter.py +36 -40
  141. langchain_core/utils/json.py +4 -3
  142. langchain_core/utils/json_schema.py +9 -9
  143. langchain_core/utils/mustache.py +8 -10
  144. langchain_core/utils/pydantic.py +35 -37
  145. langchain_core/utils/strings.py +6 -9
  146. langchain_core/utils/usage.py +1 -1
  147. langchain_core/utils/utils.py +66 -62
  148. langchain_core/vectorstores/base.py +182 -216
  149. langchain_core/vectorstores/in_memory.py +101 -176
  150. langchain_core/vectorstores/utils.py +5 -5
  151. langchain_core/version.py +1 -1
  152. langchain_core-1.0.4.dist-info/METADATA +69 -0
  153. langchain_core-1.0.4.dist-info/RECORD +172 -0
  154. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.4.dist-info}/WHEEL +1 -1
  155. langchain_core/memory.py +0 -120
  156. langchain_core/messages/block_translators/ollama.py +0 -47
  157. langchain_core/prompts/pipeline.py +0 -138
  158. langchain_core/pydantic_v1/__init__.py +0 -30
  159. langchain_core/pydantic_v1/dataclasses.py +0 -23
  160. langchain_core/pydantic_v1/main.py +0 -23
  161. langchain_core/tracers/langchain_v1.py +0 -31
  162. langchain_core/utils/loading.py +0 -35
  163. langchain_core-1.0.0a6.dist-info/METADATA +0 -67
  164. langchain_core-1.0.0a6.dist-info/RECORD +0 -181
  165. 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
 
@@ -54,10 +51,10 @@ def identity(x: Other) -> Other:
54
51
  """Identity function.
55
52
 
56
53
  Args:
57
- x (Other): input.
54
+ x: Input.
58
55
 
59
56
  Returns:
60
- Other: output.
57
+ Output.
61
58
  """
62
59
  return x
63
60
 
@@ -66,10 +63,10 @@ async def aidentity(x: Other) -> Other:
66
63
  """Async identity function.
67
64
 
68
65
  Args:
69
- x (Other): input.
66
+ x: Input.
70
67
 
71
68
  Returns:
72
- Other: output.
69
+ Output.
73
70
  """
74
71
  return x
75
72
 
@@ -77,78 +74,75 @@ async def aidentity(x: Other) -> Other:
77
74
  class RunnablePassthrough(RunnableSerializable[Other, Other]):
78
75
  """Runnable to passthrough inputs unchanged or with additional keys.
79
76
 
80
- This Runnable behaves almost like the identity function, except that it
77
+ This `Runnable` behaves almost like the identity function, except that it
81
78
  can be configured to add additional keys to the output, if the input is a
82
79
  dict.
83
80
 
84
- The examples below demonstrate this Runnable works using a few simple
81
+ The examples below demonstrate this `Runnable` works using a few simple
85
82
  chains. The chains rely on simple lambdas to make the examples easy to execute
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,26 +152,19 @@ 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
- """Create e RunnablePassthrough.
167
+ """Create a `RunnablePassthrough`.
181
168
 
182
169
  Args:
183
170
  func: Function to be called with the input.
@@ -193,15 +180,15 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
193
180
  @classmethod
194
181
  @override
195
182
  def is_lc_serializable(cls) -> bool:
196
- """Return True as this class is serializable."""
183
+ """Return `True` as this class is serializable."""
197
184
  return True
198
185
 
199
186
  @classmethod
200
187
  def get_lc_namespace(cls) -> list[str]:
201
- """Get the namespace of the langchain object.
188
+ """Get the namespace of the LangChain object.
202
189
 
203
190
  Returns:
204
- ``["langchain", "schema", "runnable"]``
191
+ `["langchain", "schema", "runnable"]`
205
192
  """
206
193
  return ["langchain", "schema", "runnable"]
207
194
 
@@ -219,30 +206,25 @@ 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
 
233
215
  Args:
234
- **kwargs: Runnable, Callable or a Mapping from keys to Runnables
235
- or Callables.
216
+ **kwargs: `Runnable`, `Callable` or a `Mapping` from keys to `Runnable`
217
+ objects or `Callable`s.
236
218
 
237
219
  Returns:
238
- A Runnable that merges the Dict input with the output produced by the
220
+ A `Runnable` that merges the `dict` input with the output produced by the
239
221
  mapping argument.
240
222
  """
241
223
  return RunnableAssign(RunnableParallel[dict[str, Any]](kwargs))
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]:
@@ -368,7 +350,7 @@ _graph_passthrough: RunnablePassthrough = RunnablePassthrough()
368
350
 
369
351
 
370
352
  class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
371
- """Runnable that assigns key-value pairs to dict[str, Any] inputs.
353
+ """Runnable that assigns key-value pairs to `dict[str, Any]` inputs.
372
354
 
373
355
  The `RunnableAssign` class takes input dictionaries and, through a
374
356
  `RunnableParallel` instance, applies transformations, then combines
@@ -376,45 +358,44 @@ 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
412
393
 
413
394
  def __init__(self, mapper: RunnableParallel[dict[str, Any]], **kwargs: Any) -> None:
414
- """Create a RunnableAssign.
395
+ """Create a `RunnableAssign`.
415
396
 
416
397
  Args:
417
- mapper: A ``RunnableParallel`` instance that will be used to transform the
398
+ mapper: A `RunnableParallel` instance that will be used to transform the
418
399
  input dictionary.
419
400
  """
420
401
  super().__init__(mapper=mapper, **kwargs)
@@ -422,23 +403,21 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
422
403
  @classmethod
423
404
  @override
424
405
  def is_lc_serializable(cls) -> bool:
425
- """Return True as this class is serializable."""
406
+ """Return `True` as this class is serializable."""
426
407
  return True
427
408
 
428
409
  @classmethod
429
410
  @override
430
411
  def get_lc_namespace(cls) -> list[str]:
431
- """Get the namespace of the langchain object.
412
+ """Get the namespace of the LangChain object.
432
413
 
433
414
  Returns:
434
- ``["langchain", "schema", "runnable"]``
415
+ `["langchain", "schema", "runnable"]`
435
416
  """
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]]:
@@ -691,38 +668,47 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
691
668
  yield chunk
692
669
 
693
670
 
694
- class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
695
- """Runnable that picks keys from dict[str, Any] inputs.
671
+ class RunnablePick(RunnableSerializable[dict[str, Any], Any]):
672
+ """`Runnable` that picks keys from `dict[str, Any]` inputs.
696
673
 
697
- RunnablePick class represents a Runnable that selectively picks keys from a
674
+ `RunnablePick` class represents a `Runnable` that selectively picks keys from a
698
675
  dictionary input. It allows you to specify one or more keys to extract
699
- from the input dictionary. It returns a new dictionary containing only
700
- the selected keys.
701
-
702
- Example:
703
- .. code-block:: python
676
+ from the input dictionary.
704
677
 
705
- from langchain_core.runnables.passthrough import RunnablePick
678
+ !!! note "Return Type Behavior"
679
+ The return type depends on the `keys` parameter:
706
680
 
707
- input_data = {
708
- "name": "John",
709
- "age": 30,
710
- "city": "New York",
711
- "country": "USA",
712
- }
681
+ - When `keys` is a `str`: Returns the single value associated with that key
682
+ - When `keys` is a `list`: Returns a dictionary containing only the selected
683
+ keys
713
684
 
714
- runnable = RunnablePick(keys=["name", "age"])
715
-
716
- output_data = runnable.invoke(input_data)
685
+ Example:
686
+ ```python
687
+ from langchain_core.runnables.passthrough import RunnablePick
688
+
689
+ input_data = {
690
+ "name": "John",
691
+ "age": 30,
692
+ "city": "New York",
693
+ "country": "USA",
694
+ }
717
695
 
718
- print(output_data) # Output: {'name': 'John', 'age': 30}
696
+ # Single key - returns the value directly
697
+ runnable_single = RunnablePick(keys="name")
698
+ result_single = runnable_single.invoke(input_data)
699
+ print(result_single) # Output: "John"
719
700
 
701
+ # Multiple keys - returns a dictionary
702
+ runnable_multiple = RunnablePick(keys=["name", "age"])
703
+ result_multiple = runnable_multiple.invoke(input_data)
704
+ print(result_multiple) # Output: {'name': 'John', 'age': 30}
705
+ ```
720
706
  """
721
707
 
722
- keys: Union[str, list[str]]
708
+ keys: str | list[str]
723
709
 
724
- def __init__(self, keys: Union[str, list[str]], **kwargs: Any) -> None:
725
- """Create a RunnablePick.
710
+ def __init__(self, keys: str | list[str], **kwargs: Any) -> None:
711
+ """Create a `RunnablePick`.
726
712
 
727
713
  Args:
728
714
  keys: A single key or a list of keys to pick from the input dictionary.
@@ -732,23 +718,21 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
732
718
  @classmethod
733
719
  @override
734
720
  def is_lc_serializable(cls) -> bool:
735
- """Return True as this class is serializable."""
721
+ """Return `True` as this class is serializable."""
736
722
  return True
737
723
 
738
724
  @classmethod
739
725
  @override
740
726
  def get_lc_namespace(cls) -> list[str]:
741
- """Get the namespace of the langchain object.
727
+ """Get the namespace of the LangChain object.
742
728
 
743
729
  Returns:
744
- ``["langchain", "schema", "runnable"]``
730
+ `["langchain", "schema", "runnable"]`
745
731
  """
746
732
  return ["langchain", "schema", "runnable"]
747
733
 
748
734
  @override
749
- def get_name(
750
- self, suffix: Optional[str] = None, *, name: Optional[str] = None
751
- ) -> str:
735
+ def get_name(self, suffix: str | None = None, *, name: str | None = None) -> str:
752
736
  name = (
753
737
  name
754
738
  or self.name
@@ -779,7 +763,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
779
763
  def invoke(
780
764
  self,
781
765
  input: dict[str, Any],
782
- config: Optional[RunnableConfig] = None,
766
+ config: RunnableConfig | None = None,
783
767
  **kwargs: Any,
784
768
  ) -> dict[str, Any]:
785
769
  return self._call_with_config(self._invoke, input, config, **kwargs)
@@ -794,7 +778,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
794
778
  async def ainvoke(
795
779
  self,
796
780
  input: dict[str, Any],
797
- config: Optional[RunnableConfig] = None,
781
+ config: RunnableConfig | None = None,
798
782
  **kwargs: Any,
799
783
  ) -> dict[str, Any]:
800
784
  return await self._acall_with_config(self._ainvoke, input, config, **kwargs)
@@ -812,7 +796,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
812
796
  def transform(
813
797
  self,
814
798
  input: Iterator[dict[str, Any]],
815
- config: Optional[RunnableConfig] = None,
799
+ config: RunnableConfig | None = None,
816
800
  **kwargs: Any,
817
801
  ) -> Iterator[dict[str, Any]]:
818
802
  yield from self._transform_stream_with_config(
@@ -832,7 +816,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
832
816
  async def atransform(
833
817
  self,
834
818
  input: AsyncIterator[dict[str, Any]],
835
- config: Optional[RunnableConfig] = None,
819
+ config: RunnableConfig | None = None,
836
820
  **kwargs: Any,
837
821
  ) -> AsyncIterator[dict[str, Any]]:
838
822
  async for chunk in self._atransform_stream_with_config(
@@ -844,7 +828,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
844
828
  def stream(
845
829
  self,
846
830
  input: dict[str, Any],
847
- config: Optional[RunnableConfig] = None,
831
+ config: RunnableConfig | None = None,
848
832
  **kwargs: Any,
849
833
  ) -> Iterator[dict[str, Any]]:
850
834
  return self.transform(iter([input]), config, **kwargs)
@@ -853,7 +837,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
853
837
  async def astream(
854
838
  self,
855
839
  input: dict[str, Any],
856
- config: Optional[RunnableConfig] = None,
840
+ config: RunnableConfig | None = None,
857
841
  **kwargs: Any,
858
842
  ) -> AsyncIterator[dict[str, Any]]:
859
843
  async def input_aiter() -> AsyncIterator[dict[str, Any]]: