langchain-core 1.0.0a2__py3-none-any.whl → 1.0.0a4__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 (130) hide show
  1. langchain_core/_api/beta_decorator.py +17 -40
  2. langchain_core/_api/deprecation.py +20 -7
  3. langchain_core/_api/path.py +19 -2
  4. langchain_core/_import_utils.py +7 -0
  5. langchain_core/agents.py +10 -6
  6. langchain_core/callbacks/base.py +28 -15
  7. langchain_core/callbacks/manager.py +81 -69
  8. langchain_core/callbacks/usage.py +4 -2
  9. langchain_core/chat_history.py +29 -21
  10. langchain_core/document_loaders/base.py +34 -9
  11. langchain_core/document_loaders/langsmith.py +3 -0
  12. langchain_core/documents/base.py +35 -10
  13. langchain_core/documents/transformers.py +4 -2
  14. langchain_core/embeddings/fake.py +8 -5
  15. langchain_core/env.py +2 -3
  16. langchain_core/example_selectors/base.py +12 -0
  17. langchain_core/exceptions.py +7 -0
  18. langchain_core/globals.py +17 -28
  19. langchain_core/indexing/api.py +57 -45
  20. langchain_core/indexing/base.py +5 -8
  21. langchain_core/indexing/in_memory.py +23 -3
  22. langchain_core/language_models/__init__.py +6 -2
  23. langchain_core/language_models/_utils.py +27 -5
  24. langchain_core/language_models/base.py +33 -21
  25. langchain_core/language_models/chat_models.py +104 -31
  26. langchain_core/language_models/fake_chat_models.py +5 -7
  27. langchain_core/language_models/llms.py +54 -20
  28. langchain_core/load/dump.py +2 -3
  29. langchain_core/load/load.py +15 -1
  30. langchain_core/load/serializable.py +38 -43
  31. langchain_core/memory.py +7 -3
  32. langchain_core/messages/__init__.py +1 -1
  33. langchain_core/messages/ai.py +41 -34
  34. langchain_core/messages/base.py +20 -7
  35. langchain_core/messages/block_translators/__init__.py +10 -8
  36. langchain_core/messages/block_translators/anthropic.py +11 -7
  37. langchain_core/messages/block_translators/bedrock.py +76 -27
  38. langchain_core/messages/block_translators/bedrock_converse.py +259 -23
  39. langchain_core/messages/block_translators/google_genai.py +3 -1
  40. langchain_core/messages/block_translators/google_vertexai.py +3 -1
  41. langchain_core/messages/block_translators/groq.py +3 -1
  42. langchain_core/messages/block_translators/ollama.py +3 -1
  43. langchain_core/messages/block_translators/openai.py +50 -20
  44. langchain_core/messages/content.py +23 -13
  45. langchain_core/messages/human.py +2 -13
  46. langchain_core/messages/system.py +2 -6
  47. langchain_core/messages/tool.py +34 -14
  48. langchain_core/messages/utils.py +186 -73
  49. langchain_core/output_parsers/base.py +5 -2
  50. langchain_core/output_parsers/json.py +4 -4
  51. langchain_core/output_parsers/list.py +7 -22
  52. langchain_core/output_parsers/openai_functions.py +3 -0
  53. langchain_core/output_parsers/openai_tools.py +6 -1
  54. langchain_core/output_parsers/pydantic.py +4 -0
  55. langchain_core/output_parsers/string.py +5 -1
  56. langchain_core/output_parsers/xml.py +19 -19
  57. langchain_core/outputs/chat_generation.py +18 -7
  58. langchain_core/outputs/generation.py +14 -3
  59. langchain_core/outputs/llm_result.py +8 -1
  60. langchain_core/prompt_values.py +10 -4
  61. langchain_core/prompts/base.py +6 -11
  62. langchain_core/prompts/chat.py +88 -60
  63. langchain_core/prompts/dict.py +16 -8
  64. langchain_core/prompts/few_shot.py +9 -11
  65. langchain_core/prompts/few_shot_with_templates.py +5 -1
  66. langchain_core/prompts/image.py +12 -5
  67. langchain_core/prompts/loading.py +2 -2
  68. langchain_core/prompts/message.py +5 -6
  69. langchain_core/prompts/pipeline.py +13 -8
  70. langchain_core/prompts/prompt.py +22 -8
  71. langchain_core/prompts/string.py +18 -10
  72. langchain_core/prompts/structured.py +7 -2
  73. langchain_core/rate_limiters.py +2 -2
  74. langchain_core/retrievers.py +7 -6
  75. langchain_core/runnables/base.py +387 -246
  76. langchain_core/runnables/branch.py +11 -28
  77. langchain_core/runnables/config.py +20 -17
  78. langchain_core/runnables/configurable.py +34 -19
  79. langchain_core/runnables/fallbacks.py +20 -13
  80. langchain_core/runnables/graph.py +48 -38
  81. langchain_core/runnables/graph_ascii.py +40 -17
  82. langchain_core/runnables/graph_mermaid.py +54 -25
  83. langchain_core/runnables/graph_png.py +27 -31
  84. langchain_core/runnables/history.py +55 -58
  85. langchain_core/runnables/passthrough.py +44 -21
  86. langchain_core/runnables/retry.py +44 -23
  87. langchain_core/runnables/router.py +9 -8
  88. langchain_core/runnables/schema.py +9 -0
  89. langchain_core/runnables/utils.py +53 -90
  90. langchain_core/stores.py +19 -31
  91. langchain_core/sys_info.py +9 -8
  92. langchain_core/tools/base.py +36 -27
  93. langchain_core/tools/convert.py +25 -14
  94. langchain_core/tools/simple.py +36 -8
  95. langchain_core/tools/structured.py +25 -12
  96. langchain_core/tracers/base.py +2 -2
  97. langchain_core/tracers/context.py +5 -1
  98. langchain_core/tracers/core.py +110 -46
  99. langchain_core/tracers/evaluation.py +22 -26
  100. langchain_core/tracers/event_stream.py +97 -42
  101. langchain_core/tracers/langchain.py +12 -3
  102. langchain_core/tracers/langchain_v1.py +10 -2
  103. langchain_core/tracers/log_stream.py +56 -17
  104. langchain_core/tracers/root_listeners.py +4 -20
  105. langchain_core/tracers/run_collector.py +6 -16
  106. langchain_core/tracers/schemas.py +5 -1
  107. langchain_core/utils/aiter.py +14 -6
  108. langchain_core/utils/env.py +3 -0
  109. langchain_core/utils/function_calling.py +46 -20
  110. langchain_core/utils/interactive_env.py +6 -2
  111. langchain_core/utils/iter.py +12 -5
  112. langchain_core/utils/json.py +12 -3
  113. langchain_core/utils/json_schema.py +156 -40
  114. langchain_core/utils/loading.py +5 -1
  115. langchain_core/utils/mustache.py +25 -16
  116. langchain_core/utils/pydantic.py +38 -9
  117. langchain_core/utils/utils.py +25 -9
  118. langchain_core/vectorstores/base.py +7 -20
  119. langchain_core/vectorstores/in_memory.py +20 -14
  120. langchain_core/vectorstores/utils.py +18 -12
  121. langchain_core/version.py +1 -1
  122. langchain_core-1.0.0a4.dist-info/METADATA +77 -0
  123. langchain_core-1.0.0a4.dist-info/RECORD +181 -0
  124. langchain_core/beta/__init__.py +0 -1
  125. langchain_core/beta/runnables/__init__.py +0 -1
  126. langchain_core/beta/runnables/context.py +0 -448
  127. langchain_core-1.0.0a2.dist-info/METADATA +0 -106
  128. langchain_core-1.0.0a2.dist-info/RECORD +0 -184
  129. {langchain_core-1.0.0a2.dist-info → langchain_core-1.0.0a4.dist-info}/WHEEL +0 -0
  130. {langchain_core-1.0.0a2.dist-info → langchain_core-1.0.0a4.dist-info}/entry_points.txt +0 -0
@@ -18,11 +18,12 @@ from typing import (
18
18
  NamedTuple,
19
19
  Optional,
20
20
  Protocol,
21
+ TypeGuard,
21
22
  TypeVar,
22
23
  Union,
23
24
  )
24
25
 
25
- from typing_extensions import TypeGuard, override
26
+ from typing_extensions import override
26
27
 
27
28
  # Re-export create-model for backwards compatibility
28
29
  from langchain_core.utils.pydantic import create_model # noqa: F401
@@ -122,7 +123,12 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
122
123
 
123
124
  @lru_cache(maxsize=1)
124
125
  def asyncio_accepts_context() -> bool:
125
- """Cache the result of checking if asyncio.create_task accepts a ``context`` arg."""
126
+ """Cache the result of checking if asyncio.create_task accepts a ``context`` arg.
127
+
128
+ Returns:
129
+ bool: True if ``asyncio.create_task`` accepts a context argument, False
130
+ otherwise.
131
+ """
126
132
  return accepts_context(asyncio.create_task)
127
133
 
128
134
 
@@ -160,14 +166,11 @@ class IsLocalDict(ast.NodeVisitor):
160
166
  self.keys = keys
161
167
 
162
168
  @override
163
- def visit_Subscript(self, node: ast.Subscript) -> Any:
169
+ def visit_Subscript(self, node: ast.Subscript) -> None:
164
170
  """Visit a subscript node.
165
171
 
166
172
  Args:
167
173
  node: The node to visit.
168
-
169
- Returns:
170
- Any: The result of the visit.
171
174
  """
