langchain-core 1.0.0a6__py3-none-any.whl → 1.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +23 -26
- langchain_core/_api/deprecation.py +51 -64
- langchain_core/_api/path.py +3 -6
- langchain_core/_import_utils.py +3 -4
- langchain_core/agents.py +20 -22
- langchain_core/caches.py +65 -66
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +321 -336
- langchain_core/callbacks/file.py +44 -44
- langchain_core/callbacks/manager.py +436 -513
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +32 -32
- langchain_core/callbacks/usage.py +60 -57
- langchain_core/chat_history.py +53 -68
- langchain_core/document_loaders/base.py +27 -25
- langchain_core/document_loaders/blob_loaders.py +1 -1
- langchain_core/document_loaders/langsmith.py +44 -48
- langchain_core/documents/__init__.py +23 -3
- langchain_core/documents/base.py +98 -90
- langchain_core/documents/compressor.py +10 -10
- langchain_core/documents/transformers.py +34 -35
- langchain_core/embeddings/fake.py +50 -54
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +28 -32
- langchain_core/exceptions.py +21 -20
- langchain_core/globals.py +3 -151
- langchain_core/indexing/__init__.py +1 -1
- langchain_core/indexing/api.py +121 -126
- langchain_core/indexing/base.py +73 -75
- langchain_core/indexing/in_memory.py +4 -6
- langchain_core/language_models/__init__.py +14 -29
- langchain_core/language_models/_utils.py +58 -61
- langchain_core/language_models/base.py +53 -162
- langchain_core/language_models/chat_models.py +298 -387
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +42 -36
- langchain_core/language_models/llms.py +125 -235
- langchain_core/load/dump.py +9 -12
- langchain_core/load/load.py +18 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +42 -40
- langchain_core/messages/__init__.py +10 -16
- langchain_core/messages/ai.py +148 -148
- langchain_core/messages/base.py +53 -51
- langchain_core/messages/block_translators/__init__.py +19 -22
- langchain_core/messages/block_translators/anthropic.py +6 -6
- langchain_core/messages/block_translators/bedrock_converse.py +5 -5
- langchain_core/messages/block_translators/google_genai.py +10 -7
- langchain_core/messages/block_translators/google_vertexai.py +4 -32
- langchain_core/messages/block_translators/groq.py +117 -21
- langchain_core/messages/block_translators/langchain_v0.py +5 -5
- langchain_core/messages/block_translators/openai.py +11 -11
- langchain_core/messages/chat.py +2 -6
- langchain_core/messages/content.py +337 -328
- langchain_core/messages/function.py +6 -10
- langchain_core/messages/human.py +24 -31
- langchain_core/messages/modifier.py +2 -2
- langchain_core/messages/system.py +19 -29
- langchain_core/messages/tool.py +74 -90
- langchain_core/messages/utils.py +474 -504
- langchain_core/output_parsers/__init__.py +13 -10
- langchain_core/output_parsers/base.py +61 -61
- langchain_core/output_parsers/format_instructions.py +9 -4
- langchain_core/output_parsers/json.py +12 -10
- langchain_core/output_parsers/list.py +21 -23
- langchain_core/output_parsers/openai_functions.py +49 -47
- langchain_core/output_parsers/openai_tools.py +16 -21
- langchain_core/output_parsers/pydantic.py +13 -14
- langchain_core/output_parsers/string.py +5 -5
- langchain_core/output_parsers/transform.py +15 -17
- langchain_core/output_parsers/xml.py +35 -34
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +18 -18
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +10 -11
- langchain_core/outputs/llm_result.py +10 -10
- langchain_core/prompt_values.py +11 -17
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +48 -56
- langchain_core/prompts/chat.py +275 -325
- langchain_core/prompts/dict.py +5 -5
- langchain_core/prompts/few_shot.py +81 -88
- langchain_core/prompts/few_shot_with_templates.py +11 -13
- langchain_core/prompts/image.py +12 -14
- langchain_core/prompts/loading.py +4 -6
- langchain_core/prompts/message.py +3 -3
- langchain_core/prompts/prompt.py +24 -39
- langchain_core/prompts/string.py +26 -10
- langchain_core/prompts/structured.py +49 -53
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +61 -198
- langchain_core/runnables/base.py +1476 -1626
- langchain_core/runnables/branch.py +53 -57
- langchain_core/runnables/config.py +72 -89
- langchain_core/runnables/configurable.py +120 -137
- langchain_core/runnables/fallbacks.py +83 -79
- langchain_core/runnables/graph.py +91 -97
- langchain_core/runnables/graph_ascii.py +27 -28
- langchain_core/runnables/graph_mermaid.py +38 -50
- langchain_core/runnables/graph_png.py +15 -16
- langchain_core/runnables/history.py +135 -148
- langchain_core/runnables/passthrough.py +124 -150
- langchain_core/runnables/retry.py +46 -51
- langchain_core/runnables/router.py +25 -30
- langchain_core/runnables/schema.py +75 -80
- langchain_core/runnables/utils.py +60 -67
- langchain_core/stores.py +85 -121
- langchain_core/structured_query.py +8 -8
- langchain_core/sys_info.py +27 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +284 -229
- langchain_core/tools/convert.py +160 -155
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +12 -11
- langchain_core/tools/simple.py +19 -24
- langchain_core/tools/structured.py +32 -39
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/base.py +97 -99
- langchain_core/tracers/context.py +29 -52
- langchain_core/tracers/core.py +49 -53
- langchain_core/tracers/evaluation.py +11 -11
- langchain_core/tracers/event_stream.py +65 -64
- langchain_core/tracers/langchain.py +21 -21
- langchain_core/tracers/log_stream.py +45 -45
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +16 -16
- langchain_core/tracers/run_collector.py +2 -4
- langchain_core/tracers/schemas.py +0 -129
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +2 -2
- langchain_core/utils/aiter.py +57 -61
- langchain_core/utils/env.py +9 -9
- langchain_core/utils/function_calling.py +89 -186
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +1 -1
- langchain_core/utils/iter.py +36 -40
- langchain_core/utils/json.py +4 -3
- langchain_core/utils/json_schema.py +9 -9
- langchain_core/utils/mustache.py +8 -10
- langchain_core/utils/pydantic.py +33 -35
- langchain_core/utils/strings.py +6 -9
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +66 -62
- langchain_core/vectorstores/base.py +182 -216
- langchain_core/vectorstores/in_memory.py +101 -176
- langchain_core/vectorstores/utils.py +5 -5
- langchain_core/version.py +1 -1
- langchain_core-1.0.3.dist-info/METADATA +69 -0
- langchain_core-1.0.3.dist-info/RECORD +172 -0
- {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.3.dist-info}/WHEEL +1 -1
- langchain_core/memory.py +0 -120
- langchain_core/messages/block_translators/ollama.py +0 -47
- langchain_core/prompts/pipeline.py +0 -138
- langchain_core/pydantic_v1/__init__.py +0 -30
- langchain_core/pydantic_v1/dataclasses.py +0 -23
- langchain_core/pydantic_v1/main.py +0 -23
- langchain_core/tracers/langchain_v1.py +0 -31
- langchain_core/utils/loading.py +0 -35
- langchain_core-1.0.0a6.dist-info/METADATA +0 -67
- langchain_core-1.0.0a6.dist-info/RECORD +0 -181
- 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
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
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,
|
|
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
|
|
14
|
-
block as a
|
|
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
|
|
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
|
-
) ->
|
|
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,
|
|
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
|
|
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
|
|
159
|
-
block as a
|
|
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
|
|
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
|
|
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
|
-
) ->
|
|
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:
|
|
681
|
-
|
|
682
|
-
|
|
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:
|
|
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"]
|
langchain_core/messages/chat.py
CHANGED
|
@@ -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).
|
|
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]
|