langchain-core 1.0.0a5__py3-none-any.whl → 1.0.3__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 +20 -22
  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 +436 -513
  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 +98 -90
  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 +1 -1
  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 +53 -162
  36. langchain_core/language_models/chat_models.py +298 -387
  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 +125 -235
  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 +58 -52
  47. langchain_core/messages/block_translators/__init__.py +27 -17
  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 +505 -20
  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 +337 -328
  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 +474 -504
  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 +16 -21
  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 +10 -11
  78. langchain_core/outputs/llm_result.py +10 -10
  79. langchain_core/prompt_values.py +11 -17
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +48 -56
  82. langchain_core/prompts/chat.py +275 -325
  83. langchain_core/prompts/dict.py +5 -5
  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 +3 -3
  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 +1478 -1630
  95. langchain_core/runnables/branch.py +53 -57
  96. langchain_core/runnables/config.py +72 -89
  97. langchain_core/runnables/configurable.py +120 -137
  98. langchain_core/runnables/fallbacks.py +83 -79
  99. langchain_core/runnables/graph.py +91 -97
  100. langchain_core/runnables/graph_ascii.py +27 -28
  101. langchain_core/runnables/graph_mermaid.py +38 -50
  102. langchain_core/runnables/graph_png.py +15 -16
  103. langchain_core/runnables/history.py +135 -148
  104. langchain_core/runnables/passthrough.py +124 -150
  105. langchain_core/runnables/retry.py +46 -51
  106. langchain_core/runnables/router.py +25 -30
  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 +27 -29
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +285 -229
  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 +89 -186
  137. langchain_core/utils/html.py +7 -8
  138. langchain_core/utils/input.py +6 -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 +33 -35
  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.3.dist-info/METADATA +69 -0
  153. langchain_core-1.0.3.dist-info/RECORD +172 -0
  154. {langchain_core-1.0.0a5.dist-info → langchain_core-1.0.3.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.0a5.dist-info/METADATA +0 -77
  164. langchain_core-1.0.0a5.dist-info/RECORD +0 -181
  165. langchain_core-1.0.0a5.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
  )
@@ -82,6 +77,7 @@ TOOL_MESSAGE_BLOCK_TYPES = (
82
77
  "search_result",
83
78
  "custom_tool_call_output",
84
79
  "document",
80
+ "file",
85
81
  )
86
82
 
87
83
 
@@ -96,7 +92,7 @@ def _is_annotated_type(typ: type[Any]) -> bool:
96
92
  typ: The type to check.
97
93
 
98
94
  Returns:
99
- True if the type is an Annotated type, False otherwise.
95
+ `True` if the type is an Annotated type, `False` otherwise.
100
96
  """
101
97
  return get_origin(typ) is typing.Annotated
102
98
 
@@ -230,7 +226,7 @@ def _is_pydantic_annotation(annotation: Any, pydantic_version: str = "v2") -> bo
230
226
  pydantic_version: The Pydantic version to check against ("v1" or "v2").
231
227
 
232
228
  Returns:
233
- True if the annotation is a Pydantic model, False otherwise.
229
+ `True` if the annotation is a Pydantic model, `False` otherwise.
234
230
  """
235
231
  base_model_class = BaseModelV1 if pydantic_version == "v1" else BaseModel
236
232
  try:
