langchain-core 0.3.79__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 (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 +52 -65
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +19 -19
  8. langchain_core/caches.py +53 -63
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +323 -334
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +441 -507
  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 +48 -63
  17. langchain_core/document_loaders/base.py +23 -23
  18. langchain_core/document_loaders/langsmith.py +37 -37
  19. langchain_core/documents/__init__.py +0 -1
  20. langchain_core/documents/base.py +62 -65
  21. langchain_core/documents/compressor.py +4 -4
  22. langchain_core/documents/transformers.py +28 -29
  23. langchain_core/embeddings/fake.py +50 -54
  24. langchain_core/example_selectors/length_based.py +1 -1
  25. langchain_core/example_selectors/semantic_similarity.py +21 -25
  26. langchain_core/exceptions.py +10 -11
  27. langchain_core/globals.py +3 -151
  28. langchain_core/indexing/api.py +61 -66
  29. langchain_core/indexing/base.py +58 -58
  30. langchain_core/indexing/in_memory.py +3 -3
  31. langchain_core/language_models/__init__.py +14 -27
  32. langchain_core/language_models/_utils.py +270 -84
  33. langchain_core/language_models/base.py +55 -162
  34. langchain_core/language_models/chat_models.py +442 -402
  35. langchain_core/language_models/fake.py +11 -11
  36. langchain_core/language_models/fake_chat_models.py +61 -39
  37. langchain_core/language_models/llms.py +123 -231
  38. langchain_core/load/dump.py +4 -5
  39. langchain_core/load/load.py +18 -28
  40. langchain_core/load/mapping.py +2 -4
  41. langchain_core/load/serializable.py +39 -40
  42. langchain_core/messages/__init__.py +61 -22
  43. langchain_core/messages/ai.py +368 -163
  44. langchain_core/messages/base.py +214 -43
  45. langchain_core/messages/block_translators/__init__.py +111 -0
  46. langchain_core/messages/block_translators/anthropic.py +470 -0
  47. langchain_core/messages/block_translators/bedrock.py +94 -0
  48. langchain_core/messages/block_translators/bedrock_converse.py +297 -0
  49. langchain_core/messages/block_translators/google_genai.py +530 -0
  50. langchain_core/messages/block_translators/google_vertexai.py +21 -0
  51. langchain_core/messages/block_translators/groq.py +143 -0
  52. langchain_core/messages/block_translators/langchain_v0.py +301 -0
  53. langchain_core/messages/block_translators/openai.py +1010 -0
  54. langchain_core/messages/chat.py +2 -6
  55. langchain_core/messages/content.py +1423 -0
  56. langchain_core/messages/function.py +6 -10
  57. langchain_core/messages/human.py +41 -38
  58. langchain_core/messages/modifier.py +2 -2
  59. langchain_core/messages/system.py +38 -28
  60. langchain_core/messages/tool.py +96 -103
  61. langchain_core/messages/utils.py +478 -504
  62. langchain_core/output_parsers/__init__.py +1 -14
  63. langchain_core/output_parsers/base.py +58 -61
  64. langchain_core/output_parsers/json.py +7 -8
  65. langchain_core/output_parsers/list.py +5 -7
  66. langchain_core/output_parsers/openai_functions.py +49 -47
  67. langchain_core/output_parsers/openai_tools.py +14 -19
  68. langchain_core/output_parsers/pydantic.py +12 -13
  69. langchain_core/output_parsers/string.py +2 -2
  70. langchain_core/output_parsers/transform.py +15 -17
  71. langchain_core/output_parsers/xml.py +8 -10
  72. langchain_core/outputs/__init__.py +1 -1
  73. langchain_core/outputs/chat_generation.py +18 -18
  74. langchain_core/outputs/chat_result.py +1 -3
  75. langchain_core/outputs/generation.py +8 -8
  76. langchain_core/outputs/llm_result.py +10 -10
  77. langchain_core/prompt_values.py +12 -12
  78. langchain_core/prompts/__init__.py +3 -27
  79. langchain_core/prompts/base.py +45 -55
  80. langchain_core/prompts/chat.py +254 -313
  81. langchain_core/prompts/dict.py +5 -5
  82. langchain_core/prompts/few_shot.py +81 -88
  83. langchain_core/prompts/few_shot_with_templates.py +11 -13
  84. langchain_core/prompts/image.py +12 -14
  85. langchain_core/prompts/loading.py +6 -8
  86. langchain_core/prompts/message.py +3 -3
  87. langchain_core/prompts/prompt.py +24 -39
  88. langchain_core/prompts/string.py +4 -4
  89. langchain_core/prompts/structured.py +42 -50
  90. langchain_core/rate_limiters.py +51 -60
  91. langchain_core/retrievers.py +49 -190
  92. langchain_core/runnables/base.py +1484 -1709
  93. langchain_core/runnables/branch.py +45 -61
  94. langchain_core/runnables/config.py +80 -88
  95. langchain_core/runnables/configurable.py +117 -134
  96. langchain_core/runnables/fallbacks.py +83 -79
  97. langchain_core/runnables/graph.py +85 -95
  98. langchain_core/runnables/graph_ascii.py +27 -28
  99. langchain_core/runnables/graph_mermaid.py +38 -50
  100. langchain_core/runnables/graph_png.py +15 -16
  101. langchain_core/runnables/history.py +135 -148
  102. langchain_core/runnables/passthrough.py +124 -150
  103. langchain_core/runnables/retry.py +46 -51
  104. langchain_core/runnables/router.py +25 -30
  105. langchain_core/runnables/schema.py +79 -74
  106. langchain_core/runnables/utils.py +62 -68
  107. langchain_core/stores.py +81 -115
  108. langchain_core/structured_query.py +8 -8
  109. langchain_core/sys_info.py +27 -29
  110. langchain_core/tools/__init__.py +1 -14
  111. langchain_core/tools/base.py +179 -187
  112. langchain_core/tools/convert.py +131 -139
  113. langchain_core/tools/render.py +10 -10
  114. langchain_core/tools/retriever.py +11 -11
  115. langchain_core/tools/simple.py +19 -24
  116. langchain_core/tools/structured.py +30 -39
  117. langchain_core/tracers/__init__.py +1 -9
  118. langchain_core/tracers/base.py +97 -99
  119. langchain_core/tracers/context.py +29 -52
  120. langchain_core/tracers/core.py +50 -60
  121. langchain_core/tracers/evaluation.py +11 -11
  122. langchain_core/tracers/event_stream.py +115 -70
  123. langchain_core/tracers/langchain.py +21 -21
  124. langchain_core/tracers/log_stream.py +43 -43
  125. langchain_core/tracers/memory_stream.py +3 -3
  126. langchain_core/tracers/root_listeners.py +16 -16
  127. langchain_core/tracers/run_collector.py +2 -4
  128. langchain_core/tracers/schemas.py +0 -129
  129. langchain_core/tracers/stdout.py +3 -3
  130. langchain_core/utils/__init__.py +1 -4
  131. langchain_core/utils/_merge.py +46 -8
  132. langchain_core/utils/aiter.py +57 -61
  133. langchain_core/utils/env.py +9 -9
  134. langchain_core/utils/function_calling.py +89 -191
  135. langchain_core/utils/html.py +7 -8
  136. langchain_core/utils/input.py +6 -6
  137. langchain_core/utils/interactive_env.py +1 -1
  138. langchain_core/utils/iter.py +37 -42
  139. langchain_core/utils/json.py +4 -3
  140. langchain_core/utils/json_schema.py +8 -8
  141. langchain_core/utils/mustache.py +9 -11
  142. langchain_core/utils/pydantic.py +33 -35
  143. langchain_core/utils/strings.py +5 -5
  144. langchain_core/utils/usage.py +1 -1
  145. langchain_core/utils/utils.py +80 -54
  146. langchain_core/vectorstores/base.py +129 -164
  147. langchain_core/vectorstores/in_memory.py +99 -174
  148. langchain_core/vectorstores/utils.py +5 -5
  149. langchain_core/version.py +1 -1
  150. {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/METADATA +28 -27
  151. langchain_core-1.0.0.dist-info/RECORD +172 -0
  152. {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
  153. langchain_core/beta/__init__.py +0 -1
  154. langchain_core/beta/runnables/__init__.py +0 -1
  155. langchain_core/beta/runnables/context.py +0 -447
  156. langchain_core/memory.py +0 -120
  157. langchain_core/messages/content_blocks.py +0 -176
  158. langchain_core/prompts/pipeline.py +0 -138
  159. langchain_core/pydantic_v1/__init__.py +0 -30
  160. langchain_core/pydantic_v1/dataclasses.py +0 -23
  161. langchain_core/pydantic_v1/main.py +0 -23
  162. langchain_core/tracers/langchain_v1.py +0 -31
  163. langchain_core/utils/loading.py +0 -35
  164. langchain_core-0.3.79.dist-info/RECORD +0 -174
  165. langchain_core-0.3.79.dist-info/entry_points.txt +0 -4
@@ -0,0 +1,1423 @@
1
+ """Standard, multimodal content blocks for Large Language Model I/O.
2
+
3
+ !!! warning
4
+ This module is under active development. The API is unstable and subject to
5
+ change in future releases.
6
+
7
+ This module provides standardized data structures for representing inputs to and
8
+ outputs from LLMs. The core abstraction is the **Content Block**, a `TypedDict`.
9
+
10
+ **Rationale**
11
+
12
+ Different LLM providers use distinct and incompatible API schemas. This module
13
+ provides a unified, provider-agnostic format to facilitate these interactions. A
14
+ message to or from a model is simply a list of content blocks, allowing for the natural
15
+ interleaving of text, images, and other content in a single ordered sequence.
16
+
17
+ An adapter for a specific provider is responsible for translating this standard list of
18
+ blocks into the format required by its API.
19
+
20
+ **Extensibility**
21
+
22
+ Data **not yet mapped** to a standard block may be represented using the
23
+ `NonStandardContentBlock`, which allows for provider-specific data to be included
24
+ without losing the benefits of type checking and validation.
25
+
26
+ Furthermore, provider-specific fields **within** a standard block are fully supported
27
+ by default in the `extras` field of each block. This allows for additional metadata
28
+ to be included without breaking the standard structure.
29
+
30
+ !!! warning
31
+ Do not heavily rely on the `extras` field for provider-specific data! This field
32
+ is subject to deprecation in future releases as we move towards PEP 728.
33
+
34
+ !!! note
35
+ Following widespread adoption of [PEP 728](https://peps.python.org/pep-0728/), we
36
+ will add `extra_items=Any` as a param to Content Blocks. This will signify to type
37
+ checkers that additional provider-specific fields are allowed outside of the
38
+ `extras` field, and that will become the new standard approach to adding
39
+ provider-specific metadata.
40
+
41
+ ??? note
42
+
43
+ **Example with PEP 728 provider-specific fields:**
44
+
45
+ ```python
46
+ # Content block definition
47
+ # NOTE: `extra_items=Any`
48
+ class TextContentBlock(TypedDict, extra_items=Any):
49
+ type: Literal["text"]
50
+ id: NotRequired[str]
51
+ text: str
52
+ annotations: NotRequired[list[Annotation]]
53
+ index: NotRequired[int]
54
+ ```
55
+
56
+ ```python
57
+ from langchain_core.messages.content import TextContentBlock
58
+
59
+ # Create a text content block with provider-specific fields
60
+ my_block: TextContentBlock = {
61
+ # Add required fields
62
+ "type": "text",
63
+ "text": "Hello, world!",
64
+ # Additional fields not specified in the TypedDict
65
+ # These are valid with PEP 728 and are typed as Any
66
+ "openai_metadata": {"model": "gpt-4", "temperature": 0.7},
67
+ "anthropic_usage": {"input_tokens": 10, "output_tokens": 20},
68
+ "custom_field": "any value",
69
+ }
70
+
71
+ # Mutating an existing block to add provider-specific fields
72
+ openai_data = my_block["openai_metadata"] # Type: Any
73
+ ```
74
+
75
+ PEP 728 is enabled with `# type: ignore[call-arg]` comments to suppress
76
+ warnings from type checkers that don't yet support it. The functionality works
77
+ correctly in Python 3.13+ and will be fully supported as the ecosystem catches
78
+ up.
79
+
80
+ **Key Block Types**
81
+
82
+ The module defines several types of content blocks, including:
83
+
84
+ - `TextContentBlock`: Standard text output.
85
+ - `Citation`: For annotations that link text output to a source document.
86
+ - `ToolCall`: For function calling.
87
+ - `ReasoningContentBlock`: To capture a model's thought process.
88
+ - Multimodal data:
89
+ - `ImageContentBlock`
90
+ - `AudioContentBlock`
91
+ - `VideoContentBlock`
92
+ - `PlainTextContentBlock` (e.g. .txt or .md files)
93
+ - `FileContentBlock` (e.g. PDFs, etc.)
94
+
95
+ **Example Usage**
96
+
97
+ ```python
98
+ # Direct construction:
99
+ from langchain_core.messages.content import TextContentBlock, ImageContentBlock
100
+
101
+ multimodal_message: AIMessage(
102
+ content_blocks=[
103
+ TextContentBlock(type="text", text="What is shown in this image?"),
104
+ ImageContentBlock(
105
+ type="image",
106
+ url="https://www.langchain.com/images/brand/langchain_logo_text_w_white.png",
107
+ mime_type="image/png",
108
+ ),
109
+ ]
110
+ )
111
+
112
+ # Using factories:
113
+ from langchain_core.messages.content import create_text_block, create_image_block
114
+
115
+ multimodal_message: AIMessage(
116
+ content=[
117
+ create_text_block("What is shown in this image?"),
118
+ create_image_block(
119
+ url="https://www.langchain.com/images/brand/langchain_logo_text_w_white.png",
120
+ mime_type="image/png",
121
+ ),
122
+ ]
123
+ )
124
+ ```
125
+
126
+ Factory functions offer benefits such as:
127
+ - Automatic ID generation (when not provided)
128
+ - No need to manually specify the `type` field
129
+ """
130
+
131
+ from typing import Any, Literal, get_args, get_type_hints
132
+
133
+ from typing_extensions import NotRequired, TypedDict
134
+
135
+ from langchain_core.utils.utils import ensure_id
136
+
137
+
138
+ class Citation(TypedDict):
139
+ """Annotation for citing data from a document.
140
+
141
+ !!! note
142
+ `start`/`end` indices refer to the **response text**,
143
+ not the source text. This means that the indices are relative to the model's
144
+ response, not the original document (as specified in the `url`).
145
+
146
+ !!! note "Factory function"
147
+ `create_citation` may also be used as a factory to create a `Citation`.
148
+ Benefits include:
149
+
150
+ * Automatic ID generation (when not provided)
151
+ * Required arguments strictly validated at creation time
152
+
153
+ """
154
+
155
+ type: Literal["citation"]
156
+ """Type of the content block. Used for discrimination."""
157
+
158
+ id: NotRequired[str]
159
+ """Content block identifier.
160
+
161
+ Either:
162
+
163
+ - Generated by the provider (e.g., OpenAI's file ID)
164
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
165
+
166
+ """
167
+
168
+ url: NotRequired[str]
169
+ """URL of the document source."""
170
+
171
+ title: NotRequired[str]
172
+ """Source document title.
173
+
174
+ For example, the page title for a web page or the title of a paper.
175
+ """
176
+
177
+ start_index: NotRequired[int]
178
+ """Start index of the **response text** (`TextContentBlock.text`)."""
179
+
180
+ end_index: NotRequired[int]
181
+ """End index of the **response text** (`TextContentBlock.text`)"""
182
+
183
+ cited_text: NotRequired[str]
184
+ """Excerpt of source text being cited."""
185
+
186
+ # NOTE: not including spans for the raw document text (such as `text_start_index`
187
+ # and `text_end_index`) as this is not currently supported by any provider. The
188
+ # thinking is that the `cited_text` should be sufficient for most use cases, and it
189
+ # is difficult to reliably extract spans from the raw document text across file
190
+ # formats or encoding schemes.
191
+
192
+ extras: NotRequired[dict[str, Any]]
193
+ """Provider-specific metadata."""
194
+
195
+
196
+ class NonStandardAnnotation(TypedDict):
197
+ """Provider-specific annotation format."""
198
+
199
+ type: Literal["non_standard_annotation"]
200
+ """Type of the content block. Used for discrimination."""
201
+
202
+ id: NotRequired[str]
203
+ """Content block identifier.
204
+
205
+ Either:
206
+
207
+ - Generated by the provider (e.g., OpenAI's file ID)
208
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
209
+
210
+ """
211
+
212
+ value: dict[str, Any]
213
+ """Provider-specific annotation data."""
214
+
215
+
216
+ Annotation = Citation | NonStandardAnnotation
217
+ """A union of all defined `Annotation` types."""
218
+
219
+
220
+ class TextContentBlock(TypedDict):
221
+ """Text output from a LLM.
222
+
223
+ This typically represents the main text content of a message, such as the response
224
+ from a language model or the text of a user message.
225
+
226
+ !!! note "Factory function"
227
+ `create_text_block` may also be used as a factory to create a
228
+ `TextContentBlock`. Benefits include:
229
+
230
+ * Automatic ID generation (when not provided)
231
+ * Required arguments strictly validated at creation time
232
+
233
+ """
234
+
235
+ type: Literal["text"]
236
+ """Type of the content block. Used for discrimination."""
237
+
238
+ id: NotRequired[str]
239
+ """Content block identifier.
240
+
241
+ Either:
242
+
243
+ - Generated by the provider (e.g., OpenAI's file ID)
244
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
245
+
246
+ """
247
+
248
+ text: str
249
+ """Block text."""
250
+
251
+ annotations: NotRequired[list[Annotation]]
252
+ """`Citation`s and other annotations."""
253
+
254
+ index: NotRequired[int | str]
255
+ """Index of block in aggregate response. Used during streaming."""
256
+
257
+ extras: NotRequired[dict[str, Any]]
258
+ """Provider-specific metadata."""
259
+
260
+
261
+ class ToolCall(TypedDict):
262
+ """Represents an AI's request to call a tool.
263
+
264
+ Example:
265
+ ```python
266
+ {"name": "foo", "args": {"a": 1}, "id": "123"}
267
+ ```
268
+
269
+ This represents a request to call the tool named "foo" with arguments {"a": 1}
270
+ and an identifier of "123".
271
+
272
+ !!! note "Factory function"
273
+ `create_tool_call` may also be used as a factory to create a
274
+ `ToolCall`. Benefits include:
275
+
276
+ * Automatic ID generation (when not provided)
277
+ * Required arguments strictly validated at creation time
278
+
279
+ """
280
+
281
+ type: Literal["tool_call"]
282
+ """Used for discrimination."""
283
+
284
+ id: str | None
285
+ """An identifier associated with the tool call.
286
+
287
+ An identifier is needed to associate a tool call request with a tool
288
+ call result in events when multiple concurrent tool calls are made.
289
+
290
+ """
291
+ # TODO: Consider making this NotRequired[str] in the future.
292
+
293
+ name: str
294
+ """The name of the tool to be called."""
295
+
296
+ args: dict[str, Any]
297
+ """The arguments to the tool call."""
298
+
299
+ index: NotRequired[int | str]
300
+ """Index of block in aggregate response. Used during streaming."""
301
+
302
+ extras: NotRequired[dict[str, Any]]
303
+ """Provider-specific metadata."""
304
+
305
+
306
+ class ToolCallChunk(TypedDict):
307
+ """A chunk of a tool call (yielded when streaming).
308
+
309
+ When merging `ToolCallChunks` (e.g., via `AIMessageChunk.__add__`),
310
+ all string attributes are concatenated. Chunks are only merged if their
311
+ values of `index` are equal and not `None`.
312
+
313
+ Example:
314
+ ```python
315
+ left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)]
316
+ right_chunks = [ToolCallChunk(name=None, args="1}", index=0)]
317
+
318
+ (
319
+ AIMessageChunk(content="", tool_call_chunks=left_chunks)
320
+ + AIMessageChunk(content="", tool_call_chunks=right_chunks)
321
+ ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)]
322
+ ```
323
+ """
324
+
325
+ # TODO: Consider making fields NotRequired[str] in the future.
326
+
327
+ type: Literal["tool_call_chunk"]
328
+ """Used for serialization."""
329
+
330
+ id: str | None
331
+ """An identifier associated with the tool call.
332
+
333
+ An identifier is needed to associate a tool call request with a tool
334
+ call result in events when multiple concurrent tool calls are made.
335
+
336
+ """
337
+
338
+ name: str | None
339
+ """The name of the tool to be called."""
340
+
341
+ args: str | None
342
+ """The arguments to the tool call."""
343
+
344
+ index: NotRequired[int | str]
345
+ """The index of the tool call in a sequence."""
346
+
347
+ extras: NotRequired[dict[str, Any]]
348
+ """Provider-specific metadata."""
349
+
350
+
351
+ class InvalidToolCall(TypedDict):
352
+ """Allowance for errors made by LLM.
353
+
354
+ Here we add an `error` key to surface errors made during generation
355
+ (e.g., invalid JSON arguments.)
356
+
357
+ """
358
+
359
+ # TODO: Consider making fields NotRequired[str] in the future.
360
+
361
+ type: Literal["invalid_tool_call"]
362
+ """Used for discrimination."""
363
+
364
+ id: str | None
365
+ """An identifier associated with the tool call.
366
+
367
+ An identifier is needed to associate a tool call request with a tool
368
+ call result in events when multiple concurrent tool calls are made.
369
+
370
+ """
371
+
372
+ name: str | None
373
+ """The name of the tool to be called."""
374
+
375
+ args: str | None
376
+ """The arguments to the tool call."""
377
+
378
+ error: str | None
379
+ """An error message associated with the tool call."""
380
+
381
+ index: NotRequired[int | str]
382
+ """Index of block in aggregate response. Used during streaming."""
383
+
384
+ extras: NotRequired[dict[str, Any]]
385
+ """Provider-specific metadata."""
386
+
387
+
388
+ class ServerToolCall(TypedDict):
389
+ """Tool call that is executed server-side.
390
+
391
+ For example: code execution, web search, etc.
392
+ """
393
+
394
+ type: Literal["server_tool_call"]
395
+ """Used for discrimination."""
396
+
397
+ id: str
398
+ """An identifier associated with the tool call."""
399
+
400
+ name: str
401
+ """The name of the tool to be called."""
402
+
403
+ args: dict[str, Any]
404
+ """The arguments to the tool call."""
405
+
406
+ index: NotRequired[int | str]
407
+ """Index of block in aggregate response. Used during streaming."""
408
+
409
+ extras: NotRequired[dict[str, Any]]
410
+ """Provider-specific metadata."""
411
+
412
+
413
+ class ServerToolCallChunk(TypedDict):
414
+ """A chunk of a server-side tool call (yielded when streaming)."""
415
+
416
+ type: Literal["server_tool_call_chunk"]
417
+ """Used for discrimination."""
418
+
419
+ name: NotRequired[str]
420
+ """The name of the tool to be called."""
421
+
422
+ args: NotRequired[str]
423
+ """JSON substring of the arguments to the tool call."""
424
+
425
+ id: NotRequired[str]
426
+ """An identifier associated with the tool call."""
427
+
428
+ index: NotRequired[int | str]
429
+ """Index of block in aggregate response. Used during streaming."""
430
+
431
+ extras: NotRequired[dict[str, Any]]
432
+ """Provider-specific metadata."""
433
+
434
+
435
+ class ServerToolResult(TypedDict):
436
+ """Result of a server-side tool call."""
437
+
438
+ type: Literal["server_tool_result"]
439
+ """Used for discrimination."""
440
+
441
+ id: NotRequired[str]
442
+ """An identifier associated with the server tool result."""
443
+
444
+ tool_call_id: str
445
+ """ID of the corresponding server tool call."""
446
+
447
+ status: Literal["success", "error"]
448
+ """Execution status of the server-side tool."""
449
+
450
+ output: NotRequired[Any]
451
+ """Output of the executed tool."""
452
+
453
+ index: NotRequired[int | str]
454
+ """Index of block in aggregate response. Used during streaming."""
455
+
456
+ extras: NotRequired[dict[str, Any]]
457
+ """Provider-specific metadata."""
458
+
459
+
460
+ class ReasoningContentBlock(TypedDict):
461
+ """Reasoning output from a LLM.
462
+
463
+ !!! note "Factory function"
464
+ `create_reasoning_block` may also be used as a factory to create a
465
+ `ReasoningContentBlock`. Benefits include:
466
+
467
+ * Automatic ID generation (when not provided)
468
+ * Required arguments strictly validated at creation time
469
+
470
+ """
471
+
472
+ type: Literal["reasoning"]
473
+ """Type of the content block. Used for discrimination."""
474
+
475
+ id: NotRequired[str]
476
+ """Content block identifier.
477
+
478
+ Either:
479
+
480
+ - Generated by the provider (e.g., OpenAI's file ID)
481
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
482
+
483
+ """
484
+
485
+ reasoning: NotRequired[str]
486
+ """Reasoning text.
487
+
488
+ Either the thought summary or the raw reasoning text itself. This is often parsed
489
+ from `<think>` tags in the model's response.
490
+
491
+ """
492
+
493
+ index: NotRequired[int | str]
494
+ """Index of block in aggregate response. Used during streaming."""
495
+
496
+ extras: NotRequired[dict[str, Any]]
497
+ """Provider-specific metadata."""
498
+
499
+
500
+ # Note: `title` and `context` are fields that could be used to provide additional
501
+ # information about the file, such as a description or summary of its content.
502
+ # E.g. with Claude, you can provide a context for a file which is passed to the model.
503
+ class ImageContentBlock(TypedDict):
504
+ """Image data.
505
+
506
+ !!! note "Factory function"
507
+ `create_image_block` may also be used as a factory to create a
508
+ `ImageContentBlock`. Benefits include:
509
+
510
+ * Automatic ID generation (when not provided)
511
+ * Required arguments strictly validated at creation time
512
+
513
+ """
514
+
515
+ type: Literal["image"]
516
+ """Type of the content block. Used for discrimination."""
517
+
518
+ id: NotRequired[str]
519
+ """Content block identifier.
520
+
521
+ Either:
522
+
523
+ - Generated by the provider (e.g., OpenAI's file ID)
524
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
525
+
526
+ """
527
+
528
+ file_id: NotRequired[str]
529
+ """ID of the image file, e.g., from a file storage system."""
530
+
531
+ mime_type: NotRequired[str]
532
+ """MIME type of the image. Required for base64.
533
+
534
+ [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#image)
535
+
536
+ """
537
+
538
+ index: NotRequired[int | str]
539
+ """Index of block in aggregate response. Used during streaming."""
540
+
541
+ url: NotRequired[str]
542
+ """URL of the image."""
543
+
544
+ base64: NotRequired[str]
545
+ """Data as a base64 string."""
546
+
547
+ extras: NotRequired[dict[str, Any]]
548
+ """Provider-specific metadata. This shouldn't be used for the image data itself."""
549
+
550
+
551
+ class VideoContentBlock(TypedDict):
552
+ """Video data.
553
+
554
+ !!! note "Factory function"
555
+ `create_video_block` may also be used as a factory to create a
556
+ `VideoContentBlock`. Benefits include:
557
+
558
+ * Automatic ID generation (when not provided)
559
+ * Required arguments strictly validated at creation time
560
+
561
+ """
562
+
563
+ type: Literal["video"]
564
+ """Type of the content block. Used for discrimination."""
565
+
566
+ id: NotRequired[str]
567
+ """Content block identifier.
568
+
569
+ Either:
570
+
571
+ - Generated by the provider (e.g., OpenAI's file ID)
572
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
573
+
574
+ """
575
+
576
+ file_id: NotRequired[str]
577
+ """ID of the video file, e.g., from a file storage system."""
578
+
579
+ mime_type: NotRequired[str]
580
+ """MIME type of the video. Required for base64.
581
+
582
+ [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#video)
583
+
584
+ """
585
+
586
+ index: NotRequired[int | str]
587
+ """Index of block in aggregate response. Used during streaming."""
588
+
589
+ url: NotRequired[str]
590
+ """URL of the video."""
591
+
592
+ base64: NotRequired[str]
593
+ """Data as a base64 string."""
594
+
595
+ extras: NotRequired[dict[str, Any]]
596
+ """Provider-specific metadata. This shouldn't be used for the video data itself."""
597
+
598
+
599
+ class AudioContentBlock(TypedDict):
600
+ """Audio data.
601
+
602
+ !!! note "Factory function"
603
+ `create_audio_block` may also be used as a factory to create an
604
+ `AudioContentBlock`. Benefits include:
605
+ * Automatic ID generation (when not provided)
606
+ * Required arguments strictly validated at creation time
607
+
608
+ """
609
+
610
+ type: Literal["audio"]
611
+ """Type of the content block. Used for discrimination."""
612
+
613
+ id: NotRequired[str]
614
+ """Content block identifier.
615
+
616
+ Either:
617
+
618
+ - Generated by the provider (e.g., OpenAI's file ID)
619
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
620
+
621
+ """
622
+
623
+ file_id: NotRequired[str]
624
+ """ID of the audio file, e.g., from a file storage system."""
625
+
626
+ mime_type: NotRequired[str]
627
+ """MIME type of the audio. Required for base64.
628
+
629
+ [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#audio)
630
+
631
+ """
632
+
633
+ index: NotRequired[int | str]
634
+ """Index of block in aggregate response. Used during streaming."""
635
+
636
+ url: NotRequired[str]
637
+ """URL of the audio."""
638
+
639
+ base64: NotRequired[str]
640
+ """Data as a base64 string."""
641
+
642
+ extras: NotRequired[dict[str, Any]]
643
+ """Provider-specific metadata. This shouldn't be used for the audio data itself."""
644
+
645
+
646
+ class PlainTextContentBlock(TypedDict):
647
+ """Plaintext data (e.g., from a document).
648
+
649
+ !!! note
650
+ A `PlainTextContentBlock` existed in `langchain-core<1.0.0`. Although the
651
+ name has carried over, the structure has changed significantly. The only shared
652
+ keys between the old and new versions are `type` and `text`, though the
653
+ `type` value has changed from `'text'` to `'text-plain'`.
654
+
655
+ !!! note
656
+ Title and context are optional fields that may be passed to the model. See
657
+ Anthropic [example](https://docs.claude.com/en/docs/build-with-claude/citations#citable-vs-non-citable-content).
658
+
659
+ !!! note "Factory function"
660
+ `create_plaintext_block` may also be used as a factory to create a
661
+ `PlainTextContentBlock`. Benefits include:
662
+
663
+ * Automatic ID generation (when not provided)
664
+ * Required arguments strictly validated at creation time
665
+
666
+ """
667
+
668
+ type: Literal["text-plain"]
669
+ """Type of the content block. Used for discrimination."""
670
+
671
+ id: NotRequired[str]
672
+ """Content block identifier.
673
+
674
+ Either:
675
+
676
+ - Generated by the provider (e.g., OpenAI's file ID)
677
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
678
+
679
+ """
680
+
681
+ file_id: NotRequired[str]
682
+ """ID of the plaintext file, e.g., from a file storage system."""
683
+
684
+ mime_type: Literal["text/plain"]
685
+ """MIME type of the file. Required for base64."""
686
+
687
+ index: NotRequired[int | str]
688
+ """Index of block in aggregate response. Used during streaming."""
689
+
690
+ url: NotRequired[str]
691
+ """URL of the plaintext."""
692
+
693
+ base64: NotRequired[str]
694
+ """Data as a base64 string."""
695
+
696
+ text: NotRequired[str]
697
+ """Plaintext content. This is optional if the data is provided as base64."""
698
+
699
+ title: NotRequired[str]
700
+ """Title of the text data, e.g., the title of a document."""
701
+
702
+ context: NotRequired[str]
703
+ """Context for the text, e.g., a description or summary of the text's content."""
704
+
705
+ extras: NotRequired[dict[str, Any]]
706
+ """Provider-specific metadata. This shouldn't be used for the data itself."""
707
+
708
+
709
+ class FileContentBlock(TypedDict):
710
+ """File data that doesn't fit into other multimodal block types.
711
+
712
+ This block is intended for files that are not images, audio, or plaintext. For
713
+ example, it can be used for PDFs, Word documents, etc.
714
+
715
+ If the file is an image, audio, or plaintext, you should use the corresponding
716
+ content block type (e.g., `ImageContentBlock`, `AudioContentBlock`,
717
+ `PlainTextContentBlock`).
718
+
719
+ !!! note "Factory function"
720
+ `create_file_block` may also be used as a factory to create a
721
+ `FileContentBlock`. Benefits include:
722
+
723
+ * Automatic ID generation (when not provided)
724
+ * Required arguments strictly validated at creation time
725
+
726
+ """
727
+
728
+ type: Literal["file"]
729
+ """Type of the content block. Used for discrimination."""
730
+
731
+ id: NotRequired[str]
732
+ """Content block identifier.
733
+
734
+ Either:
735
+
736
+ - Generated by the provider (e.g., OpenAI's file ID)
737
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
738
+
739
+ """
740
+
741
+ file_id: NotRequired[str]
742
+ """ID of the file, e.g., from a file storage system."""
743
+
744
+ mime_type: NotRequired[str]
745
+ """MIME type of the file. Required for base64.
746
+
747
+ [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml)
748
+
749
+ """
750
+
751
+ index: NotRequired[int | str]
752
+ """Index of block in aggregate response. Used during streaming."""
753
+
754
+ url: NotRequired[str]
755
+ """URL of the file."""
756
+
757
+ base64: NotRequired[str]
758
+ """Data as a base64 string."""
759
+
760
+ extras: NotRequired[dict[str, Any]]
761
+ """Provider-specific metadata. This shouldn't be used for the file data itself."""
762
+
763
+
764
+ # Future modalities to consider:
765
+ # - 3D models
766
+ # - Tabular data
767
+
768
+
769
+ class NonStandardContentBlock(TypedDict):
770
+ """Provider-specific data.
771
+
772
+ This block contains data for which there is not yet a standard type.
773
+
774
+ The purpose of this block should be to simply hold a provider-specific payload.
775
+ If a provider's non-standard output includes reasoning and tool calls, it should be
776
+ the adapter's job to parse that payload and emit the corresponding standard
777
+ `ReasoningContentBlock` and `ToolCalls`.
778
+
779
+ Has no `extras` field, as provider-specific data should be included in the
780
+ `value` field.
781
+
782
+ !!! note "Factory function"
783
+ `create_non_standard_block` may also be used as a factory to create a
784
+ `NonStandardContentBlock`. Benefits include:
785
+
786
+ * Automatic ID generation (when not provided)
787
+ * Required arguments strictly validated at creation time
788
+
789
+ """
790
+
791
+ type: Literal["non_standard"]
792
+ """Type of the content block. Used for discrimination."""
793
+
794
+ id: NotRequired[str]
795
+ """Content block identifier.
796
+
797
+ Either:
798
+
799
+ - Generated by the provider (e.g., OpenAI's file ID)
800
+ - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))
801
+
802
+ """
803
+
804
+ value: dict[str, Any]
805
+ """Provider-specific data."""
806
+
807
+ index: NotRequired[int | str]
808
+ """Index of block in aggregate response. Used during streaming."""
809
+
810
+
811
+ # --- Aliases ---
812
+ DataContentBlock = (
813
+ ImageContentBlock
814
+ | VideoContentBlock
815
+ | AudioContentBlock
816
+ | PlainTextContentBlock
817
+ | FileContentBlock
818
+ )
819
+ """A union of all defined multimodal data `ContentBlock` types."""
820
+
821
+ ToolContentBlock = (
822
+ ToolCall | ToolCallChunk | ServerToolCall | ServerToolCallChunk | ServerToolResult
823
+ )
824
+
825
+ ContentBlock = (
826
+ TextContentBlock
827
+ | InvalidToolCall
828
+ | ReasoningContentBlock
829
+ | NonStandardContentBlock
830
+ | DataContentBlock
831
+ | ToolContentBlock
832
+ )
833
+ """A union of all defined `ContentBlock` types and aliases."""
834
+
835
+
836
+ KNOWN_BLOCK_TYPES = {
837
+ # Text output
838
+ "text",
839
+ "reasoning",
840
+ # Tools
841
+ "tool_call",
842
+ "invalid_tool_call",
843
+ "tool_call_chunk",
844
+ # Multimodal data
845
+ "image",
846
+ "audio",
847
+ "file",
848
+ "text-plain",
849
+ "video",
850
+ # Server-side tool calls
851
+ "server_tool_call",
852
+ "server_tool_call_chunk",
853
+ "server_tool_result",
854
+ # Catch-all
855
+ "non_standard",
856
+ # citation and non_standard_annotation intentionally omitted
857
+ }
858
+ """These are block types known to `langchain-core>=1.0.0`.
859
+
860
+ If a block has a type not in this set, it is considered to be provider-specific.
861
+ """
862
+
863
+
864
+ def _get_data_content_block_types() -> tuple[str, ...]:
865
+ """Get type literals from DataContentBlock union members dynamically.
866
+
867
+ Example: ("image", "video", "audio", "text-plain", "file")
868
+
869
+ Note that old style multimodal blocks type literals with new style blocks.
870
+ Speficially, "image", "audio", and "file".
871
+
872
+ See the docstring of `_normalize_messages` in `language_models._utils` for details.
873
+ """
874
+ data_block_types = []
875
+
876
+ for block_type in get_args(DataContentBlock):
877
+ hints = get_type_hints(block_type)
878
+ if "type" in hints:
879
+ type_annotation = hints["type"]
880
+ if hasattr(type_annotation, "__args__"):
881
+ # This is a Literal type, get the literal value
882
+ literal_value = type_annotation.__args__[0]
883
+ data_block_types.append(literal_value)
884
+
885
+ return tuple(data_block_types)
886
+
887
+
888
+ def is_data_content_block(block: dict) -> bool:
889
+ """Check if the provided content block is a data content block.
890
+
891
+ Returns True for both v0 (old-style) and v1 (new-style) multimodal data blocks.
892
+
893
+ Args:
894
+ block: The content block to check.
895
+
896
+ Returns:
897
+ `True` if the content block is a data content block, `False` otherwise.
898
+
899
+ """
900
+ if block.get("type") not in _get_data_content_block_types():
901
+ return False
902
+
903
+ if any(key in block for key in ("url", "base64", "file_id", "text")):
904
+ # Type is valid and at least one data field is present
905
+ # (Accepts old-style image and audio URLContentBlock)
906
+
907
+ # 'text' is checked to support v0 PlainTextContentBlock types
908
+ # We must guard against new style TextContentBlock which also has 'text' `type`
909
+ # by ensuring the presense of `source_type`
910
+ if block["type"] == "text" and "source_type" not in block: # noqa: SIM103 # This is more readable
911
+ return False
912
+
913
+ return True
914
+
915
+ if "source_type" in block:
916
+ # Old-style content blocks had possible types of 'image', 'audio', and 'file'
917
+ # which is not captured in the prior check
918
+ source_type = block["source_type"]
919
+ if (source_type == "url" and "url" in block) or (
920
+ source_type == "base64" and "data" in block
921
+ ):
922
+ return True
923
+ if (source_type == "id" and "id" in block) or (
924
+ source_type == "text" and "url" in block
925
+ ):
926
+ return True
927
+
928
+ return False
929
+
930
+
931
+ def create_text_block(
932
+ text: str,
933
+ *,
934
+ id: str | None = None,
935
+ annotations: list[Annotation] | None = None,
936
+ index: int | str | None = None,
937
+ **kwargs: Any,
938
+ ) -> TextContentBlock:
939
+ """Create a `TextContentBlock`.
940
+
941
+ Args:
942
+ text: The text content of the block.
943
+ id: Content block identifier. Generated automatically if not provided.
944
+ annotations: `Citation`s and other annotations for the text.
945
+ index: Index of block in aggregate response. Used during streaming.
946
+
947
+ Returns:
948
+ A properly formatted `TextContentBlock`.
949
+
950
+ !!! note
951
+ The `id` is generated automatically if not provided, using a UUID4 format
952
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
953
+
954
+ """
955
+ block = TextContentBlock(
956
+ type="text",
957
+ text=text,
958
+ id=ensure_id(id),
959
+ )
960
+ if annotations is not None:
961
+ block["annotations"] = annotations
962
+ if index is not None:
963
+ block["index"] = index
964
+
965
+ extras = {k: v for k, v in kwargs.items() if v is not None}
966
+ if extras:
967
+ block["extras"] = extras
968
+
969
+ return block
970
+
971
+
972
+ def create_image_block(
973
+ *,
974
+ url: str | None = None,
975
+ base64: str | None = None,
976
+ file_id: str | None = None,
977
+ mime_type: str | None = None,
978
+ id: str | None = None,
979
+ index: int | str | None = None,
980
+ **kwargs: Any,
981
+ ) -> ImageContentBlock:
982
+ """Create an `ImageContentBlock`.
983
+
984
+ Args:
985
+ url: URL of the image.
986
+ base64: Base64-encoded image data.
987
+ file_id: ID of the image file from a file storage system.
988
+ mime_type: MIME type of the image. Required for base64 data.
989
+ id: Content block identifier. Generated automatically if not provided.
990
+ index: Index of block in aggregate response. Used during streaming.
991
+
992
+ Returns:
993
+ A properly formatted `ImageContentBlock`.
994
+
995
+ Raises:
996
+ ValueError: If no image source is provided or if `base64` is used without
997
+ `mime_type`.
998
+
999
+ !!! note
1000
+ The `id` is generated automatically if not provided, using a UUID4 format
1001
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1002
+
1003
+ """
1004
+ if not any([url, base64, file_id]):
1005
+ msg = "Must provide one of: url, base64, or file_id"
1006
+ raise ValueError(msg)
1007
+
1008
+ block = ImageContentBlock(type="image", id=ensure_id(id))
1009
+
1010
+ if url is not None:
1011
+ block["url"] = url
1012
+ if base64 is not None:
1013
+ block["base64"] = base64
1014
+ if file_id is not None:
1015
+ block["file_id"] = file_id
1016
+ if mime_type is not None:
1017
+ block["mime_type"] = mime_type
1018
+ if index is not None:
1019
+ block["index"] = index
1020
+
1021
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1022
+ if extras:
1023
+ block["extras"] = extras
1024
+
1025
+ return block
1026
+
1027
+
1028
+ def create_video_block(
1029
+ *,
1030
+ url: str | None = None,
1031
+ base64: str | None = None,
1032
+ file_id: str | None = None,
1033
+ mime_type: str | None = None,
1034
+ id: str | None = None,
1035
+ index: int | str | None = None,
1036
+ **kwargs: Any,
1037
+ ) -> VideoContentBlock:
1038
+ """Create a `VideoContentBlock`.
1039
+
1040
+ Args:
1041
+ url: URL of the video.
1042
+ base64: Base64-encoded video data.
1043
+ file_id: ID of the video file from a file storage system.
1044
+ mime_type: MIME type of the video. Required for base64 data.
1045
+ id: Content block identifier. Generated automatically if not provided.
1046
+ index: Index of block in aggregate response. Used during streaming.
1047
+
1048
+ Returns:
1049
+ A properly formatted `VideoContentBlock`.
1050
+
1051
+ Raises:
1052
+ ValueError: If no video source is provided or if `base64` is used without
1053
+ `mime_type`.
1054
+
1055
+ !!! note
1056
+ The `id` is generated automatically if not provided, using a UUID4 format
1057
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1058
+
1059
+ """
1060
+ if not any([url, base64, file_id]):
1061
+ msg = "Must provide one of: url, base64, or file_id"
1062
+ raise ValueError(msg)
1063
+
1064
+ if base64 and not mime_type:
1065
+ msg = "mime_type is required when using base64 data"
1066
+ raise ValueError(msg)
1067
+
1068
+ block = VideoContentBlock(type="video", id=ensure_id(id))
1069
+
1070
+ if url is not None:
1071
+ block["url"] = url
1072
+ if base64 is not None:
1073
+ block["base64"] = base64
1074
+ if file_id is not None:
1075
+ block["file_id"] = file_id
1076
+ if mime_type is not None:
1077
+ block["mime_type"] = mime_type
1078
+ if index is not None:
1079
+ block["index"] = index
1080
+
1081
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1082
+ if extras:
1083
+ block["extras"] = extras
1084
+
1085
+ return block
1086
+
1087
+
1088
+ def create_audio_block(
1089
+ *,
1090
+ url: str | None = None,
1091
+ base64: str | None = None,
1092
+ file_id: str | None = None,
1093
+ mime_type: str | None = None,
1094
+ id: str | None = None,
1095
+ index: int | str | None = None,
1096
+ **kwargs: Any,
1097
+ ) -> AudioContentBlock:
1098
+ """Create an `AudioContentBlock`.
1099
+
1100
+ Args:
1101
+ url: URL of the audio.
1102
+ base64: Base64-encoded audio data.
1103
+ file_id: ID of the audio file from a file storage system.
1104
+ mime_type: MIME type of the audio. Required for base64 data.
1105
+ id: Content block identifier. Generated automatically if not provided.
1106
+ index: Index of block in aggregate response. Used during streaming.
1107
+
1108
+ Returns:
1109
+ A properly formatted `AudioContentBlock`.
1110
+
1111
+ Raises:
1112
+ ValueError: If no audio source is provided or if `base64` is used without
1113
+ `mime_type`.
1114
+
1115
+ !!! note
1116
+ The `id` is generated automatically if not provided, using a UUID4 format
1117
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1118
+
1119
+ """
1120
+ if not any([url, base64, file_id]):
1121
+ msg = "Must provide one of: url, base64, or file_id"
1122
+ raise ValueError(msg)
1123
+
1124
+ if base64 and not mime_type:
1125
+ msg = "mime_type is required when using base64 data"
1126
+ raise ValueError(msg)
1127
+
1128
+ block = AudioContentBlock(type="audio", id=ensure_id(id))
1129
+
1130
+ if url is not None:
1131
+ block["url"] = url
1132
+ if base64 is not None:
1133
+ block["base64"] = base64
1134
+ if file_id is not None:
1135
+ block["file_id"] = file_id
1136
+ if mime_type is not None:
1137
+ block["mime_type"] = mime_type
1138
+ if index is not None:
1139
+ block["index"] = index
1140
+
1141
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1142
+ if extras:
1143
+ block["extras"] = extras
1144
+
1145
+ return block
1146
+
1147
+
1148
+ def create_file_block(
1149
+ *,
1150
+ url: str | None = None,
1151
+ base64: str | None = None,
1152
+ file_id: str | None = None,
1153
+ mime_type: str | None = None,
1154
+ id: str | None = None,
1155
+ index: int | str | None = None,
1156
+ **kwargs: Any,
1157
+ ) -> FileContentBlock:
1158
+ """Create a `FileContentBlock`.
1159
+
1160
+ Args:
1161
+ url: URL of the file.
1162
+ base64: Base64-encoded file data.
1163
+ file_id: ID of the file from a file storage system.
1164
+ mime_type: MIME type of the file. Required for base64 data.
1165
+ id: Content block identifier. Generated automatically if not provided.
1166
+ index: Index of block in aggregate response. Used during streaming.
1167
+
1168
+ Returns:
1169
+ A properly formatted `FileContentBlock`.
1170
+
1171
+ Raises:
1172
+ ValueError: If no file source is provided or if `base64` is used without
1173
+ `mime_type`.
1174
+
1175
+ !!! note
1176
+ The `id` is generated automatically if not provided, using a UUID4 format
1177
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1178
+
1179
+ """
1180
+ if not any([url, base64, file_id]):
1181
+ msg = "Must provide one of: url, base64, or file_id"
1182
+ raise ValueError(msg)
1183
+
1184
+ if base64 and not mime_type:
1185
+ msg = "mime_type is required when using base64 data"
1186
+ raise ValueError(msg)
1187
+
1188
+ block = FileContentBlock(type="file", id=ensure_id(id))
1189
+
1190
+ if url is not None:
1191
+ block["url"] = url
1192
+ if base64 is not None:
1193
+ block["base64"] = base64
1194
+ if file_id is not None:
1195
+ block["file_id"] = file_id
1196
+ if mime_type is not None:
1197
+ block["mime_type"] = mime_type
1198
+ if index is not None:
1199
+ block["index"] = index
1200
+
1201
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1202
+ if extras:
1203
+ block["extras"] = extras
1204
+
1205
+ return block
1206
+
1207
+
1208
+ def create_plaintext_block(
1209
+ text: str | None = None,
1210
+ url: str | None = None,
1211
+ base64: str | None = None,
1212
+ file_id: str | None = None,
1213
+ title: str | None = None,
1214
+ context: str | None = None,
1215
+ id: str | None = None,
1216
+ index: int | str | None = None,
1217
+ **kwargs: Any,
1218
+ ) -> PlainTextContentBlock:
1219
+ """Create a `PlainTextContentBlock`.
1220
+
1221
+ Args:
1222
+ text: The plaintext content.
1223
+ url: URL of the plaintext file.
1224
+ base64: Base64-encoded plaintext data.
1225
+ file_id: ID of the plaintext file from a file storage system.
1226
+ title: Title of the text data.
1227
+ context: Context or description of the text content.
1228
+ id: Content block identifier. Generated automatically if not provided.
1229
+ index: Index of block in aggregate response. Used during streaming.
1230
+
1231
+ Returns:
1232
+ A properly formatted `PlainTextContentBlock`.
1233
+
1234
+ !!! note
1235
+ The `id` is generated automatically if not provided, using a UUID4 format
1236
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1237
+
1238
+ """
1239
+ block = PlainTextContentBlock(
1240
+ type="text-plain",
1241
+ mime_type="text/plain",
1242
+ id=ensure_id(id),
1243
+ )
1244
+
1245
+ if text is not None:
1246
+ block["text"] = text
1247
+ if url is not None:
1248
+ block["url"] = url
1249
+ if base64 is not None:
1250
+ block["base64"] = base64
1251
+ if file_id is not None:
1252
+ block["file_id"] = file_id
1253
+ if title is not None:
1254
+ block["title"] = title
1255
+ if context is not None:
1256
+ block["context"] = context
1257
+ if index is not None:
1258
+ block["index"] = index
1259
+
1260
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1261
+ if extras:
1262
+ block["extras"] = extras
1263
+
1264
+ return block
1265
+
1266
+
1267
+ def create_tool_call(
1268
+ name: str,
1269
+ args: dict[str, Any],
1270
+ *,
1271
+ id: str | None = None,
1272
+ index: int | str | None = None,
1273
+ **kwargs: Any,
1274
+ ) -> ToolCall:
1275
+ """Create a `ToolCall`.
1276
+
1277
+ Args:
1278
+ name: The name of the tool to be called.
1279
+ args: The arguments to the tool call.
1280
+ id: An identifier for the tool call. Generated automatically if not provided.
1281
+ index: Index of block in aggregate response. Used during streaming.
1282
+
1283
+ Returns:
1284
+ A properly formatted `ToolCall`.
1285
+
1286
+ !!! note
1287
+ The `id` is generated automatically if not provided, using a UUID4 format
1288
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1289
+
1290
+ """
1291
+ block = ToolCall(
1292
+ type="tool_call",
1293
+ name=name,
1294
+ args=args,
1295
+ id=ensure_id(id),
1296
+ )
1297
+
1298
+ if index is not None:
1299
+ block["index"] = index
1300
+
1301
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1302
+ if extras:
1303
+ block["extras"] = extras
1304
+
1305
+ return block
1306
+
1307
+
1308
+ def create_reasoning_block(
1309
+ reasoning: str | None = None,
1310
+ id: str | None = None,
1311
+ index: int | str | None = None,
1312
+ **kwargs: Any,
1313
+ ) -> ReasoningContentBlock:
1314
+ """Create a `ReasoningContentBlock`.
1315
+
1316
+ Args:
1317
+ reasoning: The reasoning text or thought summary.
1318
+ id: Content block identifier. Generated automatically if not provided.
1319
+ index: Index of block in aggregate response. Used during streaming.
1320
+
1321
+ Returns:
1322
+ A properly formatted `ReasoningContentBlock`.
1323
+
1324
+ !!! note
1325
+ The `id` is generated automatically if not provided, using a UUID4 format
1326
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1327
+
1328
+ """
1329
+ block = ReasoningContentBlock(
1330
+ type="reasoning",
1331
+ reasoning=reasoning or "",
1332
+ id=ensure_id(id),
1333
+ )
1334
+
1335
+ if index is not None:
1336
+ block["index"] = index
1337
+
1338
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1339
+ if extras:
1340
+ block["extras"] = extras
1341
+
1342
+ return block
1343
+
1344
+
1345
+ def create_citation(
1346
+ *,
1347
+ url: str | None = None,
1348
+ title: str | None = None,
1349
+ start_index: int | None = None,
1350
+ end_index: int | None = None,
1351
+ cited_text: str | None = None,
1352
+ id: str | None = None,
1353
+ **kwargs: Any,
1354
+ ) -> Citation:
1355
+ """Create a `Citation`.
1356
+
1357
+ Args:
1358
+ url: URL of the document source.
1359
+ title: Source document title.
1360
+ start_index: Start index in the response text where citation applies.
1361
+ end_index: End index in the response text where citation applies.
1362
+ cited_text: Excerpt of source text being cited.
1363
+ id: Content block identifier. Generated automatically if not provided.
1364
+
1365
+ Returns:
1366
+ A properly formatted `Citation`.
1367
+
1368
+ !!! note
1369
+ The `id` is generated automatically if not provided, using a UUID4 format
1370
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1371
+
1372
+ """
1373
+ block = Citation(type="citation", id=ensure_id(id))
1374
+
1375
+ if url is not None:
1376
+ block["url"] = url
1377
+ if title is not None:
1378
+ block["title"] = title
1379
+ if start_index is not None:
1380
+ block["start_index"] = start_index
1381
+ if end_index is not None:
1382
+ block["end_index"] = end_index
1383
+ if cited_text is not None:
1384
+ block["cited_text"] = cited_text
1385
+
1386
+ extras = {k: v for k, v in kwargs.items() if v is not None}
1387
+ if extras:
1388
+ block["extras"] = extras
1389
+
1390
+ return block
1391
+
1392
+
1393
+ def create_non_standard_block(
1394
+ value: dict[str, Any],
1395
+ *,
1396
+ id: str | None = None,
1397
+ index: int | str | None = None,
1398
+ ) -> NonStandardContentBlock:
1399
+ """Create a `NonStandardContentBlock`.
1400
+
1401
+ Args:
1402
+ value: Provider-specific data.
1403
+ id: Content block identifier. Generated automatically if not provided.
1404
+ index: Index of block in aggregate response. Used during streaming.
1405
+
1406
+ Returns:
1407
+ A properly formatted `NonStandardContentBlock`.
1408
+
1409
+ !!! note
1410
+ The `id` is generated automatically if not provided, using a UUID4 format
1411
+ prefixed with `'lc_'` to indicate it is a LangChain-generated ID.
1412
+
1413
+ """
1414
+ block = NonStandardContentBlock(
1415
+ type="non_standard",
1416
+ value=value,
1417
+ id=ensure_id(id),
1418
+ )
1419
+
1420
+ if index is not None:
1421
+ block["index"] = index
1422
+
1423
+ return block