langchain-core 1.0.0a6__py3-none-any.whl → 1.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. langchain_core/__init__.py +1 -1
  2. langchain_core/_api/__init__.py +3 -4
  3. langchain_core/_api/beta_decorator.py +23 -26
  4. langchain_core/_api/deprecation.py +51 -64
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +55 -48
  8. langchain_core/caches.py +65 -66
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +321 -336
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +454 -514
  13. langchain_core/callbacks/stdout.py +29 -30
  14. langchain_core/callbacks/streaming_stdout.py +32 -32
  15. langchain_core/callbacks/usage.py +60 -57
  16. langchain_core/chat_history.py +53 -68
  17. langchain_core/document_loaders/base.py +27 -25
  18. langchain_core/document_loaders/blob_loaders.py +1 -1
  19. langchain_core/document_loaders/langsmith.py +44 -48
  20. langchain_core/documents/__init__.py +23 -3
  21. langchain_core/documents/base.py +102 -94
  22. langchain_core/documents/compressor.py +10 -10
  23. langchain_core/documents/transformers.py +34 -35
  24. langchain_core/embeddings/fake.py +50 -54
  25. langchain_core/example_selectors/length_based.py +2 -2
  26. langchain_core/example_selectors/semantic_similarity.py +28 -32
  27. langchain_core/exceptions.py +21 -20
  28. langchain_core/globals.py +3 -151
  29. langchain_core/indexing/__init__.py +1 -1
  30. langchain_core/indexing/api.py +121 -126
  31. langchain_core/indexing/base.py +73 -75
  32. langchain_core/indexing/in_memory.py +4 -6
  33. langchain_core/language_models/__init__.py +14 -29
  34. langchain_core/language_models/_utils.py +58 -61
  35. langchain_core/language_models/base.py +82 -172
  36. langchain_core/language_models/chat_models.py +329 -402
  37. langchain_core/language_models/fake.py +11 -11
  38. langchain_core/language_models/fake_chat_models.py +42 -36
  39. langchain_core/language_models/llms.py +189 -269
  40. langchain_core/load/dump.py +9 -12
  41. langchain_core/load/load.py +18 -28
  42. langchain_core/load/mapping.py +2 -4
  43. langchain_core/load/serializable.py +42 -40
  44. langchain_core/messages/__init__.py +10 -16
  45. langchain_core/messages/ai.py +148 -148
  46. langchain_core/messages/base.py +53 -51
  47. langchain_core/messages/block_translators/__init__.py +19 -22
  48. langchain_core/messages/block_translators/anthropic.py +6 -6
  49. langchain_core/messages/block_translators/bedrock_converse.py +5 -5
  50. langchain_core/messages/block_translators/google_genai.py +10 -7
  51. langchain_core/messages/block_translators/google_vertexai.py +4 -32
  52. langchain_core/messages/block_translators/groq.py +117 -21
  53. langchain_core/messages/block_translators/langchain_v0.py +5 -5
  54. langchain_core/messages/block_translators/openai.py +11 -11
  55. langchain_core/messages/chat.py +2 -6
  56. langchain_core/messages/content.py +339 -330
  57. langchain_core/messages/function.py +6 -10
  58. langchain_core/messages/human.py +24 -31
  59. langchain_core/messages/modifier.py +2 -2
  60. langchain_core/messages/system.py +19 -29
  61. langchain_core/messages/tool.py +74 -90
  62. langchain_core/messages/utils.py +484 -510
  63. langchain_core/output_parsers/__init__.py +13 -10
  64. langchain_core/output_parsers/base.py +61 -61
  65. langchain_core/output_parsers/format_instructions.py +9 -4
  66. langchain_core/output_parsers/json.py +12 -10
  67. langchain_core/output_parsers/list.py +21 -23
  68. langchain_core/output_parsers/openai_functions.py +49 -47
  69. langchain_core/output_parsers/openai_tools.py +30 -23
  70. langchain_core/output_parsers/pydantic.py +13 -14
  71. langchain_core/output_parsers/string.py +5 -5
  72. langchain_core/output_parsers/transform.py +15 -17
  73. langchain_core/output_parsers/xml.py +35 -34
  74. langchain_core/outputs/__init__.py +1 -1
  75. langchain_core/outputs/chat_generation.py +18 -18
  76. langchain_core/outputs/chat_result.py +1 -3
  77. langchain_core/outputs/generation.py +16 -16
  78. langchain_core/outputs/llm_result.py +10 -10
  79. langchain_core/prompt_values.py +13 -19
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +81 -86
  82. langchain_core/prompts/chat.py +308 -351
  83. langchain_core/prompts/dict.py +6 -6
  84. langchain_core/prompts/few_shot.py +81 -88
  85. langchain_core/prompts/few_shot_with_templates.py +11 -13
  86. langchain_core/prompts/image.py +12 -14
  87. langchain_core/prompts/loading.py +4 -6
  88. langchain_core/prompts/message.py +7 -7
  89. langchain_core/prompts/prompt.py +24 -39
  90. langchain_core/prompts/string.py +26 -10
  91. langchain_core/prompts/structured.py +49 -53
  92. langchain_core/rate_limiters.py +51 -60
  93. langchain_core/retrievers.py +61 -198
  94. langchain_core/runnables/base.py +1551 -1656
  95. langchain_core/runnables/branch.py +68 -70
  96. langchain_core/runnables/config.py +72 -89
  97. langchain_core/runnables/configurable.py +145 -161
  98. langchain_core/runnables/fallbacks.py +102 -96
  99. langchain_core/runnables/graph.py +91 -97
  100. langchain_core/runnables/graph_ascii.py +27 -28
  101. langchain_core/runnables/graph_mermaid.py +42 -51
  102. langchain_core/runnables/graph_png.py +43 -16
  103. langchain_core/runnables/history.py +175 -177
  104. langchain_core/runnables/passthrough.py +151 -167
  105. langchain_core/runnables/retry.py +46 -51
  106. langchain_core/runnables/router.py +30 -35
  107. langchain_core/runnables/schema.py +75 -80
  108. langchain_core/runnables/utils.py +60 -67
  109. langchain_core/stores.py +85 -121
  110. langchain_core/structured_query.py +8 -8
  111. langchain_core/sys_info.py +29 -29
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +306 -245
  114. langchain_core/tools/convert.py +160 -155
  115. langchain_core/tools/render.py +10 -10
  116. langchain_core/tools/retriever.py +12 -11
  117. langchain_core/tools/simple.py +19 -24
  118. langchain_core/tools/structured.py +32 -39
  119. langchain_core/tracers/__init__.py +1 -9
  120. langchain_core/tracers/base.py +97 -99
  121. langchain_core/tracers/context.py +29 -52
  122. langchain_core/tracers/core.py +49 -53
  123. langchain_core/tracers/evaluation.py +11 -11
  124. langchain_core/tracers/event_stream.py +65 -64
  125. langchain_core/tracers/langchain.py +21 -21
  126. langchain_core/tracers/log_stream.py +45 -45
  127. langchain_core/tracers/memory_stream.py +3 -3
  128. langchain_core/tracers/root_listeners.py +16 -16
  129. langchain_core/tracers/run_collector.py +2 -4
  130. langchain_core/tracers/schemas.py +0 -129
  131. langchain_core/tracers/stdout.py +3 -3
  132. langchain_core/utils/__init__.py +1 -4
  133. langchain_core/utils/_merge.py +2 -2
  134. langchain_core/utils/aiter.py +57 -61
  135. langchain_core/utils/env.py +9 -9
  136. langchain_core/utils/function_calling.py +94 -188
  137. langchain_core/utils/html.py +7 -8
  138. langchain_core/utils/input.py +9 -6
  139. langchain_core/utils/interactive_env.py +1 -1
  140. langchain_core/utils/iter.py +36 -40
  141. langchain_core/utils/json.py +4 -3
  142. langchain_core/utils/json_schema.py +9 -9
  143. langchain_core/utils/mustache.py +8 -10
  144. langchain_core/utils/pydantic.py +35 -37
  145. langchain_core/utils/strings.py +6 -9
  146. langchain_core/utils/usage.py +1 -1
  147. langchain_core/utils/utils.py +66 -62
  148. langchain_core/vectorstores/base.py +182 -216
  149. langchain_core/vectorstores/in_memory.py +101 -176
  150. langchain_core/vectorstores/utils.py +5 -5
  151. langchain_core/version.py +1 -1
  152. langchain_core-1.0.4.dist-info/METADATA +69 -0
  153. langchain_core-1.0.4.dist-info/RECORD +172 -0
  154. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.4.dist-info}/WHEEL +1 -1
  155. langchain_core/memory.py +0 -120
  156. langchain_core/messages/block_translators/ollama.py +0 -47
  157. langchain_core/prompts/pipeline.py +0 -138
  158. langchain_core/pydantic_v1/__init__.py +0 -30
  159. langchain_core/pydantic_v1/dataclasses.py +0 -23
  160. langchain_core/pydantic_v1/main.py +0 -23
  161. langchain_core/tracers/langchain_v1.py +0 -31
  162. langchain_core/utils/loading.py +0 -35
  163. langchain_core-1.0.0a6.dist-info/METADATA +0 -67
  164. langchain_core-1.0.0a6.dist-info/RECORD +0 -181
  165. langchain_core-1.0.0a6.dist-info/entry_points.txt +0 -4
