langchain-core 0.4.0.dev0__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.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +45 -70
- langchain_core/_api/deprecation.py +80 -80
- langchain_core/_api/path.py +22 -8
- langchain_core/_import_utils.py +10 -4
- langchain_core/agents.py +25 -21
- langchain_core/caches.py +53 -63
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +341 -348
- langchain_core/callbacks/file.py +55 -44
- langchain_core/callbacks/manager.py +546 -683
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +35 -36
- langchain_core/callbacks/usage.py +65 -70
- langchain_core/chat_history.py +48 -55
- langchain_core/document_loaders/base.py +46 -21
- langchain_core/document_loaders/langsmith.py +39 -36
- langchain_core/documents/__init__.py +0 -1
- langchain_core/documents/base.py +96 -74
- langchain_core/documents/compressor.py +12 -9
- langchain_core/documents/transformers.py +29 -28
- langchain_core/embeddings/fake.py +56 -57
- langchain_core/env.py +2 -3
- langchain_core/example_selectors/base.py +12 -0
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +21 -25
- langchain_core/exceptions.py +15 -9
- langchain_core/globals.py +4 -163
- langchain_core/indexing/api.py +132 -125
- langchain_core/indexing/base.py +64 -67
- langchain_core/indexing/in_memory.py +26 -6
- langchain_core/language_models/__init__.py +15 -27
- langchain_core/language_models/_utils.py +267 -117
- langchain_core/language_models/base.py +92 -177
- langchain_core/language_models/chat_models.py +547 -407
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +72 -118
- langchain_core/language_models/llms.py +168 -242
- langchain_core/load/dump.py +8 -11
- langchain_core/load/load.py +32 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +50 -56
- langchain_core/messages/__init__.py +36 -51
- langchain_core/messages/ai.py +377 -150
- langchain_core/messages/base.py +239 -47
- langchain_core/messages/block_translators/__init__.py +111 -0
- langchain_core/messages/block_translators/anthropic.py +470 -0
- langchain_core/messages/block_translators/bedrock.py +94 -0
- langchain_core/messages/block_translators/bedrock_converse.py +297 -0
- langchain_core/messages/block_translators/google_genai.py +530 -0
- langchain_core/messages/block_translators/google_vertexai.py +21 -0
- langchain_core/messages/block_translators/groq.py +143 -0
- langchain_core/messages/block_translators/langchain_v0.py +301 -0
- langchain_core/messages/block_translators/openai.py +1010 -0
- langchain_core/messages/chat.py +2 -3
- langchain_core/messages/content.py +1423 -0
- langchain_core/messages/function.py +7 -7
- langchain_core/messages/human.py +44 -38
- langchain_core/messages/modifier.py +3 -2
- langchain_core/messages/system.py +40 -27
- langchain_core/messages/tool.py +160 -58
- langchain_core/messages/utils.py +527 -638
- langchain_core/output_parsers/__init__.py +1 -14
- langchain_core/output_parsers/base.py +68 -104
- langchain_core/output_parsers/json.py +13 -17
- langchain_core/output_parsers/list.py +11 -33
- langchain_core/output_parsers/openai_functions.py +56 -74
- langchain_core/output_parsers/openai_tools.py +68 -109
- langchain_core/output_parsers/pydantic.py +15 -13
- langchain_core/output_parsers/string.py +6 -2
- langchain_core/output_parsers/transform.py +17 -60
- langchain_core/output_parsers/xml.py +34 -44
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +26 -11
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +17 -6
- langchain_core/outputs/llm_result.py +15 -8
- langchain_core/prompt_values.py +29 -123
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +48 -63
- langchain_core/prompts/chat.py +259 -288
- langchain_core/prompts/dict.py +19 -11
- langchain_core/prompts/few_shot.py +84 -90
- langchain_core/prompts/few_shot_with_templates.py +14 -12
- langchain_core/prompts/image.py +19 -14
- langchain_core/prompts/loading.py +6 -8
- langchain_core/prompts/message.py +7 -8
- langchain_core/prompts/prompt.py +42 -43
- langchain_core/prompts/string.py +37 -16
- langchain_core/prompts/structured.py +43 -46
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +52 -192
- langchain_core/runnables/base.py +1727 -1683
- langchain_core/runnables/branch.py +52 -73
- langchain_core/runnables/config.py +89 -103
- langchain_core/runnables/configurable.py +128 -130
- langchain_core/runnables/fallbacks.py +93 -82
- langchain_core/runnables/graph.py +127 -127
- langchain_core/runnables/graph_ascii.py +63 -41
- langchain_core/runnables/graph_mermaid.py +87 -70
- langchain_core/runnables/graph_png.py +31 -36
- langchain_core/runnables/history.py +145 -161
- langchain_core/runnables/passthrough.py +141 -144
- langchain_core/runnables/retry.py +84 -68
- langchain_core/runnables/router.py +33 -37
- langchain_core/runnables/schema.py +79 -72
- langchain_core/runnables/utils.py +95 -139
- langchain_core/stores.py +85 -131
- langchain_core/structured_query.py +11 -15
- langchain_core/sys_info.py +31 -32
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +221 -247
- langchain_core/tools/convert.py +144 -161
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +12 -19
- langchain_core/tools/simple.py +52 -29
- langchain_core/tools/structured.py +56 -60
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/_streaming.py +6 -7
- langchain_core/tracers/base.py +103 -112
- langchain_core/tracers/context.py +29 -48
- langchain_core/tracers/core.py +142 -105
- langchain_core/tracers/evaluation.py +30 -34
- langchain_core/tracers/event_stream.py +162 -117
- langchain_core/tracers/langchain.py +34 -36
- langchain_core/tracers/log_stream.py +87 -49
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +18 -34
- langchain_core/tracers/run_collector.py +8 -20
- langchain_core/tracers/schemas.py +0 -125
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +47 -9
- langchain_core/utils/aiter.py +70 -66
- langchain_core/utils/env.py +12 -9
- langchain_core/utils/function_calling.py +139 -206
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +6 -2
- langchain_core/utils/iter.py +48 -45
- langchain_core/utils/json.py +14 -4
- langchain_core/utils/json_schema.py +159 -43
- langchain_core/utils/mustache.py +32 -25
- langchain_core/utils/pydantic.py +67 -40
- langchain_core/utils/strings.py +5 -5
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +104 -62
- langchain_core/vectorstores/base.py +131 -179
- langchain_core/vectorstores/in_memory.py +113 -182
- langchain_core/vectorstores/utils.py +23 -17
- langchain_core/version.py +1 -1
- langchain_core-1.0.0.dist-info/METADATA +68 -0
- langchain_core-1.0.0.dist-info/RECORD +172 -0
- {langchain_core-0.4.0.dev0.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
- langchain_core/beta/__init__.py +0 -1
- langchain_core/beta/runnables/__init__.py +0 -1
- langchain_core/beta/runnables/context.py +0 -448
- langchain_core/memory.py +0 -116
- langchain_core/messages/content_blocks.py +0 -1435
- langchain_core/prompts/pipeline.py +0 -133
- 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 -23
- langchain_core/utils/loading.py +0 -31
- 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/METADATA +0 -108
- langchain_core-0.4.0.dev0.dist-info/RECORD +0 -177
- langchain_core-0.4.0.dev0.dist-info/entry_points.txt +0 -4
|
@@ -3,14 +3,11 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import inspect
|
|
6
|
-
from collections.abc import Sequence
|
|
6
|
+
from collections.abc import Callable, Sequence
|
|
7
7
|
from types import GenericAlias
|
|
8
8
|
from typing import (
|
|
9
9
|
TYPE_CHECKING,
|
|
10
10
|
Any,
|
|
11
|
-
Callable,
|
|
12
|
-
Optional,
|
|
13
|
-
Union,
|
|
14
11
|
)
|
|
15
12
|
|
|
16
13
|
from pydantic import BaseModel
|
|
@@ -18,6 +15,7 @@ from typing_extensions import override
|
|
|
18
15
|
|
|
19
16
|
from langchain_core.chat_history import BaseChatMessageHistory
|
|
20
17
|
from langchain_core.load.load import load
|
|
18
|
+
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
|
|
21
19
|
from langchain_core.runnables.base import Runnable, RunnableBindingBase, RunnableLambda
|
|
22
20
|
from langchain_core.runnables.passthrough import RunnablePassthrough
|
|
23
21
|
from langchain_core.runnables.utils import (
|
|
@@ -29,16 +27,15 @@ from langchain_core.utils.pydantic import create_model_v2
|
|
|
29
27
|
|
|
30
28
|
if TYPE_CHECKING:
|
|
31
29
|
from langchain_core.language_models.base import LanguageModelLike
|
|
32
|
-
from langchain_core.messages.base import BaseMessage
|
|
33
30
|
from langchain_core.runnables.config import RunnableConfig
|
|
34
31
|
from langchain_core.tracers.schemas import Run
|
|
35
32
|
|
|
36
33
|
|
|
37
|
-
MessagesOrDictWithMessages =
|
|
34
|
+
MessagesOrDictWithMessages = Sequence["BaseMessage"] | dict[str, Any]
|
|
38
35
|
GetSessionHistoryCallable = Callable[..., BaseChatMessageHistory]
|
|
39
36
|
|
|
40
37
|
|
|
41
|
-
class RunnableWithMessageHistory(RunnableBindingBase):
|
|
38
|
+
class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
42
39
|
"""Runnable that manages chat message history for another Runnable.
|
|
43
40
|
|
|
44
41
|
A chat message history is a sequence of messages that represent a conversation.
|
|
@@ -60,36 +57,21 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
60
57
|
In this case, the invocation would look like this:
|
|
61
58
|
|
|
62
59
|
`with_history.invoke(..., config={"configurable": {"session_id": "bar"}})`
|
|
63
|
-
; e.g.,
|
|
60
|
+
; e.g., `{"configurable": {"session_id": "<SESSION_ID>"}}`.
|
|
64
61
|
|
|
65
62
|
The configuration can be customized by passing in a list of
|
|
66
|
-
|
|
63
|
+
`ConfigurableFieldSpec` objects to the `history_factory_config` parameter (see
|
|
67
64
|
example below).
|
|
68
65
|
|
|
69
66
|
In the examples, we will use a chat message history with an in-memory
|
|
70
67
|
implementation to make it easy to experiment and see the results.
|
|
71
68
|
|
|
72
69
|
For production use cases, you will want to use a persistent implementation
|
|
73
|
-
of chat message history, such as
|
|
74
|
-
|
|
75
|
-
Parameters:
|
|
76
|
-
get_session_history: Function that returns a new BaseChatMessageHistory.
|
|
77
|
-
This function should either take a single positional argument
|
|
78
|
-
`session_id` of type string and return a corresponding
|
|
79
|
-
chat message history instance.
|
|
80
|
-
input_messages_key: Must be specified if the base runnable accepts a dict
|
|
81
|
-
as input. The key in the input dict that contains the messages.
|
|
82
|
-
output_messages_key: Must be specified if the base Runnable returns a dict
|
|
83
|
-
as output. The key in the output dict that contains the messages.
|
|
84
|
-
history_messages_key: Must be specified if the base runnable accepts a dict
|
|
85
|
-
as input and expects a separate key for historical messages.
|
|
86
|
-
history_factory_config: Configure fields that should be passed to the
|
|
87
|
-
chat history factory. See ``ConfigurableFieldSpec`` for more details.
|
|
70
|
+
of chat message history, such as `RedisChatMessageHistory`.
|
|
88
71
|
|
|
89
72
|
Example: Chat message history with an in-memory implementation for testing.
|
|
90
73
|
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
```python
|
|
93
75
|
from operator import itemgetter
|
|
94
76
|
|
|
95
77
|
from langchain_openai.chat_models import ChatOpenAI
|
|
@@ -133,184 +115,198 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
133
115
|
history.add_message(AIMessage(content="hello"))
|
|
134
116
|
print(store) # noqa: T201
|
|
135
117
|
|
|
118
|
+
```
|
|
136
119
|
|
|
137
120
|
Example where the wrapped Runnable takes a dictionary input:
|
|
138
121
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
from typing import Optional
|
|
122
|
+
```python
|
|
123
|
+
from typing import Optional
|
|
142
124
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
125
|
+
from langchain_community.chat_models import ChatAnthropic
|
|
126
|
+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
127
|
+
from langchain_core.runnables.history import RunnableWithMessageHistory
|
|
146
128
|
|
|
147
129
|
|
|
148
|
-
|
|
130
|
+
prompt = ChatPromptTemplate.from_messages(
|
|
131
|
+
[
|
|
149
132
|
("system", "You're an assistant who's good at {ability}"),
|
|
150
133
|
MessagesPlaceholder(variable_name="history"),
|
|
151
134
|
("human", "{question}"),
|
|
152
|
-
]
|
|
135
|
+
]
|
|
136
|
+
)
|
|
153
137
|
|
|
154
|
-
|
|
138
|
+
chain = prompt | ChatAnthropic(model="claude-2")
|
|
155
139
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
140
|
+
chain_with_history = RunnableWithMessageHistory(
|
|
141
|
+
chain,
|
|
142
|
+
# Uses the get_by_session_id function defined in the example
|
|
143
|
+
# above.
|
|
144
|
+
get_by_session_id,
|
|
145
|
+
input_messages_key="question",
|
|
146
|
+
history_messages_key="history",
|
|
147
|
+
)
|
|
164
148
|
|
|
165
|
-
|
|
149
|
+
print(
|
|
150
|
+
chain_with_history.invoke( # noqa: T201
|
|
166
151
|
{"ability": "math", "question": "What does cosine mean?"},
|
|
167
|
-
config={"configurable": {"session_id": "foo"}}
|
|
168
|
-
)
|
|
152
|
+
config={"configurable": {"session_id": "foo"}},
|
|
153
|
+
)
|
|
154
|
+
)
|
|
169
155
|
|
|
170
|
-
|
|
171
|
-
|
|
156
|
+
# Uses the store defined in the example above.
|
|
157
|
+
print(store) # noqa: T201
|
|
172
158
|
|
|
173
|
-
|
|
159
|
+
print(
|
|
160
|
+
chain_with_history.invoke( # noqa: T201
|
|
174
161
|
{"ability": "math", "question": "What's its inverse"},
|
|
175
|
-
config={"configurable": {"session_id": "foo"}}
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
print(store) # noqa: T201
|
|
162
|
+
config={"configurable": {"session_id": "foo"}},
|
|
163
|
+
)
|
|
164
|
+
)
|
|
179
165
|
|
|
166
|
+
print(store) # noqa: T201
|
|
167
|
+
```
|
|
180
168
|
|
|
181
169
|
Example where the session factory takes two keys, user_id and conversation id):
|
|
182
170
|
|
|
183
|
-
|
|
171
|
+
```python
|
|
172
|
+
store = {}
|
|
173
|
+
|
|
184
174
|
|
|
185
|
-
|
|
175
|
+
def get_session_history(
|
|
176
|
+
user_id: str, conversation_id: str
|
|
177
|
+
) -> BaseChatMessageHistory:
|
|
178
|
+
if (user_id, conversation_id) not in store:
|
|
179
|
+
store[(user_id, conversation_id)] = InMemoryHistory()
|
|
180
|
+
return store[(user_id, conversation_id)]
|
|
186
181
|
|
|
187
|
-
def get_session_history(
|
|
188
|
-
user_id: str, conversation_id: str
|
|
189
|
-
) -> BaseChatMessageHistory:
|
|
190
|
-
if (user_id, conversation_id) not in store:
|
|
191
|
-
store[(user_id, conversation_id)] = InMemoryHistory()
|
|
192
|
-
return store[(user_id, conversation_id)]
|
|
193
182
|
|
|
194
|
-
|
|
183
|
+
prompt = ChatPromptTemplate.from_messages(
|
|
184
|
+
[
|
|
195
185
|
("system", "You're an assistant who's good at {ability}"),
|
|
196
186
|
MessagesPlaceholder(variable_name="history"),
|
|
197
187
|
("human", "{question}"),
|
|
198
|
-
]
|
|
199
|
-
|
|
200
|
-
chain = prompt | ChatAnthropic(model="claude-2")
|
|
201
|
-
|
|
202
|
-
with_message_history = RunnableWithMessageHistory(
|
|
203
|
-
chain,
|
|
204
|
-
get_session_history=get_session_history,
|
|
205
|
-
input_messages_key="question",
|
|
206
|
-
history_messages_key="history",
|
|
207
|
-
history_factory_config=[
|
|
208
|
-
ConfigurableFieldSpec(
|
|
209
|
-
id="user_id",
|
|
210
|
-
annotation=str,
|
|
211
|
-
name="User ID",
|
|
212
|
-
description="Unique identifier for the user.",
|
|
213
|
-
default="",
|
|
214
|
-
is_shared=True,
|
|
215
|
-
),
|
|
216
|
-
ConfigurableFieldSpec(
|
|
217
|
-
id="conversation_id",
|
|
218
|
-
annotation=str,
|
|
219
|
-
name="Conversation ID",
|
|
220
|
-
description="Unique identifier for the conversation.",
|
|
221
|
-
default="",
|
|
222
|
-
is_shared=True,
|
|
223
|
-
),
|
|
224
|
-
],
|
|
225
|
-
)
|
|
188
|
+
]
|
|
189
|
+
)
|
|
226
190
|
|
|
227
|
-
|
|
228
|
-
{"ability": "math", "question": "What does cosine mean?"},
|
|
229
|
-
config={"configurable": {"user_id": "123", "conversation_id": "1"}}
|
|
230
|
-
)
|
|
191
|
+
chain = prompt | ChatAnthropic(model="claude-2")
|
|
231
192
|
|
|
193
|
+
with_message_history = RunnableWithMessageHistory(
|
|
194
|
+
chain,
|
|
195
|
+
get_session_history=get_session_history,
|
|
196
|
+
input_messages_key="question",
|
|
197
|
+
history_messages_key="history",
|
|
198
|
+
history_factory_config=[
|
|
199
|
+
ConfigurableFieldSpec(
|
|
200
|
+
id="user_id",
|
|
201
|
+
annotation=str,
|
|
202
|
+
name="User ID",
|
|
203
|
+
description="Unique identifier for the user.",
|
|
204
|
+
default="",
|
|
205
|
+
is_shared=True,
|
|
206
|
+
),
|
|
207
|
+
ConfigurableFieldSpec(
|
|
208
|
+
id="conversation_id",
|
|
209
|
+
annotation=str,
|
|
210
|
+
name="Conversation ID",
|
|
211
|
+
description="Unique identifier for the conversation.",
|
|
212
|
+
default="",
|
|
213
|
+
is_shared=True,
|
|
214
|
+
),
|
|
215
|
+
],
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
with_message_history.invoke(
|
|
219
|
+
{"ability": "math", "question": "What does cosine mean?"},
|
|
220
|
+
config={"configurable": {"user_id": "123", "conversation_id": "1"}},
|
|
221
|
+
)
|
|
222
|
+
```
|
|
232
223
|
"""
|
|
233
224
|
|
|
234
225
|
get_session_history: GetSessionHistoryCallable
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
226
|
+
"""Function that returns a new BaseChatMessageHistory.
|
|
227
|
+
This function should either take a single positional argument `session_id` of type
|
|
228
|
+
string and return a corresponding chat message history instance"""
|
|
229
|
+
input_messages_key: str | None = None
|
|
230
|
+
"""Must be specified if the base runnable accepts a dict as input.
|
|
231
|
+
The key in the input dict that contains the messages."""
|
|
232
|
+
output_messages_key: str | None = None
|
|
233
|
+
"""Must be specified if the base Runnable returns a dict as output.
|
|
234
|
+
The key in the output dict that contains the messages."""
|
|
235
|
+
history_messages_key: str | None = None
|
|
236
|
+
"""Must be specified if the base runnable accepts a dict as input and expects a
|
|
237
|
+
separate key for historical messages."""
|
|
238
238
|
history_factory_config: Sequence[ConfigurableFieldSpec]
|
|
239
|
+
"""Configure fields that should be passed to the chat history factory.
|
|
240
|
+
See `ConfigurableFieldSpec` for more details."""
|
|
239
241
|
|
|
240
242
|
def __init__(
|
|
241
243
|
self,
|
|
242
|
-
runnable:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
Runnable[
|
|
248
|
-
dict[str, Any],
|
|
249
|
-
Union[str, BaseMessage, MessagesOrDictWithMessages],
|
|
250
|
-
],
|
|
251
|
-
LanguageModelLike,
|
|
252
|
-
],
|
|
244
|
+
runnable: Runnable[
|
|
245
|
+
list[BaseMessage], str | BaseMessage | MessagesOrDictWithMessages
|
|
246
|
+
]
|
|
247
|
+
| Runnable[dict[str, Any], str | BaseMessage | MessagesOrDictWithMessages]
|
|
248
|
+
| LanguageModelLike,
|
|
253
249
|
get_session_history: GetSessionHistoryCallable,
|
|
254
250
|
*,
|
|
255
|
-
input_messages_key:
|
|
256
|
-
output_messages_key:
|
|
257
|
-
history_messages_key:
|
|
258
|
-
history_factory_config:
|
|
251
|
+
input_messages_key: str | None = None,
|
|
252
|
+
output_messages_key: str | None = None,
|
|
253
|
+
history_messages_key: str | None = None,
|
|
254
|
+
history_factory_config: Sequence[ConfigurableFieldSpec] | None = None,
|
|
259
255
|
**kwargs: Any,
|
|
260
256
|
) -> None:
|
|
261
257
|
"""Initialize RunnableWithMessageHistory.
|
|
262
258
|
|
|
263
259
|
Args:
|
|
264
|
-
runnable: The base Runnable to be wrapped.
|
|
265
|
-
|
|
260
|
+
runnable: The base Runnable to be wrapped.
|
|
261
|
+
Must take as input one of:
|
|
262
|
+
|
|
263
|
+
1. A list of `BaseMessage`
|
|
266
264
|
2. A dict with one key for all messages
|
|
267
265
|
3. A dict with one key for the current input string/message(s) and
|
|
268
266
|
a separate key for historical messages. If the input key points
|
|
269
|
-
to a string, it will be treated as a HumanMessage in history.
|
|
267
|
+
to a string, it will be treated as a `HumanMessage` in history.
|
|
270
268
|
|
|
271
269
|
Must return as output one of:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
|
|
271
|
+
1. A string which can be treated as an `AIMessage`
|
|
272
|
+
2. A `BaseMessage` or sequence of `BaseMessage`
|
|
273
|
+
3. A dict with a key for a `BaseMessage` or sequence of
|
|
274
|
+
`BaseMessage`
|
|
275
275
|
|
|
276
276
|
get_session_history: Function that returns a new BaseChatMessageHistory.
|
|
277
277
|
This function should either take a single positional argument
|
|
278
278
|
`session_id` of type string and return a corresponding
|
|
279
279
|
chat message history instance.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
user_id: Optional[str]=None
|
|
286
|
-
) -> BaseChatMessageHistory:
|
|
287
|
-
...
|
|
280
|
+
```python
|
|
281
|
+
def get_session_history(
|
|
282
|
+
session_id: str, *, user_id: str | None = None
|
|
283
|
+
) -> BaseChatMessageHistory: ...
|
|
284
|
+
```
|
|
288
285
|
|
|
289
286
|
Or it should take keyword arguments that match the keys of
|
|
290
287
|
`session_history_config_specs` and return a corresponding
|
|
291
288
|
chat message history instance.
|
|
292
289
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
...
|
|
290
|
+
```python
|
|
291
|
+
def get_session_history(
|
|
292
|
+
*,
|
|
293
|
+
user_id: str,
|
|
294
|
+
thread_id: str,
|
|
295
|
+
) -> BaseChatMessageHistory: ...
|
|
296
|
+
```
|
|
301
297
|
|
|
302
298
|
input_messages_key: Must be specified if the base runnable accepts a dict
|
|
303
|
-
as input.
|
|
299
|
+
as input.
|
|
304
300
|
output_messages_key: Must be specified if the base runnable returns a dict
|
|
305
|
-
as output.
|
|
301
|
+
as output.
|
|
306
302
|
history_messages_key: Must be specified if the base runnable accepts a dict
|
|
307
303
|
as input and expects a separate key for historical messages.
|
|
308
304
|
history_factory_config: Configure fields that should be passed to the
|
|
309
|
-
chat history factory. See
|
|
305
|
+
chat history factory. See `ConfigurableFieldSpec` for more details.
|
|
310
306
|
Specifying these allows you to pass multiple config keys
|
|
311
307
|
into the get_session_history factory.
|
|
312
308
|
**kwargs: Arbitrary additional kwargs to pass to parent class
|
|
313
|
-
|
|
309
|
+
`RunnableBindingBase` init.
|
|
314
310
|
|
|
315
311
|
"""
|
|
316
312
|
history_chain: Runnable = RunnableLambda(
|
|
@@ -374,15 +370,11 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
374
370
|
)
|
|
375
371
|
|
|
376
372
|
@override
|
|
377
|
-
def get_input_schema(
|
|
378
|
-
self, config: Optional[RunnableConfig] = None
|
|
379
|
-
) -> type[BaseModel]:
|
|
380
|
-
from langchain_core.messages import BaseMessage
|
|
381
|
-
|
|
373
|
+
def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
|
|
382
374
|
fields: dict = {}
|
|
383
375
|
if self.input_messages_key and self.history_messages_key:
|
|
384
376
|
fields[self.input_messages_key] = (
|
|
385
|
-
|
|
377
|
+
str | BaseMessage | Sequence[BaseMessage],
|
|
386
378
|
...,
|
|
387
379
|
)
|
|
388
380
|
elif self.input_messages_key:
|
|
@@ -406,13 +398,13 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
406
398
|
|
|
407
399
|
@override
|
|
408
400
|
def get_output_schema(
|
|
409
|
-
self, config:
|
|
401
|
+
self, config: RunnableConfig | None = None
|
|
410
402
|
) -> type[BaseModel]:
|
|
411
|
-
"""Get a
|
|
403
|
+
"""Get a Pydantic model that can be used to validate output to the `Runnable`.
|
|
412
404
|
|
|
413
|
-
|
|
414
|
-
methods will have a dynamic output schema that
|
|
415
|
-
configuration the Runnable is invoked with.
|
|
405
|
+
`Runnable` objects that leverage the `configurable_fields` and
|
|
406
|
+
`configurable_alternatives` methods will have a dynamic output schema that
|
|
407
|
+
depends on which configuration the `Runnable` is invoked with.
|
|
416
408
|
|
|
417
409
|
This method allows to get an output schema for a specific configuration.
|
|
418
410
|
|
|
@@ -420,7 +412,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
420
412
|
config: A config to use when generating the schema.
|
|
421
413
|
|
|
422
414
|
Returns:
|
|
423
|
-
A
|
|
415
|
+
A Pydantic model that can be used to validate output.
|
|
424
416
|
"""
|
|
425
417
|
root_type = self.OutputType
|
|
426
418
|
|
|
@@ -438,10 +430,8 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
438
430
|
)
|
|
439
431
|
|
|
440
432
|
def _get_input_messages(
|
|
441
|
-
self, input_val:
|
|
433
|
+
self, input_val: str | BaseMessage | Sequence[BaseMessage] | dict
|
|
442
434
|
) -> list[BaseMessage]:
|
|
443
|
-
from langchain_core.messages import BaseMessage
|
|
444
|
-
|
|
445
435
|
# If dictionary, try to pluck the single key representing messages
|
|
446
436
|
if isinstance(input_val, dict):
|
|
447
437
|
if self.input_messages_key:
|
|
@@ -454,8 +444,6 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
454
444
|
|
|
455
445
|
# If value is a string, convert to a human message
|
|
456
446
|
if isinstance(input_val, str):
|
|
457
|
-
from langchain_core.messages import HumanMessage
|
|
458
|
-
|
|
459
447
|
return [HumanMessage(content=input_val)]
|
|
460
448
|
# If value is a single message, convert to a list
|
|
461
449
|
if isinstance(input_val, BaseMessage):
|
|
@@ -480,10 +468,8 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
480
468
|
raise ValueError(msg)
|
|
481
469
|
|
|
482
470
|
def _get_output_messages(
|
|
483
|
-
self, output_val:
|
|
471
|
+
self, output_val: str | BaseMessage | Sequence[BaseMessage] | dict
|
|
484
472
|
) -> list[BaseMessage]:
|
|
485
|
-
from langchain_core.messages import BaseMessage
|
|
486
|
-
|
|
487
473
|
# If dictionary, try to pluck the single key representing messages
|
|
488
474
|
if isinstance(output_val, dict):
|
|
489
475
|
if self.output_messages_key:
|
|
@@ -500,8 +486,6 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
500
486
|
output_val = output_val[key]
|
|
501
487
|
|
|
502
488
|
if isinstance(output_val, str):
|
|
503
|
-
from langchain_core.messages import AIMessage
|
|
504
|
-
|
|
505
489
|
return [AIMessage(content=output_val)]
|
|
506
490
|
# If value is a single message, convert to a list
|
|
507
491
|
if isinstance(output_val, BaseMessage):
|
|
@@ -574,7 +558,7 @@ class RunnableWithMessageHistory(RunnableBindingBase):
|
|
|
574
558
|
output_messages = self._get_output_messages(output_val)
|
|
575
559
|
await hist.aadd_messages(input_messages + output_messages)
|
|
576
560
|
|
|
577
|
-
def _merge_configs(self, *configs:
|
|
561
|
+
def _merge_configs(self, *configs: RunnableConfig | None) -> RunnableConfig:
|
|
578
562
|
config = super()._merge_configs(*configs)
|
|
579
563
|
expected_keys = [field_spec.id for field_spec in self.history_factory_config]
|
|
580
564
|
|