@@ -249,7 +245,7 @@ def _function_annotations_are_pydantic_v1(
249
245
  func: The function being checked.
250
246
 
251
247
  Returns:
252
- True if all Pydantic annotations are from V1, False otherwise.
248
+ True if all Pydantic annotations are from V1, `False` otherwise.
253
249
 
254
250
  Raises:
255
251
  NotImplementedError: If the function contains mixed V1 and V2 annotations.
@@ -284,29 +280,28 @@ def create_schema_from_function(
284
280
  model_name: str,
285
281
  func: Callable,
286
282
  *,
287
- filter_args: Optional[Sequence[str]] = None,
283
+ filter_args: Sequence[str] | None = None,
288
284
  parse_docstring: bool = False,
289
285
  error_on_invalid_docstring: bool = False,
290
286
  include_injected: bool = True,
291
287
  ) -> type[BaseModel]:
292
- """Create a pydantic schema from a function's signature.
288
+ """Create a Pydantic schema from a function's signature.
293
289
 
294
290
  Args:
295
- model_name: Name to assign to the generated pydantic schema.
291
+ model_name: Name to assign to the generated Pydantic schema.
296
292
  func: Function to generate the schema from.
297
293
  filter_args: Optional list of arguments to exclude from the schema.
298
- Defaults to FILTERED_ARGS.
294
+ Defaults to `FILTERED_ARGS`.
299
295
  parse_docstring: Whether to parse the function's docstring for descriptions
300
- for each argument. Defaults to False.
301
- error_on_invalid_docstring: if ``parse_docstring`` is provided, configure
302
- whether to raise ValueError on invalid Google Style docstrings.
303
- Defaults to False.
296
+ for each argument.
297
+ error_on_invalid_docstring: if `parse_docstring` is provided, configure
298
+ whether to raise `ValueError` on invalid Google Style docstrings.
304
299
  include_injected: Whether to include injected arguments in the schema.
305
- Defaults to True, since we want to include them in the schema
300
+ Defaults to `True`, since we want to include them in the schema
306
301
  when *validating* tool inputs.
307
302
 
308
303
  Returns:
309
- A pydantic model with the same arguments as the function.
304
+ A Pydantic model with the same arguments as the function.
310
305
  """
311
306
  sig = inspect.signature(func)
312
307
 
@@ -316,7 +311,7 @@ def create_schema_from_function(
316
311
  # https://docs.pydantic.dev/latest/usage/validation_decorator/
317
312
  with warnings.catch_warnings():
318
313
  # We are using deprecated functionality here.
319
- # This code should be re-written to simply construct a pydantic model
314
+ # This code should be re-written to simply construct a Pydantic model
320
315
  # using inspect.signature and create_model.
321
316
  warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
322
317
  validated = validate_arguments(func, config=_SchemaConfig) # type: ignore[operator]
@@ -389,13 +384,14 @@ class ToolException(Exception): # noqa: N818
389
384
  """
390
385
 
391
386
 
392
- ArgsSchema = Union[TypeBaseModel, dict[str, Any]]
387
+ ArgsSchema = TypeBaseModel | dict[str, Any]
393
388
 
394
389
 
395
- class BaseTool(RunnableSerializable[Union[str, dict, ToolCall], Any]):
390
+ class BaseTool(RunnableSerializable[str | dict | ToolCall, Any]):
396
391
  """Base class for all LangChain tools.
397
392
 
398
393
  This abstract class defines the interface that all LangChain tools must implement.
394
+
399
395
  Tools are components that can be called by agents to perform specific actions.
400
396
  """
401
397
 
@@ -406,7 +402,7 @@ class BaseTool(RunnableSerializable[Union[str, dict, ToolCall], Any]):
406
402
  **kwargs: Additional keyword arguments passed to the parent class.
407
403
 
408
404
  Raises:
409
- SchemaAnnotationError: If args_schema has incorrect type annotation.
405
+ SchemaAnnotationError: If `args_schema` has incorrect type annotation.
410
406
  """
411
407
  super().__init_subclass__(**kwargs)
412
408
 
@@ -440,22 +436,22 @@ class ChildTool(BaseTool):
440
436
  You can provide few-shot examples as a part of the description.
441
437
  """
442
438
 
443
- args_schema: Annotated[Optional[ArgsSchema], SkipValidation()] = Field(
439
+ args_schema: Annotated[ArgsSchema | None, SkipValidation()] = Field(
444
440
  default=None, description="The tool schema."
445
441
  )
446
442
  """Pydantic model class to validate and parse the tool's input arguments.
447
443
 
448
444
  Args schema should be either:
449
445
 
450
- - A subclass of pydantic.BaseModel.
451
- - A subclass of pydantic.v1.BaseModel if accessing v1 namespace in pydantic 2
452
- - a JSON schema dict
446
+ - A subclass of `pydantic.BaseModel`.
447
+ - A subclass of `pydantic.v1.BaseModel` if accessing v1 namespace in pydantic 2
448
+ - A JSON schema dict
453
449
  """
454
450
  return_direct: bool = False
455
451
  """Whether to return the tool's output directly.
456
452
 
457
- Setting this to True means
458
- that after the tool is called, the AgentExecutor will stop looping.
453
+ Setting this to `True` means that after the tool is called, the `AgentExecutor` will
454
+ stop looping.
459
455
  """
460
456
  verbose: bool = False
461
457
  """Whether to log the tool's progress."""
@@ -463,52 +459,47 @@ class ChildTool(BaseTool):
463
459
  callbacks: Callbacks = Field(default=None, exclude=True)
464
460
  """Callbacks to be called during tool execution."""
465
461
 
466
- callback_manager: Optional[BaseCallbackManager] = deprecated(
467
- name="callback_manager", since="0.1.7", removal="1.0", alternative="callbacks"
468
- )(
469
- Field(
470
- default=None,
471
- exclude=True,
472
- description="Callback manager to add to the run trace.",
473
- )
474
- )
475
- tags: Optional[list[str]] = None
476
- """Optional list of tags associated with the tool. Defaults to None.
462
+ tags: list[str] | None = None
463
+ """Optional list of tags associated with the tool.
464
+
477
465
  These tags will be associated with each call to this tool,
478
466
  and passed as arguments to the handlers defined in `callbacks`.
479
- You can use these to eg identify a specific instance of a tool with its use case.
467
+
468
+ You can use these to, e.g., identify a specific instance of a tool with its use
469
+ case.
480
470
  """
481
- metadata: Optional[dict[str, Any]] = None
482
- """Optional metadata associated with the tool. Defaults to None.
471
+ metadata: dict[str, Any] | None = None
472
+ """Optional metadata associated with the tool.
473
+
483
474
  This metadata will be associated with each call to this tool,
484
475
  and passed as arguments to the handlers defined in `callbacks`.
485
- You can use these to eg identify a specific instance of a tool with its use case.
476
+
477
+ You can use these to, e.g., identify a specific instance of a tool with its use
478
+ case.
486
479
  """
487
480
 
488
- handle_tool_error: Optional[Union[bool, str, Callable[[ToolException], str]]] = (
489
- False
490
- )
491
- """Handle the content of the ToolException thrown."""
481
+ handle_tool_error: bool | str | Callable[[ToolException], str] | None = False
482
+ """Handle the content of the `ToolException` thrown."""
492
483
 
493
- handle_validation_error: Optional[
494
- Union[bool, str, Callable[[Union[ValidationError, ValidationErrorV1]], str]]
495
- ] = False
496
- """Handle the content of the ValidationError thrown."""
484
+ handle_validation_error: (
485
+ bool | str | Callable[[ValidationError | ValidationErrorV1], str] | None
486
+ ) = False
487
+ """Handle the content of the `ValidationError` thrown."""
497
488
 
498
489
  response_format: Literal["content", "content_and_artifact"] = "content"
499
- """The tool response format. Defaults to 'content'.
490
+ """The tool response format.
500
491
 
501
- If "content" then the output of the tool is interpreted as the contents of a
502
- ToolMessage. If "content_and_artifact" then the output is expected to be a
503
- two-tuple corresponding to the (content, artifact) of a ToolMessage.
492
+ If `'content'` then the output of the tool is interpreted as the contents of a
493
+ `ToolMessage`. If `'content_and_artifact'` then the output is expected to be a
494
+ two-tuple corresponding to the `(content, artifact)` of a `ToolMessage`.
504
495
  """
505
496
 
506
497
  def __init__(self, **kwargs: Any) -> None:
507
498
  """Initialize the tool.
508
499
 
509
500
  Raises:
510
- TypeError: If ``args_schema`` is not a subclass of pydantic ``BaseModel`` or
511
- dict.
501
+ TypeError: If `args_schema` is not a subclass of pydantic `BaseModel` or
502
+ `dict`.
512
503
  """
513
504
  if (
514
505
  "args_schema" in kwargs
@@ -532,7 +523,7 @@ class ChildTool(BaseTool):
532
523
  """Check if the tool accepts only a single input argument.
533
524
 
534
525
  Returns:
535
- True if the tool has only one input argument, False otherwise.
526
+ `True` if the tool has only one input argument, `False` otherwise.
536
527
  """
537
528
  keys = {k for k in self.args if k != "kwargs"}
538
529
  return len(keys) == 1
@@ -542,7 +533,7 @@ class ChildTool(BaseTool):
542
533
  """Get the tool's input arguments schema.
543
534
 
544
535
  Returns:
545
- Dictionary containing the tool's argument properties.
536
+ `dict` containing the tool's argument properties.
546
537
  """
547
538
  if isinstance(self.args_schema, dict):
548
539
  json_schema = self.args_schema
@@ -581,9 +572,7 @@ class ChildTool(BaseTool):
581
572
  # --- Runnable ---
582
573
 
583
574
  @override
584
- def get_input_schema(
585
- self, config: Optional[RunnableConfig] = None
586
- ) -> type[BaseModel]:
575
+ def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
587
576
  """The tool's input schema.
588
577
 
589
578
  Args:
@@ -601,8 +590,8 @@ class ChildTool(BaseTool):
601
590
  @override
602
591
  def invoke(
603
592
  self,
604
- input: Union[str, dict, ToolCall],
605
- config: Optional[RunnableConfig] = None,
593
+ input: str | dict | ToolCall,
594
+ config: RunnableConfig | None = None,
606
595
  **kwargs: Any,
607
596
  ) -> Any:
608
597
  tool_input, kwargs = _prep_run_args(input, config, **kwargs)
@@ -611,8 +600,8 @@ class ChildTool(BaseTool):
611
600
  @override
612
601
  async def ainvoke(
613
602
  self,
614
- input: Union[str, dict, ToolCall],
615
- config: Optional[RunnableConfig] = None,
603
+ input: str | dict | ToolCall,
604
+ config: RunnableConfig | None = None,
616
605
  **kwargs: Any,
617
606
  ) -> Any:
618
607
  tool_input, kwargs = _prep_run_args(input, config, **kwargs)
@@ -621,8 +610,8 @@ class ChildTool(BaseTool):
621
610
  # --- Tool ---
622
611
 
623
612
  def _parse_input(
624
- self, tool_input: Union[str, dict], tool_call_id: Optional[str]
625
- ) -> Union[str, dict[str, Any]]:
613
+ self, tool_input: str | dict, tool_call_id: str | None
614
+ ) -> str | dict[str, Any]:
626
615
  """Parse and validate tool input using the args schema.
627
616
 
628
617
  Args:
@@ -633,10 +622,10 @@ class ChildTool(BaseTool):
633
622
  The parsed and validated input.
634
623
 
635
624
  Raises:
636
- ValueError: If string input is provided with JSON schema ``args_schema``.
637
- ValueError: If InjectedToolCallId is required but ``tool_call_id`` is not
625
+ ValueError: If `string` input is provided with JSON schema `args_schema`.
626
+ ValueError: If `InjectedToolCallId` is required but `tool_call_id` is not
638
627
  provided.
639
- TypeError: If args_schema is not a Pydantic ``BaseModel`` or dict.
628
+ TypeError: If `args_schema` is not a Pydantic `BaseModel` or dict.
640
629
  """
641
630
  input_args = self.args_schema
642
631
  if isinstance(tool_input, str):
@@ -699,32 +688,12 @@ class ChildTool(BaseTool):
699
688
  }
