langchain-core 1.0.3__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/agents.py +36 -27
- langchain_core/callbacks/manager.py +18 -1
- langchain_core/callbacks/usage.py +2 -2
- langchain_core/documents/base.py +6 -6
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/indexing/api.py +6 -6
- langchain_core/language_models/_utils.py +1 -1
- langchain_core/language_models/base.py +37 -18
- langchain_core/language_models/chat_models.py +44 -28
- langchain_core/language_models/llms.py +66 -36
- langchain_core/messages/ai.py +3 -3
- langchain_core/messages/base.py +1 -1
- langchain_core/messages/content.py +2 -2
- langchain_core/messages/utils.py +12 -8
- langchain_core/output_parsers/openai_tools.py +14 -2
- langchain_core/outputs/generation.py +6 -5
- langchain_core/prompt_values.py +2 -2
- langchain_core/prompts/base.py +47 -44
- langchain_core/prompts/chat.py +35 -28
- langchain_core/prompts/dict.py +1 -1
- langchain_core/prompts/message.py +4 -4
- langchain_core/runnables/base.py +97 -52
- langchain_core/runnables/branch.py +22 -20
- langchain_core/runnables/configurable.py +30 -29
- langchain_core/runnables/fallbacks.py +22 -20
- langchain_core/runnables/graph_mermaid.py +4 -1
- langchain_core/runnables/graph_png.py +28 -0
- langchain_core/runnables/history.py +43 -32
- langchain_core/runnables/passthrough.py +35 -25
- langchain_core/runnables/router.py +5 -5
- langchain_core/runnables/schema.py +1 -1
- langchain_core/sys_info.py +4 -2
- langchain_core/tools/base.py +22 -16
- langchain_core/utils/function_calling.py +9 -6
- langchain_core/utils/input.py +3 -0
- langchain_core/utils/pydantic.py +2 -2
- langchain_core/version.py +1 -1
- {langchain_core-1.0.3.dist-info → langchain_core-1.0.4.dist-info}/METADATA +1 -1
- {langchain_core-1.0.3.dist-info → langchain_core-1.0.4.dist-info}/RECORD +40 -40
- {langchain_core-1.0.3.dist-info → langchain_core-1.0.4.dist-info}/WHEEL +0 -0
langchain_core/prompts/chat.py
CHANGED
|
@@ -587,14 +587,15 @@ class _StringImageMessagePromptTemplate(BaseMessagePromptTemplate):
|
|
|
587
587
|
for prompt in self.prompt:
|
|
588
588
|
inputs = {var: kwargs[var] for var in prompt.input_variables}
|
|
589
589
|
if isinstance(prompt, StringPromptTemplate):
|
|
590
|
-
|
|
591
|
-
|
|
590
|
+
formatted_text: str = prompt.format(**inputs)
|
|
591
|
+
if formatted_text != "":
|
|
592
|
+
content.append({"type": "text", "text": formatted_text})
|
|
592
593
|
elif isinstance(prompt, ImagePromptTemplate):
|
|
593
|
-
|
|
594
|
-
content.append({"type": "image_url", "image_url":
|
|
594
|
+
formatted_image: ImageURL = prompt.format(**inputs)
|
|
595
|
+
content.append({"type": "image_url", "image_url": formatted_image})
|
|
595
596
|
elif isinstance(prompt, DictPromptTemplate):
|
|
596
|
-
|
|
597
|
-
content.append(
|
|
597
|
+
formatted_dict: dict[str, Any] = prompt.format(**inputs)
|
|
598
|
+
content.append(formatted_dict)
|
|
598
599
|
return self._msg_class(
|
|
599
600
|
content=content, additional_kwargs=self.additional_kwargs
|
|
600
601
|
)
|
|
@@ -617,16 +618,15 @@ class _StringImageMessagePromptTemplate(BaseMessagePromptTemplate):
|
|
|
617
618
|
for prompt in self.prompt:
|
|
618
619
|
inputs = {var: kwargs[var] for var in prompt.input_variables}
|
|
619
620
|
if isinstance(prompt, StringPromptTemplate):
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
content.append({"type": "text", "text": formatted})
|
|
621
|
+
formatted_text: str = await prompt.aformat(**inputs)
|
|
622
|
+
if formatted_text != "":
|
|
623
|
+
content.append({"type": "text", "text": formatted_text})
|
|
624
624
|
elif isinstance(prompt, ImagePromptTemplate):
|
|
625
|
-
|
|
626
|
-
content.append({"type": "image_url", "image_url":
|
|
625
|
+
formatted_image: ImageURL = await prompt.aformat(**inputs)
|
|
626
|
+
content.append({"type": "image_url", "image_url": formatted_image})
|
|
627
627
|
elif isinstance(prompt, DictPromptTemplate):
|
|
628
|
-
|
|
629
|
-
content.append(
|
|
628
|
+
formatted_dict: dict[str, Any] = prompt.format(**inputs)
|
|
629
|
+
content.append(formatted_dict)
|
|
630
630
|
return self._msg_class(
|
|
631
631
|
content=content, additional_kwargs=self.additional_kwargs
|
|
632
632
|
)
|
|
@@ -1343,11 +1343,25 @@ def _create_template_from_message_type(
|
|
|
1343
1343
|
raise ValueError(msg)
|
|
1344
1344
|
var_name = template[1:-1]
|
|
1345
1345
|
message = MessagesPlaceholder(variable_name=var_name, optional=True)
|
|
1346
|
-
|
|
1347
|
-
|
|
1346
|
+
else:
|
|
1347
|
+
try:
|
|
1348
|
+
var_name_wrapped, is_optional = template
|
|
1349
|
+
except ValueError as e:
|
|
1350
|
+
msg = (
|
|
1351
|
+
"Unexpected arguments for placeholder message type."
|
|
1352
|
+
" Expected either a single string variable name"
|
|
1353
|
+
" or a list of [variable_name: str, is_optional: bool]."
|
|
1354
|
+
f" Got: {template}"
|
|
1355
|
+
)
|
|
1356
|
+
raise ValueError(msg) from e
|
|
1357
|
+
|
|
1358
|
+
if not isinstance(is_optional, bool):
|
|
1359
|
+
msg = f"Expected is_optional to be a boolean. Got: {is_optional}"
|
|
1360
|
+
raise ValueError(msg) # noqa: TRY004
|
|
1361
|
+
|
|
1348
1362
|
if not isinstance(var_name_wrapped, str):
|
|
1349
1363
|
msg = f"Expected variable name to be a string. Got: {var_name_wrapped}"
|
|
1350
|
-
raise ValueError(msg) # noqa:TRY004
|
|
1364
|
+
raise ValueError(msg) # noqa: TRY004
|
|
1351
1365
|
if var_name_wrapped[0] != "{" or var_name_wrapped[-1] != "}":
|
|
1352
1366
|
msg = (
|
|
1353
1367
|
f"Invalid placeholder template: {var_name_wrapped}."
|
|
@@ -1357,14 +1371,6 @@ def _create_template_from_message_type(
|
|
|
1357
1371
|
var_name = var_name_wrapped[1:-1]
|
|
1358
1372
|
|
|
1359
1373
|
message = MessagesPlaceholder(variable_name=var_name, optional=is_optional)
|
|
1360
|
-
else:
|
|
1361
|
-
msg = (
|
|
1362
|
-
"Unexpected arguments for placeholder message type."
|
|
1363
|
-
" Expected either a single string variable name"
|
|
1364
|
-
" or a list of [variable_name: str, is_optional: bool]."
|
|
1365
|
-
f" Got: {template}"
|
|
1366
|
-
)
|
|
1367
|
-
raise ValueError(msg)
|
|
1368
1374
|
else:
|
|
1369
1375
|
msg = (
|
|
1370
1376
|
f"Unexpected message type: {message_type}. Use one of 'human',"
|
|
@@ -1418,10 +1424,11 @@ def _convert_to_message_template(
|
|
|
1418
1424
|
)
|
|
1419
1425
|
raise ValueError(msg)
|
|
1420
1426
|
message = (message["role"], message["content"])
|
|
1421
|
-
|
|
1427
|
+
try:
|
|
1428
|
+
message_type_str, template = message
|
|
1429
|
+
except ValueError as e:
|
|
1422
1430
|
msg = f"Expected 2-tuple of (role, template), got {message}"
|
|
1423
|
-
raise ValueError(msg)
|
|
1424
|
-
message_type_str, template = message
|
|
1431
|
+
raise ValueError(msg) from e
|
|
1425
1432
|
if isinstance(message_type_str, str):
|
|
1426
1433
|
message_ = _create_template_from_message_type(
|
|
1427
1434
|
message_type_str, template, template_format=template_format
|
langchain_core/prompts/dict.py
CHANGED
|
@@ -18,7 +18,7 @@ class BaseMessagePromptTemplate(Serializable, ABC):
|
|
|
18
18
|
|
|
19
19
|
@classmethod
|
|
20
20
|
def is_lc_serializable(cls) -> bool:
|
|
21
|
-
"""Return True as this class is serializable."""
|
|
21
|
+
"""Return `True` as this class is serializable."""
|
|
22
22
|
return True
|
|
23
23
|
|
|
24
24
|
@classmethod
|
|
@@ -32,13 +32,13 @@ class BaseMessagePromptTemplate(Serializable, ABC):
|
|
|
32
32
|
|
|
33
33
|
@abstractmethod
|
|
34
34
|
def format_messages(self, **kwargs: Any) -> list[BaseMessage]:
|
|
35
|
-
"""Format messages from kwargs. Should return a list of
|
|
35
|
+
"""Format messages from kwargs. Should return a list of `BaseMessage` objects.
|
|
36
36
|
|
|
37
37
|
Args:
|
|
38
38
|
**kwargs: Keyword arguments to use for formatting.
|
|
39
39
|
|
|
40
40
|
Returns:
|
|
41
|
-
List of
|
|
41
|
+
List of `BaseMessage` objects.
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
44
|
async def aformat_messages(self, **kwargs: Any) -> list[BaseMessage]:
|
|
@@ -48,7 +48,7 @@ class BaseMessagePromptTemplate(Serializable, ABC):
|
|
|
48
48
|
**kwargs: Keyword arguments to use for formatting.
|
|
49
49
|
|
|
50
50
|
Returns:
|
|
51
|
-
List of
|
|
51
|
+
List of `BaseMessage` objects.
|
|
52
52
|
"""
|
|
53
53
|
return self.format_messages(**kwargs)
|
|
54
54
|
|
langchain_core/runnables/base.py
CHANGED
|
@@ -118,6 +118,8 @@ if TYPE_CHECKING:
|
|
|
118
118
|
|
|
119
119
|
Other = TypeVar("Other")
|
|
120
120
|
|
|
121
|
+
_RUNNABLE_GENERIC_NUM_ARGS = 2 # Input and Output
|
|
122
|
+
|
|
121
123
|
|
|
122
124
|
class Runnable(ABC, Generic[Input, Output]):
|
|
123
125
|
"""A unit of work that can be invoked, batched, streamed, transformed and composed.
|
|
@@ -309,7 +311,10 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
309
311
|
for base in self.__class__.mro():
|
|
310
312
|
if hasattr(base, "__pydantic_generic_metadata__"):
|
|
311
313
|
metadata = base.__pydantic_generic_metadata__
|
|
312
|
-
if
|
|
314
|
+
if (
|
|
315
|
+
"args" in metadata
|
|
316
|
+
and len(metadata["args"]) == _RUNNABLE_GENERIC_NUM_ARGS
|
|
317
|
+
):
|
|
313
318
|
return metadata["args"][0]
|
|
314
319
|
|
|
315
320
|
# If we didn't find a Pydantic model in the parent classes,
|
|
@@ -317,7 +322,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
317
322
|
# Runnables that are not pydantic models.
|
|
318
323
|
for cls in self.__class__.__orig_bases__: # type: ignore[attr-defined]
|
|
319
324
|
type_args = get_args(cls)
|
|
320
|
-
if type_args and len(type_args) ==
|
|
325
|
+
if type_args and len(type_args) == _RUNNABLE_GENERIC_NUM_ARGS:
|
|
321
326
|
return type_args[0]
|
|
322
327
|
|
|
323
328
|
msg = (
|
|
@@ -340,12 +345,15 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
340
345
|
for base in self.__class__.mro():
|
|
341
346
|
if hasattr(base, "__pydantic_generic_metadata__"):
|
|
342
347
|
metadata = base.__pydantic_generic_metadata__
|
|
343
|
-
if
|
|
348
|
+
if (
|
|
349
|
+
"args" in metadata
|
|
350
|
+
and len(metadata["args"]) == _RUNNABLE_GENERIC_NUM_ARGS
|
|
351
|
+
):
|
|
344
352
|
return metadata["args"][1]
|
|
345
353
|
|
|
346
354
|
for cls in self.__class__.__orig_bases__: # type: ignore[attr-defined]
|
|
347
355
|
type_args = get_args(cls)
|
|
348
|
-
if type_args and len(type_args) ==
|
|
356
|
+
if type_args and len(type_args) == _RUNNABLE_GENERIC_NUM_ARGS:
|
|
349
357
|
return type_args[1]
|
|
350
358
|
|
|
351
359
|
msg = (
|
|
@@ -424,7 +432,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
424
432
|
print(runnable.get_input_jsonschema())
|
|
425
433
|
```
|
|
426
434
|
|
|
427
|
-
!!! version-added "Added in
|
|
435
|
+
!!! version-added "Added in `langchain-core` 0.3.0"
|
|
428
436
|
|
|
429
437
|
"""
|
|
430
438
|
return self.get_input_schema(config).model_json_schema()
|
|
@@ -502,7 +510,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
502
510
|
print(runnable.get_output_jsonschema())
|
|
503
511
|
```
|
|
504
512
|
|
|
505
|
-
!!! version-added "Added in
|
|
513
|
+
!!! version-added "Added in `langchain-core` 0.3.0"
|
|
506
514
|
|
|
507
515
|
"""
|
|
508
516
|
return self.get_output_schema(config).model_json_schema()
|
|
@@ -566,7 +574,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
566
574
|
Returns:
|
|
567
575
|
A JSON schema that represents the config of the `Runnable`.
|
|
568
576
|
|
|
569
|
-
!!! version-added "Added in
|
|
577
|
+
!!! version-added "Added in `langchain-core` 0.3.0"
|
|
570
578
|
|
|
571
579
|
"""
|
|
572
580
|
return self.config_schema(include=include).model_json_schema()
|
|
@@ -766,7 +774,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
766
774
|
"""Assigns new fields to the `dict` output of this `Runnable`.
|
|
767
775
|
|
|
768
776
|
```python
|
|
769
|
-
from
|
|
777
|
+
from langchain_core.language_models.fake import FakeStreamingListLLM
|
|
770
778
|
from langchain_core.output_parsers import StrOutputParser
|
|
771
779
|
from langchain_core.prompts import SystemMessagePromptTemplate
|
|
772
780
|
from langchain_core.runnables import Runnable
|
|
@@ -818,10 +826,12 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
818
826
|
Args:
|
|
819
827
|
input: The input to the `Runnable`.
|
|
820
828
|
config: A config to use when invoking the `Runnable`.
|
|
829
|
+
|
|
821
830
|
The config supports standard keys like `'tags'`, `'metadata'` for
|
|
822
831
|
tracing purposes, `'max_concurrency'` for controlling how much work to
|
|
823
|
-
do in parallel, and other keys.
|
|
824
|
-
|
|
832
|
+
do in parallel, and other keys.
|
|
833
|
+
|
|
834
|
+
Please refer to `RunnableConfig` for more details.
|
|
825
835
|
|
|
826
836
|
Returns:
|
|
827
837
|
The output of the `Runnable`.
|
|
@@ -838,10 +848,12 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
838
848
|
Args:
|
|
839
849
|
input: The input to the `Runnable`.
|
|
840
850
|
config: A config to use when invoking the `Runnable`.
|
|
851
|
+
|
|
841
852
|
The config supports standard keys like `'tags'`, `'metadata'` for
|
|
842
853
|
tracing purposes, `'max_concurrency'` for controlling how much work to
|
|
843
|
-
do in parallel, and other keys.
|
|
844
|
-
|
|
854
|
+
do in parallel, and other keys.
|
|
855
|
+
|
|
856
|
+
Please refer to `RunnableConfig` for more details.
|
|
845
857
|
|
|
846
858
|
Returns:
|
|
847
859
|
The output of the `Runnable`.
|
|
@@ -868,8 +880,9 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
868
880
|
config: A config to use when invoking the `Runnable`. The config supports
|
|
869
881
|
standard keys like `'tags'`, `'metadata'` for
|
|
870
882
|
tracing purposes, `'max_concurrency'` for controlling how much work
|
|
871
|
-
to do in parallel, and other keys.
|
|
872
|
-
|
|
883
|
+
to do in parallel, and other keys.
|
|
884
|
+
|
|
885
|
+
Please refer to `RunnableConfig` for more details.
|
|
873
886
|
return_exceptions: Whether to return exceptions instead of raising them.
|
|
874
887
|
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
875
888
|
|
|
@@ -932,10 +945,12 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
932
945
|
Args:
|
|
933
946
|
inputs: A list of inputs to the `Runnable`.
|
|
934
947
|
config: A config to use when invoking the `Runnable`.
|
|
948
|
+
|
|
935
949
|
The config supports standard keys like `'tags'`, `'metadata'` for
|
|
936
950
|
tracing purposes, `'max_concurrency'` for controlling how much work to
|
|
937
|
-
do in parallel, and other keys.
|
|
938
|
-
|
|
951
|
+
do in parallel, and other keys.
|
|
952
|
+
|
|
953
|
+
Please refer to `RunnableConfig` for more details.
|
|
939
954
|
return_exceptions: Whether to return exceptions instead of raising them.
|
|
940
955
|
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
941
956
|
|
|
@@ -998,10 +1013,12 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
998
1013
|
Args:
|
|
999
1014
|
inputs: A list of inputs to the `Runnable`.
|
|
1000
1015
|
config: A config to use when invoking the `Runnable`.
|
|
1016
|
+
|
|
1001
1017
|
The config supports standard keys like `'tags'`, `'metadata'` for
|
|
1002
1018
|
tracing purposes, `'max_concurrency'` for controlling how much work to
|
|
1003
|
-
do in parallel, and other keys.
|
|
1004
|
-
|
|
1019
|
+
do in parallel, and other keys.
|
|
1020
|
+
|
|
1021
|
+
Please refer to `RunnableConfig` for more details.
|
|
1005
1022
|
return_exceptions: Whether to return exceptions instead of raising them.
|
|
1006
1023
|
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
1007
1024
|
|
|
@@ -1061,10 +1078,12 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1061
1078
|
Args:
|
|
1062
1079
|
inputs: A list of inputs to the `Runnable`.
|
|
1063
1080
|
config: A config to use when invoking the `Runnable`.
|
|
1081
|
+
|
|
1064
1082
|
The config supports standard keys like `'tags'`, `'metadata'` for
|
|
1065
1083
|
tracing purposes, `'max_concurrency'` for controlling how much work to
|
|
1066
|
-
do in parallel, and other keys.
|
|
1067
|
-
|
|
1084
|
+
do in parallel, and other keys.
|
|
1085
|
+
|
|
1086
|
+
Please refer to `RunnableConfig` for more details.
|
|
1068
1087
|
return_exceptions: Whether to return exceptions instead of raising them.
|
|
1069
1088
|
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
1070
1089
|
|
|
@@ -1742,46 +1761,52 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1742
1761
|
import time
|
|
1743
1762
|
import asyncio
|
|
1744
1763
|
|
|
1764
|
+
|
|
1745
1765
|
def format_t(timestamp: float) -> str:
|
|
1746
1766
|
return datetime.fromtimestamp(timestamp, tz=timezone.utc).isoformat()
|
|
1747
1767
|
|
|
1768
|
+
|
|
1748
1769
|
async def test_runnable(time_to_sleep: int):
|
|
1749
1770
|
print(f"Runnable[{time_to_sleep}s]: starts at {format_t(time.time())}")
|
|
1750
1771
|
await asyncio.sleep(time_to_sleep)
|
|
1751
1772
|
print(f"Runnable[{time_to_sleep}s]: ends at {format_t(time.time())}")
|
|
1752
1773
|
|
|
1774
|
+
|
|
1753
1775
|
async def fn_start(run_obj: Runnable):
|
|
1754
1776
|
print(f"on start callback starts at {format_t(time.time())}")
|
|
1755
1777
|
await asyncio.sleep(3)
|
|
1756
1778
|
print(f"on start callback ends at {format_t(time.time())}")
|
|
1757
1779
|
|
|
1780
|
+
|
|
1758
1781
|
async def fn_end(run_obj: Runnable):
|
|
1759
1782
|
print(f"on end callback starts at {format_t(time.time())}")
|
|
1760
1783
|
await asyncio.sleep(2)
|
|
1761
1784
|
print(f"on end callback ends at {format_t(time.time())}")
|
|
1762
1785
|
|
|
1786
|
+
|
|
1763
1787
|
runnable = RunnableLambda(test_runnable).with_alisteners(
|
|
1764
|
-
on_start=fn_start,
|
|
1765
|
-
on_end=fn_end
|
|
1788
|
+
on_start=fn_start, on_end=fn_end
|
|
1766
1789
|
)
|
|
1790
|
+
|
|
1791
|
+
|
|
1767
1792
|
async def concurrent_runs():
|
|
1768
1793
|
await asyncio.gather(runnable.ainvoke(2), runnable.ainvoke(3))
|
|
1769
1794
|
|
|
1770
|
-
asyncio.run(concurrent_runs())
|
|
1771
|
-
Result:
|
|
1772
|
-
on start callback starts at 2025-03-01T07:05:22.875378+00:00
|
|
1773
|
-
on start callback starts at 2025-03-01T07:05:22.875495+00:00
|
|
1774
|
-
on start callback ends at 2025-03-01T07:05:25.878862+00:00
|
|
1775
|
-
on start callback ends at 2025-03-01T07:05:25.878947+00:00
|
|
1776
|
-
Runnable[2s]: starts at 2025-03-01T07:05:25.879392+00:00
|
|
1777
|
-
Runnable[3s]: starts at 2025-03-01T07:05:25.879804+00:00
|
|
1778
|
-
Runnable[2s]: ends at 2025-03-01T07:05:27.881998+00:00
|
|
1779
|
-
on end callback starts at 2025-03-01T07:05:27.882360+00:00
|
|
1780
|
-
Runnable[3s]: ends at 2025-03-01T07:05:28.881737+00:00
|
|
1781
|
-
on end callback starts at 2025-03-01T07:05:28.882428+00:00
|
|
1782
|
-
on end callback ends at 2025-03-01T07:05:29.883893+00:00
|
|
1783
|
-
on end callback ends at 2025-03-01T07:05:30.884831+00:00
|
|
1784
1795
|
|
|
1796
|
+
asyncio.run(concurrent_runs())
|
|
1797
|
+
# Result:
|
|
1798
|
+
# on start callback starts at 2025-03-01T07:05:22.875378+00:00
|
|
1799
|
+
# on start callback starts at 2025-03-01T07:05:22.875495+00:00
|
|
1800
|
+
# on start callback ends at 2025-03-01T07:05:25.878862+00:00
|
|
1801
|
+
# on start callback ends at 2025-03-01T07:05:25.878947+00:00
|
|
1802
|
+
# Runnable[2s]: starts at 2025-03-01T07:05:25.879392+00:00
|
|
1803
|
+
# Runnable[3s]: starts at 2025-03-01T07:05:25.879804+00:00
|
|
1804
|
+
# Runnable[2s]: ends at 2025-03-01T07:05:27.881998+00:00
|
|
1805
|
+
# on end callback starts at 2025-03-01T07:05:27.882360+00:00
|
|
1806
|
+
# Runnable[3s]: ends at 2025-03-01T07:05:28.881737+00:00
|
|
1807
|
+
# on end callback starts at 2025-03-01T07:05:28.882428+00:00
|
|
1808
|
+
# on end callback ends at 2025-03-01T07:05:29.883893+00:00
|
|
1809
|
+
# on end callback ends at 2025-03-01T07:05:30.884831+00:00
|
|
1785
1810
|
```
|
|
1786
1811
|
"""
|
|
1787
1812
|
return RunnableBinding(
|
|
@@ -1843,7 +1868,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1843
1868
|
`exp_base`, and `jitter` (all `float` values).
|
|
1844
1869
|
|
|
1845
1870
|
Returns:
|
|
1846
|
-
A new Runnable that retries the original Runnable on exceptions.
|
|
1871
|
+
A new `Runnable` that retries the original `Runnable` on exceptions.
|
|
1847
1872
|
|
|
1848
1873
|
Example:
|
|
1849
1874
|
```python
|
|
@@ -1927,7 +1952,9 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1927
1952
|
exceptions_to_handle: A tuple of exception types to handle.
|
|
1928
1953
|
exception_key: If `string` is specified then handled exceptions will be
|
|
1929
1954
|
passed to fallbacks as part of the input under the specified key.
|
|
1955
|
+
|
|
1930
1956
|
If `None`, exceptions will not be passed to fallbacks.
|
|
1957
|
+
|
|
1931
1958
|
If used, the base `Runnable` and its fallbacks must accept a
|
|
1932
1959
|
dictionary as input.
|
|
1933
1960
|
|
|
@@ -1963,7 +1990,9 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1963
1990
|
exceptions_to_handle: A tuple of exception types to handle.
|
|
1964
1991
|
exception_key: If `string` is specified then handled exceptions will be
|
|
1965
1992
|
passed to fallbacks as part of the input under the specified key.
|
|
1993
|
+
|
|
1966
1994
|
If `None`, exceptions will not be passed to fallbacks.
|
|
1995
|
+
|
|
1967
1996
|
If used, the base `Runnable` and its fallbacks must accept a
|
|
1968
1997
|
dictionary as input.
|
|
1969
1998
|
|
|
@@ -2429,10 +2458,14 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
2429
2458
|
|
|
2430
2459
|
`as_tool` will instantiate a `BaseTool` with a name, description, and
|
|
2431
2460
|
`args_schema` from a `Runnable`. Where possible, schemas are inferred
|
|
2432
|
-
from `runnable.get_input_schema`.
|
|
2433
|
-
|
|
2434
|
-
the
|
|
2435
|
-
|
|
2461
|
+
from `runnable.get_input_schema`.
|
|
2462
|
+
|
|
2463
|
+
Alternatively (e.g., if the `Runnable` takes a dict as input and the specific
|
|
2464
|
+
`dict` keys are not typed), the schema can be specified directly with
|
|
2465
|
+
`args_schema`.
|
|
2466
|
+
|
|
2467
|
+
You can also pass `arg_types` to just specify the required arguments and their
|
|
2468
|
+
types.
|
|
2436
2469
|
|
|
2437
2470
|
Args:
|
|
2438
2471
|
args_schema: The schema for the tool.
|
|
@@ -2501,7 +2534,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
2501
2534
|
as_tool.invoke({"a": 3, "b": [1, 2]})
|
|
2502
2535
|
```
|
|
2503
2536
|
|
|
2504
|
-
|
|
2537
|
+
`str` input:
|
|
2505
2538
|
|
|
2506
2539
|
```python
|
|
2507
2540
|
from langchain_core.runnables import RunnableLambda
|
|
@@ -2750,6 +2783,9 @@ def _seq_output_schema(
|
|
|
2750
2783
|
return last.get_output_schema(config)
|
|
2751
2784
|
|
|
2752
2785
|
|
|
2786
|
+
_RUNNABLE_SEQUENCE_MIN_STEPS = 2
|
|
2787
|
+
|
|
2788
|
+
|
|
2753
2789
|
class RunnableSequence(RunnableSerializable[Input, Output]):
|
|
2754
2790
|
"""Sequence of `Runnable` objects, where the output of one is the input of the next.
|
|
2755
2791
|
|
|
@@ -2859,7 +2895,7 @@ class RunnableSequence(RunnableSerializable[Input, Output]):
|
|
|
2859
2895
|
name: The name of the `Runnable`.
|
|
2860
2896
|
first: The first `Runnable` in the sequence.
|
|
2861
2897
|
middle: The middle `Runnable` objects in the sequence.
|
|
2862
|
-
last: The last Runnable in the sequence.
|
|
2898
|
+
last: The last `Runnable` in the sequence.
|
|
2863
2899
|
|
|
2864
2900
|
Raises:
|
|
2865
2901
|
ValueError: If the sequence has less than 2 steps.
|
|
@@ -2872,8 +2908,11 @@ class RunnableSequence(RunnableSerializable[Input, Output]):
|
|
|
2872
2908
|
steps_flat.extend(step.steps)
|
|
2873
2909
|
else:
|
|
2874
2910
|
steps_flat.append(coerce_to_runnable(step))
|
|
2875
|
-
if len(steps_flat) <
|
|
2876
|
-
msg =
|
|
2911
|
+
if len(steps_flat) < _RUNNABLE_SEQUENCE_MIN_STEPS:
|
|
2912
|
+
msg = (
|
|
2913
|
+
f"RunnableSequence must have at least {_RUNNABLE_SEQUENCE_MIN_STEPS} "
|
|
2914
|
+
f"steps, got {len(steps_flat)}"
|
|
2915
|
+
)
|
|
2877
2916
|
raise ValueError(msg)
|
|
2878
2917
|
super().__init__(
|
|
2879
2918
|
first=steps_flat[0],
|
|
@@ -2904,7 +2943,7 @@ class RunnableSequence(RunnableSerializable[Input, Output]):
|
|
|
2904
2943
|
@classmethod
|
|
2905
2944
|
@override
|
|
2906
2945
|
def is_lc_serializable(cls) -> bool:
|
|
2907
|
-
"""Return True as this class is serializable."""
|
|
2946
|
+
"""Return `True` as this class is serializable."""
|
|
2908
2947
|
return True
|
|
2909
2948
|
|
|
2910
2949
|
model_config = ConfigDict(
|
|
@@ -3610,7 +3649,7 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]):
|
|
|
3610
3649
|
@classmethod
|
|
3611
3650
|
@override
|
|
3612
3651
|
def is_lc_serializable(cls) -> bool:
|
|
3613
|
-
"""Return True as this class is serializable."""
|
|
3652
|
+
"""Return `True` as this class is serializable."""
|
|
3614
3653
|
return True
|
|
3615
3654
|
|
|
3616
3655
|
@classmethod
|
|
@@ -3668,6 +3707,12 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]):
|
|
|
3668
3707
|
== "object"
|
|
3669
3708
|
for s in self.steps__.values()
|
|
3670
3709
|
):
|
|
3710
|
+
for step in self.steps__.values():
|
|
3711
|
+
fields = step.get_input_schema(config).model_fields
|
|
3712
|
+
root_field = fields.get("root")
|
|
3713
|
+
if root_field is not None and root_field.annotation != Any:
|
|
3714
|
+
return super().get_input_schema(config)
|
|
3715
|
+
|
|
3671
3716
|
# This is correct, but pydantic typings/mypy don't think so.
|
|
3672
3717
|
return create_model_v2(
|
|
3673
3718
|
self.get_name("Input"),
|
|
@@ -4477,7 +4522,7 @@ class RunnableLambda(Runnable[Input, Output]):
|
|
|
4477
4522
|
# on itemgetter objects, so we have to parse the repr
|
|
4478
4523
|
items = str(func).replace("operator.itemgetter(", "")[:-1].split(", ")
|
|
4479
4524
|
if all(
|
|
4480
|
-
item[0] == "'" and item[-1] == "'" and
|
|
4525
|
+
item[0] == "'" and item[-1] == "'" and item != "''" for item in items
|
|
4481
4526
|
):
|
|
4482
4527
|
fields = {item[1:-1]: (Any, ...) for item in items}
|
|
4483
4528
|
# It's a dict, lol
|
|
@@ -5139,7 +5184,7 @@ class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]):
|
|
|
5139
5184
|
@classmethod
|
|
5140
5185
|
@override
|
|
5141
5186
|
def is_lc_serializable(cls) -> bool:
|
|
5142
|
-
"""Return True as this class is serializable."""
|
|
5187
|
+
"""Return `True` as this class is serializable."""
|
|
5143
5188
|
return True
|
|
5144
5189
|
|
|
5145
5190
|
@classmethod
|
|
@@ -5322,7 +5367,7 @@ class RunnableEach(RunnableEachBase[Input, Output]):
|
|
|
5322
5367
|
|
|
5323
5368
|
|
|
5324
5369
|
class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[no-redef]
|
|
5325
|
-
"""`Runnable` that delegates calls to another `Runnable` with a set of kwargs
|
|
5370
|
+
"""`Runnable` that delegates calls to another `Runnable` with a set of `**kwargs`.
|
|
5326
5371
|
|
|
5327
5372
|
Use only if creating a new `RunnableBinding` subclass with different `__init__`
|
|
5328
5373
|
args.
|
|
@@ -5462,7 +5507,7 @@ class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[
|
|
|
5462
5507
|
@classmethod
|
|
5463
5508
|
@override
|
|
5464
5509
|
def is_lc_serializable(cls) -> bool:
|
|
5465
|
-
"""Return True as this class is serializable."""
|
|
5510
|
+
"""Return `True` as this class is serializable."""
|
|
5466
5511
|
return True
|
|
5467
5512
|
|
|
5468
5513
|
@classmethod
|
|
@@ -5752,7 +5797,7 @@ class RunnableBinding(RunnableBindingBase[Input, Output]): # type: ignore[no-re
|
|
|
5752
5797
|
```python
|
|
5753
5798
|
# Create a Runnable binding that invokes the chat model with the
|
|
5754
5799
|
# additional kwarg `stop=['-']` when running it.
|
|
5755
|
-
from
|
|
5800
|
+
from langchain_openai import ChatOpenAI
|
|
5756
5801
|
|
|
5757
5802
|
model = ChatOpenAI()
|
|
5758
5803
|
model.invoke('Say "Parrot-MAGIC"', stop=["-"]) # Should return `Parrot`
|
|
@@ -36,11 +36,13 @@ from langchain_core.runnables.utils import (
|
|
|
36
36
|
get_unique_config_specs,
|
|
37
37
|
)
|
|
38
38
|
|
|
39
|
+
_MIN_BRANCHES = 2
|
|
40
|
+
|
|
39
41
|
|
|
40
42
|
class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
41
|
-
"""Runnable that selects which branch to run based on a condition.
|
|
43
|
+
"""`Runnable` that selects which branch to run based on a condition.
|
|
42
44
|
|
|
43
|
-
The Runnable is initialized with a list of `(condition, Runnable)` pairs and
|
|
45
|
+
The `Runnable` is initialized with a list of `(condition, Runnable)` pairs and
|
|
44
46
|
a default branch.
|
|
45
47
|
|
|
46
48
|
When operating on an input, the first condition that evaluates to True is
|
|
@@ -86,12 +88,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
86
88
|
Defaults a `Runnable` to run if no condition is met.
|
|
87
89
|
|
|
88
90
|
Raises:
|
|
89
|
-
ValueError: If the number of branches is less than 2
|
|
91
|
+
ValueError: If the number of branches is less than `2`.
|
|
90
92
|
TypeError: If the default branch is not `Runnable`, `Callable` or `Mapping`.
|
|
91
|
-
TypeError: If a branch is not a tuple or list
|
|
92
|
-
ValueError: If a branch is not of length 2
|
|
93
|
+
TypeError: If a branch is not a `tuple` or `list`.
|
|
94
|
+
ValueError: If a branch is not of length `2`.
|
|
93
95
|
"""
|
|
94
|
-
if len(branches) <
|
|
96
|
+
if len(branches) < _MIN_BRANCHES:
|
|
95
97
|
msg = "RunnableBranch requires at least two branches"
|
|
96
98
|
raise ValueError(msg)
|
|
97
99
|
|
|
@@ -118,7 +120,7 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
118
120
|
)
|
|
119
121
|
raise TypeError(msg)
|
|
120
122
|
|
|
121
|
-
if len(branch) !=
|
|
123
|
+
if len(branch) != _MIN_BRANCHES:
|
|
122
124
|
msg = (
|
|
123
125
|
f"RunnableBranch branches must be "
|
|
124
126
|
f"tuples or lists of length 2, not {len(branch)}"
|
|
@@ -140,7 +142,7 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
140
142
|
|
|
141
143
|
@classmethod
|
|
142
144
|
def is_lc_serializable(cls) -> bool:
|
|
143
|
-
"""Return True as this class is serializable."""
|
|
145
|
+
"""Return `True` as this class is serializable."""
|
|
144
146
|
return True
|
|
145
147
|
|
|
146
148
|
@classmethod
|
|
@@ -187,12 +189,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
187
189
|
def invoke(
|
|
188
190
|
self, input: Input, config: RunnableConfig | None = None, **kwargs: Any
|
|
189
191
|
) -> Output:
|
|
190
|
-
"""First evaluates the condition, then delegate to
|
|
192
|
+
"""First evaluates the condition, then delegate to `True` or `False` branch.
|
|
191
193
|
|
|
192
194
|
Args:
|
|
193
|
-
input: The input to the Runnable
|
|
194
|
-
config: The configuration for the Runnable
|
|
195
|
-
**kwargs: Additional keyword arguments to pass to the Runnable
|
|
195
|
+
input: The input to the `Runnable`.
|
|
196
|
+
config: The configuration for the `Runnable`.
|
|
197
|
+
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
196
198
|
|
|
197
199
|
Returns:
|
|
198
200
|
The output of the branch that was run.
|
|
@@ -297,12 +299,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
297
299
|
config: RunnableConfig | None = None,
|
|
298
300
|
**kwargs: Any | None,
|
|
299
301
|
) -> Iterator[Output]:
|
|
300
|
-
"""First evaluates the condition, then delegate to
|
|
302
|
+
"""First evaluates the condition, then delegate to `True` or `False` branch.
|
|
301
303
|
|
|
302
304
|
Args:
|
|
303
|
-
input: The input to the Runnable
|
|
304
|
-
config: The configuration for the
|
|
305
|
-
**kwargs: Additional keyword arguments to pass to the Runnable
|
|
305
|
+
input: The input to the `Runnable`.
|
|
306
|
+
config: The configuration for the Runna`ble.
|
|
307
|
+
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
306
308
|
|
|
307
309
|
Yields:
|
|
308
310
|
The output of the branch that was run.
|
|
@@ -381,12 +383,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
381
383
|
config: RunnableConfig | None = None,
|
|
382
384
|
**kwargs: Any | None,
|
|
383
385
|
) -> AsyncIterator[Output]:
|
|
384
|
-
"""First evaluates the condition, then delegate to
|
|
386
|
+
"""First evaluates the condition, then delegate to `True` or `False` branch.
|
|
385
387
|
|
|
386
388
|
Args:
|
|
387
|
-
input: The input to the Runnable
|
|
388
|
-
config: The configuration for the Runnable
|
|
389
|
-
**kwargs: Additional keyword arguments to pass to the Runnable
|
|
389
|
+
input: The input to the `Runnable`.
|
|
390
|
+
config: The configuration for the `Runnable`.
|
|
391
|
+
**kwargs: Additional keyword arguments to pass to the `Runnable`.
|
|
390
392
|
|
|
391
393
|
Yields:
|
|
392
394
|
The output of the branch that was run.
|