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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
from typing_extensions import override
|
|
8
8
|
|
|
@@ -16,11 +16,11 @@ if TYPE_CHECKING:
|
|
|
16
16
|
class StdOutCallbackHandler(BaseCallbackHandler):
|
|
17
17
|
"""Callback Handler that prints to std out."""
|
|
18
18
|
|
|
19
|
-
def __init__(self, color:
|
|
19
|
+
def __init__(self, color: str | None = None) -> None:
|
|
20
20
|
"""Initialize callback handler.
|
|
21
21
|
|
|
22
22
|
Args:
|
|
23
|
-
color: The color to use for the text.
|
|
23
|
+
color: The color to use for the text.
|
|
24
24
|
"""
|
|
25
25
|
self.color = color
|
|
26
26
|
|
|
@@ -31,9 +31,9 @@ class StdOutCallbackHandler(BaseCallbackHandler):
|
|
|
31
31
|
"""Print out that we are entering a chain.
|
|
32
32
|
|
|
33
33
|
Args:
|
|
34
|
-
serialized
|
|
35
|
-
inputs
|
|
36
|
-
**kwargs
|
|
34
|
+
serialized: The serialized chain.
|
|
35
|
+
inputs: The inputs to the chain.
|
|
36
|
+
**kwargs: Additional keyword arguments.
|
|
37
37
|
"""
|
|
38
38
|
if "name" in kwargs:
|
|
39
39
|
name = kwargs["name"]
|
|
@@ -48,21 +48,21 @@ class StdOutCallbackHandler(BaseCallbackHandler):
|
|
|
48
48
|
"""Print out that we finished a chain.
|
|
49
49
|
|
|
50
50
|
Args:
|
|
51
|
-
outputs
|
|
52
|
-
**kwargs
|
|
51
|
+
outputs: The outputs of the chain.
|
|
52
|
+
**kwargs: Additional keyword arguments.
|
|
53
53
|
"""
|
|
54
54
|
print("\n\033[1m> Finished chain.\033[0m") # noqa: T201
|
|
55
55
|
|
|
56
56
|
@override
|
|
57
57
|
def on_agent_action(
|
|
58
|
-
self, action: AgentAction, color:
|
|
58
|
+
self, action: AgentAction, color: str | None = None, **kwargs: Any
|
|
59
59
|
) -> Any:
|
|
60
60
|
"""Run on agent action.
|
|
61
61
|
|
|
62
62
|
Args:
|
|
63
|
-
action
|
|
64
|
-
color
|
|
65
|
-
**kwargs
|
|
63
|
+
action: The agent action.
|
|
64
|
+
color: The color to use for the text.
|
|
65
|
+
**kwargs: Additional keyword arguments.
|
|
66
66
|
"""
|
|
67
67
|
print_text(action.log, color=color or self.color)
|
|
68
68
|
|
|
@@ -70,20 +70,19 @@ class StdOutCallbackHandler(BaseCallbackHandler):
|
|
|
70
70
|
def on_tool_end(
|
|
71
71
|
self,
|
|
72
72
|
output: Any,
|
|
73
|
-
color:
|
|
74
|
-
observation_prefix:
|
|
75
|
-
llm_prefix:
|
|
73
|
+
color: str | None = None,
|
|
74
|
+
observation_prefix: str | None = None,
|
|
75
|
+
llm_prefix: str | None = None,
|
|
76
76
|
**kwargs: Any,
|
|
77
77
|
) -> None:
|
|
78
78
|
"""If not the final action, print out observation.
|
|
79
79
|
|
|
80
80
|
Args:
|
|
81
|
-
output
|
|
82
|
-
color
|
|
83
|
-
observation_prefix
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
**kwargs (Any): Additional keyword arguments.
|
|
81
|
+
output: The output to print.
|
|
82
|
+
color: The color to use for the text.
|
|
83
|
+
observation_prefix: The observation prefix.
|
|
84
|
+
llm_prefix: The LLM prefix.
|
|
85
|
+
**kwargs: Additional keyword arguments.
|
|
87
86
|
"""
|
|
88
87
|
output = str(output)
|
|
89
88
|
if observation_prefix is not None:
|
|
@@ -96,29 +95,29 @@ class StdOutCallbackHandler(BaseCallbackHandler):
|
|
|
96
95
|
def on_text(
|
|
97
96
|
self,
|
|
98
97
|
text: str,
|
|
99
|
-
color:
|
|
98
|
+
color: str | None = None,
|
|
100
99
|
end: str = "",
|
|
101
100
|
**kwargs: Any,
|
|
102
101
|
) -> None:
|
|
103
102
|
"""Run when the agent ends.
|
|
104
103
|
|
|
105
104
|
Args:
|
|
106
|
-
text
|
|
107
|
-
color
|
|
108
|
-
end
|
|
109
|
-
**kwargs
|
|
105
|
+
text: The text to print.
|
|
106
|
+
color: The color to use for the text.
|
|
107
|
+
end: The end character to use.
|
|
108
|
+
**kwargs: Additional keyword arguments.
|
|
110
109
|
"""
|
|
111
110
|
print_text(text, color=color or self.color, end=end)
|
|
112
111
|
|
|
113
112
|
@override
|
|
114
113
|
def on_agent_finish(
|
|
115
|
-
self, finish: AgentFinish, color:
|
|
114
|
+
self, finish: AgentFinish, color: str | None = None, **kwargs: Any
|
|
116
115
|
) -> None:
|
|
117
116
|
"""Run on the agent end.
|
|
118
117
|
|
|
119
118
|
Args:
|
|
120
|
-
finish
|
|
121
|
-
color
|
|
122
|
-
**kwargs
|
|
119
|
+
finish: The agent finish.
|
|
120
|
+
color: The color to use for the text.
|
|
121
|
+
**kwargs: Additional keyword arguments.
|
|
123
122
|
"""
|
|
124
123
|
print_text(finish.log, color=color or self.color, end="\n")
|
|
@@ -24,9 +24,9 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
24
24
|
"""Run when LLM starts running.
|
|
25
25
|
|
|
26
26
|
Args:
|
|
27
|
-
serialized
|
|
28
|
-
prompts
|
|
29
|
-
**kwargs
|
|
27
|
+
serialized: The serialized LLM.
|
|
28
|
+
prompts: The prompts to run.
|
|
29
|
+
**kwargs: Additional keyword arguments.
|
|
30
30
|
"""
|
|
31
31
|
|
|
32
32
|
def on_chat_model_start(
|
|
@@ -38,9 +38,9 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
38
38
|
"""Run when LLM starts running.
|
|
39
39
|
|
|
40
40
|
Args:
|
|
41
|
-
serialized
|
|
42
|
-
messages
|
|
43
|
-
**kwargs
|
|
41
|
+
serialized: The serialized LLM.
|
|
42
|
+
messages: The messages to run.
|
|
43
|
+
**kwargs: Additional keyword arguments.
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
@override
|
|
@@ -48,8 +48,8 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
48
48
|
"""Run on new LLM token. Only available when streaming is enabled.
|
|
49
49
|
|
|
50
50
|
Args:
|
|
51
|
-
token
|
|
52
|
-
**kwargs
|
|
51
|
+
token: The new token.
|
|
52
|
+
**kwargs: Additional keyword arguments.
|
|
53
53
|
"""
|
|
54
54
|
sys.stdout.write(token)
|
|
55
55
|
sys.stdout.flush()
|
|
@@ -58,16 +58,16 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
58
58
|
"""Run when LLM ends running.
|
|
59
59
|
|
|
60
60
|
Args:
|
|
61
|
-
response
|
|
62
|
-
**kwargs
|
|
61
|
+
response: The response from the LLM.
|
|
62
|
+
**kwargs: Additional keyword arguments.
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
def on_llm_error(self, error: BaseException, **kwargs: Any) -> None:
|
|
66
66
|
"""Run when LLM errors.
|
|
67
67
|
|
|
68
68
|
Args:
|
|
69
|
-
error
|
|
70
|
-
**kwargs
|
|
69
|
+
error: The error that occurred.
|
|
70
|
+
**kwargs: Additional keyword arguments.
|
|
71
71
|
"""
|
|
72
72
|
|
|
73
73
|
def on_chain_start(
|
|
@@ -76,25 +76,25 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
76
76
|
"""Run when a chain starts running.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
79
|
-
serialized
|
|
80
|
-
inputs
|
|
81
|
-
**kwargs
|
|
79
|
+
serialized: The serialized chain.
|
|
80
|
+
inputs: The inputs to the chain.
|
|
81
|
+
**kwargs: Additional keyword arguments.
|
|
82
82
|
"""
|
|
83
83
|
|
|
84
84
|
def on_chain_end(self, outputs: dict[str, Any], **kwargs: Any) -> None:
|
|
85
85
|
"""Run when a chain ends running.
|
|
86
86
|
|
|
87
87
|
Args:
|
|
88
|
-
outputs
|
|
89
|
-
**kwargs
|
|
88
|
+
outputs: The outputs of the chain.
|
|
89
|
+
**kwargs: Additional keyword arguments.
|
|
90
90
|
"""
|
|
91
91
|
|
|
92
92
|
def on_chain_error(self, error: BaseException, **kwargs: Any) -> None:
|
|
93
93
|
"""Run when chain errors.
|
|
94
94
|
|
|
95
95
|
Args:
|
|
96
|
-
error
|
|
97
|
-
**kwargs
|
|
96
|
+
error: The error that occurred.
|
|
97
|
+
**kwargs: Additional keyword arguments.
|
|
98
98
|
"""
|
|
99
99
|
|
|
100
100
|
def on_tool_start(
|
|
@@ -103,47 +103,47 @@ class StreamingStdOutCallbackHandler(BaseCallbackHandler):
|
|
|
103
103
|
"""Run when the tool starts running.
|
|
104
104
|
|
|
105
105
|
Args:
|
|
106
|
-
serialized
|
|
107
|
-
input_str
|
|
108
|
-
**kwargs
|
|
106
|
+
serialized: The serialized tool.
|
|
107
|
+
input_str: The input string.
|
|
108
|
+
**kwargs: Additional keyword arguments.
|
|
109
109
|
"""
|
|
110
110
|
|
|
111
111
|
def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
|
|
112
112
|
"""Run on agent action.
|
|
113
113
|
|
|
114
114
|
Args:
|
|
115
|
-
action
|
|
116
|
-
**kwargs
|
|
115
|
+
action: The agent action.
|
|
116
|
+
**kwargs: Additional keyword arguments.
|
|
117
117
|
"""
|
|
118
118
|
|
|
119
119
|
def on_tool_end(self, output: Any, **kwargs: Any) -> None:
|
|
120
120
|
"""Run when tool ends running.
|
|
121
121
|
|
|
122
122
|
Args:
|
|
123
|
-
output
|
|
124
|
-
**kwargs
|
|
123
|
+
output: The output of the tool.
|
|
124
|
+
**kwargs: Additional keyword arguments.
|
|
125
125
|
"""
|
|
126
126
|
|
|
127
127
|
def on_tool_error(self, error: BaseException, **kwargs: Any) -> None:
|
|
128
128
|
"""Run when tool errors.
|
|
129
129
|
|
|
130
130
|
Args:
|
|
131
|
-
error
|
|
132
|
-
**kwargs
|
|
131
|
+
error: The error that occurred.
|
|
132
|
+
**kwargs: Additional keyword arguments.
|
|
133
133
|
"""
|
|
134
134
|
|
|
135
135
|
def on_text(self, text: str, **kwargs: Any) -> None:
|
|
136
136
|
"""Run on an arbitrary text.
|
|
137
137
|
|
|
138
138
|
Args:
|
|
139
|
-
text
|
|
140
|
-
**kwargs
|
|
139
|
+
text: The text to print.
|
|
140
|
+
**kwargs: Additional keyword arguments.
|
|
141
141
|
"""
|
|
142
142
|
|
|
143
143
|
def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> None:
|
|
144
144
|
"""Run on the agent end.
|
|
145
145
|
|
|
146
146
|
Args:
|
|
147
|
-
finish
|
|
148
|
-
**kwargs
|
|
147
|
+
finish: The agent finish.
|
|
148
|
+
**kwargs: Additional keyword arguments.
|
|
149
149
|
"""
|
|
@@ -4,7 +4,7 @@ import threading
|
|
|
4
4
|
from collections.abc import Generator
|
|
5
5
|
from contextlib import contextmanager
|
|
6
6
|
from contextvars import ContextVar
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
from typing_extensions import override
|
|
10
10
|
|
|
@@ -19,32 +19,31 @@ class UsageMetadataCallbackHandler(BaseCallbackHandler):
|
|
|
19
19
|
"""Callback Handler that tracks AIMessage.usage_metadata.
|
|
20
20
|
|
|
21
21
|
Example:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.. versionadded:: 0.3.49
|
|
22
|
+
```python
|
|
23
|
+
from langchain.chat_models import init_chat_model
|
|
24
|
+
from langchain_core.callbacks import UsageMetadataCallbackHandler
|
|
25
|
+
|
|
26
|
+
llm_1 = init_chat_model(model="openai:gpt-4o-mini")
|
|
27
|
+
llm_2 = init_chat_model(model="anthropic:claude-3-5-haiku-20241022")
|
|
28
|
+
|
|
29
|
+
callback = UsageMetadataCallbackHandler()
|
|
30
|
+
result_1 = llm_1.invoke("Hello", config={"callbacks": [callback]})
|
|
31
|
+
result_2 = llm_2.invoke("Hello", config={"callbacks": [callback]})
|
|
32
|
+
callback.usage_metadata
|
|
33
|
+
```
|
|
34
|
+
```txt
|
|
35
|
+
{'gpt-4o-mini-2024-07-18': {'input_tokens': 8,
|
|
36
|
+
'output_tokens': 10,
|
|
37
|
+
'total_tokens': 18,
|
|
38
|
+
'input_token_details': {'audio': 0, 'cache_read': 0},
|
|
39
|
+
'output_token_details': {'audio': 0, 'reasoning': 0}},
|
|
40
|
+
'claude-3-5-haiku-20241022': {'input_tokens': 8,
|
|
41
|
+
'output_tokens': 21,
|
|
42
|
+
'total_tokens': 29,
|
|
43
|
+
'input_token_details': {'cache_read': 0, 'cache_creation': 0}}}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
!!! version-added "Added in version 0.3.49"
|
|
48
47
|
|
|
49
48
|
"""
|
|
50
49
|
|
|
@@ -96,45 +95,49 @@ def get_usage_metadata_callback(
|
|
|
96
95
|
"""Get usage metadata callback.
|
|
97
96
|
|
|
98
97
|
Get context manager for tracking usage metadata across chat model calls using
|
|
99
|
-
|
|
98
|
+
`AIMessage.usage_metadata`.
|
|
100
99
|
|
|
101
100
|
Args:
|
|
102
|
-
name
|
|
103
|
-
``'usage_metadata_callback'``.
|
|
101
|
+
name: The name of the context variable.
|
|
104
102
|
|
|
105
103
|
Yields:
|
|
106
104
|
The usage metadata callback.
|
|
107
105
|
|
|
108
106
|
Example:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
107
|
+
```python
|
|
108
|
+
from langchain.chat_models import init_chat_model
|
|
109
|
+
from langchain_core.callbacks import get_usage_metadata_callback
|
|
110
|
+
|
|
111
|
+
llm_1 = init_chat_model(model="openai:gpt-4o-mini")
|
|
112
|
+
llm_2 = init_chat_model(model="anthropic:claude-3-5-haiku-20241022")
|
|
113
|
+
|
|
114
|
+
with get_usage_metadata_callback() as cb:
|
|
115
|
+
llm_1.invoke("Hello")
|
|
116
|
+
llm_2.invoke("Hello")
|
|
117
|
+
print(cb.usage_metadata)
|
|
118
|
+
```
|
|
119
|
+
```txt
|
|
120
|
+
{
|
|
121
|
+
"gpt-4o-mini-2024-07-18": {
|
|
122
|
+
"input_tokens": 8,
|
|
123
|
+
"output_tokens": 10,
|
|
124
|
+
"total_tokens": 18,
|
|
125
|
+
"input_token_details": {"audio": 0, "cache_read": 0},
|
|
126
|
+
"output_token_details": {"audio": 0, "reasoning": 0},
|
|
127
|
+
},
|
|
128
|
+
"claude-3-5-haiku-20241022": {
|
|
129
|
+
"input_tokens": 8,
|
|
130
|
+
"output_tokens": 21,
|
|
131
|
+
"total_tokens": 29,
|
|
132
|
+
"input_token_details": {"cache_read": 0, "cache_creation": 0},
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
!!! version-added "Added in version 0.3.49"
|
|
135
138
|
|
|
136
139
|
"""
|
|
137
|
-
usage_metadata_callback_var: ContextVar[
|
|
140
|
+
usage_metadata_callback_var: ContextVar[UsageMetadataCallbackHandler | None] = (
|
|
138
141
|
ContextVar(name, default=None)
|
|
139
142
|
)
|
|
140
143
|
register_configure_hook(usage_metadata_callback_var, inheritable=True)
|
langchain_core/chat_history.py
CHANGED
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
"""**Chat message history** stores a history of the message interactions in a chat.
|
|
2
|
-
|
|
3
|
-
**Class hierarchy:**
|
|
4
|
-
|
|
5
|
-
.. code-block::
|
|
6
|
-
|
|
7
|
-
BaseChatMessageHistory --> <name>ChatMessageHistory # Examples: FileChatMessageHistory, PostgresChatMessageHistory
|
|
8
|
-
|
|
9
|
-
**Main helpers:**
|
|
10
|
-
|
|
11
|
-
.. code-block::
|
|
12
|
-
|
|
13
|
-
AIMessage, HumanMessage, BaseMessage
|
|
14
|
-
|
|
15
|
-
""" # noqa: E501
|
|
1
|
+
"""**Chat message history** stores a history of the message interactions in a chat."""
|
|
16
2
|
|
|
17
3
|
from __future__ import annotations
|
|
18
4
|
|
|
19
5
|
from abc import ABC, abstractmethod
|
|
20
|
-
from typing import TYPE_CHECKING
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
21
7
|
|
|
22
8
|
from pydantic import BaseModel, Field
|
|
23
9
|
|
|
@@ -63,46 +49,45 @@ class BaseChatMessageHistory(ABC):
|
|
|
63
49
|
|
|
64
50
|
Example: Shows a default implementation.
|
|
65
51
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
52
|
+
```python
|
|
53
|
+
import json
|
|
54
|
+
import os
|
|
55
|
+
from langchain_core.messages import messages_from_dict, message_to_dict
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class FileChatMessageHistory(BaseChatMessageHistory):
|
|
59
|
+
storage_path: str
|
|
60
|
+
session_id: str
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def messages(self) -> list[BaseMessage]:
|
|
64
|
+
try:
|
|
65
|
+
with open(
|
|
66
|
+
os.path.join(self.storage_path, self.session_id),
|
|
67
|
+
"r",
|
|
68
|
+
encoding="utf-8",
|
|
69
|
+
) as f:
|
|
70
|
+
messages_data = json.load(f)
|
|
71
|
+
return messages_from_dict(messages_data)
|
|
72
|
+
except FileNotFoundError:
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
def add_messages(self, messages: Sequence[BaseMessage]) -> None:
|
|
76
|
+
all_messages = list(self.messages) # Existing messages
|
|
77
|
+
all_messages.extend(messages) # Add new messages
|
|
78
|
+
|
|
79
|
+
serialized = [message_to_dict(message) for message in all_messages]
|
|
80
|
+
file_path = os.path.join(self.storage_path, self.session_id)
|
|
81
|
+
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
82
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
83
|
+
json.dump(serialized, f)
|
|
84
|
+
|
|
85
|
+
def clear(self) -> None:
|
|
86
|
+
file_path = os.path.join(self.storage_path, self.session_id)
|
|
87
|
+
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
88
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
89
|
+
json.dump([], f)
|
|
90
|
+
```
|
|
106
91
|
"""
|
|
107
92
|
|
|
108
93
|
messages: list[BaseMessage]
|
|
@@ -126,34 +111,34 @@ class BaseChatMessageHistory(ABC):
|
|
|
126
111
|
"""
|
|
127
112
|
return await run_in_executor(None, lambda: self.messages)
|
|
128
113
|
|
|
129
|
-
def add_user_message(self, message:
|
|
114
|
+
def add_user_message(self, message: HumanMessage | str) -> None:
|
|
130
115
|
"""Convenience method for adding a human message string to the store.
|
|
131
116
|
|
|
132
|
-
|
|
133
|
-
This is a convenience method. Code should favor the bulk
|
|
117
|
+
!!! note
|
|
118
|
+
This is a convenience method. Code should favor the bulk `add_messages`
|
|
134
119
|
interface instead to save on round-trips to the persistence layer.
|
|
135
120
|
|
|
136
121
|
This method may be deprecated in a future release.
|
|
137
122
|
|
|
138
123
|
Args:
|
|
139
|
-
message: The
|
|
124
|
+
message: The `HumanMessage` to add to the store.
|
|
140
125
|
"""
|
|
141
126
|
if isinstance(message, HumanMessage):
|
|
142
127
|
self.add_message(message)
|
|
143
128
|
else:
|
|
144
129
|
self.add_message(HumanMessage(content=message))
|
|
145
130
|
|
|
146
|
-
def add_ai_message(self, message:
|
|
147
|
-
"""Convenience method for adding an
|
|
131
|
+
def add_ai_message(self, message: AIMessage | str) -> None:
|
|
132
|
+
"""Convenience method for adding an `AIMessage` string to the store.
|
|
148
133
|
|
|
149
|
-
|
|
150
|
-
This is a convenience method. Code should favor the bulk
|
|
134
|
+
!!! note
|
|
135
|
+
This is a convenience method. Code should favor the bulk `add_messages`
|
|
151
136
|
interface instead to save on round-trips to the persistence layer.
|
|
152
137
|
|
|
153
138
|
This method may be deprecated in a future release.
|
|
154
139
|
|
|
155
140
|
Args:
|
|
156
|
-
message: The
|
|
141
|
+
message: The `AIMessage` to add.
|
|
157
142
|
"""
|
|
158
143
|
if isinstance(message, AIMessage):
|
|
159
144
|
self.add_message(message)
|
|
@@ -168,7 +153,7 @@ class BaseChatMessageHistory(ABC):
|
|
|
168
153
|
|
|
169
154
|
Raises:
|
|
170
155
|
NotImplementedError: If the sub-class has not implemented an efficient
|
|
171
|
-
add_messages method.
|
|
156
|
+
`add_messages` method.
|
|
172
157
|
"""
|
|
173
158
|
if type(self).add_messages != BaseChatMessageHistory.add_messages:
|
|
174
159
|
# This means that the sub-class has implemented an efficient add_messages
|
|
@@ -188,7 +173,7 @@ class BaseChatMessageHistory(ABC):
|
|
|
188
173
|
in an efficient manner to avoid unnecessary round-trips to the underlying store.
|
|
189
174
|
|
|
190
175
|
Args:
|
|
191
|
-
messages: A sequence of BaseMessage objects to store.
|
|
176
|
+
messages: A sequence of `BaseMessage` objects to store.
|
|
192
177
|
"""
|
|
193
178
|
for message in messages:
|
|
194
179
|
self.add_message(message)
|
|
@@ -197,7 +182,7 @@ class BaseChatMessageHistory(ABC):
|
|
|
197
182
|
"""Async add a list of messages.
|
|
198
183
|
|
|
199
184
|
Args:
|
|
200
|
-
messages: A sequence of BaseMessage objects to store.
|
|
185
|
+
messages: A sequence of `BaseMessage` objects to store.
|
|
201
186
|
"""
|
|
202
187
|
await run_in_executor(None, self.add_messages, messages)
|
|
203
188
|
|