700
689
  return tool_input
701
690
 
702
- @model_validator(mode="before")
703
- @classmethod
704
- def raise_deprecation(cls, values: dict) -> Any:
705
- """Raise deprecation warning if callback_manager is used.
706
-
707
- Args:
708
- values: The values to validate.
709
-
710
- Returns:
711
- The validated values.
712
- """
713
- if values.get("callback_manager") is not None:
714
- warnings.warn(
715
- "callback_manager is deprecated. Please use callbacks instead.",
716
- DeprecationWarning,
717
- stacklevel=6,
718
- )
719
- values["callbacks"] = values.pop("callback_manager", None)
720
- return values
721
-
722
691
  @abstractmethod
723
692
  def _run(self, *args: Any, **kwargs: Any) -> Any:
724
693
  """Use the tool.
725
694
 
726
- Add run_manager: Optional[CallbackManagerForToolRun] = None
727
- to child implementations to enable tracing.
695
+ Add `run_manager: CallbackManagerForToolRun | None = None` to child
696
+ implementations to enable tracing.
728
697
 
729
698
  Returns:
730
699
  The result of the tool execution.
@@ -733,8 +702,8 @@ class ChildTool(BaseTool):
733
702
  async def _arun(self, *args: Any, **kwargs: Any) -> Any:
734
703
  """Use the tool asynchronously.
735
704
 
