langchain-core 0.4.0.dev0__py3-none-any.whl → 1.0.0__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 (172) hide show
  1. langchain_core/__init__.py +1 -1
  2. langchain_core/_api/__init__.py +3 -4
  3. langchain_core/_api/beta_decorator.py +45 -70
  4. langchain_core/_api/deprecation.py +80 -80
  5. langchain_core/_api/path.py +22 -8
  6. langchain_core/_import_utils.py +10 -4
  7. langchain_core/agents.py +25 -21
  8. langchain_core/caches.py +53 -63
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +341 -348
  11. langchain_core/callbacks/file.py +55 -44
  12. langchain_core/callbacks/manager.py +546 -683
  13. langchain_core/callbacks/stdout.py +29 -30
  14. langchain_core/callbacks/streaming_stdout.py +35 -36
  15. langchain_core/callbacks/usage.py +65 -70
  16. langchain_core/chat_history.py +48 -55
  17. langchain_core/document_loaders/base.py +46 -21
  18. langchain_core/document_loaders/langsmith.py +39 -36
  19. langchain_core/documents/__init__.py +0 -1
  20. langchain_core/documents/base.py +96 -74
  21. langchain_core/documents/compressor.py +12 -9
  22. langchain_core/documents/transformers.py +29 -28
  23. langchain_core/embeddings/fake.py +56 -57
  24. langchain_core/env.py +2 -3
  25. langchain_core/example_selectors/base.py +12 -0
  26. langchain_core/example_selectors/length_based.py +1 -1
  27. langchain_core/example_selectors/semantic_similarity.py +21 -25
  28. langchain_core/exceptions.py +15 -9
  29. langchain_core/globals.py +4 -163
  30. langchain_core/indexing/api.py +132 -125
  31. langchain_core/indexing/base.py +64 -67
  32. langchain_core/indexing/in_memory.py +26 -6
  33. langchain_core/language_models/__init__.py +15 -27
  34. langchain_core/language_models/_utils.py +267 -117
  35. langchain_core/language_models/base.py +92 -177
  36. langchain_core/language_models/chat_models.py +547 -407
  37. langchain_core/language_models/fake.py +11 -11
  38. langchain_core/language_models/fake_chat_models.py +72 -118
  39. langchain_core/language_models/llms.py +168 -242
  40. langchain_core/load/dump.py +8 -11
  41. langchain_core/load/load.py +32 -28
  42. langchain_core/load/mapping.py +2 -4
  43. langchain_core/load/serializable.py +50 -56
  44. langchain_core/messages/__init__.py +36 -51
  45. langchain_core/messages/ai.py +377 -150
  46. langchain_core/messages/base.py +239 -47
  47. langchain_core/messages/block_translators/__init__.py +111 -0
  48. langchain_core/messages/block_translators/anthropic.py +470 -0
  49. langchain_core/messages/block_translators/bedrock.py +94 -0
  50. langchain_core/messages/block_translators/bedrock_converse.py +297 -0
  51. langchain_core/messages/block_translators/google_genai.py +530 -0
  52. langchain_core/messages/block_translators/google_vertexai.py +21 -0
  53. langchain_core/messages/block_translators/groq.py +143 -0
  54. langchain_core/messages/block_translators/langchain_v0.py +301 -0
  55. langchain_core/messages/block_translators/openai.py +1010 -0
  56. langchain_core/messages/chat.py +2 -3
  57. langchain_core/messages/content.py +1423 -0
  58. langchain_core/messages/function.py +7 -7
  59. langchain_core/messages/human.py +44 -38
  60. langchain_core/messages/modifier.py +3 -2
  61. langchain_core/messages/system.py +40 -27
  62. langchain_core/messages/tool.py +160 -58
  63. langchain_core/messages/utils.py +527 -638
  64. langchain_core/output_parsers/__init__.py +1 -14
  65. langchain_core/output_parsers/base.py +68 -104
  66. langchain_core/output_parsers/json.py +13 -17
  67. langchain_core/output_parsers/list.py +11 -33
  68. langchain_core/output_parsers/openai_functions.py +56 -74
  69. langchain_core/output_parsers/openai_tools.py +68 -109
  70. langchain_core/output_parsers/pydantic.py +15 -13
  71. langchain_core/output_parsers/string.py +6 -2
  72. langchain_core/output_parsers/transform.py +17 -60
  73. langchain_core/output_parsers/xml.py +34 -44
  74. langchain_core/outputs/__init__.py +1 -1
  75. langchain_core/outputs/chat_generation.py +26 -11
  76. langchain_core/outputs/chat_result.py +1 -3
  77. langchain_core/outputs/generation.py +17 -6
  78. langchain_core/outputs/llm_result.py +15 -8
  79. langchain_core/prompt_values.py +29 -123
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +48 -63
  82. langchain_core/prompts/chat.py +259 -288
  83. langchain_core/prompts/dict.py +19 -11
  84. langchain_core/prompts/few_shot.py +84 -90
  85. langchain_core/prompts/few_shot_with_templates.py +14 -12
  86. langchain_core/prompts/image.py +19 -14
  87. langchain_core/prompts/loading.py +6 -8
  88. langchain_core/prompts/message.py +7 -8
  89. langchain_core/prompts/prompt.py +42 -43
  90. langchain_core/prompts/string.py +37 -16
  91. langchain_core/prompts/structured.py +43 -46
  92. langchain_core/rate_limiters.py +51 -60
  93. langchain_core/retrievers.py +52 -192
  94. langchain_core/runnables/base.py +1727 -1683
  95. langchain_core/runnables/branch.py +52 -73
  96. langchain_core/runnables/config.py +89 -103
  97. langchain_core/runnables/configurable.py +128 -130
  98. langchain_core/runnables/fallbacks.py +93 -82
  99. langchain_core/runnables/graph.py +127 -127
  100. langchain_core/runnables/graph_ascii.py +63 -41
  101. langchain_core/runnables/graph_mermaid.py +87 -70
  102. langchain_core/runnables/graph_png.py +31 -36
  103. langchain_core/runnables/history.py +145 -161
  104. langchain_core/runnables/passthrough.py +141 -144
  105. langchain_core/runnables/retry.py +84 -68
  106. langchain_core/runnables/router.py +33 -37
  107. langchain_core/runnables/schema.py +79 -72
  108. langchain_core/runnables/utils.py +95 -139
  109. langchain_core/stores.py +85 -131
  110. langchain_core/structured_query.py +11 -15
  111. langchain_core/sys_info.py +31 -32
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +221 -247
  114. langchain_core/tools/convert.py +144 -161
  115. langchain_core/tools/render.py +10 -10
  116. langchain_core/tools/retriever.py +12 -19
  117. langchain_core/tools/simple.py +52 -29
  118. langchain_core/tools/structured.py +56 -60
  119. langchain_core/tracers/__init__.py +1 -9
  120. langchain_core/tracers/_streaming.py +6 -7
  121. langchain_core/tracers/base.py +103 -112
  122. langchain_core/tracers/context.py +29 -48
  123. langchain_core/tracers/core.py +142 -105
  124. langchain_core/tracers/evaluation.py +30 -34
  125. langchain_core/tracers/event_stream.py +162 -117
  126. langchain_core/tracers/langchain.py +34 -36
  127. langchain_core/tracers/log_stream.py +87 -49
  128. langchain_core/tracers/memory_stream.py +3 -3
  129. langchain_core/tracers/root_listeners.py +18 -34
  130. langchain_core/tracers/run_collector.py +8 -20
  131. langchain_core/tracers/schemas.py +0 -125
  132. langchain_core/tracers/stdout.py +3 -3
  133. langchain_core/utils/__init__.py +1 -4
  134. langchain_core/utils/_merge.py +47 -9
  135. langchain_core/utils/aiter.py +70 -66
  136. langchain_core/utils/env.py +12 -9
  137. langchain_core/utils/function_calling.py +139 -206
  138. langchain_core/utils/html.py +7 -8
  139. langchain_core/utils/input.py +6 -6
  140. langchain_core/utils/interactive_env.py +6 -2
  141. langchain_core/utils/iter.py +48 -45
  142. langchain_core/utils/json.py +14 -4
  143. langchain_core/utils/json_schema.py +159 -43
  144. langchain_core/utils/mustache.py +32 -25
  145. langchain_core/utils/pydantic.py +67 -40
  146. langchain_core/utils/strings.py +5 -5
  147. langchain_core/utils/usage.py +1 -1
  148. langchain_core/utils/utils.py +104 -62
  149. langchain_core/vectorstores/base.py +131 -179
  150. langchain_core/vectorstores/in_memory.py +113 -182
  151. langchain_core/vectorstores/utils.py +23 -17
  152. langchain_core/version.py +1 -1
  153. langchain_core-1.0.0.dist-info/METADATA +68 -0
  154. langchain_core-1.0.0.dist-info/RECORD +172 -0
  155. {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
  156. langchain_core/beta/__init__.py +0 -1
  157. langchain_core/beta/runnables/__init__.py +0 -1
  158. langchain_core/beta/runnables/context.py +0 -448
  159. langchain_core/memory.py +0 -116
  160. langchain_core/messages/content_blocks.py +0 -1435
  161. langchain_core/prompts/pipeline.py +0 -133
  162. langchain_core/pydantic_v1/__init__.py +0 -30
  163. langchain_core/pydantic_v1/dataclasses.py +0 -23
  164. langchain_core/pydantic_v1/main.py +0 -23
  165. langchain_core/tracers/langchain_v1.py +0 -23
  166. langchain_core/utils/loading.py +0 -31
  167. langchain_core/v1/__init__.py +0 -1
  168. langchain_core/v1/chat_models.py +0 -1047
  169. langchain_core/v1/messages.py +0 -755
  170. langchain_core-0.4.0.dev0.dist-info/METADATA +0 -108
  171. langchain_core-0.4.0.dev0.dist-info/RECORD +0 -177
  172. langchain_core-0.4.0.dev0.dist-info/entry_points.txt +0 -4
@@ -1,17 +1,4 @@
1
- """**OutputParser** classes parse the output of an LLM call.
2
-
3
- **Class hierarchy:**
4
-
5
- .. code-block::
6
-
7
- BaseLLMOutputParser --> BaseOutputParser --> <name>OutputParser # ListOutputParser, PydanticOutputParser
8
-
9
- **Main helpers:**
10
-
11
- .. code-block::
12
-
13
- Serializable, Generation, PromptValue
14
- """ # noqa: E501
1
+ """**OutputParser** classes parse the output of an LLM call."""
15
2
 
16
3
  from typing import TYPE_CHECKING
17
4
 
@@ -8,10 +8,7 @@ from typing import (
8
8
  TYPE_CHECKING,
9
9
  Any,
10
10
  Generic,
11
- Optional,
12
11
  TypeVar,
13
- Union,
14
- cast,
15
12
  )
16
13
 
17
14
  from typing_extensions import override
@@ -21,48 +18,45 @@ from langchain_core.messages import AnyMessage, BaseMessage
21
18
  from langchain_core.outputs import ChatGeneration, Generation
22
19
  from langchain_core.runnables import Runnable, RunnableConfig, RunnableSerializable
23
20
  from langchain_core.runnables.config import run_in_executor
24
- from langchain_core.v1.messages import AIMessage, MessageV1, MessageV1Types
25
21
 
26
22
  if TYPE_CHECKING:
27
23
  from langchain_core.prompt_values import PromptValue
28
24
 
29
25
  T = TypeVar("T")
30
- OutputParserLike = Runnable[Union[LanguageModelOutput, AIMessage], T]
26
+ OutputParserLike = Runnable[LanguageModelOutput, T]
31
27
 
32
28
 
33
29
  class BaseLLMOutputParser(ABC, Generic[T]):
34
30
  """Abstract base class for parsing the outputs of a model."""
35
31
 
36
32
  @abstractmethod
37
- def parse_result(
38
- self, result: Union[list[Generation], AIMessage], *, partial: bool = False
39
- ) -> T:
40
- """Parse a list of candidate model Generations into a specific format.
33
+ def parse_result(self, result: list[Generation], *, partial: bool = False) -> T:
34
+ """Parse a list of candidate model `Generation` objects into a specific format.
41
35
 
42
36
  Args:
43
- result: A list of Generations to be parsed. The Generations are assumed
44
- to be different candidate outputs for a single model input.
37
+ result: A list of `Generation` to be parsed. The `Generation` objects are
38
+ assumed to be different candidate outputs for a single model input.
45
39
  partial: Whether to parse the output as a partial result. This is useful
46
- for parsers that can parse partial results. Default is False.
40
+ for parsers that can parse partial results.
47
41
 
48
42
  Returns:
49
43
  Structured output.
50
44
  """
51
45
 
52
46
  async def aparse_result(
53
- self, result: Union[list[Generation], AIMessage], *, partial: bool = False
47
+ self, result: list[Generation], *, partial: bool = False
54
48
  ) -> T:
55
- """Async parse a list of candidate model Generations into a specific format.
49
+ """Async parse a list of candidate model `Generation` objects into a specific format.
56
50
 
57
51
  Args:
58
- result: A list of Generations to be parsed. The Generations are assumed
52
+ result: A list of `Generation` to be parsed. The Generations are assumed
59
53
  to be different candidate outputs for a single model input.
60
54
  partial: Whether to parse the output as a partial result. This is useful
61
- for parsers that can parse partial results. Default is False.
55
+ for parsers that can parse partial results.
62
56
 
63
57
  Returns:
64
58
  Structured output.
65
- """
59
+ """ # noqa: E501
66
60
  return await run_in_executor(None, self.parse_result, result, partial=partial)
67
61
 
68
62
 
@@ -75,7 +69,7 @@ class BaseGenerationOutputParser(
75
69
  @override
76
70
  def InputType(self) -> Any:
77
71
  """Return the input type for the parser."""
78
- return Union[str, AnyMessage, MessageV1]
72
+ return str | AnyMessage
79
73
 
80
74
  @property
81
75
  @override
@@ -88,8 +82,8 @@ class BaseGenerationOutputParser(
88
82
  @override
89
83
  def invoke(
90
84
  self,
91
- input: Union[str, BaseMessage, MessageV1],
92
- config: Optional[RunnableConfig] = None,
85
+ input: str | BaseMessage,
86
+ config: RunnableConfig | None = None,
93
87
  **kwargs: Any,
94
88
  ) -> T:
95
89
  if isinstance(input, BaseMessage):
@@ -101,16 +95,9 @@ class BaseGenerationOutputParser(
101
95
  config,
102
96
  run_type="parser",
103
97
  )
104
- if isinstance(input, MessageV1Types):
105
- return self._call_with_config(
106
- lambda inner_input: self.parse_result(inner_input),
107
- input,
108
- config,
109
- run_type="parser",
110
- )
111
98
  return self._call_with_config(
112
99
  lambda inner_input: self.parse_result([Generation(text=inner_input)]),
113
- cast("str", input),
100
+ input,
114
101
  config,
115
102
  run_type="parser",
116
103
  )
@@ -118,9 +105,9 @@ class BaseGenerationOutputParser(
118
105
  @override
119
106
  async def ainvoke(
120
107
  self,
121
- input: Union[str, BaseMessage],
122
- config: Optional[RunnableConfig] = None,
123
- **kwargs: Optional[Any],
108
+ input: str | BaseMessage,
109
+ config: RunnableConfig | None = None,
110
+ **kwargs: Any | None,
124
111
  ) -> T:
125
112
  if isinstance(input, BaseMessage):
126
113
  return await self._acall_with_config(
@@ -131,13 +118,6 @@ class BaseGenerationOutputParser(
131
118
  config,
132
119
  run_type="parser",
133
120
  )
134
- if isinstance(input, MessageV1Types):
135
- return await self._acall_with_config(
136
- lambda inner_input: self.aparse_result(inner_input),
137
- input,
138
- config,
139
- run_type="parser",
140
- )
141
121
  return await self._acall_with_config(
142
122
  lambda inner_input: self.aparse_result([Generation(text=inner_input)]),
143
123
  input,
@@ -147,40 +127,42 @@ class BaseGenerationOutputParser(
147
127
 
148
128
 
149
129
  class BaseOutputParser(
150
- BaseLLMOutputParser, RunnableSerializable[Union[LanguageModelOutput, AIMessage], T]
130
+ BaseLLMOutputParser, RunnableSerializable[LanguageModelOutput, T]
151
131
  ):
152
132
  """Base class to parse the output of an LLM call.
153
133
 
154
134
  Output parsers help structure language model responses.
155
135
 
156
136
  Example:
157
- .. code-block:: python
158
-
159
- class BooleanOutputParser(BaseOutputParser[bool]):
160
- true_val: str = "YES"
161
- false_val: str = "NO"
162
-
163
- def parse(self, text: str) -> bool:
164
- cleaned_text = text.strip().upper()
165
- if cleaned_text not in (self.true_val.upper(), self.false_val.upper()):
166
- raise OutputParserException(
167
- f"BooleanOutputParser expected output value to either be "
168
- f"{self.true_val} or {self.false_val} (case-insensitive). "
169
- f"Received {cleaned_text}."
170
- )
171
- return cleaned_text == self.true_val.upper()
172
-
173
- @property
174
- def _type(self) -> str:
175
- return "boolean_output_parser"
176
-
177
- """ # noqa: E501
137
+ ```python
138
+ class BooleanOutputParser(BaseOutputParser[bool]):
139
+ true_val: str = "YES"
140
+ false_val: str = "NO"
141
+
142
+ def parse(self, text: str) -> bool:
143
+ cleaned_text = text.strip().upper()
144
+ if cleaned_text not in (
145
+ self.true_val.upper(),
146
+ self.false_val.upper(),
147
+ ):
148
+ raise OutputParserException(
149
+ f"BooleanOutputParser expected output value to either be "
150
+ f"{self.true_val} or {self.false_val} (case-insensitive). "
151
+ f"Received {cleaned_text}."
152
+ )
153
+ return cleaned_text == self.true_val.upper()
154
+
155
+ @property
156
+ def _type(self) -> str:
157
+ return "boolean_output_parser"
158
+ ```
159
+ """
178
160
 
179
161
  @property
180
162
  @override
181
163
  def InputType(self) -> Any:
182
164
  """Return the input type for the parser."""
183
- return Union[str, AnyMessage, MessageV1]
165
+ return str | AnyMessage
184
166
 
185
167
  @property
186
168
  @override
@@ -190,7 +172,7 @@ class BaseOutputParser(
190
172
  This property is inferred from the first type argument of the class.
191
173
 
192
174
  Raises:
193
- TypeError: If the class doesn't have an inferable OutputType.
175
+ TypeError: If the class doesn't have an inferable `OutputType`.
194
176
  """
195
177
  for base in self.__class__.mro():
196
178
  if hasattr(base, "__pydantic_generic_metadata__"):
@@ -207,8 +189,8 @@ class BaseOutputParser(
207
189
  @override
208
190
  def invoke(
209
191
  self,
210
- input: Union[str, BaseMessage, MessageV1],
211
- config: Optional[RunnableConfig] = None,
192
+ input: str | BaseMessage,
193
+ config: RunnableConfig | None = None,
212
194
  **kwargs: Any,
213
195
  ) -> T:
214
196
  if isinstance(input, BaseMessage):
@@ -220,16 +202,9 @@ class BaseOutputParser(
220
202
  config,
221
203
  run_type="parser",
222
204
  )
223
- if isinstance(input, MessageV1Types):
224
- return self._call_with_config(
225
- lambda inner_input: self.parse_result(inner_input),
226
- input,
227
- config,
228
- run_type="parser",
229
- )
230
205
  return self._call_with_config(
231
206
  lambda inner_input: self.parse_result([Generation(text=inner_input)]),
232
- cast("str", input),
207
+ input,
233
208
  config,
234
209
  run_type="parser",
235
210
  )
@@ -237,9 +212,9 @@ class BaseOutputParser(
237
212
  @override
238
213
  async def ainvoke(
239
214
  self,
240
- input: Union[str, BaseMessage, MessageV1],
241
- config: Optional[RunnableConfig] = None,
242
- **kwargs: Optional[Any],
215
+ input: str | BaseMessage,
216
+ config: RunnableConfig | None = None,
217
+ **kwargs: Any | None,
243
218
  ) -> T:
244
219
  if isinstance(input, BaseMessage):
245
220
  return await self._acall_with_config(
@@ -250,40 +225,29 @@ class BaseOutputParser(
250
225
  config,
251
226
  run_type="parser",
252
227
  )
253
- if isinstance(input, MessageV1Types):
254
- return await self._acall_with_config(
255
- lambda inner_input: self.aparse_result(inner_input),
256
- input,
257
- config,
258
- run_type="parser",
259
- )
260
228
  return await self._acall_with_config(
261
229
  lambda inner_input: self.aparse_result([Generation(text=inner_input)]),
262
- cast("str", input),
230
+ input,
263
231
  config,
264
232
  run_type="parser",
265
233
  )
266
234
 
267
235
  @override
268
- def parse_result(
269
- self, result: Union[list[Generation], AIMessage], *, partial: bool = False
270
- ) -> T:
271
- """Parse a list of candidate model Generations into a specific format.
236
+ def parse_result(self, result: list[Generation], *, partial: bool = False) -> T:
237
+ """Parse a list of candidate model `Generation` objects into a specific format.
272
238
 
273
- The return value is parsed from only the first Generation in the result, which
274
- is assumed to be the highest-likelihood Generation.
239
+ The return value is parsed from only the first `Generation` in the result, which
240
+ is assumed to be the highest-likelihood `Generation`.
275
241
 
276
242
  Args:
277
- result: A list of Generations to be parsed. The Generations are assumed
278
- to be different candidate outputs for a single model input.
243
+ result: A list of `Generation` to be parsed. The `Generation` objects are
244
+ assumed to be different candidate outputs for a single model input.
279
245
  partial: Whether to parse the output as a partial result. This is useful
280
- for parsers that can parse partial results. Default is False.
246
+ for parsers that can parse partial results.
281
247
 
282
248
  Returns:
283
249
  Structured output.
284
250
  """
285
- if isinstance(result, AIMessage):
286
- return self.parse(result.text)
287
251
  return self.parse(result[0].text)
288
252
 
289
253
  @abstractmethod
@@ -298,22 +262,22 @@ class BaseOutputParser(
298
262
  """
299
263
 
300
264
  async def aparse_result(
301
- self, result: Union[list[Generation], AIMessage], *, partial: bool = False
265
+ self, result: list[Generation], *, partial: bool = False
302
266
  ) -> T:
303
- """Async parse a list of candidate model Generations into a specific format.
267
+ """Async parse a list of candidate model `Generation` objects into a specific format.
304
268
 
305
- The return value is parsed from only the first Generation in the result, which
306
- is assumed to be the highest-likelihood Generation.
269
+ The return value is parsed from only the first `Generation` in the result, which
270
+ is assumed to be the highest-likelihood `Generation`.
307
271
 
308
272
  Args:
309
- result: A list of Generations to be parsed. The Generations are assumed
310
- to be different candidate outputs for a single model input.
273
+ result: A list of `Generation` to be parsed. The `Generation` objects are
274
+ assumed to be different candidate outputs for a single model input.
311
275
  partial: Whether to parse the output as a partial result. This is useful
312
- for parsers that can parse partial results. Default is False.
276
+ for parsers that can parse partial results.
313
277
 
314
278
  Returns:
315
279
  Structured output.
316
- """
280
+ """ # noqa: E501
317
281
  return await run_in_executor(None, self.parse_result, result, partial=partial)
318
282
 
319
283
  async def aparse(self, text: str) -> T:
@@ -335,13 +299,13 @@ class BaseOutputParser(
335
299
  ) -> Any:
336
300
  """Parse the output of an LLM call with the input prompt for context.
337
301
 
338
- The prompt is largely provided in the event the OutputParser wants
302
+ The prompt is largely provided in the event the `OutputParser` wants
339
303
  to retry or fix the output in some way, and needs information from
340
304
  the prompt to do so.
341
305
 
342
306
  Args:
343
307
  completion: String output of a language model.
344
- prompt: Input PromptValue.
308
+ prompt: Input `PromptValue`.
345
309
 
346
310
  Returns:
347
311
  Structured output.
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  from json import JSONDecodeError
7
- from typing import Annotated, Any, Optional, TypeVar, Union
7
+ from typing import Annotated, Any, TypeVar
8
8
 
9
9
  import jsonpatch # type: ignore[import-untyped]
10
10
  import pydantic
@@ -21,10 +21,9 @@ from langchain_core.utils.json import (
21
21
  parse_json_markdown,
22
22
  parse_partial_json,
23
23
  )
24
- from langchain_core.v1.messages import AIMessage
25
24
 
26
25
  # Union type needs to be last assignment to PydanticBaseModel to make mypy happy.
27
- PydanticBaseModel = Union[BaseModel, pydantic.BaseModel]
26
+ PydanticBaseModel = BaseModel | pydantic.BaseModel
28
27
 
29
28
  TBaseModel = TypeVar("TBaseModel", bound=PydanticBaseModel)
30
29
 
@@ -39,33 +38,30 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
39
38
  describing the difference between the previous and the current object.
40
39
  """
41
40
 
42
- pydantic_object: Annotated[Optional[type[TBaseModel]], SkipValidation()] = None # type: ignore[valid-type]
41
+ pydantic_object: Annotated[type[TBaseModel] | None, SkipValidation()] = None # type: ignore[valid-type]
43
42
  """The Pydantic object to use for validation.
44
- If None, no validation is performed."""
43
+ If `None`, no validation is performed."""
45
44
 
46
45
  @override
47
- def _diff(self, prev: Optional[Any], next: Any) -> Any:
46
+ def _diff(self, prev: Any | None, next: Any) -> Any:
48
47
  return jsonpatch.make_patch(prev, next).patch
49
48
 
50
- def _get_schema(self, pydantic_object: type[TBaseModel]) -> dict[str, Any]:
49
+ @staticmethod
50
+ def _get_schema(pydantic_object: type[TBaseModel]) -> dict[str, Any]:
51
51
  if issubclass(pydantic_object, pydantic.BaseModel):
52
52
  return pydantic_object.model_json_schema()
53
- if issubclass(pydantic_object, pydantic.v1.BaseModel):
54
- return pydantic_object.schema()
55
- return None
53
+ return pydantic_object.schema()
56
54
 
57
- def parse_result(
58
- self, result: Union[list[Generation], AIMessage], *, partial: bool = False
59
- ) -> Any:
55
+ @override
56
+ def parse_result(self, result: list[Generation], *, partial: bool = False) -> Any:
60
57
  """Parse the result of an LLM call to a JSON object.
61
58
 
62
59
  Args:
63
60
  result: The result of the LLM call.
64
61
  partial: Whether to parse partial JSON objects.
65
- If True, the output will be a JSON object containing
62
+ If `True`, the output will be a JSON object containing
66
63
  all the keys that have been returned so far.
67
- If False, the output will be the full JSON object.
68
- Default is False.
64
+ If `False`, the output will be the full JSON object.
69
65
 
70
66
  Returns:
71
67
  The parsed JSON object.
@@ -73,7 +69,7 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
73
69
  Raises:
74
70
  OutputParserException: If the output is not valid JSON.
75
71
  """
76
- text = result.text if isinstance(result, AIMessage) else result[0].text
72
+ text = result[0].text
77
73
  text = text.strip()
78
74
  if partial:
79
75
  try:
@@ -7,13 +7,12 @@ import re
7
7
  from abc import abstractmethod
8
8
  from collections import deque
9
9
  from io import StringIO
10
- from typing import TYPE_CHECKING, TypeVar, Union
10
+ from typing import TYPE_CHECKING, TypeVar
11
11
 
12
12
  from typing_extensions import override
13
13
 
14
14
  from langchain_core.messages import BaseMessage
15
15
  from langchain_core.output_parsers.transform import BaseTransformOutputParser
16
- from langchain_core.v1.messages import AIMessage
17
16
 
18
17
  if TYPE_CHECKING:
19
18
  from collections.abc import AsyncIterator, Iterator
@@ -71,9 +70,7 @@ class ListOutputParser(BaseTransformOutputParser[list[str]]):
71
70
  raise NotImplementedError
72
71
 
73
72
  @override
74
- def _transform(
75
- self, input: Iterator[Union[str, BaseMessage, AIMessage]]
76
- ) -> Iterator[list[str]]:
73
+ def _transform(self, input: Iterator[str | BaseMessage]) -> Iterator[list[str]]:
77
74
  buffer = ""
78
75
  for chunk in input:
79
76
  if isinstance(chunk, BaseMessage):
@@ -82,8 +79,6 @@ class ListOutputParser(BaseTransformOutputParser[list[str]]):
82
79
  if not isinstance(chunk_content, str):
83
80
  continue
84
81
  buffer += chunk_content
85
- elif isinstance(chunk, AIMessage):
86
- buffer += chunk.text
87
82
  else:
88
83
  # add current chunk to buffer
89
84
  buffer += chunk
@@ -108,7 +103,7 @@ class ListOutputParser(BaseTransformOutputParser[list[str]]):
108
103
 
109
104
  @override
110
105
  async def _atransform(
111
- self, input: AsyncIterator[Union[str, BaseMessage, AIMessage]]
106
+ self, input: AsyncIterator[str | BaseMessage]
112
107
  ) -> AsyncIterator[list[str]]:
113
108
  buffer = ""
114
109
  async for chunk in input:
@@ -118,8 +113,6 @@ class ListOutputParser(BaseTransformOutputParser[list[str]]):
118
113
  if not isinstance(chunk_content, str):
119
114
  continue
120
115
  buffer += chunk_content
121
- elif isinstance(chunk, AIMessage):
122
- buffer += chunk.text
123
116
  else:
124
117
  # add current chunk to buffer
125
118
  buffer += chunk
@@ -148,22 +141,19 @@ class CommaSeparatedListOutputParser(ListOutputParser):
148
141
 
149
142
  @classmethod
150
143
  def is_lc_serializable(cls) -> bool:
151
- """Check if the langchain object is serializable.
152
-
153
- Returns True.
154
- """
144
+ """Return True as this class is serializable."""
155
145
  return True
156
146
 
157
147
  @classmethod
158
148
  def get_lc_namespace(cls) -> list[str]:
159
- """Get the namespace of the langchain object.
149
+ """Get the namespace of the LangChain object.
160
150
 
161
151
  Returns:
162
- A list of strings.
163
- Default is ["langchain", "output_parsers", "list"].
152
+ `["langchain", "output_parsers", "list"]`
164
153
  """
165
154
  return ["langchain", "output_parsers", "list"]
166
155
 
156
+ @override
167
157
  def get_format_instructions(self) -> str:
168
158
  """Return the format instructions for the comma-separated list output."""
169
159
  return (
@@ -171,6 +161,7 @@ class CommaSeparatedListOutputParser(ListOutputParser):
171
161
  "eg: `foo, bar, baz` or `foo,bar,baz`"
172
162
  )
173
163
 
164
+ @override
174
165
  def parse(self, text: str) -> list[str]:
175
166
  """Parse the output of an LLM call.
176
167
 
@@ -218,15 +209,8 @@ class NumberedListOutputParser(ListOutputParser):
218
209
  """
219
210
  return re.findall(self.pattern, text)
220
211
 
212
+ @override
221
213
  def parse_iter(self, text: str) -> Iterator[re.Match]:
222
- """Parse the output of an LLM call.
223
-
224
- Args:
225
- text: The output of an LLM call.
226
-
227
- Yields:
228
- A match object for each part of the output.
229
- """
230
214
  return re.finditer(self.pattern, text)
231
215
 
232
216
  @property
@@ -240,6 +224,7 @@ class MarkdownListOutputParser(ListOutputParser):
240
224
  pattern: str = r"^\s*[-*]\s([^\n]+)$"
241
225
  """The pattern to match a Markdown list item."""
242
226
 
227
+ @override
243
228
  def get_format_instructions(self) -> str:
244
229
  """Return the format instructions for the Markdown list output."""
245
230
  return "Your response should be a markdown list, eg: `- foo\n- bar\n- baz`"
@@ -255,15 +240,8 @@ class MarkdownListOutputParser(ListOutputParser):
255
240
  """
256
241
  return re.findall(self.pattern, text, re.MULTILINE)
257
242
 
243
+ @override
258
244
  def parse_iter(self, text: str) -> Iterator[re.Match]:
259
- """Parse the output of an LLM call.
260
-
261
- Args:
262
- text: The output of an LLM call.
263
-
264
- Yields:
265
- A match object for each part of the output.
266
- """
267
245
  return re.finditer(self.pattern, text, re.MULTILINE)
268
246
 
269
247
  @property