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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. langchain_core/__init__.py +1 -1
  2. langchain_core/_api/__init__.py +3 -4
  3. langchain_core/_api/beta_decorator.py +23 -26
  4. langchain_core/_api/deprecation.py +51 -64
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +55 -48
  8. langchain_core/caches.py +65 -66
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +321 -336
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +454 -514
  13. langchain_core/callbacks/stdout.py +29 -30
  14. langchain_core/callbacks/streaming_stdout.py +32 -32
  15. langchain_core/callbacks/usage.py +60 -57
  16. langchain_core/chat_history.py +53 -68
  17. langchain_core/document_loaders/base.py +27 -25
  18. langchain_core/document_loaders/blob_loaders.py +1 -1
  19. langchain_core/document_loaders/langsmith.py +44 -48
  20. langchain_core/documents/__init__.py +23 -3
  21. langchain_core/documents/base.py +102 -94
  22. langchain_core/documents/compressor.py +10 -10
  23. langchain_core/documents/transformers.py +34 -35
  24. langchain_core/embeddings/fake.py +50 -54
  25. langchain_core/example_selectors/length_based.py +2 -2
  26. langchain_core/example_selectors/semantic_similarity.py +28 -32
  27. langchain_core/exceptions.py +21 -20
  28. langchain_core/globals.py +3 -151
  29. langchain_core/indexing/__init__.py +1 -1
  30. langchain_core/indexing/api.py +121 -126
  31. langchain_core/indexing/base.py +73 -75
  32. langchain_core/indexing/in_memory.py +4 -6
  33. langchain_core/language_models/__init__.py +14 -29
  34. langchain_core/language_models/_utils.py +58 -61
  35. langchain_core/language_models/base.py +82 -172
  36. langchain_core/language_models/chat_models.py +329 -402
  37. langchain_core/language_models/fake.py +11 -11
  38. langchain_core/language_models/fake_chat_models.py +42 -36
  39. langchain_core/language_models/llms.py +189 -269
  40. langchain_core/load/dump.py +9 -12
  41. langchain_core/load/load.py +18 -28
  42. langchain_core/load/mapping.py +2 -4
  43. langchain_core/load/serializable.py +42 -40
  44. langchain_core/messages/__init__.py +10 -16
  45. langchain_core/messages/ai.py +148 -148
  46. langchain_core/messages/base.py +53 -51
  47. langchain_core/messages/block_translators/__init__.py +19 -22
  48. langchain_core/messages/block_translators/anthropic.py +6 -6
  49. langchain_core/messages/block_translators/bedrock_converse.py +5 -5
  50. langchain_core/messages/block_translators/google_genai.py +10 -7
  51. langchain_core/messages/block_translators/google_vertexai.py +4 -32
  52. langchain_core/messages/block_translators/groq.py +117 -21
  53. langchain_core/messages/block_translators/langchain_v0.py +5 -5
  54. langchain_core/messages/block_translators/openai.py +11 -11
  55. langchain_core/messages/chat.py +2 -6
  56. langchain_core/messages/content.py +339 -330
  57. langchain_core/messages/function.py +6 -10
  58. langchain_core/messages/human.py +24 -31
  59. langchain_core/messages/modifier.py +2 -2
  60. langchain_core/messages/system.py +19 -29
  61. langchain_core/messages/tool.py +74 -90
  62. langchain_core/messages/utils.py +484 -510
  63. langchain_core/output_parsers/__init__.py +13 -10
  64. langchain_core/output_parsers/base.py +61 -61
  65. langchain_core/output_parsers/format_instructions.py +9 -4
  66. langchain_core/output_parsers/json.py +12 -10
  67. langchain_core/output_parsers/list.py +21 -23
  68. langchain_core/output_parsers/openai_functions.py +49 -47
  69. langchain_core/output_parsers/openai_tools.py +30 -23
  70. langchain_core/output_parsers/pydantic.py +13 -14
  71. langchain_core/output_parsers/string.py +5 -5
  72. langchain_core/output_parsers/transform.py +15 -17
  73. langchain_core/output_parsers/xml.py +35 -34
  74. langchain_core/outputs/__init__.py +1 -1
  75. langchain_core/outputs/chat_generation.py +18 -18
  76. langchain_core/outputs/chat_result.py +1 -3
  77. langchain_core/outputs/generation.py +16 -16
  78. langchain_core/outputs/llm_result.py +10 -10
  79. langchain_core/prompt_values.py +13 -19
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +81 -86
  82. langchain_core/prompts/chat.py +308 -351
  83. langchain_core/prompts/dict.py +6 -6
  84. langchain_core/prompts/few_shot.py +81 -88
  85. langchain_core/prompts/few_shot_with_templates.py +11 -13
  86. langchain_core/prompts/image.py +12 -14
  87. langchain_core/prompts/loading.py +4 -6
  88. langchain_core/prompts/message.py +7 -7
  89. langchain_core/prompts/prompt.py +24 -39
  90. langchain_core/prompts/string.py +26 -10
  91. langchain_core/prompts/structured.py +49 -53
  92. langchain_core/rate_limiters.py +51 -60
  93. langchain_core/retrievers.py +61 -198
  94. langchain_core/runnables/base.py +1551 -1656
  95. langchain_core/runnables/branch.py +68 -70
  96. langchain_core/runnables/config.py +72 -89
  97. langchain_core/runnables/configurable.py +145 -161
  98. langchain_core/runnables/fallbacks.py +102 -96
  99. langchain_core/runnables/graph.py +91 -97
  100. langchain_core/runnables/graph_ascii.py +27 -28
  101. langchain_core/runnables/graph_mermaid.py +42 -51
  102. langchain_core/runnables/graph_png.py +43 -16
  103. langchain_core/runnables/history.py +175 -177
  104. langchain_core/runnables/passthrough.py +151 -167
  105. langchain_core/runnables/retry.py +46 -51
  106. langchain_core/runnables/router.py +30 -35
  107. langchain_core/runnables/schema.py +75 -80
  108. langchain_core/runnables/utils.py +60 -67
  109. langchain_core/stores.py +85 -121
  110. langchain_core/structured_query.py +8 -8
  111. langchain_core/sys_info.py +29 -29
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +306 -245
  114. langchain_core/tools/convert.py +160 -155
  115. langchain_core/tools/render.py +10 -10
  116. langchain_core/tools/retriever.py +12 -11
  117. langchain_core/tools/simple.py +19 -24
  118. langchain_core/tools/structured.py +32 -39
  119. langchain_core/tracers/__init__.py +1 -9
  120. langchain_core/tracers/base.py +97 -99
  121. langchain_core/tracers/context.py +29 -52
  122. langchain_core/tracers/core.py +49 -53
  123. langchain_core/tracers/evaluation.py +11 -11
  124. langchain_core/tracers/event_stream.py +65 -64
  125. langchain_core/tracers/langchain.py +21 -21
  126. langchain_core/tracers/log_stream.py +45 -45
  127. langchain_core/tracers/memory_stream.py +3 -3
  128. langchain_core/tracers/root_listeners.py +16 -16
  129. langchain_core/tracers/run_collector.py +2 -4
  130. langchain_core/tracers/schemas.py +0 -129
  131. langchain_core/tracers/stdout.py +3 -3
  132. langchain_core/utils/__init__.py +1 -4
  133. langchain_core/utils/_merge.py +2 -2
  134. langchain_core/utils/aiter.py +57 -61
  135. langchain_core/utils/env.py +9 -9
  136. langchain_core/utils/function_calling.py +94 -188
  137. langchain_core/utils/html.py +7 -8
  138. langchain_core/utils/input.py +9 -6
  139. langchain_core/utils/interactive_env.py +1 -1
  140. langchain_core/utils/iter.py +36 -40
  141. langchain_core/utils/json.py +4 -3
  142. langchain_core/utils/json_schema.py +9 -9
  143. langchain_core/utils/mustache.py +8 -10
  144. langchain_core/utils/pydantic.py +35 -37
  145. langchain_core/utils/strings.py +6 -9
  146. langchain_core/utils/usage.py +1 -1
  147. langchain_core/utils/utils.py +66 -62
  148. langchain_core/vectorstores/base.py +182 -216
  149. langchain_core/vectorstores/in_memory.py +101 -176
  150. langchain_core/vectorstores/utils.py +5 -5
  151. langchain_core/version.py +1 -1
  152. langchain_core-1.0.4.dist-info/METADATA +69 -0
  153. langchain_core-1.0.4.dist-info/RECORD +172 -0
  154. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.4.dist-info}/WHEEL +1 -1
  155. langchain_core/memory.py +0 -120
  156. langchain_core/messages/block_translators/ollama.py +0 -47
  157. langchain_core/prompts/pipeline.py +0 -138
  158. langchain_core/pydantic_v1/__init__.py +0 -30
  159. langchain_core/pydantic_v1/dataclasses.py +0 -23
  160. langchain_core/pydantic_v1/main.py +0 -23
  161. langchain_core/tracers/langchain_v1.py +0 -31
  162. langchain_core/utils/loading.py +0 -35
  163. langchain_core-1.0.0a6.dist-info/METADATA +0 -67
  164. langchain_core-1.0.0a6.dist-info/RECORD +0 -181
  165. langchain_core-1.0.0a6.dist-info/entry_points.txt +0 -4
@@ -1,39 +1,135 @@
1
1
  """Derivations of standard content blocks from Groq content."""
2
2
 
3
- import warnings
3
+ import json
4
+ import re
5
+ from typing import Any
4
6
 
5
7
  from langchain_core.messages import AIMessage, AIMessageChunk
6
8
  from langchain_core.messages import content as types
9
+ from langchain_core.messages.base import _extract_reasoning_from_additional_kwargs
7
10
 
8
- WARNED = False
9
11
 
12
+ def _populate_extras(
13
+ standard_block: types.ContentBlock, block: dict[str, Any], known_fields: set[str]
14
+ ) -> types.ContentBlock:
15
+ """Mutate a block, populating extras."""
16
+ if standard_block.get("type") == "non_standard":
17
+ return standard_block
10
18
 
11
- def translate_content(message: AIMessage) -> list[types.ContentBlock]: # noqa: ARG001
12
- """Derive standard content blocks from a message with Groq content."""
13
- global WARNED # noqa: PLW0603
14
- if not WARNED:
15
- warning_message = (
16
- "Content block standardization is not yet fully supported for Groq."
19
+ for key, value in block.items():
20
+ if key not in known_fields:
21
+ if "extras" not in standard_block:
22
+ # Below type-ignores are because mypy thinks a non-standard block can
23
+ # get here, although we exclude them above.
24
+ standard_block["extras"] = {} # type: ignore[typeddict-unknown-key]
25
+ standard_block["extras"][key] = value # type: ignore[typeddict-item]
26
+
27
+ return standard_block
28
+
29
+
30
+ def _parse_code_json(s: str) -> dict:
31
+ """Extract Python code from Groq built-in tool content.
32
+
33
+ Extracts the value of the 'code' field from a string of the form:
34
+ {"code": some_arbitrary_text_with_unescaped_quotes}
35
+
36
+ As Groq may not escape quotes in the executed tools, e.g.:
37
+ ```
38
+ '{"code": "import math; print("The square root of 101 is: "); print(math.sqrt(101))"}'
39
+ ```
40
+ """ # noqa: E501
41
+ m = re.fullmatch(r'\s*\{\s*"code"\s*:\s*"(.*)"\s*\}\s*', s, flags=re.DOTALL)
42
+ if not m:
43
+ msg = (
44
+ "Could not extract Python code from Groq tool arguments. "
45
+ "Expected a JSON object with a 'code' field."
17
46
  )
18
- warnings.warn(warning_message, stacklevel=2)
19
- WARNED = True
20
- raise NotImplementedError
47
+ raise ValueError(msg)
48
+ return {"code": m.group(1)}
49
+
50
+
51
+ def _convert_to_v1_from_groq(message: AIMessage) -> list[types.ContentBlock]:
52
+ """Convert groq message content to v1 format."""
53
+ content_blocks: list[types.ContentBlock] = []
21
54
 
55
+ if reasoning_block := _extract_reasoning_from_additional_kwargs(message):
56
+ content_blocks.append(reasoning_block)
22
57
 
23
- def translate_content_chunk(message: AIMessageChunk) -> list[types.ContentBlock]: # noqa: ARG001
24
- """Derive standard content blocks from a message chunk with Groq content."""
25
- global WARNED # noqa: PLW0603
26
- if not WARNED:
27
- warning_message = (
28
- "Content block standardization is not yet fully supported for Groq."
58
+ if executed_tools := message.additional_kwargs.get("executed_tools"):
59
+ for idx, executed_tool in enumerate(executed_tools):
60
+ args: dict[str, Any] | None = None
61
+ if arguments := executed_tool.get("arguments"):
62
+ try:
63
+ args = json.loads(arguments)
64
+ except json.JSONDecodeError:
65
+ if executed_tool.get("type") == "python":
66
+ try:
67
+ args = _parse_code_json(arguments)
68
+ except ValueError:
69
+ continue
70
+ elif (
71
+ executed_tool.get("type") == "function"
72
+ and executed_tool.get("name") == "python"
73
+ ):
74
+ # GPT-OSS
75
+ args = {"code": arguments}
76
+ else:
77
+ continue
78
+ if isinstance(args, dict):
79
+ name = ""
80
+ if executed_tool.get("type") == "search":
81
+ name = "web_search"
82
+ elif executed_tool.get("type") == "python" or (
83
+ executed_tool.get("type") == "function"
84
+ and executed_tool.get("name") == "python"
85
+ ):
86
+ name = "code_interpreter"
87
+ server_tool_call: types.ServerToolCall = {
88
+ "type": "server_tool_call",
89
+ "name": name,
90
+ "id": str(idx),
91
+ "args": args,
92
+ }
93
+ content_blocks.append(server_tool_call)
94
+ if tool_output := executed_tool.get("output"):
95
+ tool_result: types.ServerToolResult = {
96
+ "type": "server_tool_result",
97
+ "tool_call_id": str(idx),
98
+ "output": tool_output,
99
+ "status": "success",
100
+ }
101
+ known_fields = {"type", "arguments", "index", "output"}
102
+ _populate_extras(tool_result, executed_tool, known_fields)
103
+ content_blocks.append(tool_result)
104
+
105
+ if isinstance(message.content, str) and message.content:
106
+ content_blocks.append({"type": "text", "text": message.content})
107
+
108
+ for tool_call in message.tool_calls:
109
+ content_blocks.append( # noqa: PERF401
110
+ {
111
+ "type": "tool_call",
112
+ "name": tool_call["name"],
113
+ "args": tool_call["args"],
114
+ "id": tool_call.get("id"),
115
+ }
29
116
  )
30
- warnings.warn(warning_message, stacklevel=2)
31
- WARNED = True
32
- raise NotImplementedError
117
+
118
+ return content_blocks
119
+
120
+
121
+ def translate_content(message: AIMessage) -> list[types.ContentBlock]:
122
+ """Derive standard content blocks from a message with groq content."""
123
+ return _convert_to_v1_from_groq(message)
124
+
125
+
126
+ def translate_content_chunk(message: AIMessageChunk) -> list[types.ContentBlock]:
127
+ """Derive standard content blocks from a message chunk with groq content."""
128
+ return _convert_to_v1_from_groq(message)
33
129
 
34
130
 
35
131
  def _register_groq_translator() -> None:
36
- """Register the Groq translator with the central registry.
132
+ """Register the groq translator with the central registry.
37
133
 
38
134
  Run automatically when the module is imported.
39
135
  """
@@ -1,6 +1,6 @@
1
1
  """Derivations of standard content blocks from LangChain v0 multimodal content."""
2
2
 
3
- from typing import Any, Union, cast
3
+ from typing import Any, cast
4
4
 
5
5
  from langchain_core.messages import content as types
6
6
 
@@ -10,12 +10,12 @@ def _convert_v0_multimodal_input_to_v1(
10
10
  ) -> list[types.ContentBlock]:
11
11
  """Convert v0 multimodal blocks to v1 format.
12
12
 
13
- During the `.content_blocks` parsing process, we wrap blocks not recognized as a v1
14
- block as a ``'non_standard'`` block with the original block stored in the ``value``
13
+ During the `content_blocks` parsing process, we wrap blocks not recognized as a v1
14
+ block as a `'non_standard'` block with the original block stored in the `value`
15
15
  field. This function attempts to unpack those blocks and convert any v0 format
16
16
  blocks to v1 format.
17
17
 
18
- If conversion fails, the block is left as a ``'non_standard'`` block.
18
+ If conversion fails, the block is left as a `'non_standard'` block.
19
19
 
20
20
  Args:
21
21
  content: List of content blocks to process.
@@ -45,7 +45,7 @@ def _convert_v0_multimodal_input_to_v1(
45
45
 
46
46
  def _convert_legacy_v0_content_block_to_v1(
47
47
  block: dict,
48
- ) -> Union[types.ContentBlock, dict]:
48
+ ) -> types.ContentBlock | dict:
49
49
  """Convert a LangChain v0 content block to v1 format.
50
50
 
51
51
  Preserves unknown keys as extras to avoid data loss.
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
  import warnings
7
7
  from collections.abc import Iterable
8
- from typing import TYPE_CHECKING, Any, Literal, Optional, Union, cast
8
+ from typing import TYPE_CHECKING, Any, Literal, cast
9
9
 
10
10
  from langchain_core.language_models._utils import (
11
11
  _parse_data_uri,
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
18
18
 
19
19
 
20
20
  def convert_to_openai_image_block(block: dict[str, Any]) -> dict:
21
- """Convert ``ImageContentBlock`` to format expected by OpenAI Chat Completions."""
21
+ """Convert `ImageContentBlock` to format expected by OpenAI Chat Completions."""
22
22
  if "url" in block:
23
23
  return {
24
24
  "type": "image_url",
@@ -155,12 +155,12 @@ def _convert_to_v1_from_chat_completions_input(
155
155
  ) -> list[types.ContentBlock]:
156
156
  """Convert OpenAI Chat Completions format blocks to v1 format.
157
157
 
158
- During the `.content_blocks` parsing process, we wrap blocks not recognized as a v1
159
- block as a ``'non_standard'`` block with the original block stored in the ``value``
158
+ During the `content_blocks` parsing process, we wrap blocks not recognized as a v1
159
+ block as a `'non_standard'` block with the original block stored in the `value`
160
160
  field. This function attempts to unpack those blocks and convert any blocks that
161
161
  might be OpenAI format to v1 ContentBlocks.
162
162
 
163
- If conversion fails, the block is left as a ``'non_standard'`` block.
163
+ If conversion fails, the block is left as a `'non_standard'` block.
164
164
 
165
165
  Args:
166
166
  content: List of content blocks to process.
@@ -263,7 +263,7 @@ _FUNCTION_CALL_IDS_MAP_KEY = "__openai_function_call_ids__"
263
263
 
264
264
 
265
265
  def _convert_from_v03_ai_message(message: AIMessage) -> AIMessage:
266
- """Convert v0 AIMessage into ``output_version="responses/v1"`` format."""
266
+ """Convert v0 AIMessage into `output_version="responses/v1"` format."""
267
267
  from langchain_core.messages import AIMessageChunk # noqa: PLC0415
268
268
 
269
269
  # Only update ChatOpenAI v0.3 AIMessages
@@ -401,7 +401,7 @@ def _convert_from_v03_ai_message(message: AIMessage) -> AIMessage:
401
401
 
402
402
  def _convert_openai_format_to_data_block(
403
403
  block: dict,
404
- ) -> Union[types.ContentBlock, dict[Any, Any]]:
404
+ ) -> types.ContentBlock | dict[Any, Any]:
405
405
  """Convert OpenAI image/audio/file content block to respective v1 multimodal block.
406
406
 
407
407
  We expect that the incoming block is verified to be in OpenAI Chat Completions
@@ -677,9 +677,9 @@ def _convert_to_v1_from_responses(message: AIMessage) -> list[types.ContentBlock
677
677
  yield cast("types.ImageContentBlock", new_block)
678
678
 
679
679
  elif block_type == "function_call":
680
- tool_call_block: Optional[
681
- Union[types.ToolCall, types.InvalidToolCall, types.ToolCallChunk]
682
- ] = None
680
+ tool_call_block: (
681
+ types.ToolCall | types.InvalidToolCall | types.ToolCallChunk | None
682
+ ) = None
683
683
  call_id = block.get("call_id", "")
684
684
 
685
685
  from langchain_core.messages import AIMessageChunk # noqa: PLC0415
@@ -726,7 +726,7 @@ def _convert_to_v1_from_responses(message: AIMessage) -> list[types.ContentBlock
726
726
  if "index" in block:
727
727
  web_search_call["index"] = f"lc_wsc_{block['index']}"
728
728
 
729
- sources: Optional[dict[str, Any]] = None
729
+ sources: dict[str, Any] | None = None
730
730
  if "action" in block and isinstance(block["action"], dict):
731
731
  if "sources" in block["action"]:
732
732
  sources = block["action"]["sources"]
@@ -19,7 +19,7 @@ class ChatMessage(BaseMessage):
19
19
  """The speaker / role of the Message."""
20
20
 
21
21
  type: Literal["chat"] = "chat"
22
- """The type of the message (used during serialization). Defaults to "chat"."""
22
+ """The type of the message (used during serialization)."""
23
23
 
24
24
 
25
25
  class ChatMessageChunk(ChatMessage, BaseMessageChunk):
@@ -29,11 +29,7 @@ class ChatMessageChunk(ChatMessage, BaseMessageChunk):
29
29
  # to make sure that the chunk variant can be discriminated from the
30
30
  # non-chunk variant.
31
31
  type: Literal["ChatMessageChunk"] = "ChatMessageChunk" # type: ignore[assignment]
32
- """The type of the message (used during serialization).
33
-
34
- Defaults to ``'ChatMessageChunk'``.
35
-
36
- """
32
+ """The type of the message (used during serialization)."""
37
33
 
38
34
  @override
39
35
  def __add__(self, other: Any) -> BaseMessageChunk: # type: ignore[override]