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
|
@@ -5,10 +5,10 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
from concurrent.futures import ThreadPoolExecutor
|
|
7
7
|
from datetime import datetime, timezone
|
|
8
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
from uuid import UUID
|
|
10
10
|
|
|
11
|
-
from langsmith import Client
|
|
11
|
+
from langsmith import Client, get_tracing_context
|
|
12
12
|
from langsmith import run_trees as rt
|
|
13
13
|
from langsmith import utils as ls_utils
|
|
14
14
|
from tenacity import (
|
|
@@ -21,19 +21,16 @@ from typing_extensions import override
|
|
|
21
21
|
|
|
22
22
|
from langchain_core.env import get_runtime_environment
|
|
23
23
|
from langchain_core.load import dumpd
|
|
24
|
-
from langchain_core.messages.utils import convert_from_v1_message
|
|
25
24
|
from langchain_core.tracers.base import BaseTracer
|
|
26
25
|
from langchain_core.tracers.schemas import Run
|
|
27
|
-
from langchain_core.v1.messages import MessageV1Types
|
|
28
26
|
|
|
29
27
|
if TYPE_CHECKING:
|
|
30
28
|
from langchain_core.messages import BaseMessage
|
|
31
29
|
from langchain_core.outputs import ChatGenerationChunk, GenerationChunk
|
|
32
|
-
from langchain_core.v1.messages import AIMessageChunk, MessageV1
|
|
33
30
|
|
|
34
31
|
logger = logging.getLogger(__name__)
|
|
35
32
|
_LOGGED = set()
|
|
36
|
-
_EXECUTOR:
|
|
33
|
+
_EXECUTOR: ThreadPoolExecutor | None = None
|
|
37
34
|
|
|
38
35
|
|
|
39
36
|
def log_error_once(method: str, exception: Exception) -> None:
|
|
@@ -56,7 +53,11 @@ def wait_for_all_tracers() -> None:
|
|
|
56
53
|
|
|
57
54
|
|
|
58
55
|
def get_client() -> Client:
|
|
59
|
-
"""Get the client.
|
|
56
|
+
"""Get the client.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The LangSmith client.
|
|
60
|
+
"""
|
|
60
61
|
return rt.get_cached_client()
|
|
61
62
|
|
|
62
63
|
|
|
@@ -75,10 +76,10 @@ class LangChainTracer(BaseTracer):
|
|
|
75
76
|
|
|
76
77
|
def __init__(
|
|
77
78
|
self,
|
|
78
|
-
example_id:
|
|
79
|
-
project_name:
|
|
80
|
-
client:
|
|
81
|
-
tags:
|
|
79
|
+
example_id: UUID | str | None = None,
|
|
80
|
+
project_name: str | None = None,
|
|
81
|
+
client: Client | None = None,
|
|
82
|
+
tags: list[str] | None = None,
|
|
82
83
|
**kwargs: Any,
|
|
83
84
|
) -> None:
|
|
84
85
|
"""Initialize the LangChain tracer.
|
|
@@ -88,7 +89,7 @@ class LangChainTracer(BaseTracer):
|
|
|
88
89
|
project_name: The project name. Defaults to the tracer project.
|
|
89
90
|
client: The client. Defaults to the global client.
|
|
90
91
|
tags: The tags. Defaults to an empty list.
|
|
91
|
-
kwargs: Additional keyword arguments.
|
|
92
|
+
**kwargs: Additional keyword arguments.
|
|
92
93
|
"""
|
|
93
94
|
super().__init__(**kwargs)
|
|
94
95
|
self.example_id = (
|
|
@@ -97,7 +98,7 @@ class LangChainTracer(BaseTracer):
|
|
|
97
98
|
self.project_name = project_name or ls_utils.get_tracer_project()
|
|
98
99
|
self.client = client or get_client()
|
|
99
100
|
self.tags = tags or []
|
|
100
|
-
self.latest_run:
|
|
101
|
+
self.latest_run: Run | None = None
|
|
101
102
|
self.run_has_token_event_map: dict[str, bool] = {}
|
|
102
103
|
|
|
103
104
|
def _start_trace(self, run: Run) -> None:
|
|
@@ -112,17 +113,19 @@ class LangChainTracer(BaseTracer):
|
|
|
112
113
|
super()._start_trace(run)
|
|
113
114
|
if run.ls_client is None:
|
|
114
115
|
run.ls_client = self.client
|
|
116
|
+
if get_tracing_context().get("enabled") is False:
|
|
117
|
+
run.extra["__disabled"] = True
|
|
115
118
|
|
|
116
119
|
def on_chat_model_start(
|
|
117
120
|
self,
|
|
118
121
|
serialized: dict[str, Any],
|
|
119
|
-
messages:
|
|
122
|
+
messages: list[list[BaseMessage]],
|
|
120
123
|
*,
|
|
121
124
|
run_id: UUID,
|
|
122
|
-
tags:
|
|
123
|
-
parent_run_id:
|
|
124
|
-
metadata:
|
|
125
|
-
name:
|
|
125
|
+
tags: list[str] | None = None,
|
|
126
|
+
parent_run_id: UUID | None = None,
|
|
127
|
+
metadata: dict[str, Any] | None = None,
|
|
128
|
+
name: str | None = None,
|
|
126
129
|
**kwargs: Any,
|
|
127
130
|
) -> Run:
|
|
128
131
|
"""Start a trace for an LLM run.
|
|
@@ -131,24 +134,18 @@ class LangChainTracer(BaseTracer):
|
|
|
131
134
|
serialized: The serialized model.
|
|
132
135
|
messages: The messages.
|
|
133
136
|
run_id: The run ID.
|
|
134
|
-
tags: The tags.
|
|
135
|
-
parent_run_id: The parent run ID.
|
|
136
|
-
metadata: The metadata.
|
|
137
|
-
name: The name.
|
|
138
|
-
kwargs: Additional keyword arguments.
|
|
137
|
+
tags: The tags.
|
|
138
|
+
parent_run_id: The parent run ID.
|
|
139
|
+
metadata: The metadata.
|
|
140
|
+
name: The name.
|
|
141
|
+
**kwargs: Additional keyword arguments.
|
|
139
142
|
|
|
140
143
|
Returns:
|
|
141
|
-
|
|
144
|
+
The run.
|
|
142
145
|
"""
|
|
143
146
|
start_time = datetime.now(timezone.utc)
|
|
144
147
|
if metadata:
|
|
145
148
|
kwargs.update({"metadata": metadata})
|
|
146
|
-
if isinstance(messages[0], MessageV1Types):
|
|
147
|
-
# Convert from v1 messages to BaseMessage
|
|
148
|
-
messages = [
|
|
149
|
-
[convert_from_v1_message(msg) for msg in messages] # type: ignore[arg-type]
|
|
150
|
-
]
|
|
151
|
-
messages = cast("list[list[BaseMessage]]", messages)
|
|
152
149
|
chat_model_run = Run(
|
|
153
150
|
id=run_id,
|
|
154
151
|
parent_run_id=parent_run_id,
|
|
@@ -178,7 +175,7 @@ class LangChainTracer(BaseTracer):
|
|
|
178
175
|
"""Get the LangSmith root run URL.
|
|
179
176
|
|
|
180
177
|
Returns:
|
|
181
|
-
|
|
178
|
+
The LangSmith root run URL.
|
|
182
179
|
|
|
183
180
|
Raises:
|
|
184
181
|
ValueError: If no traced run is found.
|
|
@@ -210,6 +207,8 @@ class LangChainTracer(BaseTracer):
|
|
|
210
207
|
|
|
211
208
|
def _persist_run_single(self, run: Run) -> None:
|
|
212
209
|
"""Persist a run."""
|
|
210
|
+
if run.extra.get("__disabled"):
|
|
211
|
+
return
|
|
213
212
|
try:
|
|
214
213
|
run.extra["runtime"] = get_runtime_environment()
|
|
215
214
|
run.tags = self._get_tags(run)
|
|
@@ -223,6 +222,8 @@ class LangChainTracer(BaseTracer):
|
|
|
223
222
|
|
|
224
223
|
def _update_run_single(self, run: Run) -> None:
|
|
225
224
|
"""Update a run."""
|
|
225
|
+
if run.extra.get("__disabled"):
|
|
226
|
+
return
|
|
226
227
|
try:
|
|
227
228
|
run.patch(exclude_inputs=run.extra.get("inputs_is_truthy", False))
|
|
228
229
|
except Exception as e:
|
|
@@ -241,12 +242,9 @@ class LangChainTracer(BaseTracer):
|
|
|
241
242
|
self,
|
|
242
243
|
token: str,
|
|
243
244
|
run_id: UUID,
|
|
244
|
-
chunk:
|
|
245
|
-
|
|
246
|
-
] = None,
|
|
247
|
-
parent_run_id: Optional[UUID] = None,
|
|
245
|
+
chunk: GenerationChunk | ChatGenerationChunk | None = None,
|
|
246
|
+
parent_run_id: UUID | None = None,
|
|
248
247
|
) -> Run:
|
|
249
|
-
"""Append token event to LLM run and return the run."""
|
|
250
248
|
run_id_str = str(run_id)
|
|
251
249
|
if run_id_str not in self.run_has_token_event_map:
|
|
252
250
|
self.run_has_token_event_map[run_id_str] = True
|
|
@@ -7,23 +7,23 @@ import contextlib
|
|
|
7
7
|
import copy
|
|
8
8
|
import threading
|
|
9
9
|
from collections import defaultdict
|
|
10
|
+
from pprint import pformat
|
|
10
11
|
from typing import (
|
|
11
12
|
TYPE_CHECKING,
|
|
12
13
|
Any,
|
|
13
14
|
Literal,
|
|
14
|
-
Optional,
|
|
15
15
|
TypeVar,
|
|
16
|
-
Union,
|
|
17
16
|
overload,
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
import jsonpatch # type: ignore[import-untyped]
|
|
21
20
|
from typing_extensions import NotRequired, TypedDict, override
|
|
22
21
|
|
|
22
|
+
from langchain_core.callbacks.base import BaseCallbackManager
|
|
23
23
|
from langchain_core.load import dumps
|
|
24
24
|
from langchain_core.load.load import load
|
|
25
25
|
from langchain_core.outputs import ChatGenerationChunk, GenerationChunk
|
|
26
|
-
from langchain_core.runnables import
|
|
26
|
+
from langchain_core.runnables import RunnableConfig, ensure_config
|
|
27
27
|
from langchain_core.tracers._streaming import _StreamingCallbackHandler
|
|
28
28
|
from langchain_core.tracers.base import BaseTracer
|
|
29
29
|
from langchain_core.tracers.memory_stream import _MemoryStream
|
|
@@ -32,9 +32,9 @@ if TYPE_CHECKING:
|
|
|
32
32
|
from collections.abc import AsyncIterator, Iterator, Sequence
|
|
33
33
|
from uuid import UUID
|
|
34
34
|
|
|
35
|
+
from langchain_core.runnables import Runnable
|
|
35
36
|
from langchain_core.runnables.utils import Input, Output
|
|
36
37
|
from langchain_core.tracers.schemas import Run
|
|
37
|
-
from langchain_core.v1.messages import AIMessageChunk
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class LogEntry(TypedDict):
|
|
@@ -57,13 +57,13 @@ class LogEntry(TypedDict):
|
|
|
57
57
|
"""List of LLM tokens streamed by this run, if applicable."""
|
|
58
58
|
streamed_output: list[Any]
|
|
59
59
|
"""List of output chunks streamed by this run, if available."""
|
|
60
|
-
inputs: NotRequired[
|
|
60
|
+
inputs: NotRequired[Any | None]
|
|
61
61
|
"""Inputs to this run. Not available currently via astream_log."""
|
|
62
|
-
final_output:
|
|
62
|
+
final_output: Any | None
|
|
63
63
|
"""Final output of this run.
|
|
64
64
|
|
|
65
65
|
Only available after the run has finished successfully."""
|
|
66
|
-
end_time:
|
|
66
|
+
end_time: str | None
|
|
67
67
|
"""ISO-8601 timestamp of when the run ended.
|
|
68
68
|
Only available after the run has finished."""
|
|
69
69
|
|
|
@@ -75,7 +75,7 @@ class RunState(TypedDict):
|
|
|
75
75
|
"""ID of the run."""
|
|
76
76
|
streamed_output: list[Any]
|
|
77
77
|
"""List of output chunks streamed by Runnable.stream()"""
|
|
78
|
-
final_output:
|
|
78
|
+
final_output: Any | None
|
|
79
79
|
"""Final output of the run, usually the result of aggregating (`+`) streamed_output.
|
|
80
80
|
Updated throughout the run when supported by the Runnable."""
|
|
81
81
|
|
|
@@ -110,8 +110,18 @@ class RunLogPatch:
|
|
|
110
110
|
"""
|
|
111
111
|
self.ops = list(ops)
|
|
112
112
|
|
|
113
|
-
def __add__(self, other:
|
|
114
|
-
"""Combine two RunLogPatch instances.
|
|
113
|
+
def __add__(self, other: RunLogPatch | Any) -> RunLog:
|
|
114
|
+
"""Combine two `RunLogPatch` instances.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
other: The other `RunLogPatch` to combine with.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
TypeError: If the other object is not a `RunLogPatch`.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
A new `RunLog` representing the combination of the two.
|
|
124
|
+
"""
|
|
115
125
|
if type(other) is RunLogPatch:
|
|
116
126
|
ops = self.ops + other.ops
|
|
117
127
|
state = jsonpatch.apply_patch(None, copy.deepcopy(ops))
|
|
@@ -122,8 +132,6 @@ class RunLogPatch:
|
|
|
122
132
|
|
|
123
133
|
@override
|
|
124
134
|
def __repr__(self) -> str:
|
|
125
|
-
from pprint import pformat
|
|
126
|
-
|
|
127
135
|
# 1:-1 to get rid of the [] around the list
|
|
128
136
|
return f"RunLogPatch({pformat(self.ops)[1:-1]})"
|
|
129
137
|
|
|
@@ -150,8 +158,18 @@ class RunLog(RunLogPatch):
|
|
|
150
158
|
super().__init__(*ops)
|
|
151
159
|
self.state = state
|
|
152
160
|
|
|
153
|
-
def __add__(self, other:
|
|
154
|
-
"""Combine two
|
|
161
|
+
def __add__(self, other: RunLogPatch | Any) -> RunLog:
|
|
162
|
+
"""Combine two `RunLog`s.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
other: The other `RunLog` or `RunLogPatch` to combine with.
|
|
166
|
+
|
|
167
|
+
Raises:
|
|
168
|
+
TypeError: If the other object is not a `RunLog` or `RunLogPatch`.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
A new `RunLog` representing the combination of the two.
|
|
172
|
+
"""
|
|
155
173
|
if type(other) is RunLogPatch:
|
|
156
174
|
ops = self.ops + other.ops
|
|
157
175
|
state = jsonpatch.apply_patch(self.state, other.ops)
|
|
@@ -162,13 +180,18 @@ class RunLog(RunLogPatch):
|
|
|
162
180
|
|
|
163
181
|
@override
|
|
164
182
|
def __repr__(self) -> str:
|
|
165
|
-
from pprint import pformat
|
|
166
|
-
|
|
167
183
|
return f"RunLog({pformat(self.state)})"
|
|
168
184
|
|
|
169
185
|
@override
|
|
170
186
|
def __eq__(self, other: object) -> bool:
|
|
171
|
-
"""Check if two
|
|
187
|
+
"""Check if two `RunLog`s are equal.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
other: The other `RunLog` to compare to.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
`True` if the `RunLog`s are equal, `False` otherwise.
|
|
194
|
+
"""
|
|
172
195
|
# First compare that the state is the same
|
|
173
196
|
if not isinstance(other, RunLog):
|
|
174
197
|
return False
|
|
@@ -177,7 +200,7 @@ class RunLog(RunLogPatch):
|
|
|
177
200
|
# Then compare that the ops are the same
|
|
178
201
|
return super().__eq__(other)
|
|
179
202
|
|
|
180
|
-
__hash__ = None
|
|
203
|
+
__hash__ = None
|
|
181
204
|
|
|
182
205
|
|
|
183
206
|
T = TypeVar("T")
|
|
@@ -190,12 +213,12 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
190
213
|
self,
|
|
191
214
|
*,
|
|
192
215
|
auto_close: bool = True,
|
|
193
|
-
include_names:
|
|
194
|
-
include_types:
|
|
195
|
-
include_tags:
|
|
196
|
-
exclude_names:
|
|
197
|
-
exclude_types:
|
|
198
|
-
exclude_tags:
|
|
216
|
+
include_names: Sequence[str] | None = None,
|
|
217
|
+
include_types: Sequence[str] | None = None,
|
|
218
|
+
include_tags: Sequence[str] | None = None,
|
|
219
|
+
exclude_names: Sequence[str] | None = None,
|
|
220
|
+
exclude_types: Sequence[str] | None = None,
|
|
221
|
+
exclude_tags: Sequence[str] | None = None,
|
|
199
222
|
# Schema format is for internal use only.
|
|
200
223
|
_schema_format: Literal["original", "streaming_events"] = "streaming_events",
|
|
201
224
|
) -> None:
|
|
@@ -241,17 +264,24 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
241
264
|
self.exclude_types = exclude_types
|
|
242
265
|
self.exclude_tags = exclude_tags
|
|
243
266
|
|
|
244
|
-
|
|
267
|
+
try:
|
|
268
|
+
loop = asyncio.get_event_loop()
|
|
269
|
+
except RuntimeError:
|
|
270
|
+
loop = asyncio.new_event_loop()
|
|
245
271
|
memory_stream = _MemoryStream[RunLogPatch](loop)
|
|
246
272
|
self.lock = threading.Lock()
|
|
247
273
|
self.send_stream = memory_stream.get_send_stream()
|
|
248
274
|
self.receive_stream = memory_stream.get_receive_stream()
|
|
249
275
|
self._key_map_by_run_id: dict[UUID, str] = {}
|
|
250
276
|
self._counter_map_by_name: dict[str, int] = defaultdict(int)
|
|
251
|
-
self.root_id:
|
|
277
|
+
self.root_id: UUID | None = None
|
|
252
278
|
|
|
253
279
|
def __aiter__(self) -> AsyncIterator[RunLogPatch]:
|
|
254
|
-
"""Iterate over the stream of run logs.
|
|
280
|
+
"""Iterate over the stream of run logs.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
An async iterator over the run log patches.
|
|
284
|
+
"""
|
|
255
285
|
return self.receive_stream.__aiter__()
|
|
256
286
|
|
|
257
287
|
def send(self, *ops: dict[str, Any]) -> bool:
|
|
@@ -261,8 +291,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
261
291
|
*ops: The operations to send to the stream.
|
|
262
292
|
|
|
263
293
|
Returns:
|
|
264
|
-
|
|
265
|
-
is closed.
|
|
294
|
+
`True` if the patch was sent successfully, False if the stream is closed.
|
|
266
295
|
"""
|
|
267
296
|
# We will likely want to wrap this in try / except at some point
|
|
268
297
|
# to handle exceptions that might arise at run time.
|
|
@@ -281,7 +310,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
281
310
|
output: The output async iterator.
|
|
282
311
|
|
|
283
312
|
Yields:
|
|
284
|
-
|
|
313
|
+
The output value.
|
|
285
314
|
"""
|
|
286
315
|
async for chunk in output:
|
|
287
316
|
# root run is handled in .astream_log()
|
|
@@ -312,7 +341,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
312
341
|
output: The output iterator.
|
|
313
342
|
|
|
314
343
|
Yields:
|
|
315
|
-
|
|
344
|
+
The output value.
|
|
316
345
|
"""
|
|
317
346
|
for chunk in output:
|
|
318
347
|
# root run is handled in .astream_log()
|
|
@@ -342,7 +371,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
342
371
|
run: The Run to check.
|
|
343
372
|
|
|
344
373
|
Returns:
|
|
345
|
-
|
|
374
|
+
`True` if the run should be included, `False` otherwise.
|
|
346
375
|
"""
|
|
347
376
|
if run.id == self.root_id:
|
|
348
377
|
return False
|
|
@@ -486,7 +515,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
486
515
|
self,
|
|
487
516
|
run: Run,
|
|
488
517
|
token: str,
|
|
489
|
-
chunk:
|
|
518
|
+
chunk: GenerationChunk | ChatGenerationChunk | None,
|
|
490
519
|
) -> None:
|
|
491
520
|
"""Process new LLM token."""
|
|
492
521
|
index = self._key_map_by_run_id.get(run.id)
|
|
@@ -512,7 +541,7 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
512
541
|
|
|
513
542
|
def _get_standardized_inputs(
|
|
514
543
|
run: Run, schema_format: Literal["original", "streaming_events"]
|
|
515
|
-
) ->
|
|
544
|
+
) -> dict[str, Any] | None:
|
|
516
545
|
"""Extract standardized inputs from a run.
|
|
517
546
|
|
|
518
547
|
Standardizes the inputs based on the type of the runnable used.
|
|
@@ -554,7 +583,7 @@ def _get_standardized_inputs(
|
|
|
554
583
|
|
|
555
584
|
def _get_standardized_outputs(
|
|
556
585
|
run: Run, schema_format: Literal["original", "streaming_events", "original+chat"]
|
|
557
|
-
) ->
|
|
586
|
+
) -> Any | None:
|
|
558
587
|
"""Extract standardized output from a run.
|
|
559
588
|
|
|
560
589
|
Standardizes the outputs based on the type of the runnable used.
|
|
@@ -588,7 +617,7 @@ def _get_standardized_outputs(
|
|
|
588
617
|
def _astream_log_implementation(
|
|
589
618
|
runnable: Runnable[Input, Output],
|
|
590
619
|
value: Any,
|
|
591
|
-
config:
|
|
620
|
+
config: RunnableConfig | None = None,
|
|
592
621
|
*,
|
|
593
622
|
stream: LogStreamCallbackHandler,
|
|
594
623
|
diff: Literal[True] = True,
|
|
@@ -601,7 +630,7 @@ def _astream_log_implementation(
|
|
|
601
630
|
def _astream_log_implementation(
|
|
602
631
|
runnable: Runnable[Input, Output],
|
|
603
632
|
value: Any,
|
|
604
|
-
config:
|
|
633
|
+
config: RunnableConfig | None = None,
|
|
605
634
|
*,
|
|
606
635
|
stream: LogStreamCallbackHandler,
|
|
607
636
|
diff: Literal[False],
|
|
@@ -613,26 +642,35 @@ def _astream_log_implementation(
|
|
|
613
642
|
async def _astream_log_implementation(
|
|
614
643
|
runnable: Runnable[Input, Output],
|
|
615
644
|
value: Any,
|
|
616
|
-
config:
|
|
645
|
+
config: RunnableConfig | None = None,
|
|
617
646
|
*,
|
|
618
647
|
stream: LogStreamCallbackHandler,
|
|
619
648
|
diff: bool = True,
|
|
620
649
|
with_streamed_output_list: bool = True,
|
|
621
650
|
**kwargs: Any,
|
|
622
|
-
) ->
|
|
651
|
+
) -> AsyncIterator[RunLogPatch] | AsyncIterator[RunLog]:
|
|
623
652
|
"""Implementation of astream_log for a given runnable.
|
|
624
653
|
|
|
625
654
|
The implementation has been factored out (at least temporarily) as both
|
|
626
655
|
astream_log and astream_events relies on it.
|
|
627
|
-
"""
|
|
628
|
-
import jsonpatch
|
|
629
|
-
|
|
630
|
-
from langchain_core.callbacks.base import BaseCallbackManager
|
|
631
|
-
from langchain_core.tracers.log_stream import (
|
|
632
|
-
RunLog,
|
|
633
|
-
RunLogPatch,
|
|
634
|
-
)
|
|
635
656
|
|
|
657
|
+
Args:
|
|
658
|
+
runnable: The runnable to run in streaming mode.
|
|
659
|
+
value: The input to the runnable.
|
|
660
|
+
config: The config to pass to the runnable.
|
|
661
|
+
stream: The stream to send the run logs to.
|
|
662
|
+
diff: Whether to yield run log patches (True) or full run logs (False).
|
|
663
|
+
with_streamed_output_list: Whether to include a list of all streamed
|
|
664
|
+
outputs in each patch. If `False`, only the final output will be included
|
|
665
|
+
in the patches.
|
|
666
|
+
**kwargs: Additional keyword arguments to pass to the runnable.
|
|
667
|
+
|
|
668
|
+
Raises:
|
|
669
|
+
ValueError: If the callbacks in the config are of an unexpected type.
|
|
670
|
+
|
|
671
|
+
Yields:
|
|
672
|
+
The run log patches or states, depending on the value of `diff`.
|
|
673
|
+
"""
|
|
636
674
|
# Assign the stream handler to the config
|
|
637
675
|
config = ensure_config(config)
|
|
638
676
|
callbacks = config.get("callbacks")
|
|
@@ -655,8 +693,8 @@ async def _astream_log_implementation(
|
|
|
655
693
|
# add each chunk to the output stream
|
|
656
694
|
async def consume_astream() -> None:
|
|
657
695
|
try:
|
|
658
|
-
prev_final_output:
|
|
659
|
-
final_output:
|
|
696
|
+
prev_final_output: Output | None = None
|
|
697
|
+
final_output: Output | None = None
|
|
660
698
|
|
|
661
699
|
async for chunk in runnable.astream(value, config, **kwargs):
|
|
662
700
|
prev_final_output = final_output
|
|
@@ -5,7 +5,7 @@ channel. The writer and reader can be in the same event loop or in different eve
|
|
|
5
5
|
loops. When they're in different event loops, they will also be in different
|
|
6
6
|
threads.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Useful in situations when there's a mix of synchronous and asynchronous
|
|
9
9
|
used in the code.
|
|
10
10
|
"""
|
|
11
11
|
|
|
@@ -130,7 +130,7 @@ class _MemoryStream(Generic[T]):
|
|
|
130
130
|
"""Get a writer for the channel.
|
|
131
131
|
|
|
132
132
|
Returns:
|
|
133
|
-
|
|
133
|
+
The writer for the channel.
|
|
134
134
|
"""
|
|
135
135
|
return _SendStream[T](
|
|
136
136
|
reader_loop=self._loop, queue=self._queue, done=self._done
|
|
@@ -140,6 +140,6 @@ class _MemoryStream(Generic[T]):
|
|
|
140
140
|
"""Get a reader for the channel.
|
|
141
141
|
|
|
142
142
|
Returns:
|
|
143
|
-
|
|
143
|
+
The reader for the channel.
|
|
144
144
|
"""
|
|
145
145
|
return _ReceiveStream[T](queue=self._queue, done=self._done)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Tracers that call listeners."""
|
|
2
2
|
|
|
3
|
-
from collections.abc import Awaitable
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from collections.abc import Awaitable, Callable
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from langchain_core.runnables.config import (
|
|
7
7
|
RunnableConfig,
|
|
@@ -14,33 +14,25 @@ from langchain_core.tracers.schemas import Run
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from uuid import UUID
|
|
16
16
|
|
|
17
|
-
Listener =
|
|
18
|
-
AsyncListener =
|
|
19
|
-
Callable[[Run], Awaitable[None]]
|
|
20
|
-
|
|
17
|
+
Listener = Callable[[Run], None] | Callable[[Run, RunnableConfig], None]
|
|
18
|
+
AsyncListener = (
|
|
19
|
+
Callable[[Run], Awaitable[None]] | Callable[[Run, RunnableConfig], Awaitable[None]]
|
|
20
|
+
)
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class RootListenersTracer(BaseTracer):
|
|
24
|
-
"""Tracer that calls listeners on run start, end, and error.
|
|
25
|
-
|
|
26
|
-
Parameters:
|
|
27
|
-
log_missing_parent: Whether to log a warning if the parent is missing.
|
|
28
|
-
Default is False.
|
|
29
|
-
config: The runnable config.
|
|
30
|
-
on_start: The listener to call on run start.
|
|
31
|
-
on_end: The listener to call on run end.
|
|
32
|
-
on_error: The listener to call on run error.
|
|
33
|
-
"""
|
|
24
|
+
"""Tracer that calls listeners on run start, end, and error."""
|
|
34
25
|
|
|
35
26
|
log_missing_parent = False
|
|
27
|
+
"""Whether to log a warning if the parent is missing."""
|
|
36
28
|
|
|
37
29
|
def __init__(
|
|
38
30
|
self,
|
|
39
31
|
*,
|
|
40
32
|
config: RunnableConfig,
|
|
41
|
-
on_start:
|
|
42
|
-
on_end:
|
|
43
|
-
on_error:
|
|
33
|
+
on_start: Listener | None,
|
|
34
|
+
on_end: Listener | None,
|
|
35
|
+
on_error: Listener | None,
|
|
44
36
|
) -> None:
|
|
45
37
|
"""Initialize the tracer.
|
|
46
38
|
|
|
@@ -56,7 +48,7 @@ class RootListenersTracer(BaseTracer):
|
|
|
56
48
|
self._arg_on_start = on_start
|
|
57
49
|
self._arg_on_end = on_end
|
|
58
50
|
self._arg_on_error = on_error
|
|
59
|
-
self.root_id:
|
|
51
|
+
self.root_id: UUID | None = None
|
|
60
52
|
|
|
61
53
|
def _persist_run(self, run: Run) -> None:
|
|
62
54
|
# This is a legacy method only called once for an entire run tree
|
|
@@ -84,26 +76,18 @@ class RootListenersTracer(BaseTracer):
|
|
|
84
76
|
|
|
85
77
|
|
|
86
78
|
class AsyncRootListenersTracer(AsyncBaseTracer):
|
|
87
|
-
"""Async Tracer that calls listeners on run start, end, and error.
|
|
88
|
-
|
|
89
|
-
Parameters:
|
|
90
|
-
log_missing_parent: Whether to log a warning if the parent is missing.
|
|
91
|
-
Default is False.
|
|
92
|
-
config: The runnable config.
|
|
93
|
-
on_start: The listener to call on run start.
|
|
94
|
-
on_end: The listener to call on run end.
|
|
95
|
-
on_error: The listener to call on run error.
|
|
96
|
-
"""
|
|
79
|
+
"""Async Tracer that calls listeners on run start, end, and error."""
|
|
97
80
|
|
|
98
81
|
log_missing_parent = False
|
|
82
|
+
"""Whether to log a warning if the parent is missing."""
|
|
99
83
|
|
|
100
84
|
def __init__(
|
|
101
85
|
self,
|
|
102
86
|
*,
|
|
103
87
|
config: RunnableConfig,
|
|
104
|
-
on_start:
|
|
105
|
-
on_end:
|
|
106
|
-
on_error:
|
|
88
|
+
on_start: AsyncListener | None,
|
|
89
|
+
on_end: AsyncListener | None,
|
|
90
|
+
on_error: AsyncListener | None,
|
|
107
91
|
) -> None:
|
|
108
92
|
"""Initialize the tracer.
|
|
109
93
|
|
|
@@ -119,7 +103,7 @@ class AsyncRootListenersTracer(AsyncBaseTracer):
|
|
|
119
103
|
self._arg_on_start = on_start
|
|
120
104
|
self._arg_on_end = on_end
|
|
121
105
|
self._arg_on_error = on_error
|
|
122
|
-
self.root_id:
|
|
106
|
+
self.root_id: UUID | None = None
|
|
123
107
|
|
|
124
108
|
async def _persist_run(self, run: Run) -> None:
|
|
125
109
|
# This is a legacy method only called once for an entire run tree
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""A tracer that collects all nested runs in a list."""
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from langchain_core.tracers.base import BaseTracer
|
|
@@ -11,27 +11,17 @@ class RunCollectorCallbackHandler(BaseTracer):
|
|
|
11
11
|
"""Tracer that collects all nested runs in a list.
|
|
12
12
|
|
|
13
13
|
This tracer is useful for inspection and evaluation purposes.
|
|
14
|
-
|
|
15
|
-
Parameters
|
|
16
|
-
----------
|
|
17
|
-
name : str, default="run-collector_callback_handler"
|
|
18
|
-
example_id : Optional[Union[UUID, str]], default=None
|
|
19
|
-
The ID of the example being traced. It can be either a UUID or a string.
|
|
20
14
|
"""
|
|
21
15
|
|
|
22
16
|
name: str = "run-collector_callback_handler"
|
|
23
17
|
|
|
24
|
-
def __init__(
|
|
25
|
-
self, example_id: Optional[Union[UUID, str]] = None, **kwargs: Any
|
|
26
|
-
) -> None:
|
|
18
|
+
def __init__(self, example_id: UUID | str | None = None, **kwargs: Any) -> None:
|
|
27
19
|
"""Initialize the RunCollectorCallbackHandler.
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
**kwargs : Any
|
|
34
|
-
Additional keyword arguments
|
|
21
|
+
Args:
|
|
22
|
+
example_id: The ID of the example being traced. (default: None).
|
|
23
|
+
It can be either a UUID or a string.
|
|
24
|
+
**kwargs: Additional keyword arguments.
|
|
35
25
|
"""
|
|
36
26
|
super().__init__(**kwargs)
|
|
37
27
|
self.example_id = (
|
|
@@ -42,10 +32,8 @@ class RunCollectorCallbackHandler(BaseTracer):
|
|
|
42
32
|
def _persist_run(self, run: Run) -> None:
|
|
43
33
|
"""Persist a run by adding it to the traced_runs list.
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
run : Run
|
|
48
|
-
The run to be persisted.
|
|
35
|
+
Args:
|
|
36
|
+
run: The run to be persisted.
|
|
49
37
|
"""
|
|
50
38
|
run_ = run.copy()
|
|
51
39
|
run_.reference_example_id = self.example_id
|