@@ -9,9 +9,7 @@ from typing import (
9
9
  Any,
10
10
  Generic,
11
11
  Literal,
12
- Optional,
13
12
  TypeVar,
14
- Union,
15
13
  overload,
16
14
  )
17
15
 
@@ -26,9 +24,9 @@ class NoLock:
26
24
 
27
25
  def __exit__(
28
26
  self,
29
- exc_type: Optional[type[BaseException]],
30
- exc_val: Optional[BaseException],
31
- exc_tb: Optional[TracebackType],
27
+ exc_type: type[BaseException] | None,
28
+ exc_val: BaseException | None,
29
+ exc_tb: TracebackType | None,
32
30
  ) -> Literal[False]:
33
31
  """Return False (exception not suppressed)."""
34
32
  return False
@@ -42,10 +40,10 @@ def tee_peer(
42
40
  peers: list[deque[T]],
43
41
  lock: AbstractContextManager[Any],
44
42
  ) -> Generator[T, None, None]:
45
- """An individual iterator of a :py:func:`~.tee`.
43
+ """An individual iterator of a `.tee`.
46
44
 
47
45
  This function is a generator that yields items from the shared iterator
48
- ``iterator``. It buffers items until the least advanced iterator has
46
+ `iterator`. It buffers items until the least advanced iterator has
49
47
  yielded them as well. The buffer is shared with all other peers.
