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
@@ -8,16 +8,14 @@ import json
8
8
  import typing
9
9
  import warnings
10
10
  from abc import ABC, abstractmethod
11
+ from collections.abc import Callable
11
12
  from inspect import signature
12
13
  from typing import (
13
14
  TYPE_CHECKING,
14
15
  Annotated,
15
16
  Any,
16
- Callable,
17
17
  Literal,
18
- Optional,
19
18
  TypeVar,
20
- Union,
21
19
  cast,
22
20
  get_args,
23
21
  get_origin,
@@ -31,7 +29,6 @@ from pydantic import (
31
29
  PydanticDeprecationWarning,
32
30
  SkipValidation,
33
31
  ValidationError,
34
- model_validator,
35
32
  validate_arguments,
36
33
  )
37
34
  from pydantic.v1 import BaseModel as BaseModelV1
@@ -39,10 +36,8 @@ from pydantic.v1 import ValidationError as ValidationErrorV1
39
36
  from pydantic.v1 import validate_arguments as validate_arguments_v1
40
37
  from typing_extensions import override
41
38
 
42
- from langchain_core._api import deprecated
43
39
  from langchain_core.callbacks import (
44
40
  AsyncCallbackManager,
45
- BaseCallbackManager,
46
41
  CallbackManager,
47
42
  Callbacks,
48
43
  )
@@ -285,7 +280,7 @@ def create_schema_from_function(
285
280
  model_name: str,
286
281
  func: Callable,
287
282
  *,
288
- filter_args: Optional[Sequence[str]] = None,
283
+ filter_args: Sequence[str] | None = None,
289
284
  parse_docstring: bool = False,
290
285
  error_on_invalid_docstring: bool = False,
291
286
  include_injected: bool = True,
@@ -390,10 +385,10 @@ class ToolException(Exception): # noqa: N818
390
385
  """
391
386
 
392
387
 
393
- ArgsSchema = Union[TypeBaseModel, dict[str, Any]]
388
+ ArgsSchema = TypeBaseModel | dict[str, Any]
394
389
 
395
390
 
396
- class BaseTool(RunnableSerializable[Union[str, dict, ToolCall], Any]):
391
+ class BaseTool(RunnableSerializable[str | dict | ToolCall, Any]):
397
392
  """Base class for all LangChain tools.
398
393
 
399
394
  This abstract class defines the interface that all LangChain tools must implement.
@@ -441,7 +436,7 @@ class ChildTool(BaseTool):
441
436
  You can provide few-shot examples as a part of the description.
442
437
  """
443
438
 
444
- args_schema: Annotated[Optional[ArgsSchema], SkipValidation()] = Field(
439
+ args_schema: Annotated[ArgsSchema | None, SkipValidation()] = Field(
445
440
  default=None, description="The tool schema."
446
441
  )
447
442
  """Pydantic model class to validate and parse the tool's input arguments.
@@ -464,36 +459,25 @@ class ChildTool(BaseTool):
464
459
  callbacks: Callbacks = Field(default=None, exclude=True)
465
460
  """Callbacks to be called during tool execution."""
466
461
 
467
- callback_manager: Optional[BaseCallbackManager] = deprecated(
468
- name="callback_manager", since="0.1.7", removal="1.0", alternative="callbacks"
469
- )(
470
- Field(
471
- default=None,
472
- exclude=True,
473
- description="Callback manager to add to the run trace.",
474
- )
475
- )
476
- tags: Optional[list[str]] = None
462
+ tags: list[str] | None = None
477
463
  """Optional list of tags associated with the tool. Defaults to None.
478
464
  These tags will be associated with each call to this tool,
479
465
  and passed as arguments to the handlers defined in `callbacks`.
480
466
  You can use these to eg identify a specific instance of a tool with its use case.
481
467
  """
482
- metadata: Optional[dict[str, Any]] = None
468
+ metadata: dict[str, Any] | None = None
483
469
  """Optional metadata associated with the tool. Defaults to None.
484
470
  This metadata will be associated with each call to this tool,
485
471
  and passed as arguments to the handlers defined in `callbacks`.
486
472
  You can use these to eg identify a specific instance of a tool with its use case.
487
473
  """
488
474
 
489
- handle_tool_error: Optional[Union[bool, str, Callable[[ToolException], str]]] = (
490
- False
491
- )
475
+ handle_tool_error: bool | str | Callable[[ToolException], str] | None = False
492
476
  """Handle the content of the ToolException thrown."""
493
477
 
494
- handle_validation_error: Optional[
495
- Union[bool, str, Callable[[Union[ValidationError, ValidationErrorV1]], str]]
496
- ] = False
478
+ handle_validation_error: (
479
+ bool | str | Callable[[ValidationError | ValidationErrorV1], str] | None
480
+ ) = False
497
481
  """Handle the content of the ValidationError thrown."""
498
482
 
499
483
  response_format: Literal["content", "content_and_artifact"] = "content"
@@ -582,9 +566,7 @@ class ChildTool(BaseTool):
582
566
  # --- Runnable ---
583
567
 
584
568
  @override
585
- def get_input_schema(
586
- self, config: Optional[RunnableConfig] = None
587
- ) -> type[BaseModel]:
569
+ def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
588
570
  """The tool's input schema.
589
571
 
590
572
  Args:
@@ -602,8 +584,8 @@ class ChildTool(BaseTool):
602
584
  @override
603
585
  def invoke(
604
586
  self,
605
- input: Union[str, dict, ToolCall],
606
- config: Optional[RunnableConfig] = None,
587
+ input: str | dict | ToolCall,
588
+ config: RunnableConfig | None = None,
607
589
  **kwargs: Any,
608
590
  ) -> Any:
609
591
  tool_input, kwargs = _prep_run_args(input, config, **kwargs)
@@ -612,8 +594,8 @@ class ChildTool(BaseTool):
612
594
  @override
613
595
  async def ainvoke(
614
596
  self,
615
- input: Union[str, dict, ToolCall],
616
- config: Optional[RunnableConfig] = None,
597
+ input: str | dict | ToolCall,
598
+ config: RunnableConfig | None = None,
617
599
  **kwargs: Any,
618
600
  ) -> Any:
619
601
  tool_input, kwargs = _prep_run_args(input, config, **kwargs)
@@ -622,8 +604,8 @@ class ChildTool(BaseTool):
622
604
  # --- Tool ---
623
605
 
624
606
  def _parse_input(
625
- self, tool_input: Union[str, dict], tool_call_id: Optional[str]
626
- ) -> Union[str, dict[str, Any]]:
607
+ self, tool_input: str | dict, tool_call_id: str | None
608
+ ) -> str | dict[str, Any]:
627
609
  """Parse and validate tool input using the args schema.
628
610
 
629
611
  Args:
@@ -700,26 +682,6 @@ class ChildTool(BaseTool):
700
682
  }
701
683
  return tool_input
702
684
 
703
- @model_validator(mode="before")
704
- @classmethod
705
- def raise_deprecation(cls, values: dict) -> Any:
706
- """Raise deprecation warning if callback_manager is used.
707
-
708
- Args:
709
- values: The values to validate.
710
-
711
- Returns:
712
- The validated values.
713
- """
714
- if values.get("callback_manager") is not None:
715
- warnings.warn(
716
- "callback_manager is deprecated. Please use callbacks instead.",
717
- DeprecationWarning,
718
- stacklevel=6,
719
- )
720
- values["callbacks"] = values.pop("callback_manager", None)
721
- return values
722
-
723
685
  @abstractmethod
724
686
  def _run(self, *args: Any, **kwargs: Any) -> Any:
725
687
  """Use the tool.
@@ -747,7 +709,7 @@ class ChildTool(BaseTool):
747
709
  return await run_in_executor(None, self._run, *args, **kwargs)
748
710
 
749
711
  def _to_args_and_kwargs(
750
- self, tool_input: Union[str, dict], tool_call_id: Optional[str]
712
+ self, tool_input: str | dict, tool_call_id: str | None
751
713
  ) -> tuple[tuple, dict]:
752
714
  """Convert tool input to positional and keyword arguments.
753
715
 
@@ -787,18 +749,18 @@ class ChildTool(BaseTool):
787
749
 
788
750
  def run(
789
751
  self,
790
- tool_input: Union[str, dict[str, Any]],
791
- verbose: Optional[bool] = None, # noqa: FBT001
792
- start_color: Optional[str] = "green",
793
- color: Optional[str] = "green",
752
+ tool_input: str | dict[str, Any],
753
+ verbose: bool | None = None, # noqa: FBT001
754
+ start_color: str | None = "green",
755
+ color: str | None = "green",
794
756
  callbacks: Callbacks = None,
795
757
  *,
796
- tags: Optional[list[str]] = None,
797
- metadata: Optional[dict[str, Any]] = None,
798
- run_name: Optional[str] = None,
799
- run_id: Optional[uuid.UUID] = None,
800
- config: Optional[RunnableConfig] = None,
801
- tool_call_id: Optional[str] = None,
758
+ tags: list[str] | None = None,
759
+ metadata: dict[str, Any] | None = None,
760
+ run_name: str | None = None,
761
+ run_id: uuid.UUID | None = None,
762
+ config: RunnableConfig | None = None,
763
+ tool_call_id: str | None = None,
802
764
  **kwargs: Any,
803
765
  ) -> Any:
804
766
  """Run the tool.
@@ -850,7 +812,7 @@ class ChildTool(BaseTool):
850
812
  content = None
851
813
  artifact = None
852
814
  status = "success"
853
- error_to_raise: Union[Exception, KeyboardInterrupt, None] = None
815
+ error_to_raise: Exception | KeyboardInterrupt | None = None
854
816
  try:
855
817
  child_config = patch_config(config, callbacks=run_manager.get_child())
856
818
  with set_config_context(child_config) as context:
@@ -899,18 +861,18 @@ class ChildTool(BaseTool):
899
861
 
900
862
  async def arun(
901
863
  self,
902
- tool_input: Union[str, dict],
903
- verbose: Optional[bool] = None, # noqa: FBT001
904
- start_color: Optional[str] = "green",
905
- color: Optional[str] = "green",
864
+ tool_input: str | dict,
865
+ verbose: bool | None = None, # noqa: FBT001
866
+ start_color: str | None = "green",
867
+ color: str | None = "green",
906
868
  callbacks: Callbacks = None,
907
869
  *,
908
- tags: Optional[list[str]] = None,
909
- metadata: Optional[dict[str, Any]] = None,
910
- run_name: Optional[str] = None,
911
- run_id: Optional[uuid.UUID] = None,
912
- config: Optional[RunnableConfig] = None,
913
- tool_call_id: Optional[str] = None,
870
+ tags: list[str] | None = None,
871
+ metadata: dict[str, Any] | None = None,
872
+ run_name: str | None = None,
873
+ run_id: uuid.UUID | None = None,
874
+ config: RunnableConfig | None = None,
875
+ tool_call_id: str | None = None,
914
876
  **kwargs: Any,
915
877
  ) -> Any:
916
878
  """Run the tool asynchronously.
@@ -960,7 +922,7 @@ class ChildTool(BaseTool):
960
922
  content = None
961
923
  artifact = None
962
924
  status = "success"
963
- error_to_raise: Optional[Union[Exception, KeyboardInterrupt]] = None
925
+ error_to_raise: Exception | KeyboardInterrupt | None = None
964
926
  try:
965
927
  tool_args, tool_kwargs = self._to_args_and_kwargs(tool_input, tool_call_id)
966
928
  child_config = patch_config(config, callbacks=run_manager.get_child())
@@ -1011,19 +973,6 @@ class ChildTool(BaseTool):
1011
973
  await run_manager.on_tool_end(output, color=color, name=self.name, **kwargs)
1012
974
  return output
1013
975
 
1014
- @deprecated("0.1.47", alternative="invoke", removal="1.0")
1015
- def __call__(self, tool_input: str, callbacks: Callbacks = None) -> str:
1016
- """Make tool callable (deprecated).
1017
-
1018
- Args:
1019
- tool_input: The input to the tool.
1020
- callbacks: Callbacks to use during execution.
1021
-
1022
- Returns:
1023
- The tool's output.
1024
- """
1025
- return self.run(tool_input, callbacks=callbacks)
1026
-
1027
976
 
1028
977
  def _is_tool_call(x: Any) -> bool:
1029
978
  """Check if the input is a tool call dictionary.
@@ -1038,11 +987,9 @@ def _is_tool_call(x: Any) -> bool:
1038
987
 
1039
988
 
1040
989
  def _handle_validation_error(
1041
- e: Union[ValidationError, ValidationErrorV1],
990
+ e: ValidationError | ValidationErrorV1,
1042
991
  *,
1043
- flag: Union[
1044
- Literal[True], str, Callable[[Union[ValidationError, ValidationErrorV1]], str]
1045
- ],
992
+ flag: Literal[True] | str | Callable[[ValidationError | ValidationErrorV1], str],
1046
993
  ) -> str:
1047
994
  """Handle validation errors based on the configured flag.
1048
995
 
@@ -1074,7 +1021,7 @@ def _handle_validation_error(
1074
1021
  def _handle_tool_error(
1075
1022
  e: ToolException,
1076
1023
  *,
1077
- flag: Optional[Union[Literal[True], str, Callable[[ToolException], str]]],
1024
+ flag: Literal[True] | str | Callable[[ToolException], str] | None,
1078
1025
  ) -> str:
1079
1026
  """Handle tool execution errors based on the configured flag.
1080
1027
 
@@ -1104,10 +1051,10 @@ def _handle_tool_error(
1104
1051
 
1105
1052
 
1106
1053
  def _prep_run_args(
1107
- value: Union[str, dict, ToolCall],
1108
- config: Optional[RunnableConfig],
1054
+ value: str | dict | ToolCall,
1055
+ config: RunnableConfig | None,
1109
1056
  **kwargs: Any,
1110
- ) -> tuple[Union[str, dict], dict]:
1057
+ ) -> tuple[str | dict, dict]:
1111
1058
  """Prepare arguments for tool execution.
1112
1059
 
1113
1060
  Args:
@@ -1120,11 +1067,11 @@ def _prep_run_args(
1120
1067
  """
1121
1068
  config = ensure_config(config)
1122
1069
  if _is_tool_call(value):
1123
- tool_call_id: Optional[str] = cast("ToolCall", value)["id"]
1124
- tool_input: Union[str, dict] = cast("ToolCall", value)["args"].copy()
1070
+ tool_call_id: str | None = cast("ToolCall", value)["id"]
1071
+ tool_input: str | dict = cast("ToolCall", value)["args"].copy()
1125
1072
  else:
1126
1073
  tool_call_id = None
1127
- tool_input = cast("Union[str, dict]", value)
1074
+ tool_input = cast("str | dict", value)
1128
1075
  return (
1129
1076
  tool_input,
1130
1077
  dict(
@@ -1143,10 +1090,10 @@ def _prep_run_args(
1143
1090
  def _format_output(
1144
1091
  content: Any,
1145
1092
  artifact: Any,
1146
- tool_call_id: Optional[str],
1093
+ tool_call_id: str | None,
1147
1094
  name: str,
1148
1095
  status: str,
1149
- ) -> Union[ToolOutputMixin, Any]:
1096
+ ) -> ToolOutputMixin | Any:
1150
1097
  """Format tool output as a ToolMessage if appropriate.
1151
1098
 
1152
1099
  Args:
@@ -1221,7 +1168,7 @@ def _stringify(content: Any) -> str:
1221
1168
  return str(content)
1222
1169
 
1223
1170
 
1224
- def _get_type_hints(func: Callable) -> Optional[dict[str, type]]:
1171
+ def _get_type_hints(func: Callable) -> dict[str, type] | None:
1225
1172
  """Get type hints from a function, handling partial functions.
1226
1173
 
1227
1174
  Args:
@@ -1238,7 +1185,7 @@ def _get_type_hints(func: Callable) -> Optional[dict[str, type]]:
1238
1185
  return None
1239
1186
 
1240
1187
 
1241
- def _get_runnable_config_param(func: Callable) -> Optional[str]:
1188
+ def _get_runnable_config_param(func: Callable) -> str | None:
1242
1189
  """Find the parameter name for RunnableConfig in a function.
1243
1190
 
1244
1191
  Args:
@@ -1292,7 +1239,7 @@ class InjectedToolCallId(InjectedToolArg):
1292
1239
 
1293
1240
 
1294
1241
  def _is_injected_arg_type(
1295
- type_: Union[type, TypeVar], injected_type: Optional[type[InjectedToolArg]] = None
1242
+ type_: type | TypeVar, injected_type: type[InjectedToolArg] | None = None
1296
1243
  ) -> bool:
1297
1244
  """Check if a type annotation indicates an injected argument.
1298
1245
 
@@ -1312,8 +1259,8 @@ def _is_injected_arg_type(
1312
1259
 
1313
1260
 
1314
1261
  def get_all_basemodel_annotations(
1315
- cls: Union[TypeBaseModel, Any], *, default_to_bound: bool = True
1316
- ) -> dict[str, Union[type, TypeVar]]:
1262
+ cls: TypeBaseModel | Any, *, default_to_bound: bool = True
1263
+ ) -> dict[str, type | TypeVar]:
1317
1264
  """Get all annotations from a Pydantic BaseModel and its parents.
1318
1265
 
1319
1266
  Args:
@@ -1328,7 +1275,7 @@ def get_all_basemodel_annotations(
1328
1275
  fields = get_fields(cls)
1329
1276
  alias_map = {field.alias: name for name, field in fields.items() if field.alias}
1330
1277
 
1331
- annotations: dict[str, Union[type, TypeVar]] = {}
1278
+ annotations: dict[str, type | TypeVar] = {}
1332
1279
  for name, param in inspect.signature(cls).parameters.items():
1333
1280
  # Exclude hidden init args added by pydantic Config. For example if
1334
1281
  # BaseModel(extra="allow") then "extra_data" will part of init sig.
@@ -1369,7 +1316,7 @@ def get_all_basemodel_annotations(
1369
1316
  # generic_type_vars = (type vars in Baz)
1370
1317
  # generic_map = {type var in Baz: str}
1371
1318
  generic_type_vars: tuple = getattr(parent_origin, "__parameters__", ())
1372
- generic_map = dict(zip(generic_type_vars, get_args(parent)))
1319
+ generic_map = dict(zip(generic_type_vars, get_args(parent), strict=False))
1373
1320
  for field in getattr(parent_origin, "__annotations__", {}):
1374
1321
  annotations[field] = _replace_type_vars(
1375
1322
  annotations[field], generic_map, default_to_bound=default_to_bound
@@ -1382,11 +1329,11 @@ def get_all_basemodel_annotations(
1382
1329
 
1383
1330
 
1384
1331
  def _replace_type_vars(
1385
- type_: Union[type, TypeVar],
1386
- generic_map: Optional[dict[TypeVar, type]] = None,
1332
+ type_: type | TypeVar,
1333
+ generic_map: dict[TypeVar, type] | None = None,
1387
1334
  *,
1388
1335
  default_to_bound: bool = True,
1389
- ) -> Union[type, TypeVar]:
1336
+ ) -> type | TypeVar:
1390
1337
  """Replace TypeVars in a type annotation with concrete types.
1391
1338
 
1392
1339
  Args:
@@ -1,7 +1,8 @@
1
1
  """Convert functions and runnables to tools."""
2
2
 
3
3
  import inspect
4
- from typing import Any, Callable, Literal, Optional, Union, get_type_hints, overload
4
+ from collections.abc import Callable
5
+ from typing import Any, Literal, get_type_hints, overload
5
6
 
6
7
  from pydantic import BaseModel, Field, create_model
7
8
 
@@ -15,14 +16,14 @@ from langchain_core.tools.structured import StructuredTool
15
16
  @overload
16
17
  def tool(
17
18
  *,
18
- description: Optional[str] = None,
19
+ description: str | None = None,
19
20
  return_direct: bool = False,
20
- args_schema: Optional[ArgsSchema] = None,
21
+ args_schema: ArgsSchema | None = None,
21
22
  infer_schema: bool = True,
22
23
  response_format: Literal["content", "content_and_artifact"] = "content",
23
24
  parse_docstring: bool = False,
24
25
  error_on_invalid_docstring: bool = True,
25
- ) -> Callable[[Union[Callable, Runnable]], BaseTool]: ...
26
+ ) -> Callable[[Callable | Runnable], BaseTool]: ...
26
27
 
27
28
 
28
29
  @overload
@@ -30,9 +31,9 @@ def tool(
30
31
  name_or_callable: str,
31
32
  runnable: Runnable,
32
33
  *,
33
- description: Optional[str] = None,
34
+ description: str | None = None,
34
35
  return_direct: bool = False,
35
- args_schema: Optional[ArgsSchema] = None,
36
+ args_schema: ArgsSchema | None = None,
36
37
  infer_schema: bool = True,
37
38
  response_format: Literal["content", "content_and_artifact"] = "content",
38
39
  parse_docstring: bool = False,
@@ -44,9 +45,9 @@ def tool(
44
45
  def tool(
45
46
  name_or_callable: Callable,
46
47
  *,
47
- description: Optional[str] = None,
48
+ description: str | None = None,
48
49
  return_direct: bool = False,
49
- args_schema: Optional[ArgsSchema] = None,
50
+ args_schema: ArgsSchema | None = None,
50
51
  infer_schema: bool = True,
51
52
  response_format: Literal["content", "content_and_artifact"] = "content",
52
53
  parse_docstring: bool = False,
@@ -58,31 +59,28 @@ def tool(
58
59
  def tool(
59
60
  name_or_callable: str,
60
61
  *,
61
- description: Optional[str] = None,
62
+ description: str | None = None,
62
63
  return_direct: bool = False,
63
- args_schema: Optional[ArgsSchema] = None,
64
+ args_schema: ArgsSchema | None = None,
64
65
  infer_schema: bool = True,
65
66
  response_format: Literal["content", "content_and_artifact"] = "content",
66
67
  parse_docstring: bool = False,
67
68
  error_on_invalid_docstring: bool = True,
68
- ) -> Callable[[Union[Callable, Runnable]], BaseTool]: ...
69
+ ) -> Callable[[Callable | Runnable], BaseTool]: ...
69
70
 
70
71
 
71
72
  def tool(
72
- name_or_callable: Optional[Union[str, Callable]] = None,
73
- runnable: Optional[Runnable] = None,
73
+ name_or_callable: str | Callable | None = None,
74
+ runnable: Runnable | None = None,
74
75
  *args: Any,
75
- description: Optional[str] = None,
76
+ description: str | None = None,
76
77
  return_direct: bool = False,
77
- args_schema: Optional[ArgsSchema] = None,
78
+ args_schema: ArgsSchema | None = None,
78
79
  infer_schema: bool = True,
79
80
  response_format: Literal["content", "content_and_artifact"] = "content",
80
81
  parse_docstring: bool = False,
81
82
  error_on_invalid_docstring: bool = True,
82
- ) -> Union[
83
- BaseTool,
84
- Callable[[Union[Callable, Runnable]], BaseTool],
85
- ]:
83
+ ) -> BaseTool | Callable[[Callable | Runnable], BaseTool]:
86
84
  """Make tools out of functions, can be used with or without arguments.
87
85
 
88
86
  Args:
@@ -157,7 +155,7 @@ def tool(
157
155
  def search_api(query: str) -> tuple[str, dict]:
158
156
  return "partial json of results", {"full": "object of results"}
159
157
 
160
- .. versionadded:: 0.2.14
158
+ !!! version-added "Added in version 0.2.14"
161
159
 
162
160
  Parse Google-style docstrings:
163
161
 
@@ -231,7 +229,7 @@ def tool(
231
229
 
232
230
  def _create_tool_factory(
233
231
  tool_name: str,
234
- ) -> Callable[[Union[Callable, Runnable]], BaseTool]:
232
+ ) -> Callable[[Callable | Runnable], BaseTool]:
235
233
  """Create a decorator that takes a callable and returns a tool.
236
234
 
237
235
  Args:
@@ -241,7 +239,7 @@ def tool(
241
239
  A function that takes a callable or Runnable and returns a tool.
242
240
  """
243
241
 
244
- def _tool_factory(dec_func: Union[Callable, Runnable]) -> BaseTool:
242
+ def _tool_factory(dec_func: Callable | Runnable) -> BaseTool:
245
243
  tool_description = description
246
244
  if isinstance(dec_func, Runnable):
247
245
  runnable = dec_func
@@ -251,18 +249,18 @@ def tool(
251
249
  raise ValueError(msg)
252
250
 
253
251
  async def ainvoke_wrapper(
254
- callbacks: Optional[Callbacks] = None, **kwargs: Any
252
+ callbacks: Callbacks | None = None, **kwargs: Any
255
253
  ) -> Any:
256
254
  return await runnable.ainvoke(kwargs, {"callbacks": callbacks})
257
255
 
258
256
  def invoke_wrapper(
259
- callbacks: Optional[Callbacks] = None, **kwargs: Any
257
+ callbacks: Callbacks | None = None, **kwargs: Any
260
258
  ) -> Any:
261
259
  return runnable.invoke(kwargs, {"callbacks": callbacks})
262
260
 
263
261
  coroutine = ainvoke_wrapper
264
262
  func = invoke_wrapper
265
- schema: Optional[ArgsSchema] = runnable.input_schema
263
+ schema: ArgsSchema | None = runnable.input_schema
266
264
  tool_description = description or repr(runnable)
267
265
  elif inspect.iscoroutinefunction(dec_func):
268
266
  coroutine = dec_func
@@ -352,7 +350,7 @@ def tool(
352
350
  # @tool(parse_docstring=True)
353
351
  # def my_tool():
354
352
  # pass
355
- def _partial(func: Union[Callable, Runnable]) -> BaseTool:
353
+ def _partial(func: Callable | Runnable) -> BaseTool:
356
354
  """Partial function that takes a callable and returns a tool."""
357
355
  name_ = func.get_name() if isinstance(func, Runnable) else func.__name__
358
356
  tool_factory = _create_tool_factory(name_)
@@ -370,7 +368,7 @@ def _get_description_from_runnable(runnable: Runnable) -> str:
370
368
  def _get_schema_from_runnable_and_arg_types(
371
369
  runnable: Runnable,
372
370
  name: str,
373
- arg_types: Optional[dict[str, type]] = None,
371
+ arg_types: dict[str, type] | None = None,
374
372
  ) -> type[BaseModel]:
375
373
  """Infer args_schema for tool."""
376
374
  if arg_types is None:
@@ -389,11 +387,11 @@ def _get_schema_from_runnable_and_arg_types(
389
387
 
390
388
  def convert_runnable_to_tool(
391
389
  runnable: Runnable,
392
- args_schema: Optional[type[BaseModel]] = None,
390
+ args_schema: type[BaseModel] | None = None,
393
391
  *,
394
- name: Optional[str] = None,
395
- description: Optional[str] = None,
396
- arg_types: Optional[dict[str, type]] = None,
392
+ name: str | None = None,
393
+ description: str | None = None,
394
+ arg_types: dict[str, type] | None = None,
397
395
  ) -> BaseTool:
398
396
  """Convert a Runnable into a BaseTool.
399
397
 
@@ -421,12 +419,10 @@ def convert_runnable_to_tool(
421
419
  description=description,
422
420
  )
423
421
 
424
- async def ainvoke_wrapper(
425
- callbacks: Optional[Callbacks] = None, **kwargs: Any
426
- ) -> Any:
422
+ async def ainvoke_wrapper(callbacks: Callbacks | None = None, **kwargs: Any) -> Any:
427
423
  return await runnable.ainvoke(kwargs, config={"callbacks": callbacks})
428
424
 
429
- def invoke_wrapper(callbacks: Optional[Callbacks] = None, **kwargs: Any) -> Any:
425
+ def invoke_wrapper(callbacks: Callbacks | None = None, **kwargs: Any) -> Any:
430
426
  return runnable.invoke(kwargs, config={"callbacks": callbacks})
431
427
 
432
428
  if (
@@ -2,8 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from collections.abc import Callable
5
6
  from inspect import signature
6
- from typing import Callable
7
7
 
8
8
  from langchain_core.tools.base import BaseTool
9
9
 
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from functools import partial
6
- from typing import TYPE_CHECKING, Literal, Optional, Union
6
+ from typing import TYPE_CHECKING, Literal
7
7
 
8
8
  from pydantic import BaseModel, Field
9
9
 
@@ -34,7 +34,7 @@ def _get_relevant_documents(
34
34
  document_separator: str,
35
35
  callbacks: Callbacks = None,
36
36
  response_format: Literal["content", "content_and_artifact"] = "content",
37
- ) -> Union[str, tuple[str, list[Document]]]:
37
+ ) -> str | tuple[str, list[Document]]:
38
38
  docs = retriever.invoke(query, config={"callbacks": callbacks})
39
39
  content = document_separator.join(
40
40
  format_document(doc, document_prompt) for doc in docs
@@ -52,7 +52,7 @@ async def _aget_relevant_documents(
52
52
  document_separator: str,
53
53
  callbacks: Callbacks = None,
54
54
  response_format: Literal["content", "content_and_artifact"] = "content",
55
- ) -> Union[str, tuple[str, list[Document]]]:
55
+ ) -> str | tuple[str, list[Document]]:
56
56
  docs = await retriever.ainvoke(query, config={"callbacks": callbacks})
57
57
  content = document_separator.join(
58
58
  [await aformat_document(doc, document_prompt) for doc in docs]
@@ -69,7 +69,7 @@ def create_retriever_tool(
69
69
  name: str,
70
70
  description: str,
71
71
  *,
72
- document_prompt: Optional[BasePromptTemplate] = None,
72
+ document_prompt: BasePromptTemplate | None = None,
73
73
  document_separator: str = "\n\n",
74
74
  response_format: Literal["content", "content_and_artifact"] = "content",
75
75
  ) -> Tool: