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
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
5
+ from typing import TYPE_CHECKING, Any, cast, overload
6
6
 
7
7
  from pydantic import ConfigDict, Field
8
8
  from typing_extensions import Self
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
22
22
 
23
23
  def _extract_reasoning_from_additional_kwargs(
24
24
  message: BaseMessage,
25
- ) -> Optional[types.ReasoningContentBlock]:
25
+ ) -> types.ReasoningContentBlock | None:
26
26
  """Extract `reasoning_content` from `additional_kwargs`.
27
27
 
28
28
  Handles reasoning content stored in various formats:
@@ -34,13 +34,11 @@ def _extract_reasoning_from_additional_kwargs(
34
34
  Returns:
35
35
  A `ReasoningContentBlock` if reasoning content is found, None otherwise.
36
36
  """
37
- from langchain_core.messages.content import create_reasoning_block # noqa: PLC0415
38
-
39
37
  additional_kwargs = getattr(message, "additional_kwargs", {})
40
38
 
41
39
  reasoning_content = additional_kwargs.get("reasoning_content")
42
40
  if reasoning_content is not None and isinstance(reasoning_content, str):
43
- return create_reasoning_block(reasoning=reasoning_content)
41
+ return {"type": "reasoning", "reasoning": reasoning_content}
44
42
 
45
43
  return None
46
44
 
@@ -50,13 +48,13 @@ class TextAccessor(str):
50
48
 
51
49
  Exists to maintain backward compatibility while transitioning from method-based to
52
50
  property-based text access in message objects. In LangChain <v1.0, message text was
53
- accessed via ``.text()`` method calls. In v1.0=<, the preferred pattern is property
54
- access via ``.text``.
51
+ accessed via `.text()` method calls. In v1.0=<, the preferred pattern is property
52
+ access via `.text`.
55
53
 
56
- Rather than breaking existing code immediately, ``TextAccessor`` allows both
54
+ Rather than breaking existing code immediately, `TextAccessor` allows both
57
55
  patterns:
58
- - Modern property access: ``message.text`` (returns string directly)
59
- - Legacy method access: ``message.text()`` (callable, emits deprecation warning)
56
+ - Modern property access: `message.text` (returns string directly)
57
+ - Legacy method access: `message.text()` (callable, emits deprecation warning)
60
58
 
61
59
  """
62
60
 
@@ -69,12 +67,12 @@ class TextAccessor(str):
69
67
  def __call__(self) -> str:
70
68
  """Enable method-style text access for backward compatibility.
71
69
 
72
- This method exists solely to support legacy code that calls ``.text()``
73
- as a method. New code should use property access (``.text``) instead.
70
+ This method exists solely to support legacy code that calls `.text()`
71
+ as a method. New code should use property access (`.text`) instead.
74
72
 
75
- .. deprecated:: 1.0.0
76
- Calling ``.text()`` as a method is deprecated. Use ``.text`` as a property
77
- instead. This method will be removed in 2.0.0.
73
+ !!! deprecated
74
+ As of `langchain-core` 1.0.0, calling `.text()` as a method is deprecated.
75
+ Use `.text` as a property instead. This method will be removed in 2.0.0.
78
76
 
79
77
  Returns:
80
78
  The string content, identical to property access.
@@ -94,11 +92,15 @@ class TextAccessor(str):
94
92
  class BaseMessage(Serializable):
95
93
  """Base abstract message class.
96
94
 
97
- Messages are the inputs and outputs of ``ChatModel``s.
95
+ Messages are the inputs and outputs of a chat model.
96
+
97
+ Examples include [`HumanMessage`][langchain.messages.HumanMessage],
98
+ [`AIMessage`][langchain.messages.AIMessage], and
99
+ [`SystemMessage`][langchain.messages.SystemMessage].
98
100
  """
99
101
 
100
- content: Union[str, list[Union[str, dict]]]
101
- """The string contents of the message."""
102
+ content: str | list[str | dict]
103
+ """The contents of the message."""
102
104
 
103
105
  additional_kwargs: dict = Field(default_factory=dict)
104
106
  """Reserved for additional payload data associated with the message.
@@ -119,7 +121,7 @@ class BaseMessage(Serializable):
119
121
 
120
122
  """
121
123
 
122
- name: Optional[str] = None
124
+ name: str | None = None
123
125
  """An optional name for the message.
124
126
 
125
127
  This can be used to provide a human-readable name for the message.
@@ -129,7 +131,7 @@ class BaseMessage(Serializable):
129
131
 
130
132
  """
131
133
 