736
- Add run_manager: Optional[AsyncCallbackManagerForToolRun] = None
737
- to child implementations to enable tracing.
705
+ Add `run_manager: AsyncCallbackManagerForToolRun | None = None` to child
706
+ implementations to enable tracing.
738
707
 
739
708
  Returns:
740
709
  The result of the tool execution.
@@ -745,8 +714,37 @@ class ChildTool(BaseTool):
745
714
  kwargs["run_manager"] = kwargs["run_manager"].get_sync()
746
715
  return await run_in_executor(None, self._run, *args, **kwargs)
747
716
 
717
+ def _filter_injected_args(self, tool_input: dict) -> dict:
718
+ """Filter out injected tool arguments from the input dictionary.
719
+
720
+ Injected arguments are those annotated with `InjectedToolArg` or its
721
+ subclasses, or arguments in `FILTERED_ARGS` like `run_manager` and callbacks.
722
+
723
+ Args:
724
+ tool_input: The tool input dictionary to filter.
725
+
726
+ Returns:
727
+ A filtered dictionary with injected arguments removed.
728
+ """
729
+ # Start with filtered args from the constant
730
+ filtered_keys = set[str](FILTERED_ARGS)
731
+
732
+ # If we have an args_schema, use it to identify injected args
733
+ if self.args_schema is not None:
734
+ try:
735
+ annotations = get_all_basemodel_annotations(self.args_schema)
736
+ for field_name, field_type in annotations.items():
737
+ if _is_injected_arg_type(field_type):
738
+ filtered_keys.add(field_name)
739
+ except Exception: # noqa: S110
740
+ # If we can't get annotations, just use FILTERED_ARGS
741
+ pass
742
+
743
+ # Filter out the injected keys from tool_input
744
+ return {k: v for k, v in tool_input.items() if k not in filtered_keys}
745
+
748
746
  def _to_args_and_kwargs(
749
- self, tool_input: Union[str, dict], tool_call_id: Optional[str]
747
+ self, tool_input: str | dict, tool_call_id: str | None
750
748
  ) -> tuple[tuple, dict]:
751
749
  """Convert tool input to positional and keyword arguments.
752
750
 
@@ -755,7 +753,7 @@ class ChildTool(BaseTool):
755
753
  tool_call_id: The ID of the tool call, if available.
756
754
 
757
755
  Returns:
758
- A tuple of (positional_args, keyword_args) for the tool.
756
+ A tuple of `(positional_args, keyword_args)` for the tool.
759
757
 
760
758
  Raises:
761
759
  TypeError: If the tool input type is invalid.
@@ -786,35 +784,35 @@ class ChildTool(BaseTool):
786
784
 
787
785
  def run(
788
786
  self,
789
- tool_input: Union[str, dict[str, Any]],
790
- verbose: Optional[bool] = None, # noqa: FBT001
791
- start_color: Optional[str] = "green",
792
- color: Optional[str] = "green",
787
+ tool_input: str | dict[str, Any],
788
+ verbose: bool | None = None, # noqa: FBT001
789
+ start_color: str | None = "green",
790
+ color: str | None = "green",
793
791
  callbacks: Callbacks = None,
794
792
  *,
795
- tags: Optional[list[str]] = None,
796
- metadata: Optional[dict[str, Any]] = None,
797
- run_name: Optional[str] = None,
798
- run_id: Optional[uuid.UUID] = None,
799
- config: Optional[RunnableConfig] = None,
800
- tool_call_id: Optional[str] = None,
793
+ tags: list[str] | None = None,
794
+ metadata: dict[str, Any] | None = None,
795
+ run_name: str | None = None,
796
+ run_id: uuid.UUID | None = None,
797
+ config: RunnableConfig | None = None,
798
+ tool_call_id: str | None = None,
801
799
  **kwargs: Any,
802
800
  ) -> Any:
803
801
  """Run the tool.
804
802
 
805
803
  Args:
806
804
  tool_input: The input to the tool.
807
- verbose: Whether to log the tool's progress. Defaults to None.
808
- start_color: The color to use when starting the tool. Defaults to 'green'.
809
- color: The color to use when ending the tool. Defaults to 'green'.
810
- callbacks: Callbacks to be called during tool execution. Defaults to None.
811
- tags: Optional list of tags associated with the tool. Defaults to None.
812
- metadata: Optional metadata associated with the tool. Defaults to None.
813
- run_name: The name of the run. Defaults to None.
814
- run_id: The id of the run. Defaults to None.
815
- config: The configuration for the tool. Defaults to None.
816
- tool_call_id: The id of the tool call. Defaults to None.
817
- kwargs: Keyword arguments to be passed to tool callbacks (event handler)
805
+ verbose: Whether to log the tool's progress.
806
+ start_color: The color to use when starting the tool.
807
+ color: The color to use when ending the tool.
808
+ callbacks: Callbacks to be called during tool execution.
809
+ tags: Optional list of tags associated with the tool.
810
+ metadata: Optional metadata associated with the tool.
811
+ run_name: The name of the run.
812
+ run_id: The id of the run.
813
+ config: The configuration for the tool.
814
+ tool_call_id: The id of the tool call.
815
+ **kwargs: Keyword arguments to be passed to tool callbacks (event handler)
818
816
 
819
817
  Returns:
820
818
  The output of the tool.
@@ -832,24 +830,36 @@ class ChildTool(BaseTool):
832
830
  self.metadata,
833
831
  )
834
832
 
