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.
- 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 +55 -48
- 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 +454 -514
- 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 +102 -94
- 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 +2 -2
- 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 +82 -172
- langchain_core/language_models/chat_models.py +329 -402
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +42 -36
- langchain_core/language_models/llms.py +189 -269
- 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 +339 -330
- 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 +484 -510
- 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 +30 -23
- 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 +16 -16
- langchain_core/outputs/llm_result.py +10 -10
- langchain_core/prompt_values.py +13 -19
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +81 -86
- langchain_core/prompts/chat.py +308 -351
- langchain_core/prompts/dict.py +6 -6
- 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 +7 -7
- 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 +1551 -1656
- langchain_core/runnables/branch.py +68 -70
- langchain_core/runnables/config.py +72 -89
- langchain_core/runnables/configurable.py +145 -161
- langchain_core/runnables/fallbacks.py +102 -96
- langchain_core/runnables/graph.py +91 -97
- langchain_core/runnables/graph_ascii.py +27 -28
- langchain_core/runnables/graph_mermaid.py +42 -51
- langchain_core/runnables/graph_png.py +43 -16
- langchain_core/runnables/history.py +175 -177
- langchain_core/runnables/passthrough.py +151 -167
- langchain_core/runnables/retry.py +46 -51
- langchain_core/runnables/router.py +30 -35
- 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 +29 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +306 -245
- 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 +94 -188
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +9 -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 +35 -37
- 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.4.dist-info/METADATA +69 -0
- langchain_core-1.0.4.dist-info/RECORD +172 -0
- {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.4.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
|
@@ -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
|
|
@@ -34,48 +31,47 @@ if TYPE_CHECKING:
|
|
|
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
38
|
class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
42
|
-
"""Runnable that manages chat message history for another Runnable
|
|
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.
|
|
45
42
|
|
|
46
|
-
RunnableWithMessageHistory wraps another Runnable and manages the chat message
|
|
43
|
+
`RunnableWithMessageHistory` wraps another `Runnable` and manages the chat message
|
|
47
44
|
history for it; it is responsible for reading and updating the chat message
|
|
48
45
|
history.
|
|
49
46
|
|
|
50
|
-
The formats supported for the inputs and outputs of the wrapped Runnable
|
|
47
|
+
The formats supported for the inputs and outputs of the wrapped `Runnable`
|
|
51
48
|
are described below.
|
|
52
49
|
|
|
53
|
-
RunnableWithMessageHistory must always be called with a config that contains
|
|
50
|
+
`RunnableWithMessageHistory` must always be called with a config that contains
|
|
54
51
|
the appropriate parameters for the chat message history factory.
|
|
55
52
|
|
|
56
|
-
By default, the Runnable is expected to take a single configuration parameter
|
|
53
|
+
By default, the `Runnable` is expected to take a single configuration parameter
|
|
57
54
|
called `session_id` which is a string. This parameter is used to create a new
|
|
58
|
-
or look up an existing chat message history that matches the given session_id
|
|
55
|
+
or look up an existing chat message history that matches the given `session_id`.
|
|
59
56
|
|
|
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
|
|
70
|
+
of chat message history, such as `RedisChatMessageHistory`.
|
|
74
71
|
|
|
75
72
|
Example: Chat message history with an in-memory implementation for testing.
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
```python
|
|
79
75
|
from operator import itemgetter
|
|
80
76
|
|
|
81
77
|
from langchain_openai.chat_models import ChatOpenAI
|
|
@@ -119,205 +115,209 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
119
115
|
history.add_message(AIMessage(content="hello"))
|
|
120
116
|
print(store) # noqa: T201
|
|
121
117
|
|
|
118
|
+
```
|
|
122
119
|
|
|
123
|
-
Example where the wrapped Runnable takes a dictionary input:
|
|
124
|
-
|
|
125
|
-
.. code-block:: python
|
|
120
|
+
Example where the wrapped `Runnable` takes a dictionary input:
|
|
126
121
|
|
|
127
|
-
|
|
122
|
+
```python
|
|
123
|
+
from typing import Optional
|
|
128
124
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
from langchain_anthropic import ChatAnthropic
|
|
126
|
+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
127
|
+
from langchain_core.runnables.history import RunnableWithMessageHistory
|
|
132
128
|
|
|
133
129
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
prompt = ChatPromptTemplate.from_messages(
|
|
131
|
+
[
|
|
132
|
+
("system", "You're an assistant who's good at {ability}"),
|
|
133
|
+
MessagesPlaceholder(variable_name="history"),
|
|
134
|
+
("human", "{question}"),
|
|
135
|
+
]
|
|
136
|
+
)
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
chain = prompt | ChatAnthropic(model="claude-2")
|
|
143
139
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
+
)
|
|
152
148
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
149
|
+
print(
|
|
150
|
+
chain_with_history.invoke( # noqa: T201
|
|
151
|
+
{"ability": "math", "question": "What does cosine mean?"},
|
|
152
|
+
config={"configurable": {"session_id": "foo"}},
|
|
158
153
|
)
|
|
154
|
+
)
|
|
159
155
|
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
# Uses the store defined in the example above.
|
|
157
|
+
print(store) # noqa: T201
|
|
162
158
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
159
|
+
print(
|
|
160
|
+
chain_with_history.invoke( # noqa: T201
|
|
161
|
+
{"ability": "math", "question": "What's its inverse"},
|
|
162
|
+
config={"configurable": {"session_id": "foo"}},
|
|
168
163
|
)
|
|
164
|
+
)
|
|
169
165
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Example where the session factory takes two keys, user_id and conversation id):
|
|
166
|
+
print(store) # noqa: T201
|
|
167
|
+
```
|
|
174
168
|
|
|
175
|
-
|
|
169
|
+
Example where the session factory takes two keys (`user_id` and `conversation_id`):
|
|
176
170
|
|
|
177
|
-
|
|
171
|
+
```python
|
|
172
|
+
store = {}
|
|
178
173
|
|
|
179
174
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
182
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
183
|
+
prompt = ChatPromptTemplate.from_messages(
|
|
184
|
+
[
|
|
185
|
+
("system", "You're an assistant who's good at {ability}"),
|
|
186
|
+
MessagesPlaceholder(variable_name="history"),
|
|
187
|
+
("human", "{question}"),
|
|
188
|
+
]
|
|
189
|
+
)
|
|
195
190
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
with_message_history = RunnableWithMessageHistory(
|
|
199
|
-
chain,
|
|
200
|
-
get_session_history=get_session_history,
|
|
201
|
-
input_messages_key="question",
|
|
202
|
-
history_messages_key="history",
|
|
203
|
-
history_factory_config=[
|
|
204
|
-
ConfigurableFieldSpec(
|
|
205
|
-
id="user_id",
|
|
206
|
-
annotation=str,
|
|
207
|
-
name="User ID",
|
|
208
|
-
description="Unique identifier for the user.",
|
|
209
|
-
default="",
|
|
210
|
-
is_shared=True,
|
|
211
|
-
),
|
|
212
|
-
ConfigurableFieldSpec(
|
|
213
|
-
id="conversation_id",
|
|
214
|
-
annotation=str,
|
|
215
|
-
name="Conversation ID",
|
|
216
|
-
description="Unique identifier for the conversation.",
|
|
217
|
-
default="",
|
|
218
|
-
is_shared=True,
|
|
219
|
-
),
|
|
220
|
-
],
|
|
221
|
-
)
|
|
191
|
+
chain = prompt | ChatAnthropic(model="claude-2")
|
|
222
192
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
+
)
|
|
227
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
|
+
```
|
|
228
223
|
"""
|
|
229
224
|
|
|
230
225
|
get_session_history: GetSessionHistoryCallable
|
|
231
|
-
"""Function that returns a new BaseChatMessageHistory
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
"""
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
"""Must be specified if the base
|
|
242
|
-
|
|
226
|
+
"""Function that returns a new `BaseChatMessageHistory`.
|
|
227
|
+
|
|
228
|
+
This function should either take a single positional argument `session_id` of type
|
|
229
|
+
string and return a corresponding chat message history instance
|
|
230
|
+
"""
|
|
231
|
+
input_messages_key: str | None = None
|
|
232
|
+
"""Must be specified if the base `Runnable` accepts a `dict` as input.
|
|
233
|
+
The key in the input `dict` that contains the messages.
|
|
234
|
+
"""
|
|
235
|
+
output_messages_key: str | None = None
|
|
236
|
+
"""Must be specified if the base `Runnable` returns a `dict` as output.
|
|
237
|
+
The key in the output `dict` that contains the messages.
|
|
238
|
+
"""
|
|
239
|
+
history_messages_key: str | None = None
|
|
240
|
+
"""Must be specified if the base `Runnable` accepts a `dict` as input and expects a
|
|
241
|
+
separate key for historical messages.
|
|
242
|
+
"""
|
|
243
243
|
history_factory_config: Sequence[ConfigurableFieldSpec]
|
|
244
244
|
"""Configure fields that should be passed to the chat history factory.
|
|
245
|
-
|
|
245
|
+
|
|
246
|
+
See `ConfigurableFieldSpec` for more details.
|
|
247
|
+
"""
|
|
246
248
|
|
|
247
249
|
def __init__(
|
|
248
250
|
self,
|
|
249
|
-
runnable:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
Runnable[
|
|
255
|
-
dict[str, Any],
|
|
256
|
-
Union[str, BaseMessage, MessagesOrDictWithMessages],
|
|
257
|
-
],
|
|
258
|
-
LanguageModelLike,
|
|
259
|
-
],
|
|
251
|
+
runnable: Runnable[
|
|
252
|
+
list[BaseMessage], str | BaseMessage | MessagesOrDictWithMessages
|
|
253
|
+
]
|
|
254
|
+
| Runnable[dict[str, Any], str | BaseMessage | MessagesOrDictWithMessages]
|
|
255
|
+
| LanguageModelLike,
|
|
260
256
|
get_session_history: GetSessionHistoryCallable,
|
|
261
257
|
*,
|
|
262
|
-
input_messages_key:
|
|
263
|
-
output_messages_key:
|
|
264
|
-
history_messages_key:
|
|
265
|
-
history_factory_config:
|
|
258
|
+
input_messages_key: str | None = None,
|
|
259
|
+
output_messages_key: str | None = None,
|
|
260
|
+
history_messages_key: str | None = None,
|
|
261
|
+
history_factory_config: Sequence[ConfigurableFieldSpec] | None = None,
|
|
266
262
|
**kwargs: Any,
|
|
267
263
|
) -> None:
|
|
268
|
-
"""Initialize RunnableWithMessageHistory
|
|
264
|
+
"""Initialize `RunnableWithMessageHistory`.
|
|
269
265
|
|
|
270
266
|
Args:
|
|
271
|
-
runnable: The base Runnable to be wrapped.
|
|
267
|
+
runnable: The base `Runnable` to be wrapped.
|
|
268
|
+
|
|
272
269
|
Must take as input one of:
|
|
273
270
|
|
|
274
|
-
1. A list of
|
|
275
|
-
2. A dict with one key for all messages
|
|
276
|
-
3. A dict with one key for the current input string/message(s) and
|
|
277
|
-
|
|
278
|
-
|
|
271
|
+
1. A list of `BaseMessage`
|
|
272
|
+
2. A `dict` with one key for all messages
|
|
273
|
+
3. A `dict` with one key for the current input string/message(s) and
|
|
274
|
+
a separate key for historical messages. If the input key points
|
|
275
|
+
to a string, it will be treated as a `HumanMessage` in history.
|
|
279
276
|
|
|
280
277
|
Must return as output one of:
|
|
281
278
|
|
|
282
|
-
1. A string which can be treated as an
|
|
283
|
-
2. A
|
|
284
|
-
3. A dict with a key for a
|
|
285
|
-
|
|
279
|
+
1. A string which can be treated as an `AIMessage`
|
|
280
|
+
2. A `BaseMessage` or sequence of `BaseMessage`
|
|
281
|
+
3. A `dict` with a key for a `BaseMessage` or sequence of
|
|
282
|
+
`BaseMessage`
|
|
283
|
+
|
|
284
|
+
get_session_history: Function that returns a new `BaseChatMessageHistory`.
|
|
286
285
|
|
|
287
|
-
get_session_history: Function that returns a new BaseChatMessageHistory.
|
|
288
286
|
This function should either take a single positional argument
|
|
289
287
|
`session_id` of type string and return a corresponding
|
|
290
288
|
chat message history instance.
|
|
291
|
-
.. code-block:: python
|
|
292
289
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
290
|
+
```python
|
|
291
|
+
def get_session_history(
|
|
292
|
+
session_id: str, *, user_id: str | None = None
|
|
293
|
+
) -> BaseChatMessageHistory: ...
|
|
294
|
+
```
|
|
296
295
|
|
|
297
296
|
Or it should take keyword arguments that match the keys of
|
|
298
297
|
`session_history_config_specs` and return a corresponding
|
|
299
298
|
chat message history instance.
|
|
300
299
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
input_messages_key: Must be specified if the base runnable accepts a dict
|
|
310
|
-
as input.
|
|
311
|
-
output_messages_key: Must be specified if the base runnable returns a dict
|
|
312
|
-
as output.
|
|
313
|
-
history_messages_key: Must be specified if the base runnable accepts a
|
|
314
|
-
as input and expects a separate key for historical messages.
|
|
300
|
+
```python
|
|
301
|
+
def get_session_history(
|
|
302
|
+
*,
|
|
303
|
+
user_id: str,
|
|
304
|
+
thread_id: str,
|
|
305
|
+
) -> BaseChatMessageHistory: ...
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
input_messages_key: Must be specified if the base runnable accepts a `dict`
|
|
309
|
+
as input.
|
|
310
|
+
output_messages_key: Must be specified if the base runnable returns a `dict`
|
|
311
|
+
as output.
|
|
312
|
+
history_messages_key: Must be specified if the base runnable accepts a
|
|
313
|
+
`dict` as input and expects a separate key for historical messages.
|
|
315
314
|
history_factory_config: Configure fields that should be passed to the
|
|
316
|
-
chat history factory. See
|
|
317
|
-
|
|
318
|
-
into the
|
|
315
|
+
chat history factory. See `ConfigurableFieldSpec` for more details.
|
|
316
|
+
|
|
317
|
+
Specifying these allows you to pass multiple config keys into the
|
|
318
|
+
`get_session_history` factory.
|
|
319
319
|
**kwargs: Arbitrary additional kwargs to pass to parent class
|
|
320
|
-
|
|
320
|
+
`RunnableBindingBase` init.
|
|
321
321
|
|
|
322
322
|
"""
|
|
323
323
|
history_chain: Runnable = RunnableLambda(
|
|
@@ -375,19 +375,17 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
375
375
|
@property
|
|
376
376
|
@override
|
|
377
377
|
def config_specs(self) -> list[ConfigurableFieldSpec]:
|
|
378
|
-
"""Get the configuration specs for the RunnableWithMessageHistory
|
|
378
|
+
"""Get the configuration specs for the `RunnableWithMessageHistory`."""
|
|
379
379
|
return get_unique_config_specs(
|
|
380
380
|
super().config_specs + list(self.history_factory_config)
|
|
381
381
|
)
|
|
382
382
|
|
|
383
383
|
@override
|
|
384
|
-
def get_input_schema(
|
|
385
|
-
self, config: Optional[RunnableConfig] = None
|
|
386
|
-
) -> type[BaseModel]:
|
|
384
|
+
def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
|
|
387
385
|
fields: dict = {}
|
|
388
386
|
if self.input_messages_key and self.history_messages_key:
|
|
389
387
|
fields[self.input_messages_key] = (
|
|
390
|
-
|
|
388
|
+
str | BaseMessage | Sequence[BaseMessage],
|
|
391
389
|
...,
|
|
392
390
|
)
|
|
393
391
|
elif self.input_messages_key:
|
|
@@ -411,13 +409,13 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
411
409
|
|
|
412
410
|
@override
|
|
413
411
|
def get_output_schema(
|
|
414
|
-
self, config:
|
|
412
|
+
self, config: RunnableConfig | None = None
|
|
415
413
|
) -> type[BaseModel]:
|
|
416
|
-
"""Get a
|
|
414
|
+
"""Get a Pydantic model that can be used to validate output to the `Runnable`.
|
|
417
415
|
|
|
418
|
-
|
|
419
|
-
methods will have a dynamic output schema that
|
|
420
|
-
configuration the Runnable is invoked with.
|
|
416
|
+
`Runnable` objects that leverage the `configurable_fields` and
|
|
417
|
+
`configurable_alternatives` methods will have a dynamic output schema that
|
|
418
|
+
depends on which configuration the `Runnable` is invoked with.
|
|
421
419
|
|
|
422
420
|
This method allows to get an output schema for a specific configuration.
|
|
423
421
|
|
|
@@ -425,7 +423,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
425
423
|
config: A config to use when generating the schema.
|
|
426
424
|
|
|
427
425
|
Returns:
|
|
428
|
-
A
|
|
426
|
+
A Pydantic model that can be used to validate output.
|
|
429
427
|
"""
|
|
430
428
|
root_type = self.OutputType
|
|
431
429
|
|
|
@@ -443,7 +441,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
443
441
|
)
|
|
444
442
|
|
|
445
443
|
def _get_input_messages(
|
|
446
|
-
self, input_val:
|
|
444
|
+
self, input_val: str | BaseMessage | Sequence[BaseMessage] | dict
|
|
447
445
|
) -> list[BaseMessage]:
|
|
448
446
|
# If dictionary, try to pluck the single key representing messages
|
|
449
447
|
if isinstance(input_val, dict):
|
|
@@ -481,7 +479,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
481
479
|
raise ValueError(msg)
|
|
482
480
|
|
|
483
481
|
def _get_output_messages(
|
|
484
|
-
self, output_val:
|
|
482
|
+
self, output_val: str | BaseMessage | Sequence[BaseMessage] | dict
|
|
485
483
|
) -> list[BaseMessage]:
|
|
486
484
|
# If dictionary, try to pluck the single key representing messages
|
|
487
485
|
if isinstance(output_val, dict):
|
|
@@ -571,7 +569,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
571
569
|
output_messages = self._get_output_messages(output_val)
|
|
572
570
|
await hist.aadd_messages(input_messages + output_messages)
|
|
573
571
|
|
|
574
|
-
def _merge_configs(self, *configs:
|
|
572
|
+
def _merge_configs(self, *configs: RunnableConfig | None) -> RunnableConfig:
|
|
575
573
|
config = super()._merge_configs(*configs)
|
|
576
574
|
expected_keys = [field_spec.id for field_spec in self.history_factory_config]
|
|
577
575
|
|
|
@@ -619,6 +617,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef]
|
|
|
619
617
|
|
|
620
618
|
|
|
621
619
|
def _get_parameter_names(callable_: GetSessionHistoryCallable) -> list[str]:
|
|
622
|
-
"""Get the parameter names of the
|
|
620
|
+
"""Get the parameter names of the `Callable`."""
|
|
623
621
|
sig = inspect.signature(callable_)
|
|
624
622
|
return list(sig.parameters.keys())
|