132
- id: Optional[str] = Field(default=None, coerce_numbers_to_str=True)
134
+ id: str | None = Field(default=None, coerce_numbers_to_str=True)
133
135
  """An optional unique identifier for the message.
134
136
 
135
137
  This should ideally be provided by the provider/model which created the message.
@@ -143,32 +145,32 @@ class BaseMessage(Serializable):
143
145
  @overload
144
146
  def __init__(
145
147
  self,
146
- content: Union[str, list[Union[str, dict]]],
148
+ content: str | list[str | dict],
147
149
  **kwargs: Any,
148
150
  ) -> None: ...
149
151
 
150
152
  @overload
151
153
  def __init__(
152
154
  self,
153
- content: Optional[Union[str, list[Union[str, dict]]]] = None,
154
- content_blocks: Optional[list[types.ContentBlock]] = None,
155
+ content: str | list[str | dict] | None = None,
156
+ content_blocks: list[types.ContentBlock] | None = None,
155
157
  **kwargs: Any,
156
158
  ) -> None: ...
157
159
 
158
160
  def __init__(
159
161
  self,
160
- content: Optional[Union[str, list[Union[str, dict]]]] = None,
161
- content_blocks: Optional[list[types.ContentBlock]] = None,
162
+ content: str | list[str | dict] | None = None,
163
+ content_blocks: list[types.ContentBlock] | None = None,
162
164
  **kwargs: Any,
163
165
  ) -> None:
164
- """Initialize ``BaseMessage``.
166
+ """Initialize a `BaseMessage`.
165
167
 
166
- Specify ``content`` as positional arg or ``content_blocks`` for typing.
168
+ Specify `content` as positional arg or `content_blocks` for typing.
167
169
 
168
170
  Args:
169
- content: The string contents of the message.
171
+ content: The contents of the message.
170
172
  content_blocks: Typed standard content.
171
- kwargs: Additional arguments to pass to the parent class.
173
+ **kwargs: Additional arguments to pass to the parent class.
172
174
  """
173
175
  if content_blocks is not None:
174
176
  super().__init__(content=content_blocks, **kwargs)
@@ -177,7 +179,7 @@ class BaseMessage(Serializable):
177
179
 
178
180
  @classmethod
179
181
  def is_lc_serializable(cls) -> bool:
180
- """``BaseMessage`` is serializable.
182
+ """`BaseMessage` is serializable.
181
183
 
182
184
  Returns:
183
185
  True
@@ -186,10 +188,10 @@ class BaseMessage(Serializable):
186
188
 
187
189
  @classmethod
188
190
  def get_lc_namespace(cls) -> list[str]:
189
- """Get the namespace of the langchain object.
191
+ """Get the namespace of the LangChain object.
190
192
 
191
193
  Returns:
192
- ``["langchain", "schema", "messages"]``
194
+ `["langchain", "schema", "messages"]`
193
195
  """
194
196
  return ["langchain", "schema", "messages"]
195
197
 
@@ -197,7 +199,7 @@ class BaseMessage(Serializable):
197
199
  def content_blocks(self) -> list[types.ContentBlock]:
198
200
  r"""Load content blocks from the message content.
199
201
 
200
- .. versionadded:: 1.0.0
202
+ !!! version-added "Added in version 1.0.0"
201
203
 
202
204
  """
203
205
  # Needed here to avoid circular import, as these classes import BaseMessages
@@ -208,6 +210,9 @@ class BaseMessage(Serializable):
208
210
  from langchain_core.messages.block_translators.bedrock_converse import ( # noqa: PLC0415
209
211
  _convert_to_v1_from_converse_input,
210
212
  )
213
+ from langchain_core.messages.block_translators.google_genai import ( # noqa: PLC0415
214
+ _convert_to_v1_from_genai_input,
215
+ )
211
216
  from langchain_core.messages.block_translators.langchain_v0 import ( # noqa: PLC0415
212
217
  _convert_v0_multimodal_input_to_v1,
213
218
  )
@@ -243,11 +248,12 @@ class BaseMessage(Serializable):
243
248
  blocks.append(cast("types.ContentBlock", item))
244
249
 
245
250
  # Subsequent passes: attempt to unpack non-standard blocks.
246
- # The block is left as non-standard if conversion fails.
251
+ # This is the last stop - if we can't parse it here, it is left as non-standard
247
252
  for parsing_step in [
248
253
  _convert_v0_multimodal_input_to_v1,
249
254
  _convert_to_v1_from_chat_completions_input,
250
255
  _convert_to_v1_from_anthropic_input,
256
+ _convert_to_v1_from_genai_input,
251
257
  _convert_to_v1_from_converse_input,
252
258
  ]:
253
259
  blocks = parsing_step(blocks)
@@ -257,11 +263,11 @@ class BaseMessage(Serializable):
257
263
  def text(self) -> TextAccessor:
258
264
  """Get the text content of the message as a string.