50
48
 
51
49
  Args:
@@ -91,39 +89,39 @@ def tee_peer(
91
89
 
92
90
 
93
91
  class Tee(Generic[T]):
94
- """Create ``n`` separate asynchronous iterators over ``iterable``.
92
+ """Create `n` separate asynchronous iterators over `iterable`.
95
93
 
96
- This splits a single ``iterable`` into multiple iterators, each providing
94
+ This splits a single `iterable` into multiple iterators, each providing
97
95
  the same items in the same order.
98
96
  All child iterators may advance separately but share the same items
99
- from ``iterable`` -- when the most advanced iterator retrieves an item,
97
+ from `iterable` -- when the most advanced iterator retrieves an item,
100
98
  it is buffered until the least advanced iterator has yielded it as well.
101
- A ``tee`` works lazily and can handle an infinite ``iterable``, provided
99
+ A `tee` works lazily and can handle an infinite `iterable`, provided
102
100
  that all iterators advance.
103
101
 
104
- .. code-block:: python
105
-
106
- async def derivative(sensor_data):
107
- previous, current = a.tee(sensor_data, n=2)
108
- await a.anext(previous) # advance one iterator
109
- return a.map(operator.sub, previous, current)
110
-
111
- Unlike :py:func:`itertools.tee`, :py:func:`~.tee` returns a custom type instead
112
- of a :py:class:`tuple`. Like a tuple, it can be indexed, iterated and unpacked
113
- to get the child iterators. In addition, its :py:meth:`~.tee.aclose` method
114
- immediately closes all children, and it can be used in an ``async with`` context
102
+ ```python
103
+ async def derivative(sensor_data):
104
+ previous, current = a.tee(sensor_data, n=2)
105
+ await a.anext(previous) # advance one iterator
106
+ return a.map(operator.sub, previous, current)
107
+ ```
108
+
109
+ Unlike `itertools.tee`, `.tee` returns a custom type instead
110
+ of a :py`tuple`. Like a tuple, it can be indexed, iterated and unpacked
111
+ to get the child iterators. In addition, its `.tee.aclose` method
112
+ immediately closes all children, and it can be used in an `async with` context
115
113
  for the same effect.
116
114
 
117
- If ``iterable`` is an iterator and read elsewhere, ``tee`` will *not*
118
- provide these items. Also, ``tee`` must internally buffer each item until the
115
+ If `iterable` is an iterator and read elsewhere, `tee` will *not*
116
+ provide these items. Also, `tee` must internally buffer each item until the
119
117
  last iterator has yielded it; if the most and least advanced iterator differ
120
- by most data, using a :py:class:`list` is more efficient (but not lazy).
118
+ by most data, using a :py`list` is more efficient (but not lazy).
121
119
 
122
- If the underlying iterable is concurrency safe (``anext`` may be awaited
120
+ If the underlying iterable is concurrency safe (`anext` may be awaited
123
121
  concurrently) the resulting iterators are concurrency safe as well. Otherwise,
124
122
  the iterators are safe if there is only ever one single "most advanced" iterator.
125
- To enforce sequential use of ``anext``, provide a ``lock``
126
- - e.g. an :py:class:`asyncio.Lock` instance in an :py:mod:`asyncio` application -
123
+ To enforce sequential use of `anext`, provide a `lock`
124
+ - e.g. an :py`asyncio.Lock` instance in an :py:mod:`asyncio` application -
127
125
  and access is automatically synchronised.
128
126
 
129
127
  """
@@ -133,15 +131,15 @@ class Tee(Generic[T]):
133
131
  iterable: Iterator[T],
134
132
  n: int = 2,
135
133
  *,
136
- lock: Optional[AbstractContextManager[Any]] = None,
134
+ lock: AbstractContextManager[Any] | None = None,
137
135
  ):
138
- """Create a ``tee``.
136
+ """Create a `tee`.
139
137
 
140
138
  Args:
141
139
  iterable: The iterable to split.
142
- n: The number of iterators to create. Defaults to 2.
140
+ n: The number of iterators to create.
143
141
  lock: The lock to synchronise access to the shared buffers.
144
- Defaults to None.
142
+
145
143
  """
146
144
  self._iterator = iter(iterable)
147
145
  self._buffers: list[deque[T]] = [deque() for _ in range(n)]
@@ -165,9 +163,7 @@ class Tee(Generic[T]):
165
163
  @overload
166
164
  def __getitem__(self, item: slice) -> tuple[Iterator[T], ...]: ...
167
165
 
168
- def __getitem__(
169
- self, item: Union[int, slice]
170
- ) -> Union[Iterator[T], tuple[Iterator[T], ...]]:
166
+ def __getitem__(self, item: int | slice) -> Iterator[T] | tuple[Iterator[T], ...]:
171
167
  """Return the child iterator(s) at the given index or slice."""
172
168
  return self._children[item]
173
169
 
@@ -185,9 +181,9 @@ class Tee(Generic[T]):
185
181
 
186
182
  def __exit__(
187
183
  self,
188
- exc_type: Optional[type[BaseException]],
189
- exc_val: Optional[BaseException],
190
- exc_tb: Optional[TracebackType],
184
+ exc_type: type[BaseException] | None,
185
+ exc_val: BaseException | None,
186
+ exc_tb: TracebackType | None,
191
187
  ) -> Literal[False]:
192
188
  """Close all child iterators.
193
189
 
@@ -207,11 +203,11 @@ class Tee(Generic[T]):
207
203
  safetee = Tee
208
204
 
209
205
 
210
- def batch_iterate(size: Optional[int], iterable: Iterable[T]) -> Iterator[list[T]]:
206
+ def batch_iterate(size: int | None, iterable: Iterable[T]) -> Iterator[list[T]]:
211
207
  """Utility batching function.
212
208
 
213
209
  Args:
214
- size: The size of the batch. If None, returns a single batch.
210
+ size: The size of the batch. If `None`, returns a single batch.
215
211
  iterable: The iterable to batch.
216
212
 
217
213
  Yields:
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  import re
7
- from typing import Any, Callable, Union
7
+ from collections.abc import Callable
8
+ from typing import Any
8
9
 
9
10
  from langchain_core.exceptions import OutputParserException
10
11
 
@@ -19,7 +20,7 @@ def _replace_new_line(match: re.Match[str]) -> str:
19
20
  return match.group(1) + value + match.group(3)
20
21
 
21
22
 
22
- def _custom_parser(multiline_string: Union[str, bytes, bytearray]) -> str:
23
+ def _custom_parser(multiline_string: str | bytes | bytearray) -> str:
23
24
  r"""Custom parser for multiline strings.
24
25
 
25
26
  The LLM response for `action_input` may be a multiline
@@ -50,7 +51,7 @@ def parse_partial_json(s: str, *, strict: bool = False) -> Any:
50
51
 
51
52
  Args:
52
53
  s: The JSON string to parse.
53
- strict: Whether to use strict parsing. Defaults to False.
54
+ strict: Whether to use strict parsing.
54
55
 
55
56
  Returns:
56
57
  The parsed JSON object as a Python dictionary.
@@ -3,13 +3,13 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from copy import deepcopy
6
- from typing import TYPE_CHECKING, Any, Optional, Union
6
+ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  if TYPE_CHECKING:
9
9
  from collections.abc import Sequence
10
10
 
11
11
 
12
- def _retrieve_ref(path: str, schema: dict) -> Union[list, dict]:
12
+ def _retrieve_ref(path: str, schema: dict) -> list | dict:
13
13
  components = path.split("/")
14
14
  if components[0] != "#":
15
15
  msg = (
@@ -17,7 +17,7 @@ def _retrieve_ref(path: str, schema: dict) -> Union[list, dict]:
17
17
  "with #."
18
18
  )
19
19
  raise ValueError(msg)
20
- out: Union[list, dict] = schema
20
+ out: list | dict = schema
21
21
  for component in components[1:]:
22
22
  if component in out:
23
23
  if isinstance(out, list):
@@ -67,7 +67,7 @@ def _process_dict_properties(
67
67
  def _dereference_refs_helper(
68
68
  obj: Any,
69
69
  full_schema: dict[str, Any],
70
- processed_refs: Optional[set[str]],
70
+ processed_refs: set[str] | None,
71
71
  skip_keys: Sequence[str],
72
72
  shallow_refs: bool, # noqa: FBT001
73
73
  ) -> Any:
@@ -85,7 +85,7 @@ def _dereference_refs_helper(
85
85
  full_schema: The complete schema containing all definitions
86
86
  processed_refs: Set tracking currently processing refs (for cycle detection)
87
87
  skip_keys: Keys under which to skip recursion
88
- shallow_refs: If True, only break cycles; if False, deep-inline all refs
88
+ shallow_refs: If `True`, only break cycles; if False, deep-inline all refs
89
89
 
90
90
  Returns:
91
91
  The object with $ref properties resolved and merged with other properties.
@@ -167,8 +167,8 @@ def _dereference_refs_helper(
167
167
  def dereference_refs(
168
168
  schema_obj: dict,
169
169
  *,
170
- full_schema: Optional[dict] = None,
171
- skip_keys: Optional[Sequence[str]] = None,
170
+ full_schema: dict | None = None,
171
+ skip_keys: Sequence[str] | None = None,
172
172
  ) -> dict:
173
173
  """Resolve and inline JSON Schema $ref references in a schema object.
174
174
 
@@ -184,7 +184,7 @@ def dereference_refs(
184
184
  point to. If not provided, defaults to schema_obj (useful when the
185
185
  schema is self-contained).
186
186
  skip_keys: Controls recursion behavior and reference resolution depth:
187
- - If None (default): Only recurse under '$defs' and use shallow reference
187
+ - If `None` (Default): Only recurse under '$defs' and use shallow reference
188
188
  resolution (break cycles but don't deep-inline nested refs)
189
189
  - If provided (even as []): Recurse under all keys and use deep reference
190
190
  resolution (fully inline all nested references)
@@ -226,7 +226,7 @@ def dereference_refs(
226
226
  ... }
227
227
  >>> result = dereference_refs(schema) # Won't cause infinite recursion
228
228
 
229
- Note:
229
+ !!! note
230
230
  - Circular references are handled gracefully by breaking cycles
231
231
  - Mixed $ref objects (with both $ref and other properties) are supported
232
232
  - Additional properties in mixed $refs override resolved properties
@@ -12,8 +12,6 @@ from typing import (
12
12
  TYPE_CHECKING,
13
13
  Any,
14
14
  Literal,
15
- Optional,
16
- Union,
17
15
  cast,
18
16
  )
19
17
 
@@ -23,7 +21,7 @@ if TYPE_CHECKING:
23
21
  logger = logging.getLogger(__name__)
24
22
 
25
23
 
26
- Scopes: TypeAlias = list[Union[Literal[False, 0], Mapping[str, Any]]]
24
+ Scopes: TypeAlias = list[Literal[False, 0] | Mapping[str, Any]]
27
25
 
28
26
 
29
27
  # Globals
@@ -48,7 +46,7 @@ def grab_literal(template: str, l_del: str) -> tuple[str, str]:
48
46
  l_del: The left delimiter.
49
47
 
50
48
  Returns:
51
- tuple[str, str]: The literal and the template.
49
+ The literal and the template.
52
50
  """
53
51
  global _CURRENT_LINE
54
52
 
@@ -78,7 +76,7 @@ def l_sa_check(
78
76
  is_standalone: Whether the tag is standalone.
79
77
 
80
78
  Returns:
81
- bool: Whether the tag could be a standalone.
79
+ Whether the tag could be a standalone.
82
80
  """
83
81
  # If there is a newline, or the previous tag was a standalone
84
82
  if literal.find("\n") != -1 or is_standalone:
@@ -104,7 +102,7 @@ def r_sa_check(
104
102
  is_standalone: Whether the tag is standalone.
105
103
 
106
104
  Returns:
107
- bool: Whether the tag could be a standalone.
105
+ Whether the tag could be a standalone.
108
106
  """
109
107
  # Check right side if we might be a standalone
110
108
  if is_standalone and tag_type not in {"variable", "no escape"}:
@@ -126,7 +124,7 @@ def parse_tag(template: str, l_del: str, r_del: str) -> tuple[tuple[str, str], s
126
124
  r_del: The right delimiter.
127
125
 
128
126
  Returns:
129
- tuple[tuple[str, str], str]: The tag and the template.
127
+ The tag and the template.
130
128
 
131
129
  Raises:
132
130
  ChevronError: If the tag is unclosed.
@@ -331,7 +329,7 @@ def tokenize(
331
329
 
332
330
 
333
331
  def _html_escape(string: str) -> str:
334
- """Return the HTML-escaped string with these characters escaped: ``" & < >``."""
332
+ """Return the HTML-escaped string with these characters escaped: `" & < >`."""
335
333
  html_codes = {
336
334
  '"': "&quot;",
337
335
  "<": "&lt;",
@@ -433,13 +431,13 @@ EMPTY_DICT: MappingProxyType[str, str] = MappingProxyType({})
433
431
 
434
432
 
435
433
  def render(
436
- template: Union[str, list[tuple[str, str]]] = "",
434
+ template: str | list[tuple[str, str]] = "",
437
435
  data: Mapping[str, Any] = EMPTY_DICT,
438
436
  partials_dict: Mapping[str, str] = EMPTY_DICT,
439
437
  padding: str = "",
440
438
  def_ldel: str = "{{",
441
439
  def_rdel: str = "}}",
442
- scopes: Optional[Scopes] = None,
440
+ scopes: Scopes | None = None,
443
441
  warn: bool = False, # noqa: FBT001,FBT002
444
442
  keep: bool = False, # noqa: FBT001,FBT002
445
443
  ) -> str:
@@ -5,16 +5,14 @@ from __future__ import annotations
5
5
  import inspect
6
6
  import textwrap
7
7
  import warnings
8
+ from collections.abc import Callable
8
9
  from contextlib import nullcontext
9
10
  from functools import lru_cache, wraps
10
11
  from types import GenericAlias
11
12
  from typing import (
12
13
  TYPE_CHECKING,
13
14
  Any,
14
- Callable,
15
- Optional,
16
15
  TypeVar,
17
- Union,
18
16
  cast,
19
17
  overload,
20
18
  )
@@ -67,8 +65,8 @@ def get_pydantic_major_version() -> int:
67
65
  PYDANTIC_MAJOR_VERSION = PYDANTIC_VERSION.major
68
66
  PYDANTIC_MINOR_VERSION = PYDANTIC_VERSION.minor
69
67
 
70
- IS_PYDANTIC_V1 = PYDANTIC_VERSION.major == 1
71
- IS_PYDANTIC_V2 = PYDANTIC_VERSION.major == 2
68
+ IS_PYDANTIC_V1 = False
69
+ IS_PYDANTIC_V2 = True
72
70
 
73
71
  PydanticBaseModel = BaseModel
74
72
  TypeBaseModel = type[BaseModel]
@@ -80,7 +78,7 @@ def is_pydantic_v1_subclass(cls: type) -> bool:
80
78
  """Check if the given class is Pydantic v1-like.
81
79
 
82
80
  Returns:
83
- True if the given class is a subclass of Pydantic ``BaseModel`` 1.x.
81
+ `True` if the given class is a subclass of Pydantic `BaseModel` 1.x.
84
82
  """
85
83
  return issubclass(cls, BaseModelV1)
86
84
 
@@ -89,7 +87,7 @@ def is_pydantic_v2_subclass(cls: type) -> bool:
89
87
  """Check if the given class is Pydantic v2-like.
90
88
 
91
89
  Returns:
92
- True if the given class is a subclass of Pydantic BaseModel 2.x.
90
+ `True` if the given class is a subclass of Pydantic BaseModel 2.x.
93
91
  """
94
92
  return issubclass(cls, BaseModel)
95
93
 
@@ -103,7 +101,7 @@ def is_basemodel_subclass(cls: type) -> bool:
103
101
  * pydantic.v1.BaseModel in Pydantic 2.x
104
102
 
105
103
  Returns:
106
- True if the given class is a subclass of Pydantic ``BaseModel``.
104
+ `True` if the given class is a subclass of Pydantic `BaseModel`.
107
105
  """
108
106
  # Before we can use issubclass on the cls we need to check if it is a class
109
107
  if not inspect.isclass(cls) or isinstance(cls, GenericAlias):
@@ -121,7 +119,7 @@ def is_basemodel_instance(obj: Any) -> bool:
121
119
  * pydantic.v1.BaseModel in Pydantic 2.x
122
120
 
123
121
  Returns:
124
- True if the given class is an instance of Pydantic ``BaseModel``.
122
+ `True` if the given class is an instance of Pydantic `BaseModel`.
125
123
  """
126
124
  return isinstance(obj, (BaseModel, BaseModelV1))
127
125
 
@@ -131,10 +129,10 @@ def pre_init(func: Callable) -> Any:
131
129
  """Decorator to run a function before model initialization.
132
130
 
133
131
  Args:
134
- func (Callable): The function to run before model initialization.
132
+ func: The function to run before model initialization.
135
133
 
136
134
  Returns:
137
- Any: The decorated function.
135
+ The decorated function.
138
136
  """
139
137
  with warnings.catch_warnings():
140
138
  warnings.filterwarnings(action="ignore", category=PydanticDeprecationWarning)
@@ -148,11 +146,11 @@ def pre_init(func: Callable) -> Any:
148
146
  """Decorator to run a function before model initialization.
149
147
 
150
148
  Args:
151
- cls (Type[BaseModel]): The model class.
152
- values (dict[str, Any]): The values to initialize the model with.
149
+ cls: The model class.
150
+ values: The values to initialize the model with.
153
151
 
154
152
  Returns:
155
- dict[str, Any]: The values to initialize the model with.
153
+ The values to initialize the model with.
156
154
  """
157
155
  # Insert default values
158
156
  fields = cls.model_fields
@@ -205,10 +203,10 @@ def _create_subset_model_v1(
205
203
  model: type[BaseModelV1],
206
204
  field_names: list,
207
205
  *,
208
- descriptions: Optional[dict] = None,
209
- fn_description: Optional[str] = None,
206
+ descriptions: dict | None = None,
207
+ fn_description: str | None = None,
210
208
  ) -> type[BaseModel]:
211
- """Create a pydantic model with only a subset of model's fields."""
209
+ """Create a Pydantic model with only a subset of model's fields."""
212
210
  fields = {}
213
211
 
214
212
  for field_name in field_names:
@@ -218,7 +216,7 @@ def _create_subset_model_v1(
218
216
  # this isn't perfect but should work for most functions
219
217
  field.outer_type_
220
218
  if field.required and not field.allow_none
221
- else Optional[field.outer_type_]
219
+ else field.outer_type_ | None
222
220
  )
223
221
  if descriptions and field_name in descriptions:
224
222
  field.field_info.description = descriptions[field_name]
@@ -234,10 +232,10 @@ def _create_subset_model_v2(
234
232
  model: type[BaseModel],
235
233
  field_names: list[str],
236
234
  *,
237
- descriptions: Optional[dict] = None,
238
- fn_description: Optional[str] = None,
235
+ descriptions: dict | None = None,
236
+ fn_description: str | None = None,
239
237
  ) -> type[BaseModel]:
240
- """Create a pydantic model with a subset of the model fields."""
238
+ """Create a Pydantic model with a subset of the model fields."""
241
239
  descriptions_ = descriptions or {}
242
240
  fields = {}
243
241
  for field_name in field_names:
@@ -276,8 +274,8 @@ def _create_subset_model(
276
274
  model: TypeBaseModel,
277
275
  field_names: list[str],
278
276
  *,
279
- descriptions: Optional[dict] = None,
280
- fn_description: Optional[str] = None,
277
+ descriptions: dict | None = None,
278
+ fn_description: str | None = None,
281
279
  ) -> type[BaseModel]:
282
280
  """Create subset model using the same pydantic version as the input model.
283
281
 
@@ -318,8 +316,8 @@ def get_fields(model: BaseModelV1) -> dict[str, ModelField]: ...
318
316
 
319
317
 
320
318
  def get_fields(
321
- model: Union[type[Union[BaseModel, BaseModelV1]], BaseModel, BaseModelV1],
322
- ) -> Union[dict[str, FieldInfoV2], dict[str, ModelField]]:
319
+ model: type[BaseModel | BaseModelV1] | BaseModel | BaseModelV1,
320
+ ) -> dict[str, FieldInfoV2] | dict[str, ModelField]:
323
321
  """Return the field names of a Pydantic model.
324
322
 
325
323
  Args:
@@ -348,7 +346,7 @@ NO_DEFAULT = object()
348
346
  def _create_root_model(
349
347
  name: str,
350
348
  type_: Any,
351
- module_name: Optional[str] = None,
349
+ module_name: str | None = None,
352
350
  default_: object = NO_DEFAULT,
353
351
  ) -> type[BaseModel]:
354
352
  """Create a base class."""
@@ -413,7 +411,7 @@ def _create_root_model_cached(
413
411
  model_name: str,
414
412
  type_: Any,
415
413
  *,
416
- module_name: Optional[str] = None,
414
+ module_name: str | None = None,
417
415
  default_: object = NO_DEFAULT,
418
416
  ) -> type[BaseModel]:
419
417
  return _create_root_model(
@@ -436,13 +434,13 @@ def _create_model_cached(
436
434
 
437
435
  def create_model(
438
436
  model_name: str,
439
- module_name: Optional[str] = None,
437
+ module_name: str | None = None,
440
438
  /,
441
439
  **field_definitions: Any,
442
440
  ) -> type[BaseModel]:
443
- """Create a pydantic model with the given field definitions.
441
+ """Create a Pydantic model with the given field definitions.
444
442
 
445
- Please use create_model_v2 instead of this function.
443
+ Please use `create_model_v2` instead of this function.
446
444
 
447
445
  Args:
448
446
  model_name: The name of the model.
@@ -451,7 +449,7 @@ def create_model(
451
449
  **field_definitions: The field definitions for the model.
452
450
 
453
451
  Returns:
454
- Type[BaseModel]: The created model.
452
+ The created model.
455
453
  """
456
454
  kwargs = {}
457
455
  if "__root__" in field_definitions:
@@ -509,11 +507,11 @@ def _remap_field_definitions(field_definitions: dict[str, Any]) -> dict[str, Any
509
507
  def create_model_v2(
510
508
  model_name: str,
511
509
  *,
512
- module_name: Optional[str] = None,
513
- field_definitions: Optional[dict[str, Any]] = None,
514
- root: Optional[Any] = None,
510
+ module_name: str | None = None,
511
+ field_definitions: dict[str, Any] | None = None,
512
+ root: Any | None = None,
515
513
  ) -> type[BaseModel]:
516
- """Create a pydantic model with the given field definitions.
514
+ """Create a Pydantic model with the given field definitions.
517
515
 
518
516
  Attention:
519
517
  Please do not use outside of langchain packages. This API
@@ -524,10 +522,10 @@ def create_model_v2(
524
522
  module_name: The name of the module where the model is defined.
525
523
  This is used by Pydantic to resolve any forward references.
526
524
  field_definitions: The field definitions for the model.
527
- root: Type for a root model (RootModel)
525
+ root: Type for a root model (`RootModel`)
528
526
 
529
527
  Returns:
530
- Type[BaseModel]: The created model.
528
+ The created model.
531
529
  """
532
530
  field_definitions = field_definitions or {}
533
531
 
@@ -10,7 +10,7 @@ def stringify_value(val: Any) -> str:
10
10
  val: The value to stringify.
11
11
 
12
12
  Returns:
13
- str: The stringified value.
13
+ The stringified value.
14
14
  """
15
15
  if isinstance(val, str):
16
16
  return val
@@ -28,12 +28,9 @@ def stringify_dict(data: dict) -> str:
28
28
  data: The dictionary to stringify.
29
29
 
30
30
  Returns:
31
- str: The stringified dictionary.
31
+ The stringified dictionary.
32
32
  """
33
- text = ""
34
- for key, value in data.items():
35
- text += key + ": " + stringify_value(value) + "\n"
36
- return text
33
+ return "".join(f"{key}: {stringify_value(value)}\n" for key, value in data.items())
37
34
 
38
35
 
39
36
  def comma_list(items: list[Any]) -> str:
@@ -43,7 +40,7 @@ def comma_list(items: list[Any]) -> str:
43
40
  items: The list to convert.
44
41
 
45
42
  Returns:
46
- str: The comma-separated string.
43
+ The comma-separated string.
47
44
  """
48
45
  return ", ".join(str(item) for item in items)
49
46
 
@@ -57,10 +54,10 @@ def sanitize_for_postgres(text: str, replacement: str = "") -> str:
57
54
 
58
55
  Args:
59
56
  text: The text to sanitize.
60
- replacement: String to replace NUL bytes with. Defaults to empty string.
57
+ replacement: String to replace NUL bytes with.
61
58
 
62
59
  Returns:
63
- str: The sanitized text with NUL bytes removed or replaced.
60
+ The sanitized text with NUL bytes removed or replaced.
64
61
 
65
62
  Example:
66
63
  >>> sanitize_for_postgres("Hello\\x00world")
@@ -1,6 +1,6 @@
1
1
  """Usage utilities."""
2
2
 
3
- from typing import Callable
3
+ from collections.abc import Callable
4
4
 
5
5
 
6
6
  def _dict_int_op(