833
+ # Filter out injected arguments from callback inputs
834
+ filtered_tool_input = (
835
+ self._filter_injected_args(tool_input)
836
+ if isinstance(tool_input, dict)
837
+ else None
838
+ )
839
+
840
+ # Use filtered inputs for the input_str parameter as well
841
+ tool_input_str = (
842
+ tool_input
843
+ if isinstance(tool_input, str)
844
+ else str(
845
+ filtered_tool_input if filtered_tool_input is not None else tool_input
846
+ )
847
+ )
848
+
835
849
  run_manager = callback_manager.on_tool_start(
836
850
  {"name": self.name, "description": self.description},
837
- tool_input if isinstance(tool_input, str) else str(tool_input),
851
+ tool_input_str,
838
852
  color=start_color,
839
853
  name=run_name,
840
854
  run_id=run_id,
841
- # Inputs by definition should always be dicts.
842
- # For now, it's unclear whether this assumption is ever violated,
843
- # but if it is we will send a `None` value to the callback instead
844
- # TODO: will need to address issue via a patch.
845
- inputs=tool_input if isinstance(tool_input, dict) else None,
855
+ inputs=filtered_tool_input,
846
856
  **kwargs,
847
857
  )
848
858
 
849
859
  content = None
850
860
  artifact = None
851
861
  status = "success"
852
- error_to_raise: Union[Exception, KeyboardInterrupt, None] = None
862
+ error_to_raise: Exception | KeyboardInterrupt | None = None
853
863
  try:
854
864
  child_config = patch_config(config, callbacks=run_manager.get_child())
855
865
  with set_config_context(child_config) as context:
@@ -898,35 +908,35 @@ class ChildTool(BaseTool):
898
908
 
899
909
  async def arun(
900
910
  self,
901
- tool_input: Union[str, dict],
902
- verbose: Optional[bool] = None, # noqa: FBT001
903
- start_color: Optional[str] = "green",
904
- color: Optional[str] = "green",
911
+ tool_input: str | dict,
912
+ verbose: bool | None = None, # noqa: FBT001
913
+ start_color: str | None = "green",
914
+ color: str | None = "green",
905
915
  callbacks: Callbacks = None,
906
916
  *,
907
- tags: Optional[list[str]] = None,
908
- metadata: Optional[dict[str, Any]] = None,
909
- run_name: Optional[str] = None,
910
- run_id: Optional[uuid.UUID] = None,
911
- config: Optional[RunnableConfig] = None,
912
- tool_call_id: Optional[str] = None,
917
+ tags: list[str] | None = None,
918
+ metadata: dict[str, Any] | None = None,
919
+ run_name: str | None = None,
920
+ run_id: uuid.UUID | None = None,
921
+ config: RunnableConfig | None = None,
922
+ tool_call_id: str | None = None,
913
923
  **kwargs: Any,
914
924
  ) -> Any:
915
925
  """Run the tool asynchronously.
916
926
 
917
927
  Args:
918
928
  tool_input: The input to the tool.
919
- verbose: Whether to log the tool's progress. Defaults to None.
920
- start_color: The color to use when starting the tool. Defaults to 'green'.
921
- color: The color to use when ending the tool. Defaults to 'green'.
922
- callbacks: Callbacks to be called during tool execution. Defaults to None.
923
- tags: Optional list of tags associated with the tool. Defaults to None.
924
- metadata: Optional metadata associated with the tool. Defaults to None.
925
- run_name: The name of the run. Defaults to None.
926
- run_id: The id of the run. Defaults to None.
927
- config: The configuration for the tool. Defaults to None.
928
- tool_call_id: The id of the tool call. Defaults to None.
929
- kwargs: Keyword arguments to be passed to tool callbacks
929
+ verbose: Whether to log the tool's progress.
930
+ start_color: The color to use when starting the tool.
931
+ color: The color to use when ending the tool.
932
+ callbacks: Callbacks to be called during tool execution.
933
+ tags: Optional list of tags associated with the tool.
934
+ metadata: Optional metadata associated with the tool.
935
+ run_name: The name of the run.
936
+ run_id: The id of the run.
937
+ config: The configuration for the tool.
938
+ tool_call_id: The id of the tool call.
939
+ **kwargs: Keyword arguments to be passed to tool callbacks
930
940
 
931
941
  Returns:
932
942
  The output of the tool.
@@ -943,23 +953,36 @@ class ChildTool(BaseTool):
943
953
  metadata,
944
954
  self.metadata,
945
955
  )
956
+
957
+ # Filter out injected arguments from callback inputs
958
+ filtered_tool_input = (
959
+ self._filter_injected_args(tool_input)
960
+ if isinstance(tool_input, dict)
961
+ else None
962
+ )
963
+
964
+ # Use filtered inputs for the input_str parameter as well
965
+ tool_input_str = (
966
+ tool_input
967
+ if isinstance(tool_input, str)
968
+ else str(
969
+ filtered_tool_input if filtered_tool_input is not None else tool_input
970
+ )
971
+ )
972
+
946
973
  run_manager = await callback_manager.on_tool_start(
947
974
  {"name": self.name, "description": self.description},
948
- tool_input if isinstance(tool_input, str) else str(tool_input),
975
+ tool_input_str,
949
976
  color=start_color,
950
977
  name=run_name,
951
978
  run_id=run_id,
952
- # Inputs by definition should always be dicts.
953
- # For now, it's unclear whether this assumption is ever violated,
954
- # but if it is we will send a `None` value to the callback instead
955
- # TODO: will need to address issue via a patch.
956
- inputs=tool_input if isinstance(tool_input, dict) else None,
979
+ inputs=filtered_tool_input,
957
980
  **kwargs,
958
981
  )
959
982
  content = None
960
983
  artifact = None
961
984
  status = "success"
962
- error_to_raise: Optional[Union[Exception, KeyboardInterrupt]] = None
985
+ error_to_raise: Exception | KeyboardInterrupt | None = None
963
986
  try:
964
987
  tool_args, tool_kwargs = self._to_args_and_kwargs(tool_input, tool_call_id)
965
988
  child_config = patch_config(config, callbacks=run_manager.get_child())
@@ -1010,19 +1033,6 @@ class ChildTool(BaseTool):
1010
1033
  await run_manager.on_tool_end(output, color=color, name=self.name, **kwargs)
1011
1034
  return output
1012
1035
 
1013
- @deprecated("0.1.47", alternative="invoke", removal="1.0")
1014
- def __call__(self, tool_input: str, callbacks: Callbacks = None) -> str:
1015
- """Make tool callable (deprecated).
1016
-
1017
- Args:
1018
- tool_input: The input to the tool.
1019
- callbacks: Callbacks to use during execution.
1020
-
1021
- Returns:
1022
- The tool's output.
1023
- """
1024
- return self.run(tool_input, callbacks=callbacks)
1025
-
1026
1036
 
1027
1037
  def _is_tool_call(x: Any) -> bool:
1028
1038
  """Check if the input is a tool call dictionary.
