langchain-core 0.3.75__py3-none-any.whl → 0.3.77__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/_api/beta_decorator.py +22 -44
- langchain_core/_api/deprecation.py +30 -17
- langchain_core/_api/path.py +19 -2
- langchain_core/_import_utils.py +7 -0
- langchain_core/agents.py +10 -6
- langchain_core/beta/runnables/context.py +1 -2
- langchain_core/callbacks/base.py +28 -15
- langchain_core/callbacks/manager.py +83 -71
- langchain_core/callbacks/usage.py +6 -4
- langchain_core/chat_history.py +29 -21
- langchain_core/document_loaders/base.py +34 -9
- langchain_core/document_loaders/langsmith.py +4 -1
- langchain_core/documents/base.py +35 -10
- langchain_core/documents/transformers.py +4 -2
- langchain_core/embeddings/fake.py +8 -5
- langchain_core/env.py +2 -3
- langchain_core/example_selectors/base.py +12 -0
- langchain_core/exceptions.py +7 -0
- langchain_core/globals.py +17 -28
- langchain_core/indexing/api.py +88 -76
- langchain_core/indexing/base.py +5 -8
- langchain_core/indexing/in_memory.py +23 -3
- langchain_core/language_models/__init__.py +3 -2
- langchain_core/language_models/base.py +31 -20
- langchain_core/language_models/chat_models.py +98 -27
- langchain_core/language_models/fake_chat_models.py +10 -9
- langchain_core/language_models/llms.py +52 -18
- langchain_core/load/dump.py +2 -3
- langchain_core/load/load.py +15 -1
- langchain_core/load/serializable.py +39 -44
- langchain_core/memory.py +7 -3
- langchain_core/messages/ai.py +53 -24
- langchain_core/messages/base.py +43 -22
- langchain_core/messages/chat.py +4 -1
- langchain_core/messages/content_blocks.py +23 -2
- langchain_core/messages/function.py +9 -5
- langchain_core/messages/human.py +13 -10
- langchain_core/messages/modifier.py +1 -0
- langchain_core/messages/system.py +11 -8
- langchain_core/messages/tool.py +60 -29
- langchain_core/messages/utils.py +250 -131
- langchain_core/output_parsers/base.py +5 -2
- langchain_core/output_parsers/json.py +4 -4
- langchain_core/output_parsers/list.py +7 -22
- langchain_core/output_parsers/openai_functions.py +3 -0
- langchain_core/output_parsers/openai_tools.py +6 -1
- langchain_core/output_parsers/pydantic.py +4 -0
- langchain_core/output_parsers/string.py +5 -1
- langchain_core/output_parsers/xml.py +19 -19
- langchain_core/outputs/chat_generation.py +25 -10
- langchain_core/outputs/generation.py +14 -3
- langchain_core/outputs/llm_result.py +8 -1
- langchain_core/prompt_values.py +16 -6
- langchain_core/prompts/base.py +4 -9
- langchain_core/prompts/chat.py +89 -57
- langchain_core/prompts/dict.py +16 -8
- langchain_core/prompts/few_shot.py +12 -11
- langchain_core/prompts/few_shot_with_templates.py +5 -1
- langchain_core/prompts/image.py +12 -5
- langchain_core/prompts/message.py +5 -6
- langchain_core/prompts/pipeline.py +13 -8
- langchain_core/prompts/prompt.py +22 -8
- langchain_core/prompts/string.py +18 -10
- langchain_core/prompts/structured.py +7 -2
- langchain_core/rate_limiters.py +2 -2
- langchain_core/retrievers.py +7 -6
- langchain_core/runnables/base.py +406 -186
- langchain_core/runnables/branch.py +14 -19
- langchain_core/runnables/config.py +9 -15
- langchain_core/runnables/configurable.py +34 -19
- langchain_core/runnables/fallbacks.py +20 -13
- langchain_core/runnables/graph.py +48 -38
- langchain_core/runnables/graph_ascii.py +41 -18
- langchain_core/runnables/graph_mermaid.py +54 -25
- langchain_core/runnables/graph_png.py +27 -31
- langchain_core/runnables/history.py +55 -58
- langchain_core/runnables/passthrough.py +44 -21
- langchain_core/runnables/retry.py +44 -23
- langchain_core/runnables/router.py +9 -8
- langchain_core/runnables/schema.py +2 -0
- langchain_core/runnables/utils.py +51 -89
- langchain_core/stores.py +19 -31
- langchain_core/sys_info.py +9 -8
- langchain_core/tools/base.py +37 -28
- langchain_core/tools/convert.py +26 -15
- langchain_core/tools/simple.py +36 -8
- langchain_core/tools/structured.py +25 -12
- langchain_core/tracers/base.py +2 -2
- langchain_core/tracers/context.py +5 -1
- langchain_core/tracers/core.py +109 -39
- langchain_core/tracers/evaluation.py +22 -26
- langchain_core/tracers/event_stream.py +45 -34
- langchain_core/tracers/langchain.py +12 -3
- langchain_core/tracers/langchain_v1.py +10 -2
- langchain_core/tracers/log_stream.py +56 -17
- langchain_core/tracers/root_listeners.py +4 -20
- langchain_core/tracers/run_collector.py +6 -16
- langchain_core/tracers/schemas.py +5 -1
- langchain_core/utils/aiter.py +15 -7
- langchain_core/utils/env.py +3 -0
- langchain_core/utils/function_calling.py +50 -28
- langchain_core/utils/interactive_env.py +6 -2
- langchain_core/utils/iter.py +12 -4
- langchain_core/utils/json.py +12 -3
- langchain_core/utils/json_schema.py +156 -40
- langchain_core/utils/loading.py +5 -1
- langchain_core/utils/mustache.py +24 -15
- langchain_core/utils/pydantic.py +38 -9
- langchain_core/utils/utils.py +25 -9
- langchain_core/vectorstores/base.py +7 -20
- langchain_core/vectorstores/in_memory.py +23 -17
- langchain_core/vectorstores/utils.py +18 -12
- langchain_core/version.py +1 -1
- langchain_core-0.3.77.dist-info/METADATA +67 -0
- langchain_core-0.3.77.dist-info/RECORD +174 -0
- langchain_core-0.3.75.dist-info/METADATA +0 -106
- langchain_core-0.3.75.dist-info/RECORD +0 -174
- {langchain_core-0.3.75.dist-info → langchain_core-0.3.77.dist-info}/WHEEL +0 -0
- {langchain_core-0.3.75.dist-info → langchain_core-0.3.77.dist-info}/entry_points.txt +0 -0
langchain_core/stores.py
CHANGED
|
@@ -16,6 +16,8 @@ from typing import (
|
|
|
16
16
|
Union,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
+
from typing_extensions import override
|
|
20
|
+
|
|
19
21
|
from langchain_core.exceptions import LangChainException
|
|
20
22
|
from langchain_core.runnables import run_in_executor
|
|
21
23
|
|
|
@@ -52,24 +54,24 @@ class BaseStore(ABC, Generic[K, V]):
|
|
|
52
54
|
|
|
53
55
|
from langchain.storage import BaseStore
|
|
54
56
|
|
|
55
|
-
class MyInMemoryStore(BaseStore[str, int]):
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
class MyInMemoryStore(BaseStore[str, int]):
|
|
59
|
+
def __init__(self) -> None:
|
|
60
|
+
self.store: dict[str, int] = {}
|
|
59
61
|
|
|
60
|
-
def mget(self, keys):
|
|
62
|
+
def mget(self, keys: Sequence[str]) -> list[int | None]:
|
|
61
63
|
return [self.store.get(key) for key in keys]
|
|
62
64
|
|
|
63
|
-
def mset(self, key_value_pairs):
|
|
65
|
+
def mset(self, key_value_pairs: Sequence[tuple[str, int]]) -> None:
|
|
64
66
|
for key, value in key_value_pairs:
|
|
65
67
|
self.store[key] = value
|
|
66
68
|
|
|
67
|
-
def mdelete(self, keys):
|
|
69
|
+
def mdelete(self, keys: Sequence[str]) -> None:
|
|
68
70
|
for key in keys:
|
|
69
71
|
if key in self.store:
|
|
70
72
|
del self.store[key]
|
|
71
73
|
|
|
72
|
-
def yield_keys(self, prefix=None):
|
|
74
|
+
def yield_keys(self, prefix: str | None = None) -> Iterator[str]:
|
|
73
75
|
if prefix is None:
|
|
74
76
|
yield from self.store.keys()
|
|
75
77
|
else:
|
|
@@ -206,27 +208,13 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
|
|
|
206
208
|
"""
|
|
207
209
|
return self.mget(keys)
|
|
208
210
|
|
|
211
|
+
@override
|
|
209
212
|
def mset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None:
|
|
210
|
-
"""Set the values for the given keys.
|
|
211
|
-
|
|
212
|
-
Args:
|
|
213
|
-
key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs.
|
|
214
|
-
|
|
215
|
-
Returns:
|
|
216
|
-
None
|
|
217
|
-
"""
|
|
218
213
|
for key, value in key_value_pairs:
|
|
219
214
|
self.store[key] = value
|
|
220
215
|
|
|
216
|
+
@override
|
|
221
217
|
async def amset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None:
|
|
222
|
-
"""Async set the values for the given keys.
|
|
223
|
-
|
|
224
|
-
Args:
|
|
225
|
-
key_value_pairs (Sequence[tuple[str, V]]): A sequence of key-value pairs.
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
None
|
|
229
|
-
"""
|
|
230
218
|
return self.mset(key_value_pairs)
|
|
231
219
|
|
|
232
220
|
def mdelete(self, keys: Sequence[str]) -> None:
|
|
@@ -295,13 +283,13 @@ class InMemoryStore(InMemoryBaseStore[Any]):
|
|
|
295
283
|
from langchain.storage import InMemoryStore
|
|
296
284
|
|
|
297
285
|
store = InMemoryStore()
|
|
298
|
-
store.mset([(
|
|
299
|
-
store.mget([
|
|
286
|
+
store.mset([("key1", "value1"), ("key2", "value2")])
|
|
287
|
+
store.mget(["key1", "key2"])
|
|
300
288
|
# ['value1', 'value2']
|
|
301
|
-
store.mdelete([
|
|
289
|
+
store.mdelete(["key1"])
|
|
302
290
|
list(store.yield_keys())
|
|
303
291
|
# ['key2']
|
|
304
|
-
list(store.yield_keys(prefix=
|
|
292
|
+
list(store.yield_keys(prefix="k"))
|
|
305
293
|
# ['key2']
|
|
306
294
|
|
|
307
295
|
"""
|
|
@@ -321,13 +309,13 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]):
|
|
|
321
309
|
from langchain.storage import InMemoryByteStore
|
|
322
310
|
|
|
323
311
|
store = InMemoryByteStore()
|
|
324
|
-
store.mset([(
|
|
325
|
-
store.mget([
|
|
312
|
+
store.mset([("key1", b"value1"), ("key2", b"value2")])
|
|
313
|
+
store.mget(["key1", "key2"])
|
|
326
314
|
# [b'value1', b'value2']
|
|
327
|
-
store.mdelete([
|
|
315
|
+
store.mdelete(["key1"])
|
|
328
316
|
list(store.yield_keys())
|
|
329
317
|
# ['key2']
|
|
330
|
-
list(store.yield_keys(prefix=
|
|
318
|
+
list(store.yield_keys(prefix="k"))
|
|
331
319
|
# ['key2']
|
|
332
320
|
|
|
333
321
|
"""
|
langchain_core/sys_info.py
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
"""**sys_info**
|
|
1
|
+
"""**sys_info** implementation.
|
|
2
2
|
|
|
3
|
+
sys_info prints information about the system and langchain packages for
|
|
4
|
+
debugging purposes.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pkgutil
|
|
8
|
+
import platform
|
|
9
|
+
import sys
|
|
3
10
|
from collections.abc import Sequence
|
|
11
|
+
from importlib import metadata, util
|
|
4
12
|
|
|
5
13
|
|
|
6
14
|
def _get_sub_deps(packages: Sequence[str]) -> list[str]:
|
|
7
15
|
"""Get any specified sub-dependencies."""
|
|
8
|
-
from importlib import metadata
|
|
9
|
-
|
|
10
16
|
sub_deps = set()
|
|
11
17
|
underscored_packages = {pkg.replace("-", "_") for pkg in packages}
|
|
12
18
|
|
|
@@ -33,11 +39,6 @@ def print_sys_info(*, additional_pkgs: Sequence[str] = ()) -> None:
|
|
|
33
39
|
Args:
|
|
34
40
|
additional_pkgs: Additional packages to include in the output.
|
|
35
41
|
"""
|
|
36
|
-
import pkgutil
|
|
37
|
-
import platform
|
|
38
|
-
import sys
|
|
39
|
-
from importlib import metadata, util
|
|
40
|
-
|
|
41
42
|
# Packages that do not start with "langchain" prefix.
|
|
42
43
|
other_langchain_packages = [
|
|
43
44
|
"langserve",
|
langchain_core/tools/base.py
CHANGED
|
@@ -81,6 +81,8 @@ TOOL_MESSAGE_BLOCK_TYPES = (
|
|
|
81
81
|
"json",
|
|
82
82
|
"search_result",
|
|
83
83
|
"custom_tool_call_output",
|
|
84
|
+
"document",
|
|
85
|
+
"file",
|
|
84
86
|
)
|
|
85
87
|
|
|
86
88
|
|
|
@@ -271,15 +273,12 @@ def _function_annotations_are_pydantic_v1(
|
|
|
271
273
|
|
|
272
274
|
|
|
273
275
|
class _SchemaConfig:
|
|
274
|
-
"""Configuration for Pydantic models generated from function signatures.
|
|
275
|
-
|
|
276
|
-
Attributes:
|
|
277
|
-
extra: Whether to allow extra fields in the model.
|
|
278
|
-
arbitrary_types_allowed: Whether to allow arbitrary types in the model.
|
|
279
|
-
"""
|
|
276
|
+
"""Configuration for Pydantic models generated from function signatures."""
|
|
280
277
|
|
|
281
278
|
extra: str = "forbid"
|
|
279
|
+
"""Whether to allow extra fields in the model."""
|
|
282
280
|
arbitrary_types_allowed: bool = True
|
|
281
|
+
"""Whether to allow arbitrary types in the model."""
|
|
283
282
|
|
|
284
283
|
|
|
285
284
|
def create_schema_from_function(
|
|
@@ -506,7 +505,12 @@ class ChildTool(BaseTool):
|
|
|
506
505
|
"""
|
|
507
506
|
|
|
508
507
|
def __init__(self, **kwargs: Any) -> None:
|
|
509
|
-
"""Initialize the tool.
|
|
508
|
+
"""Initialize the tool.
|
|
509
|
+
|
|
510
|
+
Raises:
|
|
511
|
+
TypeError: If ``args_schema`` is not a subclass of pydantic ``BaseModel`` or
|
|
512
|
+
dict.
|
|
513
|
+
"""
|
|
510
514
|
if (
|
|
511
515
|
"args_schema" in kwargs
|
|
512
516
|
and kwargs["args_schema"] is not None
|
|
@@ -543,6 +547,8 @@ class ChildTool(BaseTool):
|
|
|
543
547
|
"""
|
|
544
548
|
if isinstance(self.args_schema, dict):
|
|
545
549
|
json_schema = self.args_schema
|
|
550
|
+
elif self.args_schema and issubclass(self.args_schema, BaseModelV1):
|
|
551
|
+
json_schema = self.args_schema.schema()
|
|
546
552
|
else:
|
|
547
553
|
input_schema = self.get_input_schema()
|
|
548
554
|
json_schema = input_schema.model_json_schema()
|
|
@@ -628,9 +634,10 @@ class ChildTool(BaseTool):
|
|
|
628
634
|
The parsed and validated input.
|
|
629
635
|
|
|
630
636
|
Raises:
|
|
631
|
-
ValueError: If string input is provided with JSON schema
|
|
632
|
-
|
|
633
|
-
|
|
637
|
+
ValueError: If string input is provided with JSON schema ``args_schema``.
|
|
638
|
+
ValueError: If InjectedToolCallId is required but ``tool_call_id`` is not
|
|
639
|
+
provided.
|
|
640
|
+
TypeError: If args_schema is not a Pydantic ``BaseModel`` or dict.
|
|
634
641
|
"""
|
|
635
642
|
input_args = self.args_schema
|
|
636
643
|
if isinstance(tool_input, str):
|
|
@@ -655,10 +662,7 @@ class ChildTool(BaseTool):
|
|
|
655
662
|
return tool_input
|
|
656
663
|
if issubclass(input_args, BaseModel):
|
|
657
664
|
for k, v in get_all_basemodel_annotations(input_args).items():
|
|
658
|
-
if (
|
|
659
|
-
_is_injected_arg_type(v, injected_type=InjectedToolCallId)
|
|
660
|
-
and k not in tool_input
|
|
661
|
-
):
|
|
665
|
+
if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
|
|
662
666
|
if tool_call_id is None:
|
|
663
667
|
msg = (
|
|
664
668
|
"When tool includes an InjectedToolCallId "
|
|
@@ -673,10 +677,7 @@ class ChildTool(BaseTool):
|
|
|
673
677
|
result_dict = result.model_dump()
|
|
674
678
|
elif issubclass(input_args, BaseModelV1):
|
|
675
679
|
for k, v in get_all_basemodel_annotations(input_args).items():
|
|
676
|
-
if (
|
|
677
|
-
_is_injected_arg_type(v, injected_type=InjectedToolCallId)
|
|
678
|
-
and k not in tool_input
|
|
679
|
-
):
|
|
680
|
+
if _is_injected_arg_type(v, injected_type=InjectedToolCallId):
|
|
680
681
|
if tool_call_id is None:
|
|
681
682
|
msg = (
|
|
682
683
|
"When tool includes an InjectedToolCallId "
|
|
@@ -725,6 +726,9 @@ class ChildTool(BaseTool):
|
|
|
725
726
|
|
|
726
727
|
Add run_manager: Optional[CallbackManagerForToolRun] = None
|
|
727
728
|
to child implementations to enable tracing.
|
|
729
|
+
|
|
730
|
+
Returns:
|
|
731
|
+
The result of the tool execution.
|
|
728
732
|
"""
|
|
729
733
|
|
|
730
734
|
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
|
|
@@ -732,6 +736,9 @@ class ChildTool(BaseTool):
|
|
|
732
736
|
|
|
733
737
|
Add run_manager: Optional[AsyncCallbackManagerForToolRun] = None
|
|
734
738
|
to child implementations to enable tracing.
|
|
739
|
+
|
|
740
|
+
Returns:
|
|
741
|
+
The result of the tool execution.
|
|
735
742
|
"""
|
|
736
743
|
if kwargs.get("run_manager") and signature(self._run).parameters.get(
|
|
737
744
|
"run_manager"
|
|
@@ -1285,7 +1292,7 @@ class InjectedToolCallId(InjectedToolArg):
|
|
|
1285
1292
|
|
|
1286
1293
|
|
|
1287
1294
|
def _is_injected_arg_type(
|
|
1288
|
-
type_: type, injected_type: Optional[type[InjectedToolArg]] = None
|
|
1295
|
+
type_: Union[type, TypeVar], injected_type: Optional[type[InjectedToolArg]] = None
|
|
1289
1296
|
) -> bool:
|
|
1290
1297
|
"""Check if a type annotation indicates an injected argument.
|
|
1291
1298
|
|
|
@@ -1306,20 +1313,22 @@ def _is_injected_arg_type(
|
|
|
1306
1313
|
|
|
1307
1314
|
def get_all_basemodel_annotations(
|
|
1308
1315
|
cls: Union[TypeBaseModel, Any], *, default_to_bound: bool = True
|
|
1309
|
-
) -> dict[str, type]:
|
|
1316
|
+
) -> dict[str, Union[type, TypeVar]]:
|
|
1310
1317
|
"""Get all annotations from a Pydantic BaseModel and its parents.
|
|
1311
1318
|
|
|
1312
1319
|
Args:
|
|
1313
1320
|
cls: The Pydantic BaseModel class.
|
|
1314
1321
|
default_to_bound: Whether to default to the bound of a TypeVar if it exists.
|
|
1322
|
+
|
|
1323
|
+
Returns:
|
|
1324
|
+
A dictionary of field names to their type annotations.
|
|
1315
1325
|
"""
|
|
1316
1326
|
# cls has no subscript: cls = FooBar
|
|
1317
1327
|
if isinstance(cls, type):
|
|
1318
|
-
|
|
1319
|
-
fields = getattr(cls, "model_fields", {}) or getattr(cls, "__fields__", {})
|
|
1328
|
+
fields = get_fields(cls)
|
|
1320
1329
|
alias_map = {field.alias: name for name, field in fields.items() if field.alias}
|
|
1321
1330
|
|
|
1322
|
-
annotations: dict[str, type] = {}
|
|
1331
|
+
annotations: dict[str, Union[type, TypeVar]] = {}
|
|
1323
1332
|
for name, param in inspect.signature(cls).parameters.items():
|
|
1324
1333
|
# Exclude hidden init args added by pydantic Config. For example if
|
|
1325
1334
|
# BaseModel(extra="allow") then "extra_data" will part of init sig.
|
|
@@ -1355,8 +1364,8 @@ def get_all_basemodel_annotations(
|
|
|
1355
1364
|
continue
|
|
1356
1365
|
|
|
1357
1366
|
# if class = FooBar inherits from Baz[str]:
|
|
1358
|
-
# parent = Baz[str],
|
|
1359
|
-
# parent_origin = Baz,
|
|
1367
|
+
# parent = class Baz[str],
|
|
1368
|
+
# parent_origin = class Baz,
|
|
1360
1369
|
# generic_type_vars = (type vars in Baz)
|
|
1361
1370
|
# generic_map = {type var in Baz: str}
|
|
1362
1371
|
generic_type_vars: tuple = getattr(parent_origin, "__parameters__", ())
|
|
@@ -1373,11 +1382,11 @@ def get_all_basemodel_annotations(
|
|
|
1373
1382
|
|
|
1374
1383
|
|
|
1375
1384
|
def _replace_type_vars(
|
|
1376
|
-
type_: type,
|
|
1385
|
+
type_: Union[type, TypeVar],
|
|
1377
1386
|
generic_map: Optional[dict[TypeVar, type]] = None,
|
|
1378
1387
|
*,
|
|
1379
1388
|
default_to_bound: bool = True,
|
|
1380
|
-
) -> type:
|
|
1389
|
+
) -> Union[type, TypeVar]:
|
|
1381
1390
|
"""Replace TypeVars in a type annotation with concrete types.
|
|
1382
1391
|
|
|
1383
1392
|
Args:
|
|
@@ -1393,7 +1402,7 @@ def _replace_type_vars(
|
|
|
1393
1402
|
if type_ in generic_map:
|
|
1394
1403
|
return generic_map[type_]
|
|
1395
1404
|
if default_to_bound:
|
|
1396
|
-
return type_.__bound__
|
|
1405
|
+
return type_.__bound__ if type_.__bound__ is not None else Any
|
|
1397
1406
|
return type_
|
|
1398
1407
|
if (origin := get_origin(type_)) and (args := get_args(type_)):
|
|
1399
1408
|
new_args = tuple(
|
langchain_core/tools/convert.py
CHANGED
|
@@ -92,12 +92,13 @@ def tool(
|
|
|
92
92
|
positional argument.
|
|
93
93
|
description: Optional description for the tool.
|
|
94
94
|
Precedence for the tool description value is as follows:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
|
|
96
|
+
- ``description`` argument
|
|
97
|
+
(used even if docstring and/or ``args_schema`` are provided)
|
|
98
|
+
- tool function docstring
|
|
99
|
+
(used even if ``args_schema`` is provided)
|
|
100
|
+
- ``args_schema`` description
|
|
101
|
+
(used only if `description` / docstring are not provided)
|
|
101
102
|
*args: Extra positional arguments. Must be empty.
|
|
102
103
|
return_direct: Whether to return directly from the tool rather
|
|
103
104
|
than continuing the agent loop. Defaults to False.
|
|
@@ -119,6 +120,17 @@ def tool(
|
|
|
119
120
|
whether to raise ValueError on invalid Google Style docstrings.
|
|
120
121
|
Defaults to True.
|
|
121
122
|
|
|
123
|
+
Raises:
|
|
124
|
+
ValueError: If too many positional arguments are provided.
|
|
125
|
+
ValueError: If a runnable is provided without a string name.
|
|
126
|
+
ValueError: If the first argument is not a string or callable with
|
|
127
|
+
a ``__name__`` attribute.
|
|
128
|
+
ValueError: If the function does not have a docstring and description
|
|
129
|
+
is not provided and ``infer_schema`` is False.
|
|
130
|
+
ValueError: If ``parse_docstring`` is True and the function has an invalid
|
|
131
|
+
Google-style docstring and ``error_on_invalid_docstring`` is True.
|
|
132
|
+
ValueError: If a Runnable is provided that does not have an object schema.
|
|
133
|
+
|
|
122
134
|
Returns:
|
|
123
135
|
The tool.
|
|
124
136
|
|
|
@@ -134,11 +146,13 @@ def tool(
|
|
|
134
146
|
# Searches the API for the query.
|
|
135
147
|
return
|
|
136
148
|
|
|
149
|
+
|
|
137
150
|
@tool("search", return_direct=True)
|
|
138
151
|
def search_api(query: str) -> str:
|
|
139
152
|
# Searches the API for the query.
|
|
140
153
|
return
|
|
141
154
|
|
|
155
|
+
|
|
142
156
|
@tool(response_format="content_and_artifact")
|
|
143
157
|
def search_api(query: str) -> tuple[str, dict]:
|
|
144
158
|
return "partial json of results", {"full": "object of results"}
|
|
@@ -171,18 +185,15 @@ def tool(
|
|
|
171
185
|
"bar": {
|
|
172
186
|
"title": "Bar",
|
|
173
187
|
"description": "The bar.",
|
|
174
|
-
"type": "string"
|
|
188
|
+
"type": "string",
|
|
175
189
|
},
|
|
176
190
|
"baz": {
|
|
177
191
|
"title": "Baz",
|
|
178
192
|
"description": "The baz.",
|
|
179
|
-
"type": "integer"
|
|
180
|
-
}
|
|
193
|
+
"type": "integer",
|
|
194
|
+
},
|
|
181
195
|
},
|
|
182
|
-
"required": [
|
|
183
|
-
"bar",
|
|
184
|
-
"baz"
|
|
185
|
-
]
|
|
196
|
+
"required": ["bar", "baz"],
|
|
186
197
|
}
|
|
187
198
|
|
|
188
199
|
Note that parsing by default will raise ``ValueError`` if the docstring
|
|
@@ -216,7 +227,7 @@ def tool(
|
|
|
216
227
|
\"\"\"
|
|
217
228
|
return bar
|
|
218
229
|
|
|
219
|
-
""" # noqa: D214, D410, D411
|
|
230
|
+
""" # noqa: D214, D410, D411 # We're intentionally showing bad formatting in examples
|
|
220
231
|
|
|
221
232
|
def _create_tool_factory(
|
|
222
233
|
tool_name: str,
|
|
@@ -304,7 +315,7 @@ def tool(
|
|
|
304
315
|
|
|
305
316
|
if runnable is not None:
|
|
306
317
|
# tool is used as a function
|
|
307
|
-
# tool_from_runnable = tool("name", runnable)
|
|
318
|
+
# for instance tool_from_runnable = tool("name", runnable)
|
|
308
319
|
if not name_or_callable:
|
|
309
320
|
msg = "Runnable without name for tool constructor"
|
|
310
321
|
raise ValueError(msg)
|
langchain_core/tools/simple.py
CHANGED
|
@@ -64,11 +64,7 @@ class Tool(BaseTool):
|
|
|
64
64
|
The input arguments for the tool.
|
|
65
65
|
"""
|
|
66
66
|
if self.args_schema is not None:
|
|
67
|
-
|
|
68
|
-
json_schema = self.args_schema
|
|
69
|
-
else:
|
|
70
|
-
json_schema = self.args_schema.model_json_schema()
|
|
71
|
-
return json_schema["properties"]
|
|
67
|
+
return super().args
|
|
72
68
|
# For backwards compatibility, if the function signature is ambiguous,
|
|
73
69
|
# assume it takes a single string input.
|
|
74
70
|
return {"tool_input": {"type": "string"}}
|
|
@@ -76,7 +72,19 @@ class Tool(BaseTool):
|
|
|
76
72
|
def _to_args_and_kwargs(
|
|
77
73
|
self, tool_input: Union[str, dict], tool_call_id: Optional[str]
|
|
78
74
|
) -> tuple[tuple, dict]:
|
|
79
|
-
"""Convert tool input to pydantic model.
|
|
75
|
+
"""Convert tool input to pydantic model.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
tool_input: The input to the tool.
|
|
79
|
+
tool_call_id: The ID of the tool call.
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
ToolException: If the tool input is invalid.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
the pydantic model args and kwargs.
|
|
86
|
+
|
|
87
|
+
"""
|
|
80
88
|
args, kwargs = super()._to_args_and_kwargs(tool_input, tool_call_id)
|
|
81
89
|
# For backwards compatibility. The tool must be run with a single input
|
|
82
90
|
all_args = list(args) + list(kwargs.values())
|
|
@@ -96,7 +104,17 @@ class Tool(BaseTool):
|
|
|
96
104
|
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
97
105
|
**kwargs: Any,
|
|
98
106
|
) -> Any:
|
|
99
|
-
"""Use the tool.
|
|
107
|
+
"""Use the tool.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
*args: Positional arguments to pass to the tool
|
|
111
|
+
config: Configuration for the run
|
|
112
|
+
run_manager: Optional callback manager to use for the run
|
|
113
|
+
**kwargs: Keyword arguments to pass to the tool
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
The result of the tool execution
|
|
117
|
+
"""
|
|
100
118
|
if self.func:
|
|
101
119
|
if run_manager and signature(self.func).parameters.get("callbacks"):
|
|
102
120
|
kwargs["callbacks"] = run_manager.get_child()
|
|
@@ -113,7 +131,17 @@ class Tool(BaseTool):
|
|
|
113
131
|
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
114
132
|
**kwargs: Any,
|
|
115
133
|
) -> Any:
|
|
116
|
-
"""Use the tool asynchronously.
|
|
134
|
+
"""Use the tool asynchronously.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
*args: Positional arguments to pass to the tool
|
|
138
|
+
config: Configuration for the run
|
|
139
|
+
run_manager: Optional callback manager to use for the run
|
|
140
|
+
**kwargs: Keyword arguments to pass to the tool
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
The result of the tool execution
|
|
144
|
+
"""
|
|
117
145
|
if self.coroutine:
|
|
118
146
|
if run_manager and signature(self.coroutine).parameters.get("callbacks"):
|
|
119
147
|
kwargs["callbacks"] = run_manager.get_child()
|
|
@@ -67,16 +67,6 @@ class StructuredTool(BaseTool):
|
|
|
67
67
|
|
|
68
68
|
# --- Tool ---
|
|
69
69
|
|
|
70
|
-
@property
|
|
71
|
-
def args(self) -> dict:
|
|
72
|
-
"""The tool's input arguments."""
|
|
73
|
-
if isinstance(self.args_schema, dict):
|
|
74
|
-
json_schema = self.args_schema
|
|
75
|
-
else:
|
|
76
|
-
input_schema = self.get_input_schema()
|
|
77
|
-
json_schema = input_schema.model_json_schema()
|
|
78
|
-
return json_schema["properties"]
|
|
79
|
-
|
|
80
70
|
def _run(
|
|
81
71
|
self,
|
|
82
72
|
*args: Any,
|
|
@@ -84,7 +74,17 @@ class StructuredTool(BaseTool):
|
|
|
84
74
|
run_manager: Optional[CallbackManagerForToolRun] = None,
|
|
85
75
|
**kwargs: Any,
|
|
86
76
|
) -> Any:
|
|
87
|
-
"""Use the tool.
|
|
77
|
+
"""Use the tool.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
*args: Positional arguments to pass to the tool
|
|
81
|
+
config: Configuration for the run
|
|
82
|
+
run_manager: Optional callback manager to use for the run
|
|
83
|
+
**kwargs: Keyword arguments to pass to the tool
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The result of the tool execution
|
|
87
|
+
"""
|
|
88
88
|
if self.func:
|
|
89
89
|
if run_manager and signature(self.func).parameters.get("callbacks"):
|
|
90
90
|
kwargs["callbacks"] = run_manager.get_child()
|
|
@@ -101,7 +101,17 @@ class StructuredTool(BaseTool):
|
|
|
101
101
|
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
|
|
102
102
|
**kwargs: Any,
|
|
103
103
|
) -> Any:
|
|
104
|
-
"""Use the tool asynchronously.
|
|
104
|
+
"""Use the tool asynchronously.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
*args: Positional arguments to pass to the tool
|
|
108
|
+
config: Configuration for the run
|
|
109
|
+
run_manager: Optional callback manager to use for the run
|
|
110
|
+
**kwargs: Keyword arguments to pass to the tool
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
The result of the tool execution
|
|
114
|
+
"""
|
|
105
115
|
if self.coroutine:
|
|
106
116
|
if run_manager and signature(self.coroutine).parameters.get("callbacks"):
|
|
107
117
|
kwargs["callbacks"] = run_manager.get_child()
|
|
@@ -164,6 +174,9 @@ class StructuredTool(BaseTool):
|
|
|
164
174
|
|
|
165
175
|
Raises:
|
|
166
176
|
ValueError: If the function is not provided.
|
|
177
|
+
ValueError: If the function does not have a docstring and description
|
|
178
|
+
is not provided.
|
|
179
|
+
TypeError: If the ``args_schema`` is not a ``BaseModel`` or dict.
|
|
167
180
|
|
|
168
181
|
Examples:
|
|
169
182
|
|
langchain_core/tracers/base.py
CHANGED
|
@@ -520,11 +520,11 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
|
|
|
520
520
|
return retrieval_run
|
|
521
521
|
|
|
522
522
|
def __deepcopy__(self, memo: dict) -> BaseTracer:
|
|
523
|
-
"""
|
|
523
|
+
"""Return self."""
|
|
524
524
|
return self
|
|
525
525
|
|
|
526
526
|
def __copy__(self) -> BaseTracer:
|
|
527
|
-
"""
|
|
527
|
+
"""Return self."""
|
|
528
528
|
return self
|
|
529
529
|
|
|
530
530
|
|
|
@@ -43,7 +43,11 @@ run_collector_var: ContextVar[Optional[RunCollectorCallbackHandler]] = ContextVa
|
|
|
43
43
|
def tracing_enabled(
|
|
44
44
|
session_name: str = "default", # noqa: ARG001
|
|
45
45
|
) -> Generator[TracerSessionV1, None, None]:
|
|
46
|
-
"""Throw an error because this has been replaced by tracing_v2_enabled
|
|
46
|
+
"""Throw an error because this has been replaced by ``tracing_v2_enabled``.
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
RuntimeError: Always, because this function is deprecated.
|
|
50
|
+
"""
|
|
47
51
|
msg = (
|
|
48
52
|
"tracing_enabled is no longer supported. Please use tracing_enabled_v2 instead."
|
|
49
53
|
)
|