259
265
 
260
- Can be used as both property (``message.text``) and method (``message.text()``).
266
+ Can be used as both property (`message.text`) and method (`message.text()`).
261
267
 
262
- .. deprecated:: 1.0.0
263
- Calling ``.text()`` as a method is deprecated. Use ``.text`` as a property
264
- instead. This method will be removed in 2.0.0.
268
+ !!! deprecated
269
+ As of `langchain-core` 1.0.0, calling `.text()` as a method is deprecated.
270
+ Use `.text` as a property instead. This method will be removed in 2.0.0.
265
271
 
266
272
  Returns:
267
273
  The text content of the message.
@@ -304,8 +310,8 @@ class BaseMessage(Serializable):
304
310
  """Get a pretty representation of the message.
305
311
 
306
312
  Args:
307
- html: Whether to format the message as HTML. If True, the message will be
308
- formatted with HTML tags. Default is False.
313
+ html: Whether to format the message as HTML. If `True`, the message will be
314
+ formatted with HTML tags.
309
315
 
310
316
  Returns:
311
317
  A pretty representation of the message.
@@ -323,20 +329,20 @@ class BaseMessage(Serializable):
323
329
 
324
330
 
325
331
  def merge_content(
326
- first_content: Union[str, list[Union[str, dict]]],
327
- *contents: Union[str, list[Union[str, dict]]],
328
- ) -> Union[str, list[Union[str, dict]]]:
332
+ first_content: str | list[str | dict],
333
+ *contents: str | list[str | dict],
334
+ ) -> str | list[str | dict]:
329
335
  """Merge multiple message contents.
330
336
 
331
337
  Args:
332
- first_content: The first ``content``. Can be a string or a list.
333
- contents: The other ``content``s. Can be a string or a list.
338
+ first_content: The first `content`. Can be a string or a list.
339
+ contents: The other `content`s. Can be a string or a list.
334
340
 
335
341
  Returns:
336
342
  The merged content.
337
343
 
338
344
  """
339
- merged: Union[str, list[Union[str, dict]]]
345
+ merged: str | list[str | dict]
340
346
  merged = "" if first_content is None else first_content
341
347
 
342
348
  for content in contents:
@@ -386,9 +392,9 @@ class BaseMessageChunk(BaseMessage):
386
392
 
387
393
  For example,
388
394
 
389
- ``AIMessageChunk(content="Hello") + AIMessageChunk(content=" World")``
395
+ `AIMessageChunk(content="Hello") + AIMessageChunk(content=" World")`
390
396
 
391
- will give ``AIMessageChunk(content="Hello World")``
397
+ will give `AIMessageChunk(content="Hello World")`
392
398
 
393
399
  """
394
400
  if isinstance(other, BaseMessageChunk):
@@ -437,8 +443,8 @@ def message_to_dict(message: BaseMessage) -> dict:
437
443
  message: Message to convert.
438
444
 
439
445
  Returns:
440
- Message as a dict. The dict will have a ``type`` key with the message type
441
- and a ``data`` key with the message data as a dict.
446
+ Message as a dict. The dict will have a `type` key with the message type
447
+ and a `data` key with the message data as a dict.
442
448
 
443
449
  """
444
450
  return {"type": message.type, "data": message.model_dump()}
@@ -448,7 +454,7 @@ def messages_to_dict(messages: Sequence[BaseMessage]) -> list[dict]:
448
454
  """Convert a sequence of Messages to a list of dictionaries.
449
455
 
450
456
  Args:
451
- messages: Sequence of messages (as ``BaseMessage``s) to convert.
457
+ messages: Sequence of messages (as `BaseMessage`s) to convert.
452
458
 
453
459
  Returns:
454
460
  List of messages as dicts.
@@ -462,7 +468,7 @@ def get_msg_title_repr(title: str, *, bold: bool = False) -> str:
462
468
 
463
469
  Args:
464
470
  title: The title.
465
- bold: Whether to bold the title. Default is False.
471
+ bold: Whether to bold the title.
466
472
 
467
473
  Returns:
468
474
  The title representation.