172
175
  if (
173
176
  isinstance(node.ctx, ast.Load)
@@ -180,14 +183,11 @@ class IsLocalDict(ast.NodeVisitor):
180
183
  self.keys.add(node.slice.value)
181
184
 
182
185
  @override
183
- def visit_Call(self, node: ast.Call) -> Any:
186
+ def visit_Call(self, node: ast.Call) -> None:
184
187
  """Visit a call node.
185
188
 
186
189
  Args:
187
190
  node: The node to visit.
188
-
189
- Returns:
190
- Any: The result of the visit.
191
191
  """
192
192
  if (
193
193
  isinstance(node.func, ast.Attribute)
@@ -210,14 +210,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
210
210
  self.keys: set[str] = set()
211
211
 
212
212
  @override
213
- def visit_Lambda(self, node: ast.Lambda) -> Any:
213
+ def visit_Lambda(self, node: ast.Lambda) -> None:
214
214
  """Visit a lambda function.
215
215
 
216
216
  Args:
217
217
  node: The node to visit.
218
-
219
- Returns:
220
- Any: The result of the visit.
221
218
  """
222
219
  if not node.args.args:
223
220
  return
@@ -225,14 +222,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
225
222
  IsLocalDict(input_arg_name, self.keys).visit(node.body)
226
223
 
227
224
  @override
228
- def visit_FunctionDef(self, node: ast.FunctionDef) -> Any:
225
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
229
226
  """Visit a function definition.
230
227
 
231
228
  Args:
232
229
  node: The node to visit.
233
-
234
- Returns:
235
- Any: The result of the visit.
236
230
  """
237
231
  if not node.args.args:
238
232
  return
@@ -240,14 +234,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
240
234
  IsLocalDict(input_arg_name, self.keys).visit(node)
241
235
 
242
236
  @override
243
- def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> Any:
237
+ def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
244
238
  """Visit an async function definition.
245
239
 
246
240
  Args:
247
241
  node: The node to visit.
248
-
249
- Returns:
250
- Any: The result of the visit.
251
242
  """
252
243
  if not node.args.args:
253
244
  return
@@ -264,14 +255,11 @@ class NonLocals(ast.NodeVisitor):
264
255
  self.stores: set[str] = set()
265
256
 
266
257
  @override
267
- def visit_Name(self, node: ast.Name) -> Any:
258
+ def visit_Name(self, node: ast.Name) -> None:
268
259
  """Visit a name node.
269
260
 
270
261
  Args:
271
262
  node: The node to visit.
272
-
273
- Returns:
274
- Any: The result of the visit.
275
263
  """
276
264
  if isinstance(node.ctx, ast.Load):
277
265
  self.loads.add(node.id)
@@ -279,14 +267,11 @@ class NonLocals(ast.NodeVisitor):
279
267
  self.stores.add(node.id)
280
268
 
281
269
  @override
282
- def visit_Attribute(self, node: ast.Attribute) -> Any:
270
+ def visit_Attribute(self, node: ast.Attribute) -> None:
283
271
  """Visit an attribute node.
284
272
 
285
273
  Args:
286
274
  node: The node to visit.
287
-
288
- Returns:
289
- Any: The result of the visit.
290
275
  """
291
276
  if isinstance(node.ctx, ast.Load):
292
277
  parent = node.value
@@ -321,42 +306,33 @@ class FunctionNonLocals(ast.NodeVisitor):
321
306
  self.nonlocals: set[str] = set()
322
307
 
323
308
  @override
324
- def visit_FunctionDef(self, node: ast.FunctionDef) -> Any:
309
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
325
310
  """Visit a function definition.
326
311
 
327
312
  Args:
328
313
  node: The node to visit.
329
-
330
- Returns:
331
- Any: The result of the visit.
332
314
  """
333
315
  visitor = NonLocals()
334
316
  visitor.visit(node)
335
317
  self.nonlocals.update(visitor.loads - visitor.stores)
336
318
 
337
319
  @override
338
- def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> Any:
320
+ def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
339
321
  """Visit an async function definition.
340
322
 
341
323
  Args:
342
324
  node: The node to visit.
343
-
344
- Returns:
345
- Any: The result of the visit.
346
325
  """
347
326
  visitor = NonLocals()
348
327
  visitor.visit(node)
349
328
  self.nonlocals.update(visitor.loads - visitor.stores)
350
329
 
351
330
  @override
352
- def visit_Lambda(self, node: ast.Lambda) -> Any:
331
+ def visit_Lambda(self, node: ast.Lambda) -> None:
353
332
  """Visit a lambda function.
354
333
 
355
334
  Args:
356
335
  node: The node to visit.
357
-
358
- Returns:
359
- Any: The result of the visit.
360
336
  """
361
337
  visitor = NonLocals()
362
338
  visitor.visit(node)
@@ -372,14 +348,11 @@ class GetLambdaSource(ast.NodeVisitor):
372
348
  self.count = 0
373
349
 
374
350
  @override
375
- def visit_Lambda(self, node: ast.Lambda) -> Any:
351
+ def visit_Lambda(self, node: ast.Lambda) -> None:
376
352
  """Visit a lambda function.
377
353
 
378
354
  Args:
379
355
  node: The node to visit.
380
-
381
- Returns:
382
- Any: The result of the visit.
383
356
  """
384
357
  self.count += 1
385
358
  if hasattr(ast, "unparse"):
@@ -496,6 +469,9 @@ class AddableDict(dict[str, Any]):
496
469
 
497
470
  Args:
498
471
  other: The other dictionary to add.
472
+
473
+ Returns:
474
+ A dictionary that is the result of adding the two dictionaries.
499
475
  """
500
476
  chunk = AddableDict(self)
501
477
  for key in other:
@@ -514,6 +490,9 @@ class AddableDict(dict[str, Any]):
514
490
 
515
491
  Args:
516
492
  other: The other dictionary to be added to.
493
+
494
+ Returns:
495
+ A dictionary that is the result of adding the two dictionaries.
517
496
  """
518
497
  chunk = AddableDict(other)
519
498
  for key in self:
@@ -573,22 +552,18 @@ async def aadd(addables: AsyncIterable[Addable]) -> Optional[Addable]:
573
552
 
574
553
 
575
554
  class ConfigurableField(NamedTuple):
576
- """Field that can be configured by the user.
577
-
578
- Parameters:
579
- id: The unique identifier of the field.
580
- name: The name of the field. Defaults to None.
581
- description: The description of the field. Defaults to None.
582
- annotation: The annotation of the field. Defaults to None.
583
- is_shared: Whether the field is shared. Defaults to False.
584
- """
555
+ """Field that can be configured by the user."""
585
556
 
586
557
  id: str
587
-
558
+ """The unique identifier of the field."""
588
559
  name: Optional[str] = None
560
+ """The name of the field. Defaults to None."""
589
561
  description: Optional[str] = None
562
+ """The description of the field. Defaults to None."""
590
563
  annotation: Optional[Any] = None
564
+ """The annotation of the field. Defaults to None."""
591
565
  is_shared: bool = False
566
+ """Whether the field is shared. Defaults to False."""
592
567
 
593
568
  @override
594
569
  def __hash__(self) -> int:
@@ -596,24 +571,20 @@ class ConfigurableField(NamedTuple):
596
571
 
597
572
 
598
573
  class ConfigurableFieldSingleOption(NamedTuple):
599
- """Field that can be configured by the user with a default value.
600
-
601
- Parameters:
602
- id: The unique identifier of the field.
603
- options: The options for the field.
604
- default: The default value for the field.
605
- name: The name of the field. Defaults to None.
606
- description: The description of the field. Defaults to None.
607
- is_shared: Whether the field is shared. Defaults to False.
608
- """
574
+ """Field that can be configured by the user with a default value."""
609
575
 
610
576
  id: str
577
+ """The unique identifier of the field."""
611
578
  options: Mapping[str, Any]
579
+ """The options for the field."""
612
580
  default: str
613
-
581
+ """The default value for the field."""
614
582
  name: Optional[str] = None
583
+ """The name of the field. Defaults to None."""
615
584
  description: Optional[str] = None
585
+ """The description of the field. Defaults to None."""
616
586
  is_shared: bool = False
587
+ """Whether the field is shared. Defaults to False."""
617
588
 
618
589
  @override
619
590
  def __hash__(self) -> int:
@@ -621,24 +592,20 @@ class ConfigurableFieldSingleOption(NamedTuple):
621
592
 
622
593
 
623
594
  class ConfigurableFieldMultiOption(NamedTuple):
624
- """Field that can be configured by the user with multiple default values.
625
-
626
- Parameters:
627
- id: The unique identifier of the field.
628
- options: The options for the field.
629
- default: The default values for the field.
630
- name: The name of the field. Defaults to None.
631
- description: The description of the field. Defaults to None.
632
- is_shared: Whether the field is shared. Defaults to False.
633
- """
595
+ """Field that can be configured by the user with multiple default values."""
634
596
 
635
597
  id: str
598
+ """The unique identifier of the field."""
636
599
  options: Mapping[str, Any]
600
+ """The options for the field."""
637
601
  default: Sequence[str]
638
-
602
+ """The default values for the field."""
639
603
  name: Optional[str] = None
604
+ """The name of the field. Defaults to None."""
640
605
  description: Optional[str] = None
606
+ """The description of the field. Defaults to None."""
641
607
  is_shared: bool = False
608
+ """Whether the field is shared. Defaults to False."""
642
609
 
643
610
  @override
644
611
  def __hash__(self) -> int:
@@ -651,26 +618,22 @@ AnyConfigurableField = Union[
651
618
 
652
619
 
653
620
  class ConfigurableFieldSpec(NamedTuple):
654
- """Field that can be configured by the user. It is a specification of a field.
655
-
656
- Parameters:
657
- id: The unique identifier of the field.
658
- annotation: The annotation of the field.
659
- name: The name of the field. Defaults to None.
660
- description: The description of the field. Defaults to None.
661
- default: The default value for the field. Defaults to None.
662
- is_shared: Whether the field is shared. Defaults to False.
663
- dependencies: The dependencies of the field. Defaults to None.
664
- """
621
+ """Field that can be configured by the user. It is a specification of a field."""
665
622
 
666
623
  id: str
624
+ """The unique identifier of the field."""
667
625
  annotation: Any
668
-
626
+ """The annotation of the field."""
669
627
  name: Optional[str] = None
628
+ """The name of the field. Defaults to None."""
670
629
  description: Optional[str] = None
630
+ """The description of the field. Defaults to None."""
671
631
  default: Any = None
632
+ """The default value for the field. Defaults to None."""
672
633
  is_shared: bool = False
634
+ """Whether the field is shared. Defaults to False."""
673
635
  dependencies: Optional[list[str]] = None
636
+ """The dependencies of the field. Defaults to None."""
674
637
 
675
638
 
676
639
  def get_unique_config_specs(
langchain_core/stores.py CHANGED
@@ -16,6 +16,8 @@ from typing import (
16
16
  Union,
17
17
  )
18
18
 
19
+ from typing_extensions import override
20
+
19
21
  from langchain_core.exceptions import LangChainException
20
22
  from langchain_core.runnables import run_in_executor
21
23
 
@@ -52,24 +54,24 @@ class BaseStore(ABC, Generic[K, V]):
52
54
 
53
55
  from langchain.storage import BaseStore
54
56
 
55
- class MyInMemoryStore(BaseStore[str, int]):
56
57
 
57
- def __init__(self):
58
- self.store = {}
58
+ class MyInMemoryStore(BaseStore[str, int]):
59
+ def __init__(self) -> None:
60
+ self.store: dict[str, int] = {}
59
61
 
60
- def mget(self, keys):
62
+ def mget(self, keys: Sequence[str]) -> list[int | None]:
61
63
  return [self.store.get(key) for key in keys]
62
64
 
63
- def mset(self, key_value_pairs):
65
+ def mset(self, key_value_pairs: Sequence[tuple[str, int]]) -> None:
64
66
  for key, value in key_value_pairs:
65
67
  self.store[key] = value
66
68
 
67
- def mdelete(self, keys):
69
+ def mdelete(self, keys: Sequence[str]) -> None:
68
70
  for key in keys:
69
71
  if key in self.store:
70
72
  del self.store[key]
71
73
 
72
- def yield_keys(self, prefix=None):
74
+ def yield_keys(self, prefix: str | None = None) -> Iterator[str]:
73
75
  if prefix is None:
74
76
  yield from self.store.keys()
75
77
  else:
@@ -206,27 +208,13 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
206
208
  """
207
209
  return self.mget(keys)
208
210
 
211
+ @override
209
212
  def mset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None:
210
- """Set the values for the given keys.
211
-
212
- Args:
213
- key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs.
214
-
215
- Returns:
216
- None
217
- """
218
213
  for key, value in key_value_pairs:
219
214
  self.store[key] = value
220
215
 
216
+ @override
221
217
  async def amset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None:
222
- """Async set the values for the given keys.
223
-
224
- Args:
225
- key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs.
226
-
227
- Returns:
228
- None
229
- """
230
218
  return self.mset(key_value_pairs)
231
219
 
232
220
  def mdelete(self, keys: Sequence[str]) -> None:
@@ -295,13 +283,13 @@ class InMemoryStore(InMemoryBaseStore[Any]):
295
283
  from langchain.storage import InMemoryStore
296
284
 
297
285
  store = InMemoryStore()
298
- store.mset([('key1', 'value1'), ('key2', 'value2')])
299
- store.mget(['key1', 'key2'])
286
+ store.mset([("key1", "value1"), ("key2", "value2")])
287
+ store.mget(["key1", "key2"])
300
288
  # ['value1', 'value2']
301
- store.mdelete(['key1'])
289
+ store.mdelete(["key1"])
302
290
  list(store.yield_keys())
303
291
  # ['key2']
304
- list(store.yield_keys(prefix='k'))
292
+ list(store.yield_keys(prefix="k"))
305
293
  # ['key2']
306
294
 
307
295
  """
@@ -321,13 +309,13 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]):
321
309
  from langchain.storage import InMemoryByteStore
322
310
 
323
311
  store = InMemoryByteStore()
324
- store.mset([('key1', b'value1'), ('key2', b'value2')])
325
- store.mget(['key1', 'key2'])
312
+ store.mset([("key1", b"value1"), ("key2", b"value2")])
313
+ store.mget(["key1", "key2"])
326
314
  # [b'value1', b'value2']
327
- store.mdelete(['key1'])
315
+ store.mdelete(["key1"])
328
316
  list(store.yield_keys())
329
317
  # ['key2']
330
- list(store.yield_keys(prefix='k'))
318
+ list(store.yield_keys(prefix="k"))
331
319
  # ['key2']
332
320
 
333
321
  """
@@ -1,12 +1,18 @@
1
- """**sys_info** prints information about the system and langchain packages for debugging purposes.""" # noqa: E501
1
+ """**sys_info** implementation.
2
2
 
3
+ sys_info prints information about the system and langchain packages for
4
+ debugging purposes.
5
+ """
6
+
7
+ import pkgutil
8
+ import platform
9
+ import sys
3
10
  from collections.abc import Sequence
11
+ from importlib import metadata, util
4
12
 
5
13
 
6
14
  def _get_sub_deps(packages: Sequence[str]) -> list[str]:
7
15
  """Get any specified sub-dependencies."""
8
- from importlib import metadata
9
-
10
16
  sub_deps = set()
11
17
  underscored_packages = {pkg.replace("-", "_") for pkg in packages}
12
18
 
@@ -33,11 +39,6 @@ def print_sys_info(*, additional_pkgs: Sequence[str] = ()) -> None:
33
39
  Args:
34
40
  additional_pkgs: Additional packages to include in the output.
35
41
  """
36
- import pkgutil
37
- import platform
38
- import sys
39
- from importlib import metadata, util
40
-
41
42
  # Packages that do not start with "langchain" prefix.
42
43
  other_langchain_packages = [
43
44
  "langserve",
@@ -81,6 +81,7 @@ TOOL_MESSAGE_BLOCK_TYPES = (
81
81
  "json",
82
82
  "search_result",
83
83
  "custom_tool_call_output",
84
+ "document",
84
85
  )
85
86
 
86
87
 
@@ -271,15 +272,12 @@ def _function_annotations_are_pydantic_v1(
271
272
 
272
273
 
273
274
  class _SchemaConfig:
274
- """Configuration for Pydantic models generated from function signatures.
275
-
276
- Attributes:
277
- extra: Whether to allow extra fields in the model.
278
- arbitrary_types_allowed: Whether to allow arbitrary types in the model.
279
- """
275
+ """Configuration for Pydantic models generated from function signatures."""
280
276
 
281
277
  extra: str = "forbid"
278
+ """Whether to allow extra fields in the model."""
282
279
  arbitrary_types_allowed: bool = True
280
+ """Whether to allow arbitrary types in the model."""
283
281
 
284
282
 
285
283
  def create_schema_from_function(
@@ -506,7 +504,12 @@ class ChildTool(BaseTool):
506
504
  """
507
505
 
508
506
  def __init__(self, **kwargs: Any) -> None:
509
- """Initialize the tool."""
507
+ """Initialize the tool.
508
+
509
+ Raises:
510
+ TypeError: If ``args_schema`` is not a subclass of pydantic ``BaseModel`` or
511
+ dict.
512
+ """
510
513
  if (
511
514
  "args_schema" in kwargs
512
515
  and kwargs["args_schema"] is not None
@@ -543,6 +546,8 @@ class ChildTool(BaseTool):
543
546
  """
544
547
  if isinstance(self.args_schema, dict):
545
548
  json_schema = self.args_schema
549
+ elif self.args_schema and issubclass(self.args_schema, BaseModelV1):
550
+ json_schema = self.args_schema.schema()
546
551
  else:
547
552
  input_schema = self.get_input_schema()
548
553
  json_schema = input_schema.model_json_schema()
@@ -628,9 +633,10 @@ class ChildTool(BaseTool):
628
633
  The parsed and validated input.
629
634
 
630
635
  Raises:
631
- ValueError: If string input is provided with JSON schema or if
632
- InjectedToolCallId is required but not provided.
633
- NotImplementedError: If args_schema is not a supported type.
636
+ ValueError: If string input is provided with JSON schema ``args_schema``.
637
+ ValueError: If InjectedToolCallId is required but ``tool_call_id`` is not
638
+ provided.
639
+ TypeError: If args_schema is not a Pydantic ``BaseModel`` or dict.
634
640
  """
635
641
  input_args = self.args_schema
636
642
  if isinstance(tool_input, str):
@@ -655,10 +661,7 @@ class ChildTool(BaseTool):
655
661
  return tool_input
656
662
  if issubclass(input_args, BaseModel):
657
663
  for k, v in get_all_basemodel_annotations(input_args).items():
658
- if (
659
- _is_injected_arg_type(v, injected_type=InjectedToolCallId)
660
- and k not in tool_input
661
- ):
664
+ if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
662
665
  if tool_call_id is None:
663
666
  msg = (
664
667
  "When tool includes an InjectedToolCallId "
@@ -673,10 +676,7 @@ class ChildTool(BaseTool):
673
676
  result_dict = result.model_dump()
674
677
  elif issubclass(input_args, BaseModelV1):
675
678
  for k, v in get_all_basemodel_annotations(input_args).items():
676
- if (
677
- _is_injected_arg_type(v, injected_type=InjectedToolCallId)
678
- and k not in tool_input
679
- ):
679
+ if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
680
680
  if tool_call_id is None:
681
681
  msg = (
682
682
  "When tool includes an InjectedToolCallId "
@@ -725,6 +725,9 @@ class ChildTool(BaseTool):
725
725
 
726
726
  Add run_manager: Optional[CallbackManagerForToolRun] = None
727
727
  to child implementations to enable tracing.
728
+
729
+ Returns:
730
+ The result of the tool execution.
728
731
  """
729
732
 
730
733
  async def _arun(self, *args: Any, **kwargs: Any) -> Any:
@@ -732,6 +735,9 @@ class ChildTool(BaseTool):
732
735
 
733
736
  Add run_manager: Optional[AsyncCallbackManagerForToolRun] = None
734
737
  to child implementations to enable tracing.
738
+
739
+ Returns:
740
+ The result of the tool execution.
735
741
  """
736
742
  if kwargs.get("run_manager") and signature(self._run).parameters.get(
737
743
  "run_manager"
@@ -1265,7 +1271,7 @@ class InjectedToolCallId(InjectedToolArg):
1265
1271
 
1266
1272
  .. code-block:: python
1267
1273
 
1268
- from typing_extensions import Annotated
1274
+ from typing import Annotated
1269
1275
  from langchain_core.messages import ToolMessage
1270
1276
  from langchain_core.tools import tool, InjectedToolCallId
1271
1277
 
@@ -1285,7 +1291,7 @@ class InjectedToolCallId(InjectedToolArg):
1285
1291
 
1286
1292
 
1287
1293
  def _is_injected_arg_type(
1288
- type_: type, injected_type: Optional[type[InjectedToolArg]] = None
1294
+ type_: Union[type, TypeVar], injected_type: Optional[type[InjectedToolArg]] = None
1289
1295
  ) -> bool:
1290
1296
  """Check if a type annotation indicates an injected argument.
1291
1297
 
@@ -1306,20 +1312,23 @@ def _is_injected_arg_type(
1306
1312
 
1307
1313
  def get_all_basemodel_annotations(
1308
1314
  cls: Union[TypeBaseModel, Any], *, default_to_bound: bool = True
1309
- ) -> dict[str, type]:
1315
+ ) -> dict[str, Union[type, TypeVar]]:
1310
1316
  """Get all annotations from a Pydantic BaseModel and its parents.
1311
1317
 
1312
1318
  Args:
1313
1319
  cls: The Pydantic BaseModel class.
1314
1320
  default_to_bound: Whether to default to the bound of a TypeVar if it exists.
1321
+
1322
+ Returns:
1323
+ A dictionary of field names to their type annotations.
1315
1324
  """
1316
1325
  # cls has no subscript: cls = FooBar
1317
1326
  if isinstance(cls, type):
1318
1327
  # Gather pydantic field objects (v2: model_fields / v1: __fields__)
1319
- fields = getattr(cls, "model_fields", {}) or getattr(cls, "__fields__", {})
1328
+ fields = get_fields(cls)
1320
1329
  alias_map = {field.alias: name for name, field in fields.items() if field.alias}
1321
1330
 
1322
- annotations: dict[str, type] = {}
1331
+ annotations: dict[str, Union[type, TypeVar]] = {}
1323
1332
  for name, param in inspect.signature(cls).parameters.items():
1324
1333
  # Exclude hidden init args added by pydantic Config. For example if
1325
1334
  # BaseModel(extra="allow") then "extra_data" will part of init sig.
@@ -1355,8 +1364,8 @@ def get_all_basemodel_annotations(
1355
1364
  continue
1356
1365
 
1357
1366
  # if class = FooBar inherits from Baz[str]:
1358
- # parent = Baz[str],
1359
- # parent_origin = Baz,
1367
+ # parent = class Baz[str],
1368
+ # parent_origin = class Baz,
1360
1369
  # generic_type_vars = (type vars in Baz)
1361
1370
  # generic_map = {type var in Baz: str}
1362
1371
  generic_type_vars: tuple = getattr(parent_origin, "__parameters__", ())
@@ -1373,11 +1382,11 @@ def get_all_basemodel_annotations(
1373
1382
 
1374
1383
 
1375
1384
  def _replace_type_vars(
1376
- type_: type,
1385
+ type_: Union[type, TypeVar],
1377
1386
  generic_map: Optional[dict[TypeVar, type]] = None,
1378
1387
  *,
1379
1388
  default_to_bound: bool = True,
1380
- ) -> type:
1389
+ ) -> Union[type, TypeVar]:
1381
1390
  """Replace TypeVars in a type annotation with concrete types.
1382
1391
 
1383
1392
  Args: