langchain-core 0.4.0.dev0__py3-none-any.whl → 1.0.0a2__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/_api/beta_decorator.py +2 -2
- langchain_core/_api/deprecation.py +1 -1
- langchain_core/beta/runnables/context.py +1 -1
- langchain_core/callbacks/base.py +14 -23
- langchain_core/callbacks/file.py +13 -2
- langchain_core/callbacks/manager.py +74 -157
- langchain_core/callbacks/streaming_stdout.py +3 -4
- langchain_core/callbacks/usage.py +2 -12
- langchain_core/chat_history.py +6 -6
- langchain_core/documents/base.py +1 -1
- langchain_core/documents/compressor.py +9 -6
- langchain_core/indexing/base.py +2 -2
- langchain_core/language_models/_utils.py +232 -101
- langchain_core/language_models/base.py +35 -23
- langchain_core/language_models/chat_models.py +248 -54
- langchain_core/language_models/fake_chat_models.py +28 -81
- langchain_core/load/dump.py +3 -4
- langchain_core/messages/__init__.py +30 -24
- langchain_core/messages/ai.py +188 -30
- langchain_core/messages/base.py +164 -25
- langchain_core/messages/block_translators/__init__.py +89 -0
- langchain_core/messages/block_translators/anthropic.py +451 -0
- langchain_core/messages/block_translators/bedrock.py +45 -0
- langchain_core/messages/block_translators/bedrock_converse.py +47 -0
- langchain_core/messages/block_translators/google_genai.py +45 -0
- langchain_core/messages/block_translators/google_vertexai.py +47 -0
- langchain_core/messages/block_translators/groq.py +45 -0
- langchain_core/messages/block_translators/langchain_v0.py +164 -0
- langchain_core/messages/block_translators/ollama.py +45 -0
- langchain_core/messages/block_translators/openai.py +798 -0
- langchain_core/messages/{content_blocks.py → content.py} +303 -278
- langchain_core/messages/human.py +29 -9
- langchain_core/messages/system.py +29 -9
- langchain_core/messages/tool.py +94 -13
- langchain_core/messages/utils.py +34 -234
- langchain_core/output_parsers/base.py +14 -50
- langchain_core/output_parsers/json.py +2 -5
- langchain_core/output_parsers/list.py +2 -7
- langchain_core/output_parsers/openai_functions.py +5 -28
- langchain_core/output_parsers/openai_tools.py +49 -90
- langchain_core/output_parsers/pydantic.py +2 -3
- langchain_core/output_parsers/transform.py +12 -53
- langchain_core/output_parsers/xml.py +9 -17
- langchain_core/prompt_values.py +8 -112
- langchain_core/prompts/chat.py +1 -3
- langchain_core/runnables/base.py +500 -451
- langchain_core/runnables/branch.py +1 -1
- langchain_core/runnables/fallbacks.py +4 -4
- langchain_core/runnables/history.py +1 -1
- langchain_core/runnables/passthrough.py +3 -3
- langchain_core/runnables/retry.py +1 -1
- langchain_core/runnables/router.py +1 -1
- langchain_core/structured_query.py +3 -7
- langchain_core/tools/base.py +14 -41
- langchain_core/tools/convert.py +2 -22
- langchain_core/tools/retriever.py +1 -8
- langchain_core/tools/structured.py +2 -10
- langchain_core/tracers/_streaming.py +6 -7
- langchain_core/tracers/base.py +7 -14
- langchain_core/tracers/core.py +4 -27
- langchain_core/tracers/event_stream.py +4 -15
- langchain_core/tracers/langchain.py +3 -14
- langchain_core/tracers/log_stream.py +2 -3
- langchain_core/utils/_merge.py +45 -7
- langchain_core/utils/function_calling.py +22 -9
- langchain_core/utils/utils.py +29 -0
- langchain_core/version.py +1 -1
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0a2.dist-info}/METADATA +7 -9
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0a2.dist-info}/RECORD +71 -64
- langchain_core/v1/__init__.py +0 -1
- langchain_core/v1/chat_models.py +0 -1047
- langchain_core/v1/messages.py +0 -755
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0a2.dist-info}/WHEEL +0 -0
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0a2.dist-info}/entry_points.txt +0 -0
langchain_core/messages/base.py
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Optional, Union, cast
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
|
|
6
6
|
|
|
7
7
|
from pydantic import ConfigDict, Field
|
|
8
|
+
from typing_extensions import Self
|
|
8
9
|
|
|
10
|
+
from langchain_core._api.deprecation import warn_deprecated
|
|
9
11
|
from langchain_core.load.serializable import Serializable
|
|
12
|
+
from langchain_core.messages import content as types
|
|
10
13
|
from langchain_core.utils import get_bolded_text
|
|
11
14
|
from langchain_core.utils._merge import merge_dicts, merge_lists
|
|
12
15
|
from langchain_core.utils.interactive_env import is_interactive_env
|
|
@@ -17,6 +20,52 @@ if TYPE_CHECKING:
|
|
|
17
20
|
from langchain_core.prompts.chat import ChatPromptTemplate
|
|
18
21
|
|
|
19
22
|
|
|
23
|
+
class TextAccessor(str):
|
|
24
|
+
"""String-like object that supports both property and method access patterns.
|
|
25
|
+
|
|
26
|
+
Exists to maintain backward compatibility while transitioning from method-based to
|
|
27
|
+
property-based text access in message objects. In LangChain <v1.0, message text was
|
|
28
|
+
accessed via ``.text()`` method calls. In v1.0=<, the preferred pattern is property
|
|
29
|
+
access via ``.text``.
|
|
30
|
+
|
|
31
|
+
Rather than breaking existing code immediately, ``TextAccessor`` allows both
|
|
32
|
+
patterns:
|
|
33
|
+
- Modern property access: ``message.text`` (returns string directly)
|
|
34
|
+
- Legacy method access: ``message.text()`` (callable, emits deprecation warning)
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
__slots__ = ()
|
|
39
|
+
|
|
40
|
+
def __new__(cls, value: str) -> Self:
|
|
41
|
+
"""Create new TextAccessor instance."""
|
|
42
|
+
return str.__new__(cls, value)
|
|
43
|
+
|
|
44
|
+
def __call__(self) -> str:
|
|
45
|
+
"""Enable method-style text access for backward compatibility.
|
|
46
|
+
|
|
47
|
+
This method exists solely to support legacy code that calls ``.text()``
|
|
48
|
+
as a method. New code should use property access (``.text``) instead.
|
|
49
|
+
|
|
50
|
+
.. deprecated:: 1.0.0
|
|
51
|
+
Calling ``.text()`` as a method is deprecated. Use ``.text`` as a property
|
|
52
|
+
instead. This method will be removed in 2.0.0.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The string content, identical to property access.
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
warn_deprecated(
|
|
59
|
+
since="1.0.0",
|
|
60
|
+
message=(
|
|
61
|
+
"Calling .text() as a method is deprecated. "
|
|
62
|
+
"Use .text as a property instead (e.g., message.text)."
|
|
63
|
+
),
|
|
64
|
+
removal="2.0.0",
|
|
65
|
+
)
|
|
66
|
+
return str(self)
|
|
67
|
+
|
|
68
|
+
|
|
20
69
|
class BaseMessage(Serializable):
|
|
21
70
|
"""Base abstract message class.
|
|
22
71
|
|
|
@@ -61,15 +110,32 @@ class BaseMessage(Serializable):
|
|
|
61
110
|
extra="allow",
|
|
62
111
|
)
|
|
63
112
|
|
|
113
|
+
@overload
|
|
64
114
|
def __init__(
|
|
65
|
-
self,
|
|
66
|
-
|
|
67
|
-
|
|
115
|
+
self,
|
|
116
|
+
content: Union[str, list[Union[str, dict]]],
|
|
117
|
+
**kwargs: Any,
|
|
118
|
+
) -> None: ...
|
|
68
119
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
120
|
+
@overload
|
|
121
|
+
def __init__(
|
|
122
|
+
self,
|
|
123
|
+
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
|
124
|
+
content_blocks: Optional[list[types.ContentBlock]] = None,
|
|
125
|
+
**kwargs: Any,
|
|
126
|
+
) -> None: ...
|
|
127
|
+
|
|
128
|
+
def __init__(
|
|
129
|
+
self,
|
|
130
|
+
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
|
131
|
+
content_blocks: Optional[list[types.ContentBlock]] = None,
|
|
132
|
+
**kwargs: Any,
|
|
133
|
+
) -> None:
|
|
134
|
+
"""Specify ``content`` as positional arg or ``content_blocks`` for typing."""
|
|
135
|
+
if content_blocks is not None:
|
|
136
|
+
super().__init__(content=content_blocks, **kwargs)
|
|
137
|
+
else:
|
|
138
|
+
super().__init__(content=content, **kwargs)
|
|
73
139
|
|
|
74
140
|
@classmethod
|
|
75
141
|
def is_lc_serializable(cls) -> bool:
|
|
@@ -88,25 +154,96 @@ class BaseMessage(Serializable):
|
|
|
88
154
|
"""
|
|
89
155
|
return ["langchain", "schema", "messages"]
|
|
90
156
|
|
|
91
|
-
|
|
92
|
-
|
|
157
|
+
@property
|
|
158
|
+
def content_blocks(self) -> list[types.ContentBlock]:
|
|
159
|
+
r"""Return ``content`` as a list of standardized :class:`~langchain_core.messages.content.ContentBlock`\s.
|
|
160
|
+
|
|
161
|
+
.. important::
|
|
162
|
+
|
|
163
|
+
To use this property correctly, the corresponding ``ChatModel`` must support
|
|
164
|
+
``message_version='v1'`` or higher (and it must be set):
|
|
165
|
+
|
|
166
|
+
.. code-block:: python
|
|
167
|
+
|
|
168
|
+
from langchain.chat_models import init_chat_model
|
|
169
|
+
llm = init_chat_model("...", message_version="v1")
|
|
170
|
+
|
|
171
|
+
# or
|
|
172
|
+
|
|
173
|
+
from langchain-openai import ChatOpenAI
|
|
174
|
+
llm = ChatOpenAI(model="gpt-4o", message_version="v1")
|
|
175
|
+
|
|
176
|
+
Otherwise, the property will perform best-effort parsing to standard types,
|
|
177
|
+
though some content may be misinterpreted.
|
|
178
|
+
|
|
179
|
+
.. versionadded:: 1.0.0
|
|
180
|
+
|
|
181
|
+
""" # noqa: E501
|
|
182
|
+
from langchain_core.messages import content as types
|
|
183
|
+
from langchain_core.messages.block_translators.anthropic import (
|
|
184
|
+
_convert_to_v1_from_anthropic_input,
|
|
185
|
+
)
|
|
186
|
+
from langchain_core.messages.block_translators.langchain_v0 import (
|
|
187
|
+
_convert_v0_multimodal_input_to_v1,
|
|
188
|
+
)
|
|
189
|
+
from langchain_core.messages.block_translators.openai import (
|
|
190
|
+
_convert_to_v1_from_chat_completions_input,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
blocks: list[types.ContentBlock] = []
|
|
194
|
+
|
|
195
|
+
# First pass: convert to standard blocks
|
|
196
|
+
content = (
|
|
197
|
+
[self.content]
|
|
198
|
+
if isinstance(self.content, str) and self.content
|
|
199
|
+
else self.content
|
|
200
|
+
)
|
|
201
|
+
for item in content:
|
|
202
|
+
if isinstance(item, str):
|
|
203
|
+
blocks.append({"type": "text", "text": item})
|
|
204
|
+
elif isinstance(item, dict):
|
|
205
|
+
item_type = item.get("type")
|
|
206
|
+
if item_type not in types.KNOWN_BLOCK_TYPES:
|
|
207
|
+
blocks.append({"type": "non_standard", "value": item})
|
|
208
|
+
else:
|
|
209
|
+
blocks.append(cast("types.ContentBlock", item))
|
|
210
|
+
|
|
211
|
+
# Subsequent passes: attempt to unpack non-standard blocks
|
|
212
|
+
for parsing_step in [
|
|
213
|
+
_convert_v0_multimodal_input_to_v1,
|
|
214
|
+
_convert_to_v1_from_chat_completions_input,
|
|
215
|
+
_convert_to_v1_from_anthropic_input,
|
|
216
|
+
]:
|
|
217
|
+
blocks = parsing_step(blocks)
|
|
218
|
+
return blocks
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def text(self) -> TextAccessor:
|
|
222
|
+
"""Get the text content of the message as a string.
|
|
223
|
+
|
|
224
|
+
Can be used as both property (``message.text``) and method (``message.text()``).
|
|
225
|
+
|
|
226
|
+
.. deprecated:: 1.0.0
|
|
227
|
+
Calling ``.text()`` as a method is deprecated. Use ``.text`` as a property
|
|
228
|
+
instead. This method will be removed in 2.0.0.
|
|
93
229
|
|
|
94
230
|
Returns:
|
|
95
231
|
The text content of the message.
|
|
96
232
|
"""
|
|
97
233
|
if isinstance(self.content, str):
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
234
|
+
text_value = self.content
|
|
235
|
+
else:
|
|
236
|
+
# must be a list
|
|
237
|
+
blocks = [
|
|
238
|
+
block
|
|
239
|
+
for block in self.content
|
|
240
|
+
if isinstance(block, str)
|
|
241
|
+
or (block.get("type") == "text" and isinstance(block.get("text"), str))
|
|
242
|
+
]
|
|
243
|
+
text_value = "".join(
|
|
244
|
+
block if isinstance(block, str) else block["text"] for block in blocks
|
|
245
|
+
)
|
|
246
|
+
return TextAccessor(text_value)
|
|
110
247
|
|
|
111
248
|
def __add__(self, other: Any) -> ChatPromptTemplate:
|
|
112
249
|
"""Concatenate this message with another message."""
|
|
@@ -152,7 +289,9 @@ def merge_content(
|
|
|
152
289
|
Returns:
|
|
153
290
|
The merged content.
|
|
154
291
|
"""
|
|
155
|
-
merged
|
|
292
|
+
merged: Union[str, list[Union[str, dict]]]
|
|
293
|
+
merged = "" if first_content is None else first_content
|
|
294
|
+
|
|
156
295
|
for content in contents:
|
|
157
296
|
# If current is a string
|
|
158
297
|
if isinstance(merged, str):
|
|
@@ -173,8 +312,8 @@ def merge_content(
|
|
|
173
312
|
# If second content is an empty string, treat as a no-op
|
|
174
313
|
elif content == "":
|
|
175
314
|
pass
|
|
176
|
-
|
|
177
|
-
|
|
315
|
+
# Otherwise, add the second content as a new element of the list
|
|
316
|
+
elif merged:
|
|
178
317
|
merged.append(content)
|
|
179
318
|
return merged
|
|
180
319
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Derivations of standard content blocks from provider content."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Callable
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from langchain_core.messages import AIMessage, AIMessageChunk
|
|
9
|
+
from langchain_core.messages import content as types
|
|
10
|
+
|
|
11
|
+
# Provider to translator mapping
|
|
12
|
+
PROVIDER_TRANSLATORS: dict[str, dict[str, Callable[..., list[types.ContentBlock]]]] = {}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def register_translator(
|
|
16
|
+
provider: str,
|
|
17
|
+
translate_content: Callable[[AIMessage], list[types.ContentBlock]],
|
|
18
|
+
translate_content_chunk: Callable[[AIMessageChunk], list[types.ContentBlock]],
|
|
19
|
+
) -> None:
|
|
20
|
+
"""Register content translators for a provider.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
provider: The model provider name (e.g. ``'openai'``, ``'anthropic'``).
|
|
24
|
+
translate_content: Function to translate ``AIMessage`` content.
|
|
25
|
+
translate_content_chunk: Function to translate ``AIMessageChunk`` content.
|
|
26
|
+
"""
|
|
27
|
+
PROVIDER_TRANSLATORS[provider] = {
|
|
28
|
+
"translate_content": translate_content,
|
|
29
|
+
"translate_content_chunk": translate_content_chunk,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_translator(
|
|
34
|
+
provider: str,
|
|
35
|
+
) -> dict[str, Callable[..., list[types.ContentBlock]]] | None:
|
|
36
|
+
"""Get the translator functions for a provider.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
provider: The model provider name.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Dictionary with ``'translate_content'`` and ``'translate_content_chunk'``
|
|
43
|
+
functions, or None if no translator is registered for the provider.
|
|
44
|
+
"""
|
|
45
|
+
return PROVIDER_TRANSLATORS.get(provider)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _register_translators() -> None:
|
|
49
|
+
"""Register all translators in langchain-core.
|
|
50
|
+
|
|
51
|
+
A unit test ensures all modules in ``block_translators`` are represented here.
|
|
52
|
+
|
|
53
|
+
For translators implemented outside langchain-core, they can be registered by
|
|
54
|
+
calling ``register_translator`` from within the integration package.
|
|
55
|
+
"""
|
|
56
|
+
from langchain_core.messages.block_translators.anthropic import (
|
|
57
|
+
_register_anthropic_translator,
|
|
58
|
+
)
|
|
59
|
+
from langchain_core.messages.block_translators.bedrock import (
|
|
60
|
+
_register_bedrock_translator,
|
|
61
|
+
)
|
|
62
|
+
from langchain_core.messages.block_translators.bedrock_converse import (
|
|
63
|
+
_register_bedrock_converse_translator,
|
|
64
|
+
)
|
|
65
|
+
from langchain_core.messages.block_translators.google_genai import (
|
|
66
|
+
_register_google_genai_translator,
|
|
67
|
+
)
|
|
68
|
+
from langchain_core.messages.block_translators.google_vertexai import (
|
|
69
|
+
_register_google_vertexai_translator,
|
|
70
|
+
)
|
|
71
|
+
from langchain_core.messages.block_translators.groq import _register_groq_translator
|
|
72
|
+
from langchain_core.messages.block_translators.ollama import (
|
|
73
|
+
_register_ollama_translator,
|
|
74
|
+
)
|
|
75
|
+
from langchain_core.messages.block_translators.openai import (
|
|
76
|
+
_register_openai_translator,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
_register_bedrock_translator()
|
|
80
|
+
_register_bedrock_converse_translator()
|
|
81
|
+
_register_anthropic_translator()
|
|
82
|
+
_register_google_genai_translator()
|
|
83
|
+
_register_google_vertexai_translator()
|
|
84
|
+
_register_groq_translator()
|
|
85
|
+
_register_ollama_translator()
|
|
86
|
+
_register_openai_translator()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
_register_translators()
|