@@ -1031,23 +1041,21 @@ def _is_tool_call(x: Any) -> bool:
1031
1041
  x: The input to check.
1032
1042
 
1033
1043
  Returns:
1034
- True if the input is a tool call, False otherwise.
1044
+ `True` if the input is a tool call, `False` otherwise.
1035
1045
  """
1036
1046
  return isinstance(x, dict) and x.get("type") == "tool_call"
1037
1047
 
1038
1048
 
1039
1049
  def _handle_validation_error(
1040
- e: Union[ValidationError, ValidationErrorV1],
1050
+ e: ValidationError | ValidationErrorV1,
1041
1051
  *,
1042
- flag: Union[
1043
- Literal[True], str, Callable[[Union[ValidationError, ValidationErrorV1]], str]
1044
- ],
1052
+ flag: Literal[True] | str | Callable[[ValidationError | ValidationErrorV1], str],
1045
1053
  ) -> str:
1046
1054
  """Handle validation errors based on the configured flag.
1047
1055
 
1048
1056
  Args:
1049
1057
  e: The validation error that occurred.
1050
- flag: How to handle the error (bool, string, or callable).
1058
+ flag: How to handle the error (`bool`, `str`, or `Callable`).
1051
1059
 
1052
1060
  Returns:
1053
1061
  The error message to return.
@@ -1073,13 +1081,13 @@ def _handle_validation_error(
1073
1081
  def _handle_tool_error(
1074
1082
  e: ToolException,
1075
1083
  *,
1076
- flag: Optional[Union[Literal[True], str, Callable[[ToolException], str]]],
1084
+ flag: Literal[True] | str | Callable[[ToolException], str] | None,
1077
1085
  ) -> str:
1078
1086
  """Handle tool execution errors based on the configured flag.
1079
1087
 
1080
1088
  Args:
1081
1089
  e: The tool exception that occurred.
1082
- flag: How to handle the error (bool, string, or callable).
1090
+ flag: How to handle the error (`bool`, `str`, or `Callable`).
1083
1091
 
1084
1092
  Returns:
1085
1093
  The error message to return.
@@ -1103,27 +1111,27 @@ def _handle_tool_error(
1103
1111
 
1104
1112
 
1105
1113
  def _prep_run_args(
1106
- value: Union[str, dict, ToolCall],
1107
- config: Optional[RunnableConfig],
1114
+ value: str | dict | ToolCall,
1115
+ config: RunnableConfig | None,
1108
1116
  **kwargs: Any,
1109
- ) -> tuple[Union[str, dict], dict]:
1117
+ ) -> tuple[str | dict, dict]:
1110
1118
  """Prepare arguments for tool execution.
1111
1119
 
1112
1120
  Args:
1113
- value: The input value (string, dict, or ToolCall).
1121
+ value: The input value (`str`, `dict`, or `ToolCall`).
1114
1122
  config: The runnable configuration.
1115
1123
  **kwargs: Additional keyword arguments.
1116
1124
 
1117
1125
  Returns:
1118
- A tuple of (tool_input, run_kwargs).
1126
+ A tuple of `(tool_input, run_kwargs)`.
1119
1127
  """
1120
1128
  config = ensure_config(config)
1121
1129
  if _is_tool_call(value):
1122
- tool_call_id: Optional[str] = cast("ToolCall", value)["id"]
1123
- tool_input: Union[str, dict] = cast("ToolCall", value)["args"].copy()
1130
+ tool_call_id: str | None = cast("ToolCall", value)["id"]
1131
+ tool_input: str | dict = cast("ToolCall", value)["args"].copy()
1124
1132
  else:
1125
1133
  tool_call_id = None
1126
- tool_input = cast("Union[str, dict]", value)
1134
+ tool_input = cast("str | dict", value)
1127
1135
  return (
1128
1136
  tool_input,
1129
1137
  dict(
@@ -1142,11 +1150,11 @@ def _prep_run_args(
1142
1150
  def _format_output(
1143
1151
  content: Any,
1144
1152
  artifact: Any,
1145
- tool_call_id: Optional[str],
1153
+ tool_call_id: str | None,
1146
1154
  name: str,
1147
1155
  status: str,
1148
- ) -> Union[ToolOutputMixin, Any]:
1149
- """Format tool output as a ToolMessage if appropriate.
1156
+ ) -> ToolOutputMixin | Any:
1157
+ """Format tool output as a `ToolMessage` if appropriate.
1150
1158
 
1151
1159
  Args:
1152
1160
  content: The main content of the tool output.
@@ -1156,7 +1164,7 @@ def _format_output(
1156
1164
  status: The execution status.
1157
1165
 
1158
1166
  Returns:
1159
- The formatted output, either as a ToolMessage or the original content.
1167
+ The formatted output, either as a `ToolMessage` or the original content.
1160
1168
  """
