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,9 +3,7 @@
|
|
|
3
3
|
from typing import (
|
|
4
4
|
TYPE_CHECKING,
|
|
5
5
|
Any,
|
|
6
|
-
Optional,
|
|
7
6
|
TypeVar,
|
|
8
|
-
Union,
|
|
9
7
|
cast,
|
|
10
8
|
)
|
|
11
9
|
|
|
@@ -35,7 +33,7 @@ U = TypeVar("U")
|
|
|
35
33
|
|
|
36
34
|
|
|
37
35
|
class ExponentialJitterParams(TypedDict, total=False):
|
|
38
|
-
"""Parameters for
|
|
36
|
+
"""Parameters for `tenacity.wait_exponential_jitter`."""
|
|
39
37
|
|
|
40
38
|
initial: float
|
|
41
39
|
"""Initial wait."""
|
|
@@ -62,36 +60,34 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
62
60
|
Example:
|
|
63
61
|
Here's an example that uses a RunnableLambda to raise an exception
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
```python
|
|
64
|
+
import time
|
|
66
65
|
|
|
67
|
-
import time
|
|
68
66
|
|
|
67
|
+
def foo(input) -> None:
|
|
68
|
+
'''Fake function that raises an exception.'''
|
|
69
|
+
raise ValueError(f"Invoking foo failed. At time {time.time()}")
|
|
69
70
|
|
|
70
|
-
def foo(input) -> None:
|
|
71
|
-
'''Fake function that raises an exception.'''
|
|
72
|
-
raise ValueError(f"Invoking foo failed. At time {time.time()}")
|
|
73
71
|
|
|
72
|
+
runnable = RunnableLambda(foo)
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
exponential_jitter_params={
|
|
82
|
-
"initial": 2
|
|
83
|
-
}, # if desired, customize backoff
|
|
84
|
-
)
|
|
74
|
+
runnable_with_retries = runnable.with_retry(
|
|
75
|
+
retry_if_exception_type=(ValueError,), # Retry only on ValueError
|
|
76
|
+
wait_exponential_jitter=True, # Add jitter to the exponential backoff
|
|
77
|
+
stop_after_attempt=2, # Try twice
|
|
78
|
+
exponential_jitter_params={"initial": 2}, # if desired, customize backoff
|
|
79
|
+
)
|
|
85
80
|
|
|
86
|
-
|
|
81
|
+
# The method invocation above is equivalent to the longer form below:
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
runnable_with_retries = RunnableRetry(
|
|
84
|
+
bound=runnable,
|
|
85
|
+
retry_exception_types=(ValueError,),
|
|
86
|
+
max_attempt_number=2,
|
|
87
|
+
wait_exponential_jitter=True,
|
|
88
|
+
exponential_jitter_params={"initial": 2},
|
|
89
|
+
)
|
|
90
|
+
```
|
|
95
91
|
|
|
96
92
|
This logic can be used to retry any Runnable, including a chain of Runnables,
|
|
97
93
|
but in general it's best practice to keep the scope of the retry as small as
|
|
@@ -99,22 +95,20 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
99
95
|
the Runnable that is likely to fail, not the entire chain.
|
|
100
96
|
|
|
101
97
|
Example:
|
|
98
|
+
```python
|
|
99
|
+
from langchain_core.chat_models import ChatOpenAI
|
|
100
|
+
from langchain_core.prompts import PromptTemplate
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
from langchain_core.chat_models import ChatOpenAI
|
|
106
|
-
from langchain_core.prompts import PromptTemplate
|
|
107
|
-
|
|
108
|
-
template = PromptTemplate.from_template("tell me a joke about {topic}.")
|
|
109
|
-
model = ChatOpenAI(temperature=0.5)
|
|
110
|
-
|
|
111
|
-
# Good
|
|
112
|
-
chain = template | model.with_retry()
|
|
102
|
+
template = PromptTemplate.from_template("tell me a joke about {topic}.")
|
|
103
|
+
model = ChatOpenAI(temperature=0.5)
|
|
113
104
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
retryable_chain = chain.with_retry()
|
|
105
|
+
# Good
|
|
106
|
+
chain = template | model.with_retry()
|
|
117
107
|
|
|
108
|
+
# Bad
|
|
109
|
+
chain = template | model
|
|
110
|
+
retryable_chain = chain.with_retry()
|
|
111
|
+
```
|
|
118
112
|
"""
|
|
119
113
|
|
|
120
114
|
retry_exception_types: tuple[type[BaseException], ...] = (Exception,)
|
|
@@ -130,9 +124,9 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
130
124
|
wait_exponential_jitter: bool = True
|
|
131
125
|
"""Whether to add jitter to the exponential backoff."""
|
|
132
126
|
|
|
133
|
-
exponential_jitter_params:
|
|
134
|
-
"""Parameters for
|
|
135
|
-
|
|
127
|
+
exponential_jitter_params: ExponentialJitterParams | None = None
|
|
128
|
+
"""Parameters for `tenacity.wait_exponential_jitter`. Namely: `initial`,
|
|
129
|
+
`max`, `exp_base`, and `jitter` (all `float` values).
|
|
136
130
|
"""
|
|
137
131
|
|
|
138
132
|
max_attempt_number: int = 3
|
|
@@ -178,7 +172,8 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
178
172
|
retry_state: RetryCallState,
|
|
179
173
|
) -> list[RunnableConfig]:
|
|
180
174
|
return [
|
|
181
|
-
self._patch_config(c, rm, retry_state)
|
|
175
|
+
self._patch_config(c, rm, retry_state)
|
|
176
|
+
for c, rm in zip(config, run_manager, strict=False)
|
|
182
177
|
]
|
|
183
178
|
|
|
184
179
|
def _invoke(
|
|
@@ -201,7 +196,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
201
196
|
|
|
202
197
|
@override
|
|
203
198
|
def invoke(
|
|
204
|
-
self, input: Input, config:
|
|
199
|
+
self, input: Input, config: RunnableConfig | None = None, **kwargs: Any
|
|
205
200
|
) -> Output:
|
|
206
201
|
return self._call_with_config(self._invoke, input, config, **kwargs)
|
|
207
202
|
|
|
@@ -225,7 +220,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
225
220
|
|
|
226
221
|
@override
|
|
227
222
|
async def ainvoke(
|
|
228
|
-
self, input: Input, config:
|
|
223
|
+
self, input: Input, config: RunnableConfig | None = None, **kwargs: Any
|
|
229
224
|
) -> Output:
|
|
230
225
|
return await self._acall_with_config(self._ainvoke, input, config, **kwargs)
|
|
231
226
|
|
|
@@ -235,7 +230,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
235
230
|
run_manager: list["CallbackManagerForChainRun"],
|
|
236
231
|
config: list[RunnableConfig],
|
|
237
232
|
**kwargs: Any,
|
|
238
|
-
) -> list[
|
|
233
|
+
) -> list[Output | Exception]:
|
|
239
234
|
results_map: dict[int, Output] = {}
|
|
240
235
|
|
|
241
236
|
not_set: list[Output] = []
|
|
@@ -284,7 +279,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
284
279
|
if result is not_set:
|
|
285
280
|
result = cast("list[Output]", [e] * len(inputs))
|
|
286
281
|
|
|
287
|
-
outputs: list[
|
|
282
|
+
outputs: list[Output | Exception] = []
|
|
288
283
|
for idx in range(len(inputs)):
|
|
289
284
|
if idx in results_map:
|
|
290
285
|
outputs.append(results_map[idx])
|
|
@@ -296,7 +291,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
296
291
|
def batch(
|
|
297
292
|
self,
|
|
298
293
|
inputs: list[Input],
|
|
299
|
-
config:
|
|
294
|
+
config: RunnableConfig | list[RunnableConfig] | None = None,
|
|
300
295
|
*,
|
|
301
296
|
return_exceptions: bool = False,
|
|
302
297
|
**kwargs: Any,
|
|
@@ -311,7 +306,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
311
306
|
run_manager: list["AsyncCallbackManagerForChainRun"],
|
|
312
307
|
config: list[RunnableConfig],
|
|
313
308
|
**kwargs: Any,
|
|
314
|
-
) -> list[
|
|
309
|
+
) -> list[Output | Exception]:
|
|
315
310
|
results_map: dict[int, Output] = {}
|
|
316
311
|
|
|
317
312
|
not_set: list[Output] = []
|
|
@@ -359,7 +354,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
359
354
|
if result is not_set:
|
|
360
355
|
result = cast("list[Output]", [e] * len(inputs))
|
|
361
356
|
|
|
362
|
-
outputs: list[
|
|
357
|
+
outputs: list[Output | Exception] = []
|
|
363
358
|
for idx in range(len(inputs)):
|
|
364
359
|
if idx in results_map:
|
|
365
360
|
outputs.append(results_map[idx])
|
|
@@ -371,7 +366,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
371
366
|
async def abatch(
|
|
372
367
|
self,
|
|
373
368
|
inputs: list[Input],
|
|
374
|
-
config:
|
|
369
|
+
config: RunnableConfig | list[RunnableConfig] | None = None,
|
|
375
370
|
*,
|
|
376
371
|
return_exceptions: bool = False,
|
|
377
372
|
**kwargs: Any,
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import Mapping
|
|
5
|
+
from collections.abc import Callable, Mapping
|
|
6
6
|
from typing import (
|
|
7
7
|
TYPE_CHECKING,
|
|
8
8
|
Any,
|
|
9
|
-
Callable,
|
|
10
|
-
Optional,
|
|
11
|
-
Union,
|
|
12
9
|
cast,
|
|
13
10
|
)
|
|
14
11
|
|
|
@@ -43,27 +40,25 @@ class RouterInput(TypedDict):
|
|
|
43
40
|
key: str
|
|
44
41
|
"""The key to route on."""
|
|
45
42
|
input: Any
|
|
46
|
-
"""The input to pass to the selected Runnable
|
|
43
|
+
"""The input to pass to the selected `Runnable`."""
|
|
47
44
|
|
|
48
45
|
|
|
49
46
|
class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
50
|
-
"""Runnable that routes to a set of
|
|
47
|
+
"""`Runnable` that routes to a set of `Runnable` based on `Input['key']`.
|
|
51
48
|
|
|
52
49
|
Returns the output of the selected Runnable.
|
|
53
50
|
|
|
54
51
|
Example:
|
|
52
|
+
```python
|
|
53
|
+
from langchain_core.runnables.router import RouterRunnable
|
|
54
|
+
from langchain_core.runnables import RunnableLambda
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
from langchain_core.runnables.router import RouterRunnable
|
|
59
|
-
from langchain_core.runnables import RunnableLambda
|
|
60
|
-
|
|
61
|
-
add = RunnableLambda(func=lambda x: x + 1)
|
|
62
|
-
square = RunnableLambda(func=lambda x: x**2)
|
|
63
|
-
|
|
64
|
-
router = RouterRunnable(runnables={"add": add, "square": square})
|
|
65
|
-
router.invoke({"key": "square", "input": 3})
|
|
56
|
+
add = RunnableLambda(func=lambda x: x + 1)
|
|
57
|
+
square = RunnableLambda(func=lambda x: x**2)
|
|
66
58
|
|
|
59
|
+
router = RouterRunnable(runnables={"add": add, "square": square})
|
|
60
|
+
router.invoke({"key": "square", "input": 3})
|
|
61
|
+
```
|
|
67
62
|
"""
|
|
68
63
|
|
|
69
64
|
runnables: Mapping[str, Runnable[Any, Output]]
|
|
@@ -77,12 +72,12 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
77
72
|
|
|
78
73
|
def __init__(
|
|
79
74
|
self,
|
|
80
|
-
runnables: Mapping[str,
|
|
75
|
+
runnables: Mapping[str, Runnable[Any, Output] | Callable[[Any], Output]],
|
|
81
76
|
) -> None:
|
|
82
|
-
"""Create a RouterRunnable
|
|
77
|
+
"""Create a `RouterRunnable`.
|
|
83
78
|
|
|
84
79
|
Args:
|
|
85
|
-
runnables: A mapping of keys to
|
|
80
|
+
runnables: A mapping of keys to `Runnable` objects.
|
|
86
81
|
"""
|
|
87
82
|
super().__init__(
|
|
88
83
|
runnables={key: coerce_to_runnable(r) for key, r in runnables.items()}
|
|
@@ -95,22 +90,22 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
95
90
|
@classmethod
|
|
96
91
|
@override
|
|
97
92
|
def is_lc_serializable(cls) -> bool:
|
|
98
|
-
"""Return True as this class is serializable."""
|
|
93
|
+
"""Return `True` as this class is serializable."""
|
|
99
94
|
return True
|
|
100
95
|
|
|
101
96
|
@classmethod
|
|
102
97
|
@override
|
|
103
98
|
def get_lc_namespace(cls) -> list[str]:
|
|
104
|
-
"""Get the namespace of the
|
|
99
|
+
"""Get the namespace of the LangChain object.
|
|
105
100
|
|
|
106
101
|
Returns:
|
|
107
|
-
|
|
102
|
+
`["langchain", "schema", "runnable"]`
|
|
108
103
|
"""
|
|
109
104
|
return ["langchain", "schema", "runnable"]
|
|
110
105
|
|
|
111
106
|
@override
|
|
112
107
|
def invoke(
|
|
113
|
-
self, input: RouterInput, config:
|
|
108
|
+
self, input: RouterInput, config: RunnableConfig | None = None, **kwargs: Any
|
|
114
109
|
) -> Output:
|
|
115
110
|
key = input["key"]
|
|
116
111
|
actual_input = input["input"]
|
|
@@ -125,8 +120,8 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
125
120
|
async def ainvoke(
|
|
126
121
|
self,
|
|
127
122
|
input: RouterInput,
|
|
128
|
-
config:
|
|
129
|
-
**kwargs:
|
|
123
|
+
config: RunnableConfig | None = None,
|
|
124
|
+
**kwargs: Any | None,
|
|
130
125
|
) -> Output:
|
|
131
126
|
key = input["key"]
|
|
132
127
|
actual_input = input["input"]
|
|
@@ -141,10 +136,10 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
141
136
|
def batch(
|
|
142
137
|
self,
|
|
143
138
|
inputs: list[RouterInput],
|
|
144
|
-
config:
|
|
139
|
+
config: RunnableConfig | list[RunnableConfig] | None = None,
|
|
145
140
|
*,
|
|
146
141
|
return_exceptions: bool = False,
|
|
147
|
-
**kwargs:
|
|
142
|
+
**kwargs: Any | None,
|
|
148
143
|
) -> list[Output]:
|
|
149
144
|
if not inputs:
|
|
150
145
|
return []
|
|
@@ -157,7 +152,7 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
157
152
|
|
|
158
153
|
def invoke(
|
|
159
154
|
runnable: Runnable, input_: Input, config: RunnableConfig
|
|
160
|
-
) ->
|
|
155
|
+
) -> Output | Exception:
|
|
161
156
|
if return_exceptions:
|
|
162
157
|
try:
|
|
163
158
|
return runnable.invoke(input_, config, **kwargs)
|
|
@@ -178,10 +173,10 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
178
173
|
async def abatch(
|
|
179
174
|
self,
|
|
180
175
|
inputs: list[RouterInput],
|
|
181
|
-
config:
|
|
176
|
+
config: RunnableConfig | list[RunnableConfig] | None = None,
|
|
182
177
|
*,
|
|
183
178
|
return_exceptions: bool = False,
|
|
184
|
-
**kwargs:
|
|
179
|
+
**kwargs: Any | None,
|
|
185
180
|
) -> list[Output]:
|
|
186
181
|
if not inputs:
|
|
187
182
|
return []
|
|
@@ -194,7 +189,7 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
194
189
|
|
|
195
190
|
async def ainvoke(
|
|
196
191
|
runnable: Runnable, input_: Input, config: RunnableConfig
|
|
197
|
-
) ->
|
|
192
|
+
) -> Output | Exception:
|
|
198
193
|
if return_exceptions:
|
|
199
194
|
try:
|
|
200
195
|
return await runnable.ainvoke(input_, config, **kwargs)
|
|
@@ -214,8 +209,8 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
214
209
|
def stream(
|
|
215
210
|
self,
|
|
216
211
|
input: RouterInput,
|
|
217
|
-
config:
|
|
218
|
-
**kwargs:
|
|
212
|
+
config: RunnableConfig | None = None,
|
|
213
|
+
**kwargs: Any | None,
|
|
219
214
|
) -> Iterator[Output]:
|
|
220
215
|
key = input["key"]
|
|
221
216
|
actual_input = input["input"]
|
|
@@ -230,8 +225,8 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
230
225
|
async def astream(
|
|
231
226
|
self,
|
|
232
227
|
input: RouterInput,
|
|
233
|
-
config:
|
|
234
|
-
**kwargs:
|
|
228
|
+
config: RunnableConfig | None = None,
|
|
229
|
+
**kwargs: Any | None,
|
|
235
230
|
) -> AsyncIterator[Output]:
|
|
236
231
|
key = input["key"]
|
|
237
232
|
actual_input = input["input"]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""Module contains typedefs that are used with
|
|
1
|
+
"""Module contains typedefs that are used with `Runnable` objects."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Literal
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
6
6
|
|
|
7
7
|
from typing_extensions import NotRequired, TypedDict
|
|
8
8
|
|
|
@@ -14,127 +14,125 @@ class EventData(TypedDict, total=False):
|
|
|
14
14
|
"""Data associated with a streaming event."""
|
|
15
15
|
|
|
16
16
|
input: Any
|
|
17
|
-
"""The input passed to the Runnable that generated the event.
|
|
17
|
+
"""The input passed to the `Runnable` that generated the event.
|
|
18
18
|
|
|
19
|
-
Inputs will sometimes be available at the *START* of the Runnable
|
|
20
|
-
sometimes at the *END* of the Runnable
|
|
19
|
+
Inputs will sometimes be available at the *START* of the `Runnable`, and
|
|
20
|
+
sometimes at the *END* of the `Runnable`.
|
|
21
21
|
|
|
22
|
-
If a Runnable is able to stream its inputs, then its input by definition
|
|
23
|
-
won't be known until the *END* of the Runnable when it has finished streaming
|
|
22
|
+
If a `Runnable` is able to stream its inputs, then its input by definition
|
|
23
|
+
won't be known until the *END* of the `Runnable` when it has finished streaming
|
|
24
24
|
its inputs.
|
|
25
25
|
"""
|
|
26
26
|
error: NotRequired[BaseException]
|
|
27
|
-
"""The error that occurred during the execution of the Runnable
|
|
27
|
+
"""The error that occurred during the execution of the `Runnable`.
|
|
28
28
|
|
|
29
|
-
This field is only available if the Runnable raised an exception.
|
|
29
|
+
This field is only available if the `Runnable` raised an exception.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
!!! version-added "Added in `langchain-core` 1.0.0"
|
|
32
32
|
"""
|
|
33
33
|
output: Any
|
|
34
|
-
"""The output of the Runnable that generated the event.
|
|
34
|
+
"""The output of the `Runnable` that generated the event.
|
|
35
35
|
|
|
36
|
-
Outputs will only be available at the *END* of the Runnable
|
|
36
|
+
Outputs will only be available at the *END* of the `Runnable`.
|
|
37
37
|
|
|
38
|
-
For most
|
|
39
|
-
though there might be some exceptions for special cased
|
|
38
|
+
For most `Runnable` objects, this field can be inferred from the `chunk` field,
|
|
39
|
+
though there might be some exceptions for special a cased `Runnable` (e.g., like
|
|
40
40
|
chat models), which may return more information.
|
|
41
41
|
"""
|
|
42
42
|
chunk: Any
|
|
43
43
|
"""A streaming chunk from the output that generated the event.
|
|
44
44
|
|
|
45
45
|
chunks support addition in general, and adding them up should result
|
|
46
|
-
in the output of the Runnable that generated the event.
|
|
46
|
+
in the output of the `Runnable` that generated the event.
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class BaseStreamEvent(TypedDict):
|
|
51
51
|
"""Streaming event.
|
|
52
52
|
|
|
53
|
-
Schema of a streaming event which is produced from the astream_events method.
|
|
53
|
+
Schema of a streaming event which is produced from the `astream_events` method.
|
|
54
54
|
|
|
55
55
|
Example:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
56
|
+
```python
|
|
57
|
+
from langchain_core.runnables import RunnableLambda
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def reverse(s: str) -> str:
|
|
61
|
+
return s[::-1]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
chain = RunnableLambda(func=reverse)
|
|
65
|
+
|
|
66
|
+
events = [event async for event in chain.astream_events("hello")]
|
|
67
|
+
|
|
68
|
+
# Will produce the following events
|
|
69
|
+
# (where some fields have been omitted for brevity):
|
|
70
|
+
[
|
|
71
|
+
{
|
|
72
|
+
"data": {"input": "hello"},
|
|
73
|
+
"event": "on_chain_start",
|
|
74
|
+
"metadata": {},
|
|
75
|
+
"name": "reverse",
|
|
76
|
+
"tags": [],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"data": {"chunk": "olleh"},
|
|
80
|
+
"event": "on_chain_stream",
|
|
81
|
+
"metadata": {},
|
|
82
|
+
"name": "reverse",
|
|
83
|
+
"tags": [],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"data": {"output": "olleh"},
|
|
87
|
+
"event": "on_chain_end",
|
|
88
|
+
"metadata": {},
|
|
89
|
+
"name": "reverse",
|
|
90
|
+
"tags": [],
|
|
91
|
+
},
|
|
92
|
+
]
|
|
93
|
+
```
|
|
96
94
|
"""
|
|
97
95
|
|
|
98
96
|
event: str
|
|
99
|
-
"""Event names are of the format: on_[runnable_type]_(start|stream|end)
|
|
97
|
+
"""Event names are of the format: `on_[runnable_type]_(start|stream|end)`.
|
|
100
98
|
|
|
101
99
|
Runnable types are one of:
|
|
102
100
|
|
|
103
101
|
- **llm** - used by non chat models
|
|
104
102
|
- **chat_model** - used by chat models
|
|
105
|
-
- **prompt** -- e.g., ChatPromptTemplate
|
|
106
|
-
- **tool** -- from tools defined via
|
|
107
|
-
from Tool
|
|
108
|
-
- **chain** - most
|
|
103
|
+
- **prompt** -- e.g., `ChatPromptTemplate`
|
|
104
|
+
- **tool** -- from tools defined via `@tool` decorator or inheriting
|
|
105
|
+
from `Tool`/`BaseTool`
|
|
106
|
+
- **chain** - most `Runnable` objects are of this type
|
|
109
107
|
|
|
110
108
|
Further, the events are categorized as one of:
|
|
111
109
|
|
|
112
|
-
- **start** - when the Runnable starts
|
|
113
|
-
- **stream** - when the Runnable is streaming
|
|
114
|
-
- **end* - when the Runnable ends
|
|
110
|
+
- **start** - when the `Runnable` starts
|
|
111
|
+
- **stream** - when the `Runnable` is streaming
|
|
112
|
+
- **end* - when the `Runnable` ends
|
|
115
113
|
|
|
116
114
|
start, stream and end are associated with slightly different `data` payload.
|
|
117
115
|
|
|
118
116
|
Please see the documentation for `EventData` for more details.
|
|
119
117
|
"""
|
|
120
118
|
run_id: str
|
|
121
|
-
"""An randomly generated ID to keep track of the execution of the given Runnable
|
|
119
|
+
"""An randomly generated ID to keep track of the execution of the given `Runnable`.
|
|
122
120
|
|
|
123
|
-
Each child Runnable that gets invoked as part of the execution of a parent
|
|
124
|
-
is assigned its own unique ID.
|
|
121
|
+
Each child `Runnable` that gets invoked as part of the execution of a parent
|
|
122
|
+
`Runnable` is assigned its own unique ID.
|
|
125
123
|
"""
|
|
126
124
|
tags: NotRequired[list[str]]
|
|
127
|
-
"""Tags associated with the Runnable that generated this event.
|
|
125
|
+
"""Tags associated with the `Runnable` that generated this event.
|
|
128
126
|
|
|
129
|
-
Tags are always inherited from parent
|
|
127
|
+
Tags are always inherited from parent `Runnable` objects.
|
|
130
128
|
|
|
131
|
-
Tags can either be bound to a Runnable using `.with_config({"tags": ["hello"]})`
|
|
129
|
+
Tags can either be bound to a `Runnable` using `.with_config({"tags": ["hello"]})`
|
|
132
130
|
or passed at run time using `.astream_events(..., {"tags": ["hello"]})`.
|
|
133
131
|
"""
|
|
134
132
|
metadata: NotRequired[dict[str, Any]]
|
|
135
|
-
"""Metadata associated with the Runnable that generated this event.
|
|
133
|
+
"""Metadata associated with the `Runnable` that generated this event.
|
|
136
134
|
|
|
137
|
-
Metadata can either be bound to a Runnable using
|
|
135
|
+
Metadata can either be bound to a `Runnable` using
|
|
138
136
|
|
|
139
137
|
`.with_config({"metadata": { "foo": "bar" }})`
|
|
140
138
|
|
|
@@ -148,8 +146,8 @@ class BaseStreamEvent(TypedDict):
|
|
|
148
146
|
|
|
149
147
|
Root Events will have an empty list.
|
|
150
148
|
|
|
151
|
-
For example, if a Runnable A calls Runnable B, then the event generated by
|
|
152
|
-
B will have Runnable A's ID in the parent_ids field.
|
|
149
|
+
For example, if a `Runnable` A calls `Runnable` B, then the event generated by
|
|
150
|
+
`Runnable` B will have `Runnable` A's ID in the `parent_ids` field.
|
|
153
151
|
|
|
154
152
|
The order of the parent IDs is from the root parent to the immediate parent.
|
|
155
153
|
|
|
@@ -166,14 +164,11 @@ class StandardStreamEvent(BaseStreamEvent):
|
|
|
166
164
|
The contents of the event data depend on the event type.
|
|
167
165
|
"""
|
|
168
166
|
name: str
|
|
169
|
-
"""The name of the Runnable that generated the event."""
|
|
167
|
+
"""The name of the `Runnable` that generated the event."""
|
|
170
168
|
|
|
171
169
|
|
|
172
170
|
class CustomStreamEvent(BaseStreamEvent):
|
|
173
|
-
"""Custom stream event created by the user.
|
|
174
|
-
|
|
175
|
-
.. versionadded:: 0.2.15
|
|
176
|
-
"""
|
|
171
|
+
"""Custom stream event created by the user."""
|
|
177
172
|
|
|
178
173
|
# Overwrite the event field to be more specific.
|
|
179
174
|
event: Literal["on_custom_event"] # type: ignore[misc]
|
|
@@ -184,4 +179,4 @@ class CustomStreamEvent(BaseStreamEvent):
|
|
|
184
179
|
"""The data associated with the event. Free form and can be anything."""
|
|
185
180
|
|
|
186
181
|
|
|
187
|
-
StreamEvent =
|
|
182
|
+
StreamEvent = StandardStreamEvent | CustomStreamEvent
|