@@ -1,18 +1,19 @@
1
1
  """Derivations of standard content blocks from provider content.
2
2
 
3
- ``AIMessage`` will first attempt to use a provider-specific translator if
4
- ``model_provider`` is set in ``response_metadata`` on the message. Consequently, each
3
+ `AIMessage` will first attempt to use a provider-specific translator if
4
+ `model_provider` is set in `response_metadata` on the message. Consequently, each
5
5
  provider translator must handle all possible content response types from the provider,
6
6
  including text.
7
7
 
8
8
  If no provider is set, or if the provider does not have a registered translator,
9
- ``AIMessage`` will fall back to best-effort parsing of the content into blocks using
10
- the implementation in ``BaseMessage``.
9
+ `AIMessage` will fall back to best-effort parsing of the content into blocks using
10
+ the implementation in `BaseMessage`.
11
11
  """
12
12
 
13
13
  from __future__ import annotations
14
14
 
15
- from typing import TYPE_CHECKING, Callable
15
+ from collections.abc import Callable
16
+ from typing import TYPE_CHECKING
16
17
 
17
18
  if TYPE_CHECKING:
18
19
  from langchain_core.messages import AIMessage, AIMessageChunk
@@ -20,6 +21,18 @@ if TYPE_CHECKING:
20
21
 
21
22
  # Provider to translator mapping
22
23
  PROVIDER_TRANSLATORS: dict[str, dict[str, Callable[..., list[types.ContentBlock]]]] = {}
24
+ """Map model provider names to translator functions.
25
+
26
+ The dictionary maps provider names (e.g. `'openai'`, `'anthropic'`) to another
27
+ dictionary with two keys:
28
+ - `'translate_content'`: Function to translate `AIMessage` content.
29
+ - `'translate_content_chunk'`: Function to translate `AIMessageChunk` content.
30
+
31
+ When calling `content_blocks` on an `AIMessage` or `AIMessageChunk`, if
32
+ `model_provider` is set in `response_metadata`, the corresponding translator
33
+ functions will be used to parse the content into blocks. Otherwise, best-effort parsing
34
+ in `BaseMessage` will be used.
35
+ """
23
36
 
24
37
 
