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,297 @@
1
+ """Derivations of standard content blocks from Amazon (Bedrock Converse) content."""
2
+
3
+ import base64
4
+ from collections.abc import Iterable
5
+ from typing import Any, cast
6
+
7
+ from langchain_core.messages import AIMessage, AIMessageChunk
8
+ from langchain_core.messages import content as types
9
+
10
+
11
+ def _bytes_to_b64_str(bytes_: bytes) -> str:
12
+ return base64.b64encode(bytes_).decode("utf-8")
13
+
14
+
15
+ def _populate_extras(
16
+ standard_block: types.ContentBlock, block: dict[str, Any], known_fields: set[str]
17
+ ) -> types.ContentBlock:
18
+ """Mutate a block, populating extras."""
19
+ if standard_block.get("type") == "non_standard":
20
+ return standard_block
21
+
22
+ for key, value in block.items():
23
+ if key not in known_fields:
24
+ if "extras" not in standard_block:
25
+ # Below type-ignores are because mypy thinks a non-standard block can
26
+ # get here, although we exclude them above.
27
+ standard_block["extras"] = {} # type: ignore[typeddict-unknown-key]
28
+ standard_block["extras"][key] = value # type: ignore[typeddict-item]
29
+
30
+ return standard_block
31
+
32
+
33
+ def _convert_to_v1_from_converse_input(
34
+ content: list[types.ContentBlock],
35
+ ) -> list[types.ContentBlock]:
36
+ """Convert Bedrock Converse format blocks to v1 format.
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`
40
+ field. This function attempts to unpack those blocks and convert any blocks that
41
+ might be Converse format to v1 ContentBlocks.
42
+
43
+ If conversion fails, the block is left as a `'non_standard'` block.
44
+
45
+ Args:
46
+ content: List of content blocks to process.
47
+
48
+ Returns:
49
+ Updated list with Converse blocks converted to v1 format.
50
+ """
51
+
52
+ def _iter_blocks() -> Iterable[types.ContentBlock]:
53
+ blocks: list[dict[str, Any]] = [
54
+ cast("dict[str, Any]", block)
55
+ if block.get("type") != "non_standard"
56
+ else block["value"] # type: ignore[typeddict-item] # this is only non-standard blocks
57
+ for block in content
58
+ ]
59
+ for block in blocks:
60
+ num_keys = len(block)
61
+
62
+ if num_keys == 1 and (text := block.get("text")):
63
+ yield {"type": "text", "text": text}
64
+
65
+ elif (
66
+ num_keys == 1
67
+ and (document := block.get("document"))
68
+ and isinstance(document, dict)
69
+ and "format" in document
70
+ ):
71
+ if document.get("format") == "pdf":
72
+ if "bytes" in document.get("source", {}):
73
+ file_block: types.FileContentBlock = {
74
+ "type": "file",
75
+ "base64": _bytes_to_b64_str(document["source"]["bytes"]),
76
+ "mime_type": "application/pdf",
77
+ }
78
+ _populate_extras(file_block, document, {"format", "source"})
79
+ yield file_block
80
+
81
+ else:
82
+ yield {"type": "non_standard", "value": block}
83
+
84
+ elif document["format"] == "txt":
85
+ if "text" in document.get("source", {}):
86
+ plain_text_block: types.PlainTextContentBlock = {
87
+ "type": "text-plain",
88
+ "text": document["source"]["text"],
89
+ "mime_type": "text/plain",
90
+ }
91
+ _populate_extras(
92
+ plain_text_block, document, {"format", "source"}
93
+ )
94
+ yield plain_text_block
95
+ else:
96
+ yield {"type": "non_standard", "value": block}
97
+
98
+ else:
99
+ yield {"type": "non_standard", "value": block}
100
+
101
+ elif (
102
+ num_keys == 1
103
+ and (image := block.get("image"))
104
+ and isinstance(image, dict)
105
+ and "format" in image
106
+ ):
107
+ if "bytes" in image.get("source", {}):
108
+ image_block: types.ImageContentBlock = {
109
+ "type": "image",
110
+ "base64": _bytes_to_b64_str(image["source"]["bytes"]),
111
+ "mime_type": f"image/{image['format']}",
112
+ }
113
+ _populate_extras(image_block, image, {"format", "source"})
114
+ yield image_block
115
+
116
+ else:
117
+ yield {"type": "non_standard", "value": block}
118
+
119
+ elif block.get("type") in types.KNOWN_BLOCK_TYPES:
120
+ yield cast("types.ContentBlock", block)
121
+
122
+ else:
123
+ yield {"type": "non_standard", "value": block}
124
+
125
+ return list(_iter_blocks())
126
+
127
+
128
+ def _convert_citation_to_v1(citation: dict[str, Any]) -> types.Annotation:
129
+ standard_citation: types.Citation = {"type": "citation"}
130
+ if "title" in citation:
131
+ standard_citation["title"] = citation["title"]
132
+ if (
133
+ (source_content := citation.get("source_content"))
134
+ and isinstance(source_content, list)
135
+ and all(isinstance(item, dict) for item in source_content)
136
+ ):
137
+ standard_citation["cited_text"] = "".join(
138
+ item.get("text", "") for item in source_content
139
+ )
140
+
141
+ known_fields = {"type", "source_content", "title", "index", "extras"}
142
+
143
+ for key, value in citation.items():
144
+ if key not in known_fields:
145
+ if "extras" not in standard_citation:
146
+ standard_citation["extras"] = {}
147
+ standard_citation["extras"][key] = value
148
+
149
+ return standard_citation
150
+
151
+
152
+ def _convert_to_v1_from_converse(message: AIMessage) -> list[types.ContentBlock]:
153
+ """Convert Bedrock Converse message content to v1 format."""
154
+ if (
155
+ message.content == ""
156
+ and not message.additional_kwargs
157
+ and not message.tool_calls
158
+ ):
159
+ # Converse outputs multiple chunks containing response metadata
160
+ return []
161
+
162
+ if isinstance(message.content, str):
163
+ message.content = [{"type": "text", "text": message.content}]
164
+
165
+ def _iter_blocks() -> Iterable[types.ContentBlock]:
166
+ for block in message.content:
167
+ if not isinstance(block, dict):
168
+ continue
169
+ block_type = block.get("type")
170
+
171
+ if block_type == "text":
172
+ if citations := block.get("citations"):
173
+ text_block: types.TextContentBlock = {
174
+ "type": "text",
175
+ "text": block.get("text", ""),
176
+ "annotations": [_convert_citation_to_v1(a) for a in citations],
177
+ }
178
+ else:
179
+ text_block = {"type": "text", "text": block["text"]}
180
+ if "index" in block:
181
+ text_block["index"] = block["index"]
182
+ yield text_block
183
+
184
+ elif block_type == "reasoning_content":
185
+ reasoning_block: types.ReasoningContentBlock = {"type": "reasoning"}
186
+ if reasoning_content := block.get("reasoning_content"):
187
+ if reasoning := reasoning_content.get("text"):
188
+ reasoning_block["reasoning"] = reasoning
189
+ if signature := reasoning_content.get("signature"):
190
+ if "extras" not in reasoning_block:
191
+ reasoning_block["extras"] = {}
192
+ reasoning_block["extras"]["signature"] = signature
193
+
194
+ if "index" in block:
195
+ reasoning_block["index"] = block["index"]
196
+
197
+ known_fields = {"type", "reasoning_content", "index", "extras"}
198
+ for key in block:
199
+ if key not in known_fields:
200
+ if "extras" not in reasoning_block:
201
+ reasoning_block["extras"] = {}
202
+ reasoning_block["extras"][key] = block[key]
203
+ yield reasoning_block
204
+
205
+ elif block_type == "tool_use":
206
+ if (
207
+ isinstance(message, AIMessageChunk)
208
+ and len(message.tool_call_chunks) == 1
209
+ and message.chunk_position != "last"
210
+ ):
211
+ # Isolated chunk
212
+ tool_call_chunk: types.ToolCallChunk = (
213
+ message.tool_call_chunks[0].copy() # type: ignore[assignment]
214
+ )
215
+ if "type" not in tool_call_chunk:
216
+ tool_call_chunk["type"] = "tool_call_chunk"
217
+ yield tool_call_chunk
218
+ else:
219
+ tool_call_block: types.ToolCall | None = None
220
+ # Non-streaming or gathered chunk
221
+ if len(message.tool_calls) == 1:
222
+ tool_call_block = {
223
+ "type": "tool_call",
224
+ "name": message.tool_calls[0]["name"],
225
+ "args": message.tool_calls[0]["args"],
226
+ "id": message.tool_calls[0].get("id"),
227
+ }
228
+ elif call_id := block.get("id"):
229
+ for tc in message.tool_calls:
230
+ if tc.get("id") == call_id:
231
+ tool_call_block = {
232
+ "type": "tool_call",
233
+ "name": tc["name"],
234
+ "args": tc["args"],
235
+ "id": tc.get("id"),
236
+ }
237
+ break
238
+ else:
239
+ pass
240
+ if not tool_call_block:
241
+ tool_call_block = {
242
+ "type": "tool_call",
243
+ "name": block.get("name", ""),
244
+ "args": block.get("input", {}),
245
+ "id": block.get("id", ""),
246
+ }
247
+ if "index" in block:
248
+ tool_call_block["index"] = block["index"]
249
+ yield tool_call_block
250
+
251
+ elif (
252
+ block_type == "input_json_delta"
253
+ and isinstance(message, AIMessageChunk)
254
+ and len(message.tool_call_chunks) == 1
255
+ ):
256
+ tool_call_chunk = (
257
+ message.tool_call_chunks[0].copy() # type: ignore[assignment]
258
+ )
259
+ if "type" not in tool_call_chunk:
260
+ tool_call_chunk["type"] = "tool_call_chunk"
261
+ yield tool_call_chunk
262
+
263
+ else:
264
+ new_block: types.NonStandardContentBlock = {
265
+ "type": "non_standard",
266
+ "value": block,
267
+ }
268
+ if "index" in new_block["value"]:
269
+ new_block["index"] = new_block["value"].pop("index")
270
+ yield new_block
271
+
272
+ return list(_iter_blocks())
273
+
274
+
275
+ def translate_content(message: AIMessage) -> list[types.ContentBlock]:
276
+ """Derive standard content blocks from a message with Bedrock Converse content."""
277
+ return _convert_to_v1_from_converse(message)
278
+
279
+
280
+ def translate_content_chunk(message: AIMessageChunk) -> list[types.ContentBlock]:
281
+ """Derive standard content blocks from a chunk with Bedrock Converse content."""
282
+ return _convert_to_v1_from_converse(message)
283
+
284
+
285
+ def _register_bedrock_converse_translator() -> None:
286
+ """Register the Bedrock Converse translator with the central registry.
287
+
288
+ Run automatically when the module is imported.
289
+ """
290
+ from langchain_core.messages.block_translators import ( # noqa: PLC0415
291
+ register_translator,
292
+ )
293
+
294
+ register_translator("bedrock_converse", translate_content, translate_content_chunk)
295
+
296
+
297
+ _register_bedrock_converse_translator()