1161
1169
  if isinstance(content, ToolOutputMixin) or tool_call_id is None:
1162
1170
  return content
@@ -1180,7 +1188,7 @@ def _is_message_content_type(obj: Any) -> bool:
1180
1188
  obj: The object to check.
1181
1189
 
1182
1190
  Returns:
1183
- True if the object is valid message content, False otherwise.
1191
+ `True` if the object is valid message content, `False` otherwise.
1184
1192
  """
1185
1193
  return isinstance(obj, str) or (
1186
1194
  isinstance(obj, list) and all(_is_message_content_block(e) for e in obj)
@@ -1196,7 +1204,7 @@ def _is_message_content_block(obj: Any) -> bool:
1196
1204
  obj: The object to check.
1197
1205
 
1198
1206
  Returns:
1199
- True if the object is a valid content block, False otherwise.
1207
+ `True` if the object is a valid content block, `False` otherwise.
1200
1208
  """
1201
1209
  if isinstance(obj, str):
1202
1210
  return True
@@ -1220,14 +1228,14 @@ def _stringify(content: Any) -> str:
1220
1228
  return str(content)
1221
1229
 
1222
1230
 
1223
- def _get_type_hints(func: Callable) -> Optional[dict[str, type]]:
1231
+ def _get_type_hints(func: Callable) -> dict[str, type] | None:
1224
1232
  """Get type hints from a function, handling partial functions.
1225
1233
 
1226
1234
  Args:
1227
1235
  func: The function to get type hints from.
1228
1236
 
1229
1237
  Returns:
1230
- Dictionary of type hints, or None if extraction fails.
1238
+ `dict` of type hints, or `None` if extraction fails.
1231
1239
  """
1232
1240
  if isinstance(func, functools.partial):
1233
1241
  func = func.func
@@ -1237,14 +1245,14 @@ def _get_type_hints(func: Callable) -> Optional[dict[str, type]]:
1237
1245
  return None
1238
1246
 
1239
1247
 
1240
- def _get_runnable_config_param(func: Callable) -> Optional[str]:
1241
- """Find the parameter name for RunnableConfig in a function.
1248
+ def _get_runnable_config_param(func: Callable) -> str | None:
1249
+ """Find the parameter name for `RunnableConfig` in a function.
1242
1250
 
1243
1251
  Args:
1244
1252
  func: The function to check.
1245
1253
 
1246
1254
  Returns:
1247
- The parameter name for RunnableConfig, or None if not found.
1255
+ The parameter name for `RunnableConfig`, or `None` if not found.
1248
1256
  """
1249
1257
  type_hints = _get_type_hints(func)
1250
1258
  if not type_hints:
@@ -1263,35 +1271,75 @@ class InjectedToolArg:
1263
1271
  """
1264
1272
 
1265
1273
 
1274
+ class _DirectlyInjectedToolArg:
1275
+ """Annotation for tool arguments that are injected at runtime.
1276
+
1277
+ Injected via direct type annotation, rather than annotated metadata.
1278
+
1279
+ For example, `ToolRuntime` is a directly injected argument.
1280
+
1281
+ Note the direct annotation rather than the verbose alternative:
1282
+ `Annotated[ToolRuntime, InjectedRuntime]`
1283
+
1284
+ ```python
1285
+ from langchain_core.tools import tool, ToolRuntime
1286
+
1287
+
1288
+ @tool
1289
+ def foo(x: int, runtime: ToolRuntime) -> str:
1290
+ # use runtime.state, runtime.context, runtime.store, etc.
1291
+ ...
1292
+ ```
1293
+ """
1294
+
1295
+
1266
1296
  class InjectedToolCallId(InjectedToolArg):
1267
1297
  """Annotation for injecting the tool call ID.
1268
1298
 
1269
1299
  This annotation is used to mark a tool parameter that should receive
1270
1300
  the tool call ID at runtime.
1271
1301
 
1272
- .. code-block:: python
1273
-
1274
- from typing import Annotated
1275
- from langchain_core.messages import ToolMessage
1276
- from langchain_core.tools import tool, InjectedToolCallId
1277
-
1278
- @tool
1279
- def foo(
1280
- x: int, tool_call_id: Annotated[str, InjectedToolCallId]
1281
- ) -> ToolMessage:
1282
- \"\"\"Return x.\"\"\"
1283
- return ToolMessage(
1284
- str(x),
1285
- artifact=x,
1286
- name="foo",
1287
- tool_call_id=tool_call_id
1288
- )
1302
+ ```python
1303
+ from typing import Annotated
1304
+ from langchain_core.messages import ToolMessage
1305
+ from langchain_core.tools import tool, InjectedToolCallId
1306
+
1307
+ @tool
1308
+ def foo(
1309
+ x: int, tool_call_id: Annotated[str, InjectedToolCallId]
1310
+ ) -> ToolMessage:
1311
+ \"\"\"Return x.\"\"\"
1312
+ return ToolMessage(
1313
+ str(x),
1314
+ artifact=x,
1315
+ name="foo",
1316
+ tool_call_id=tool_call_id
1317
+ )
1289
1318
 
1319
+ ```
1290
1320
  """
1291
1321
 
1292
1322
 