25
38
  def register_translator(
@@ -27,12 +40,12 @@ def register_translator(
27
40
  translate_content: Callable[[AIMessage], list[types.ContentBlock]],
28
41
  translate_content_chunk: Callable[[AIMessageChunk], list[types.ContentBlock]],
29
42
  ) -> None:
30
- """Register content translators for a provider.
43
+ """Register content translators for a provider in `PROVIDER_TRANSLATORS`.
31
44
 
32
45
  Args:
33
- provider: The model provider name (e.g. ``'openai'``, ``'anthropic'``).
34
- translate_content: Function to translate ``AIMessage`` content.
35
- translate_content_chunk: Function to translate ``AIMessageChunk`` content.
46
+ provider: The model provider name (e.g. `'openai'`, `'anthropic'`).
47
+ translate_content: Function to translate `AIMessage` content.
48
+ translate_content_chunk: Function to translate `AIMessageChunk` content.
36
49
  """
37
50
  PROVIDER_TRANSLATORS[provider] = {
38
51
  "translate_content": translate_content,
@@ -49,8 +62,9 @@ def get_translator(
49
62
  provider: The model provider name.
50
63
 
51
64
  Returns:
52
- Dictionary with ``'translate_content'`` and ``'translate_content_chunk'``
53
- functions, or None if no translator is registered for the provider.
65
+ Dictionary with `'translate_content'` and `'translate_content_chunk'`
66
+ functions, or None if no translator is registered for the provider. In such
67
+ case, best-effort parsing in `BaseMessage` will be used.
54
68
  """
55
69
  return PROVIDER_TRANSLATORS.get(provider)
56
70
 
@@ -58,10 +72,10 @@ def get_translator(
58
72
  def _register_translators() -> None:
59
73
  """Register all translators in langchain-core.
60
74
 
61
- A unit test ensures all modules in ``block_translators`` are represented here.
75
+ A unit test ensures all modules in `block_translators` are represented here.
62
76
 
63
77
  For translators implemented outside langchain-core, they can be registered by
64
- calling ``register_translator`` from within the integration package.
78
+ calling `register_translator` from within the integration package.
65
79
  """
66
80
  from langchain_core.messages.block_translators.anthropic import ( # noqa: PLC0415
67
81
  _register_anthropic_translator,
@@ -81,9 +95,6 @@ def _register_translators() -> None:
81
95
  from langchain_core.messages.block_translators.groq import ( # noqa: PLC0415
82
96
  _register_groq_translator,
83
97
  )
84
- from langchain_core.messages.block_translators.ollama import ( # noqa: PLC0415
85
- _register_ollama_translator,
86
- )
87
98
  from langchain_core.messages.block_translators.openai import ( # noqa: PLC0415
88
99
  _register_openai_translator,
89
100
  )
@@ -94,7 +105,6 @@ def _register_translators() -> None:
94
105
  _register_google_genai_translator()
95
106
  _register_google_vertexai_translator()
96
107
  _register_groq_translator()
97
- _register_ollama_translator()
98
108
  _register_openai_translator()
99
109
 
100
110
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import json
4
4
  from collections.abc import Iterable
5
- from typing import Any, Optional, Union, cast
5
+ from typing import Any, cast
6
6
 
7
7
  from langchain_core.messages import AIMessage, AIMessageChunk
8
8
  from langchain_core.messages import content as types
@@ -31,12 +31,12 @@ def _convert_to_v1_from_anthropic_input(
31
31
  ) -> list[types.ContentBlock]:
32
32
  """Convert Anthropic format blocks to v1 format.
33
33
 
34
- During the `.content_blocks` parsing process, we wrap blocks not recognized as a v1
35
- block as a ``'non_standard'`` block with the original block stored in the ``value``
34
+ During the `content_blocks` parsing process, we wrap blocks not recognized as a v1
35
+ block as a `'non_standard'` block with the original block stored in the `value`
36
36
  field. This function attempts to unpack those blocks and convert any blocks that
37
37
  might be Anthropic format to v1 ContentBlocks.
38
38
 
39
- If conversion fails, the block is left as a ``'non_standard'`` block.
39
+ If conversion fails, the block is left as a `'non_standard'` block.
40
40
 
41
41
  Args:
42
42
  content: List of content blocks to process.
@@ -200,7 +200,7 @@ def _convert_citation_to_v1(citation: dict[str, Any]) -> types.Annotation:
200
200
  def _convert_to_v1_from_anthropic(message: AIMessage) -> list[types.ContentBlock]:
201
201
  """Convert Anthropic message content to v1 format."""
202
202
  if isinstance(message.content, str):
203
- content: list[Union[str, dict]] = [{"type": "text", "text": message.content}]
203
+ content: list[str | dict] = [{"type": "text", "text": message.content}]
204
204
  else:
205
205
  content = message.content
206
206
 
@@ -252,7 +252,7 @@ def _convert_to_v1_from_anthropic(message: AIMessage) -> list[types.ContentBlock
252
252
  tool_call_chunk["type"] = "tool_call_chunk"
253
253
  yield tool_call_chunk
254
254
  else:
255
- tool_call_block: Optional[types.ToolCall] = None
255
+ tool_call_block: types.ToolCall | None = None
256
256
  # Non-streaming or gathered chunk
257
257
  if len(message.tool_calls) == 1:
258
258
  tool_call_block = {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import base64
4
4
  from collections.abc import Iterable
5
- from typing import Any, Optional, cast
5
+ from typing import Any, cast
6
6
 
7
7
  from langchain_core.messages import AIMessage, AIMessageChunk
8
8
  from langchain_core.messages import content as types
@@ -35,12 +35,12 @@ def _convert_to_v1_from_converse_input(
35
35
  ) -> list[types.ContentBlock]:
36
36
  """Convert Bedrock Converse format blocks to v1 format.
37
37
 
38
- During the `.content_blocks` parsing process, we wrap blocks not recognized as a v1
39
- block as a ``'non_standard'`` block with the original block stored in the ``value``
38
+ During the `content_blocks` parsing process, we wrap blocks not recognized as a v1
39
+ block as a `'non_standard'` block with the original block stored in the `value`
40
40
  field. This function attempts to unpack those blocks and convert any blocks that
41
41
  might be Converse format to v1 ContentBlocks.
42
42
 
43
- If conversion fails, the block is left as a ``'non_standard'`` block.
43
+ If conversion fails, the block is left as a `'non_standard'` block.
44
44
 
45
45
  Args:
46
46
  content: List of content blocks to process.
@@ -216,7 +216,7 @@ def _convert_to_v1_from_converse(message: AIMessage) -> list[types.ContentBlock]
216
216
  tool_call_chunk["type"] = "tool_call_chunk"
217
217
  yield tool_call_chunk
218
218
  else:
219
- tool_call_block: Optional[types.ToolCall] = None
219
+ tool_call_block: types.ToolCall | None = None
220
220
  # Non-streaming or gathered chunk
221
221
  if len(message.tool_calls) == 1:
222
222
  tool_call_block = {