1323
+ def _is_directly_injected_arg_type(type_: Any) -> bool:
1324
+ """Check if a type annotation indicates a directly injected argument.
1325
+
1326
+ This is currently only used for `ToolRuntime`.
1327
+ Checks if either the annotation itself is a subclass of `_DirectlyInjectedToolArg`
1328
+ or the origin of the annotation is a subclass of `_DirectlyInjectedToolArg`.
1329
+
1330
+ Ex: `ToolRuntime` or `ToolRuntime[ContextT, StateT]` would both return `True`.
1331
+ """
1332
+ return (
1333
+ isinstance(type_, type) and issubclass(type_, _DirectlyInjectedToolArg)
1334
+ ) or (
1335
+ (origin := get_origin(type_)) is not None
1336
+ and isinstance(origin, type)
1337
+ and issubclass(origin, _DirectlyInjectedToolArg)
1338
+ )
1339
+
1340
+
1293
1341
  def _is_injected_arg_type(
1294
- type_: Union[type, TypeVar], injected_type: Optional[type[InjectedToolArg]] = None
1342
+ type_: type | TypeVar, injected_type: type[InjectedToolArg] | None = None
1295
1343
  ) -> bool:
1296
1344
  """Check if a type annotation indicates an injected argument.
1297
1345
 
@@ -1300,9 +1348,17 @@ def _is_injected_arg_type(
1300
1348
  injected_type: The specific injected type to check for.
1301
1349
 
1302
1350
  Returns:
1303
- True if the type is an injected argument, False otherwise.
1351
+ `True` if the type is an injected argument, `False` otherwise.
1304
1352
  """
1305
- injected_type = injected_type or InjectedToolArg
1353
+ if injected_type is None:
1354
+ # if no injected type is specified,
1355
+ # check if the type is a directly injected argument
1356
+ if _is_directly_injected_arg_type(type_):
1357
+ return True
1358
+ injected_type = InjectedToolArg
1359
+
1360
+ # if the type is an Annotated type, check if annotated metadata
1361
+ # is an intance or subclass of the injected type
1306
1362
  return any(
1307
1363
  isinstance(arg, injected_type)
1308
1364
  or (isinstance(arg, type) and issubclass(arg, injected_type))
@@ -1311,23 +1367,23 @@ def _is_injected_arg_type(
1311
1367
 
1312
1368
 
1313
1369
  def get_all_basemodel_annotations(
1314
- cls: Union[TypeBaseModel, Any], *, default_to_bound: bool = True
1315
- ) -> dict[str, Union[type, TypeVar]]:
1316
- """Get all annotations from a Pydantic BaseModel and its parents.
1370
+ cls: TypeBaseModel | Any, *, default_to_bound: bool = True
1371
+ ) -> dict[str, type | TypeVar]:
1372
+ """Get all annotations from a Pydantic `BaseModel` and its parents.
1317
1373
 
1318
1374
  Args:
1319
- cls: The Pydantic BaseModel class.
1320
- default_to_bound: Whether to default to the bound of a TypeVar if it exists.
1375
+ cls: The Pydantic `BaseModel` class.
1376
+ default_to_bound: Whether to default to the bound of a `TypeVar` if it exists.
1321
1377
 
1322
1378
  Returns:
1323
- A dictionary of field names to their type annotations.
1379
+ `dict` of field names to their type annotations.
1324
1380
  """
1325
1381
  # cls has no subscript: cls = FooBar
1326
1382
  if isinstance(cls, type):
1327
1383
  fields = get_fields(cls)
1328
1384
  alias_map = {field.alias: name for name, field in fields.items() if field.alias}
1329
1385
 
1330
- annotations: dict[str, Union[type, TypeVar]] = {}
1386
+ annotations: dict[str, type | TypeVar] = {}
1331
1387
  for name, param in inspect.signature(cls).parameters.items():
1332
1388
  # Exclude hidden init args added by pydantic Config. For example if
1333
1389
  # BaseModel(extra="allow") then "extra_data" will part of init sig.
@@ -1368,7 +1424,7 @@ def get_all_basemodel_annotations(
1368
1424
  # generic_type_vars = (type vars in Baz)
1369
1425
  # generic_map = {type var in Baz: str}
1370
1426
  generic_type_vars: tuple = getattr(parent_origin, "__parameters__", ())
1371
- generic_map = dict(zip(generic_type_vars, get_args(parent)))
1427
+ generic_map = dict(zip(generic_type_vars, get_args(parent), strict=False))
1372
1428
  for field in getattr(parent_origin, "__annotations__", {}):
1373
1429
  annotations[field] = _replace_type_vars(
1374
1430
  annotations[field], generic_map, default_to_bound=default_to_bound
@@ -1381,20 +1437,20 @@ def get_all_basemodel_annotations(
1381
1437
 
1382
1438
 
1383
1439
  def _replace_type_vars(
1384
- type_: Union[type, TypeVar],
1385
- generic_map: Optional[dict[TypeVar, type]] = None,
1440
+ type_: type | TypeVar,
1441
+ generic_map: dict[TypeVar, type] | None = None,
1386
1442
  *,
1387
1443
  default_to_bound: bool = True,
1388
- ) -> Union[type, TypeVar]:
1389
- """Replace TypeVars in a type annotation with concrete types.
1444
+ ) -> type | TypeVar:
1445
+ """Replace `TypeVar`s in a type annotation with concrete types.
1390
1446
 
1391
1447
  Args:
1392
1448
  type_: The type annotation to process.
1393
- generic_map: Mapping of TypeVars to concrete types.
1394
- default_to_bound: Whether to use TypeVar bounds as defaults.
1449
+ generic_map: Mapping of `TypeVar`s to concrete types.
1450
+ default_to_bound: Whether to use `TypeVar` bounds as defaults.
1395
1451
 
1396
1452
  Returns:
1397
- The type with TypeVars replaced.
1453
+ The type with `TypeVar`s replaced.
1398
1454
  """
1399
1455
  generic_map = generic_map or {}
1400
1456
  if isinstance(type_, TypeVar):