langchain-core 1.0.0a8__py3-none-any.whl → 1.0.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langchain-core might be problematic. Click here for more details.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +0 -1
- langchain_core/_api/beta_decorator.py +17 -20
- langchain_core/_api/deprecation.py +30 -35
- langchain_core/_import_utils.py +1 -1
- langchain_core/agents.py +10 -9
- langchain_core/caches.py +46 -56
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +232 -243
- langchain_core/callbacks/file.py +33 -33
- langchain_core/callbacks/manager.py +353 -416
- langchain_core/callbacks/stdout.py +21 -22
- langchain_core/callbacks/streaming_stdout.py +32 -32
- langchain_core/callbacks/usage.py +54 -51
- langchain_core/chat_history.py +43 -58
- langchain_core/document_loaders/base.py +21 -21
- langchain_core/document_loaders/langsmith.py +22 -22
- langchain_core/documents/__init__.py +0 -1
- langchain_core/documents/base.py +46 -49
- langchain_core/documents/transformers.py +28 -29
- langchain_core/embeddings/fake.py +50 -54
- langchain_core/example_selectors/semantic_similarity.py +4 -6
- langchain_core/exceptions.py +7 -8
- langchain_core/indexing/api.py +19 -25
- langchain_core/indexing/base.py +24 -24
- langchain_core/language_models/__init__.py +11 -27
- langchain_core/language_models/_utils.py +53 -54
- langchain_core/language_models/base.py +30 -24
- langchain_core/language_models/chat_models.py +123 -148
- langchain_core/language_models/fake_chat_models.py +7 -7
- langchain_core/language_models/llms.py +14 -16
- langchain_core/load/dump.py +3 -4
- langchain_core/load/load.py +7 -16
- langchain_core/load/serializable.py +37 -36
- langchain_core/messages/__init__.py +1 -16
- langchain_core/messages/ai.py +122 -123
- langchain_core/messages/base.py +31 -31
- langchain_core/messages/block_translators/__init__.py +17 -17
- langchain_core/messages/block_translators/anthropic.py +3 -3
- langchain_core/messages/block_translators/bedrock_converse.py +3 -3
- langchain_core/messages/block_translators/google_genai.py +5 -4
- 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 +3 -3
- langchain_core/messages/block_translators/openai.py +5 -5
- langchain_core/messages/chat.py +2 -6
- langchain_core/messages/content.py +222 -209
- langchain_core/messages/function.py +6 -10
- langchain_core/messages/human.py +17 -24
- langchain_core/messages/modifier.py +2 -2
- langchain_core/messages/system.py +12 -22
- langchain_core/messages/tool.py +53 -69
- langchain_core/messages/utils.py +399 -417
- langchain_core/output_parsers/__init__.py +1 -14
- langchain_core/output_parsers/base.py +46 -47
- langchain_core/output_parsers/json.py +3 -4
- langchain_core/output_parsers/list.py +2 -2
- langchain_core/output_parsers/openai_functions.py +46 -44
- langchain_core/output_parsers/openai_tools.py +11 -16
- langchain_core/output_parsers/pydantic.py +10 -11
- langchain_core/output_parsers/string.py +2 -2
- langchain_core/output_parsers/transform.py +2 -2
- langchain_core/output_parsers/xml.py +1 -1
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +14 -14
- langchain_core/outputs/generation.py +6 -6
- langchain_core/outputs/llm_result.py +5 -5
- langchain_core/prompt_values.py +11 -11
- langchain_core/prompts/__init__.py +3 -23
- langchain_core/prompts/base.py +33 -38
- langchain_core/prompts/chat.py +222 -229
- langchain_core/prompts/dict.py +3 -3
- langchain_core/prompts/few_shot.py +76 -83
- langchain_core/prompts/few_shot_with_templates.py +7 -9
- langchain_core/prompts/image.py +12 -14
- langchain_core/prompts/loading.py +1 -1
- langchain_core/prompts/message.py +3 -3
- langchain_core/prompts/prompt.py +20 -23
- langchain_core/prompts/string.py +20 -8
- langchain_core/prompts/structured.py +26 -27
- langchain_core/rate_limiters.py +50 -58
- langchain_core/retrievers.py +41 -182
- langchain_core/runnables/base.py +565 -597
- langchain_core/runnables/branch.py +8 -8
- langchain_core/runnables/config.py +37 -44
- langchain_core/runnables/configurable.py +9 -10
- langchain_core/runnables/fallbacks.py +9 -9
- langchain_core/runnables/graph.py +46 -50
- langchain_core/runnables/graph_ascii.py +19 -18
- langchain_core/runnables/graph_mermaid.py +20 -31
- langchain_core/runnables/graph_png.py +7 -7
- langchain_core/runnables/history.py +22 -22
- langchain_core/runnables/passthrough.py +11 -11
- langchain_core/runnables/retry.py +3 -3
- langchain_core/runnables/router.py +2 -2
- langchain_core/runnables/schema.py +33 -33
- langchain_core/runnables/utils.py +30 -34
- langchain_core/stores.py +72 -102
- langchain_core/sys_info.py +27 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +70 -71
- langchain_core/tools/convert.py +100 -104
- langchain_core/tools/render.py +9 -9
- langchain_core/tools/retriever.py +7 -7
- langchain_core/tools/simple.py +6 -7
- langchain_core/tools/structured.py +18 -24
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/base.py +35 -35
- langchain_core/tracers/context.py +12 -17
- langchain_core/tracers/event_stream.py +3 -3
- langchain_core/tracers/langchain.py +8 -8
- langchain_core/tracers/log_stream.py +17 -18
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +2 -2
- langchain_core/tracers/schemas.py +0 -129
- langchain_core/tracers/stdout.py +1 -2
- langchain_core/utils/__init__.py +1 -1
- langchain_core/utils/aiter.py +32 -32
- langchain_core/utils/env.py +5 -5
- langchain_core/utils/function_calling.py +59 -154
- langchain_core/utils/html.py +4 -4
- langchain_core/utils/input.py +3 -3
- langchain_core/utils/interactive_env.py +1 -1
- langchain_core/utils/iter.py +20 -20
- langchain_core/utils/json.py +1 -1
- langchain_core/utils/json_schema.py +2 -2
- langchain_core/utils/mustache.py +5 -5
- langchain_core/utils/pydantic.py +17 -17
- langchain_core/utils/strings.py +5 -5
- langchain_core/utils/utils.py +25 -28
- langchain_core/vectorstores/base.py +55 -87
- langchain_core/vectorstores/in_memory.py +83 -85
- langchain_core/vectorstores/utils.py +2 -2
- langchain_core/version.py +1 -1
- {langchain_core-1.0.0a8.dist-info → langchain_core-1.0.0rc2.dist-info}/METADATA +23 -11
- langchain_core-1.0.0rc2.dist-info/RECORD +172 -0
- langchain_core/memory.py +0 -120
- 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-1.0.0a8.dist-info/RECORD +0 -176
- {langchain_core-1.0.0a8.dist-info → langchain_core-1.0.0rc2.dist-info}/WHEEL +0 -0
langchain_core/tools/base.py
CHANGED
|
@@ -92,7 +92,7 @@ def _is_annotated_type(typ: type[Any]) -> bool:
|
|
|
92
92
|
typ: The type to check.
|
|
93
93
|
|
|
94
94
|
Returns:
|
|
95
|
-
True if the type is an Annotated type, False otherwise.
|
|
95
|
+
`True` if the type is an Annotated type, `False` otherwise.
|
|
96
96
|
"""
|
|
97
97
|
return get_origin(typ) is typing.Annotated
|
|
98
98
|
|
|
@@ -226,7 +226,7 @@ def _is_pydantic_annotation(annotation: Any, pydantic_version: str = "v2") -> bo
|
|
|
226
226
|
pydantic_version: The Pydantic version to check against ("v1" or "v2").
|
|
227
227
|
|
|
228
228
|
Returns:
|
|
229
|
-
True if the annotation is a Pydantic model, False otherwise.
|
|
229
|
+
`True` if the annotation is a Pydantic model, `False` otherwise.
|
|
230
230
|
"""
|
|
231
231
|
base_model_class = BaseModelV1 if pydantic_version == "v1" else BaseModel
|
|
232
232
|
try:
|
|
@@ -245,7 +245,7 @@ def _function_annotations_are_pydantic_v1(
|
|
|
245
245
|
func: The function being checked.
|
|
246
246
|
|
|
247
247
|
Returns:
|
|
248
|
-
True if all Pydantic annotations are from V1, False otherwise.
|
|
248
|
+
True if all Pydantic annotations are from V1, `False` otherwise.
|
|
249
249
|
|
|
250
250
|
Raises:
|
|
251
251
|
NotImplementedError: If the function contains mixed V1 and V2 annotations.
|
|
@@ -285,24 +285,23 @@ def create_schema_from_function(
|
|
|
285
285
|
error_on_invalid_docstring: bool = False,
|
|
286
286
|
include_injected: bool = True,
|
|
287
287
|
) -> type[BaseModel]:
|
|
288
|
-
"""Create a
|
|
288
|
+
"""Create a Pydantic schema from a function's signature.
|
|
289
289
|
|
|
290
290
|
Args:
|
|
291
|
-
model_name: Name to assign to the generated
|
|
291
|
+
model_name: Name to assign to the generated Pydantic schema.
|
|
292
292
|
func: Function to generate the schema from.
|
|
293
293
|
filter_args: Optional list of arguments to exclude from the schema.
|
|
294
|
-
Defaults to FILTERED_ARGS
|
|
294
|
+
Defaults to `FILTERED_ARGS`.
|
|
295
295
|
parse_docstring: Whether to parse the function's docstring for descriptions
|
|
296
|
-
for each argument.
|
|
297
|
-
error_on_invalid_docstring: if
|
|
298
|
-
whether to raise ValueError on invalid Google Style docstrings.
|
|
299
|
-
Defaults to False.
|
|
296
|
+
for each argument.
|
|
297
|
+
error_on_invalid_docstring: if `parse_docstring` is provided, configure
|
|
298
|
+
whether to raise `ValueError` on invalid Google Style docstrings.
|
|
300
299
|
include_injected: Whether to include injected arguments in the schema.
|
|
301
|
-
Defaults to True
|
|
300
|
+
Defaults to `True`, since we want to include them in the schema
|
|
302
301
|
when *validating* tool inputs.
|
|
303
302
|
|
|
304
303
|
Returns:
|
|
305
|
-
A
|
|
304
|
+
A Pydantic model with the same arguments as the function.
|
|
306
305
|
"""
|
|
307
306
|
sig = inspect.signature(func)
|
|
308
307
|
|
|
@@ -312,7 +311,7 @@ def create_schema_from_function(
|
|
|
312
311
|
# https://docs.pydantic.dev/latest/usage/validation_decorator/
|
|
313
312
|
with warnings.catch_warnings():
|
|
314
313
|
# We are using deprecated functionality here.
|
|
315
|
-
# This code should be re-written to simply construct a
|
|
314
|
+
# This code should be re-written to simply construct a Pydantic model
|
|
316
315
|
# using inspect.signature and create_model.
|
|
317
316
|
warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
|
|
318
317
|
validated = validate_arguments(func, config=_SchemaConfig) # type: ignore[operator]
|
|
@@ -460,13 +459,13 @@ class ChildTool(BaseTool):
|
|
|
460
459
|
"""Callbacks to be called during tool execution."""
|
|
461
460
|
|
|
462
461
|
tags: list[str] | None = None
|
|
463
|
-
"""Optional list of tags associated with the tool.
|
|
462
|
+
"""Optional list of tags associated with the tool.
|
|
464
463
|
These tags will be associated with each call to this tool,
|
|
465
464
|
and passed as arguments to the handlers defined in `callbacks`.
|
|
466
465
|
You can use these to eg identify a specific instance of a tool with its use case.
|
|
467
466
|
"""
|
|
468
467
|
metadata: dict[str, Any] | None = None
|
|
469
|
-
"""Optional metadata associated with the tool.
|
|
468
|
+
"""Optional metadata associated with the tool.
|
|
470
469
|
This metadata will be associated with each call to this tool,
|
|
471
470
|
and passed as arguments to the handlers defined in `callbacks`.
|
|
472
471
|
You can use these to eg identify a specific instance of a tool with its use case.
|
|
@@ -481,18 +480,18 @@ class ChildTool(BaseTool):
|
|
|
481
480
|
"""Handle the content of the ValidationError thrown."""
|
|
482
481
|
|
|
483
482
|
response_format: Literal["content", "content_and_artifact"] = "content"
|
|
484
|
-
"""The tool response format.
|
|
483
|
+
"""The tool response format.
|
|
485
484
|
|
|
486
|
-
If "content" then the output of the tool is interpreted as the contents of a
|
|
487
|
-
ToolMessage. If "content_and_artifact" then the output is expected to be a
|
|
488
|
-
two-tuple corresponding to the (content, artifact) of a ToolMessage
|
|
485
|
+
If `"content"` then the output of the tool is interpreted as the contents of a
|
|
486
|
+
ToolMessage. If `"content_and_artifact"` then the output is expected to be a
|
|
487
|
+
two-tuple corresponding to the (content, artifact) of a `ToolMessage`.
|
|
489
488
|
"""
|
|
490
489
|
|
|
491
490
|
def __init__(self, **kwargs: Any) -> None:
|
|
492
491
|
"""Initialize the tool.
|
|
493
492
|
|
|
494
493
|
Raises:
|
|
495
|
-
TypeError: If
|
|
494
|
+
TypeError: If `args_schema` is not a subclass of pydantic `BaseModel` or
|
|
496
495
|
dict.
|
|
497
496
|
"""
|
|
498
497
|
if (
|
|
@@ -517,7 +516,7 @@ class ChildTool(BaseTool):
|
|
|
517
516
|
"""Check if the tool accepts only a single input argument.
|
|
518
517
|
|
|
519
518
|
Returns:
|
|
520
|
-
True if the tool has only one input argument, False otherwise.
|
|
519
|
+
`True` if the tool has only one input argument, `False` otherwise.
|
|
521
520
|
"""
|
|
522
521
|
keys = {k for k in self.args if k != "kwargs"}
|
|
523
522
|
return len(keys) == 1
|
|
@@ -616,10 +615,10 @@ class ChildTool(BaseTool):
|
|
|
616
615
|
The parsed and validated input.
|
|
617
616
|
|
|
618
617
|
Raises:
|
|
619
|
-
ValueError: If string input is provided with JSON schema
|
|
620
|
-
ValueError: If InjectedToolCallId is required but
|
|
618
|
+
ValueError: If string input is provided with JSON schema `args_schema`.
|
|
619
|
+
ValueError: If InjectedToolCallId is required but `tool_call_id` is not
|
|
621
620
|
provided.
|
|
622
|
-
TypeError: If args_schema is not a Pydantic
|
|
621
|
+
TypeError: If args_schema is not a Pydantic `BaseModel` or dict.
|
|
623
622
|
"""
|
|
624
623
|
input_args = self.args_schema
|
|
625
624
|
if isinstance(tool_input, str):
|
|
@@ -686,8 +685,8 @@ class ChildTool(BaseTool):
|
|
|
686
685
|
def _run(self, *args: Any, **kwargs: Any) -> Any:
|
|
687
686
|
"""Use the tool.
|
|
688
687
|
|
|
689
|
-
Add run_manager:
|
|
690
|
-
|
|
688
|
+
Add `run_manager: CallbackManagerForToolRun | None = None` to child
|
|
689
|
+
implementations to enable tracing.
|
|
691
690
|
|
|
692
691
|
Returns:
|
|
693
692
|
The result of the tool execution.
|
|
@@ -696,8 +695,8 @@ class ChildTool(BaseTool):
|
|
|
696
695
|
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
|
|
697
696
|
"""Use the tool asynchronously.
|
|
698
697
|
|
|
699
|
-
Add run_manager:
|
|
700
|
-
|
|
698
|
+
Add `run_manager: AsyncCallbackManagerForToolRun | None = None` to child
|
|
699
|
+
implementations to enable tracing.
|
|
701
700
|
|
|
702
701
|
Returns:
|
|
703
702
|
The result of the tool execution.
|
|
@@ -767,17 +766,17 @@ class ChildTool(BaseTool):
|
|
|
767
766
|
|
|
768
767
|
Args:
|
|
769
768
|
tool_input: The input to the tool.
|
|
770
|
-
verbose: Whether to log the tool's progress.
|
|
771
|
-
start_color: The color to use when starting the tool.
|
|
772
|
-
color: The color to use when ending the tool.
|
|
773
|
-
callbacks: Callbacks to be called during tool execution.
|
|
774
|
-
tags: Optional list of tags associated with the tool.
|
|
775
|
-
metadata: Optional metadata associated with the tool.
|
|
776
|
-
run_name: The name of the run.
|
|
777
|
-
run_id: The id of the run.
|
|
778
|
-
config: The configuration for the tool.
|
|
779
|
-
tool_call_id: The id of the tool call.
|
|
780
|
-
kwargs: Keyword arguments to be passed to tool callbacks (event handler)
|
|
769
|
+
verbose: Whether to log the tool's progress.
|
|
770
|
+
start_color: The color to use when starting the tool.
|
|
771
|
+
color: The color to use when ending the tool.
|
|
772
|
+
callbacks: Callbacks to be called during tool execution.
|
|
773
|
+
tags: Optional list of tags associated with the tool.
|
|
774
|
+
metadata: Optional metadata associated with the tool.
|
|
775
|
+
run_name: The name of the run.
|
|
776
|
+
run_id: The id of the run.
|
|
777
|
+
config: The configuration for the tool.
|
|
778
|
+
tool_call_id: The id of the tool call.
|
|
779
|
+
**kwargs: Keyword arguments to be passed to tool callbacks (event handler)
|
|
781
780
|
|
|
782
781
|
Returns:
|
|
783
782
|
The output of the tool.
|
|
@@ -879,17 +878,17 @@ class ChildTool(BaseTool):
|
|
|
879
878
|
|
|
880
879
|
Args:
|
|
881
880
|
tool_input: The input to the tool.
|
|
882
|
-
verbose: Whether to log the tool's progress.
|
|
883
|
-
start_color: The color to use when starting the tool.
|
|
884
|
-
color: The color to use when ending the tool.
|
|
885
|
-
callbacks: Callbacks to be called during tool execution.
|
|
886
|
-
tags: Optional list of tags associated with the tool.
|
|
887
|
-
metadata: Optional metadata associated with the tool.
|
|
888
|
-
run_name: The name of the run.
|
|
889
|
-
run_id: The id of the run.
|
|
890
|
-
config: The configuration for the tool.
|
|
891
|
-
tool_call_id: The id of the tool call.
|
|
892
|
-
kwargs: Keyword arguments to be passed to tool callbacks
|
|
881
|
+
verbose: Whether to log the tool's progress.
|
|
882
|
+
start_color: The color to use when starting the tool.
|
|
883
|
+
color: The color to use when ending the tool.
|
|
884
|
+
callbacks: Callbacks to be called during tool execution.
|
|
885
|
+
tags: Optional list of tags associated with the tool.
|
|
886
|
+
metadata: Optional metadata associated with the tool.
|
|
887
|
+
run_name: The name of the run.
|
|
888
|
+
run_id: The id of the run.
|
|
889
|
+
config: The configuration for the tool.
|
|
890
|
+
tool_call_id: The id of the tool call.
|
|
891
|
+
**kwargs: Keyword arguments to be passed to tool callbacks
|
|
893
892
|
|
|
894
893
|
Returns:
|
|
895
894
|
The output of the tool.
|
|
@@ -981,7 +980,7 @@ def _is_tool_call(x: Any) -> bool:
|
|
|
981
980
|
x: The input to check.
|
|
982
981
|
|
|
983
982
|
Returns:
|
|
984
|
-
True if the input is a tool call, False otherwise.
|
|
983
|
+
`True` if the input is a tool call, `False` otherwise.
|
|
985
984
|
"""
|
|
986
985
|
return isinstance(x, dict) and x.get("type") == "tool_call"
|
|
987
986
|
|
|
@@ -1128,7 +1127,7 @@ def _is_message_content_type(obj: Any) -> bool:
|
|
|
1128
1127
|
obj: The object to check.
|
|
1129
1128
|
|
|
1130
1129
|
Returns:
|
|
1131
|
-
True if the object is valid message content, False otherwise.
|
|
1130
|
+
`True` if the object is valid message content, `False` otherwise.
|
|
1132
1131
|
"""
|
|
1133
1132
|
return isinstance(obj, str) or (
|
|
1134
1133
|
isinstance(obj, list) and all(_is_message_content_block(e) for e in obj)
|
|
@@ -1144,7 +1143,7 @@ def _is_message_content_block(obj: Any) -> bool:
|
|
|
1144
1143
|
obj: The object to check.
|
|
1145
1144
|
|
|
1146
1145
|
Returns:
|
|
1147
|
-
True if the object is a valid content block, False otherwise.
|
|
1146
|
+
`True` if the object is a valid content block, `False` otherwise.
|
|
1148
1147
|
"""
|
|
1149
1148
|
if isinstance(obj, str):
|
|
1150
1149
|
return True
|
|
@@ -1217,24 +1216,24 @@ class InjectedToolCallId(InjectedToolArg):
|
|
|
1217
1216
|
This annotation is used to mark a tool parameter that should receive
|
|
1218
1217
|
the tool call ID at runtime.
|
|
1219
1218
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
)
|
|
1219
|
+
```python
|
|
1220
|
+
from typing import Annotated
|
|
1221
|
+
from langchain_core.messages import ToolMessage
|
|
1222
|
+
from langchain_core.tools import tool, InjectedToolCallId
|
|
1223
|
+
|
|
1224
|
+
@tool
|
|
1225
|
+
def foo(
|
|
1226
|
+
x: int, tool_call_id: Annotated[str, InjectedToolCallId]
|
|
1227
|
+
) -> ToolMessage:
|
|
1228
|
+
\"\"\"Return x.\"\"\"
|
|
1229
|
+
return ToolMessage(
|
|
1230
|
+
str(x),
|
|
1231
|
+
artifact=x,
|
|
1232
|
+
name="foo",
|
|
1233
|
+
tool_call_id=tool_call_id
|
|
1234
|
+
)
|
|
1237
1235
|
|
|
1236
|
+
```
|
|
1238
1237
|
"""
|
|
1239
1238
|
|
|
1240
1239
|
|
|
@@ -1248,7 +1247,7 @@ def _is_injected_arg_type(
|
|
|
1248
1247
|
injected_type: The specific injected type to check for.
|
|
1249
1248
|
|
|
1250
1249
|
Returns:
|
|
1251
|
-
True if the type is an injected argument, False otherwise.
|
|
1250
|
+
`True` if the type is an injected argument, `False` otherwise.
|
|
1252
1251
|
"""
|
|
1253
1252
|
injected_type = injected_type or InjectedToolArg
|
|
1254
1253
|
return any(
|
langchain_core/tools/convert.py
CHANGED
|
@@ -81,7 +81,7 @@ def tool(
|
|
|
81
81
|
parse_docstring: bool = False,
|
|
82
82
|
error_on_invalid_docstring: bool = True,
|
|
83
83
|
) -> BaseTool | Callable[[Callable | Runnable], BaseTool]:
|
|
84
|
-
"""Make tools out of functions, can be used with or without arguments.
|
|
84
|
+
"""Make tools out of Python functions, can be used with or without arguments.
|
|
85
85
|
|
|
86
86
|
Args:
|
|
87
87
|
name_or_callable: Optional name of the tool or the callable to be
|
|
@@ -91,140 +91,136 @@ def tool(
|
|
|
91
91
|
description: Optional description for the tool.
|
|
92
92
|
Precedence for the tool description value is as follows:
|
|
93
93
|
|
|
94
|
-
-
|
|
95
|
-
(used even if docstring and/or
|
|
96
|
-
-
|
|
97
|
-
(used even if
|
|
98
|
-
-
|
|
94
|
+
- `description` argument
|
|
95
|
+
(used even if docstring and/or `args_schema` are provided)
|
|
96
|
+
- Tool function docstring
|
|
97
|
+
(used even if `args_schema` is provided)
|
|
98
|
+
- `args_schema` description
|
|
99
99
|
(used only if `description` / docstring are not provided)
|
|
100
100
|
*args: Extra positional arguments. Must be empty.
|
|
101
101
|
return_direct: Whether to return directly from the tool rather
|
|
102
|
-
than continuing the agent loop.
|
|
103
|
-
args_schema:
|
|
104
|
-
|
|
102
|
+
than continuing the agent loop.
|
|
103
|
+
args_schema: Optional argument schema for user to specify.
|
|
104
|
+
|
|
105
105
|
infer_schema: Whether to infer the schema of the arguments from
|
|
106
106
|
the function's signature. This also makes the resultant tool
|
|
107
107
|
accept a dictionary input to its `run()` function.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
the
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Defaults to "content".
|
|
114
|
-
parse_docstring: if ``infer_schema`` and ``parse_docstring``, will attempt to
|
|
108
|
+
response_format: The tool response format. If `"content"` then the output of
|
|
109
|
+
the tool is interpreted as the contents of a `ToolMessage`. If
|
|
110
|
+
`"content_and_artifact"` then the output is expected to be a two-tuple
|
|
111
|
+
corresponding to the `(content, artifact)` of a `ToolMessage`.
|
|
112
|
+
parse_docstring: if `infer_schema` and `parse_docstring`, will attempt to
|
|
115
113
|
parse parameter descriptions from Google Style function docstrings.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
whether to raise ValueError on invalid Google Style docstrings.
|
|
119
|
-
Defaults to True.
|
|
114
|
+
error_on_invalid_docstring: if `parse_docstring` is provided, configure
|
|
115
|
+
whether to raise `ValueError` on invalid Google Style docstrings.
|
|
120
116
|
|
|
121
117
|
Raises:
|
|
122
118
|
ValueError: If too many positional arguments are provided.
|
|
123
119
|
ValueError: If a runnable is provided without a string name.
|
|
124
120
|
ValueError: If the first argument is not a string or callable with
|
|
125
|
-
a
|
|
121
|
+
a `__name__` attribute.
|
|
126
122
|
ValueError: If the function does not have a docstring and description
|
|
127
|
-
is not provided and
|
|
128
|
-
ValueError: If
|
|
129
|
-
Google-style docstring and
|
|
123
|
+
is not provided and `infer_schema` is `False`.
|
|
124
|
+
ValueError: If `parse_docstring` is `True` and the function has an invalid
|
|
125
|
+
Google-style docstring and `error_on_invalid_docstring` is True.
|
|
130
126
|
ValueError: If a Runnable is provided that does not have an object schema.
|
|
131
127
|
|
|
132
128
|
Returns:
|
|
133
129
|
The tool.
|
|
134
130
|
|
|
135
131
|
Requires:
|
|
136
|
-
- Function must be of type (str) -> str
|
|
132
|
+
- Function must be of type `(str) -> str`
|
|
137
133
|
- Function must have a docstring
|
|
138
134
|
|
|
139
135
|
Examples:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return
|
|
136
|
+
```python
|
|
137
|
+
@tool
|
|
138
|
+
def search_api(query: str) -> str:
|
|
139
|
+
# Searches the API for the query.
|
|
140
|
+
return
|
|
146
141
|
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
143
|
+
@tool("search", return_direct=True)
|
|
144
|
+
def search_api(query: str) -> str:
|
|
145
|
+
# Searches the API for the query.
|
|
146
|
+
return
|
|
152
147
|
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
@tool(response_format="content_and_artifact")
|
|
150
|
+
def search_api(query: str) -> tuple[str, dict]:
|
|
151
|
+
return "partial json of results", {"full": "object of results"}
|
|
152
|
+
```
|
|
157
153
|
|
|
158
154
|
!!! version-added "Added in version 0.2.14"
|
|
159
155
|
|
|
160
156
|
Parse Google-style docstrings:
|
|
161
157
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"type": "string",
|
|
187
|
-
},
|
|
188
|
-
"baz": {
|
|
189
|
-
"title": "Baz",
|
|
190
|
-
"description": "The baz.",
|
|
191
|
-
"type": "integer",
|
|
192
|
-
},
|
|
158
|
+
```python
|
|
159
|
+
@tool(parse_docstring=True)
|
|
160
|
+
def foo(bar: str, baz: int) -> str:
|
|
161
|
+
\"\"\"The foo.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
bar: The bar.
|
|
165
|
+
baz: The baz.
|
|
166
|
+
\"\"\"
|
|
167
|
+
return bar
|
|
168
|
+
|
|
169
|
+
foo.args_schema.model_json_schema()
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
{
|
|
174
|
+
"title": "foo",
|
|
175
|
+
"description": "The foo.",
|
|
176
|
+
"type": "object",
|
|
177
|
+
"properties": {
|
|
178
|
+
"bar": {
|
|
179
|
+
"title": "Bar",
|
|
180
|
+
"description": "The bar.",
|
|
181
|
+
"type": "string",
|
|
193
182
|
},
|
|
194
|
-
"
|
|
195
|
-
|
|
183
|
+
"baz": {
|
|
184
|
+
"title": "Baz",
|
|
185
|
+
"description": "The baz.",
|
|
186
|
+
"type": "integer",
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
"required": ["bar", "baz"],
|
|
190
|
+
}
|
|
191
|
+
```
|
|
196
192
|
|
|
197
|
-
Note that parsing by default will raise
|
|
193
|
+
Note that parsing by default will raise `ValueError` if the docstring
|
|
198
194
|
is considered invalid. A docstring is considered invalid if it contains
|
|
199
195
|
arguments not in the function signature, or is unable to be parsed into
|
|
200
|
-
a summary and "Args:" blocks. Examples below:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
196
|
+
a summary and `"Args:"` blocks. Examples below:
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
# No args section
|
|
200
|
+
def invalid_docstring_1(bar: str, baz: int) -> str:
|
|
201
|
+
\"\"\"The foo.\"\"\"
|
|
202
|
+
return bar
|
|
203
|
+
|
|
204
|
+
# Improper whitespace between summary and args section
|
|
205
|
+
def invalid_docstring_2(bar: str, baz: int) -> str:
|
|
206
|
+
\"\"\"The foo.
|
|
207
|
+
Args:
|
|
208
|
+
bar: The bar.
|
|
209
|
+
baz: The baz.
|
|
210
|
+
\"\"\"
|
|
211
|
+
return bar
|
|
212
|
+
|
|
213
|
+
# Documented args absent from function signature
|
|
214
|
+
def invalid_docstring_3(bar: str, baz: int) -> str:
|
|
215
|
+
\"\"\"The foo.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
banana: The bar.
|
|
219
|
+
monkey: The baz.
|
|
220
|
+
\"\"\"
|
|
221
|
+
return bar
|
|
222
|
+
|
|
223
|
+
```
|
|
228
224
|
""" # noqa: D214, D410, D411 # We're intentionally showing bad formatting in examples
|
|
229
225
|
|
|
230
226
|
def _create_tool_factory(
|
|
@@ -397,10 +393,10 @@ def convert_runnable_to_tool(
|
|
|
397
393
|
|
|
398
394
|
Args:
|
|
399
395
|
runnable: The runnable to convert.
|
|
400
|
-
args_schema: The schema for the tool's input arguments.
|
|
401
|
-
name: The name of the tool.
|
|
402
|
-
description: The description of the tool.
|
|
403
|
-
arg_types: The types of the arguments.
|
|
396
|
+
args_schema: The schema for the tool's input arguments.
|
|
397
|
+
name: The name of the tool.
|
|
398
|
+
description: The description of the tool.
|
|
399
|
+
arg_types: The types of the arguments.
|
|
404
400
|
|
|
405
401
|
Returns:
|
|
406
402
|
The tool.
|
langchain_core/tools/render.py
CHANGED
|
@@ -21,10 +21,10 @@ def render_text_description(tools: list[BaseTool]) -> str:
|
|
|
21
21
|
|
|
22
22
|
Output will be in the format of:
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
```txt
|
|
25
|
+
search: This tool is used for search
|
|
26
|
+
calculator: This tool is used for math
|
|
27
|
+
```
|
|
28
28
|
"""
|
|
29
29
|
descriptions = []
|
|
30
30
|
for tool in tools:
|
|
@@ -49,11 +49,11 @@ def render_text_description_and_args(tools: list[BaseTool]) -> str:
|
|
|
49
49
|
|
|
50
50
|
Output will be in the format of:
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
```txt
|
|
53
|
+
search: This tool is used for search, args: {"query": {"type": "string"}}
|
|
54
|
+
calculator: This tool is used for math, \
|
|
55
|
+
args: {"expression": {"type": "string"}}
|
|
56
|
+
```
|
|
57
57
|
"""
|
|
58
58
|
tool_strings = []
|
|
59
59
|
for tool in tools:
|
|
@@ -81,13 +81,13 @@ def create_retriever_tool(
|
|
|
81
81
|
so should be unique and somewhat descriptive.
|
|
82
82
|
description: The description for the tool. This will be passed to the language
|
|
83
83
|
model, so should be descriptive.
|
|
84
|
-
document_prompt: The prompt to use for the document.
|
|
85
|
-
document_separator: The separator to use between documents.
|
|
86
|
-
response_format: The tool response format. If "content" then the output of
|
|
87
|
-
the tool is interpreted as the contents of a ToolMessage
|
|
88
|
-
"content_and_artifact" then the output is expected to be a two-tuple
|
|
89
|
-
corresponding to the (content, artifact) of a ToolMessage (artifact
|
|
90
|
-
being a list of documents in this case).
|
|
84
|
+
document_prompt: The prompt to use for the document.
|
|
85
|
+
document_separator: The separator to use between documents.
|
|
86
|
+
response_format: The tool response format. If `"content"` then the output of
|
|
87
|
+
the tool is interpreted as the contents of a `ToolMessage`. If
|
|
88
|
+
`"content_and_artifact"` then the output is expected to be a two-tuple
|
|
89
|
+
corresponding to the `(content, artifact)` of a `ToolMessage` (artifact
|
|
90
|
+
being a list of documents in this case).
|
|
91
91
|
|
|
92
92
|
Returns:
|
|
93
93
|
Tool class to pass to an agent.
|
langchain_core/tools/simple.py
CHANGED
|
@@ -69,7 +69,7 @@ class Tool(BaseTool):
|
|
|
69
69
|
def _to_args_and_kwargs(
|
|
70
70
|
self, tool_input: str | dict, tool_call_id: str | None
|
|
71
71
|
) -> tuple[tuple, dict]:
|
|
72
|
-
"""Convert tool input to
|
|
72
|
+
"""Convert tool input to Pydantic model.
|
|
73
73
|
|
|
74
74
|
Args:
|
|
75
75
|
tool_input: The input to the tool.
|
|
@@ -79,8 +79,7 @@ class Tool(BaseTool):
|
|
|
79
79
|
ToolException: If the tool input is invalid.
|
|
80
80
|
|
|
81
81
|
Returns:
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
The Pydantic model args and kwargs.
|
|
84
83
|
"""
|
|
85
84
|
args, kwargs = super()._to_args_and_kwargs(tool_input, tool_call_id)
|
|
86
85
|
# For backwards compatibility. The tool must be run with a single input
|
|
@@ -177,10 +176,10 @@ class Tool(BaseTool):
|
|
|
177
176
|
func: The function to create the tool from.
|
|
178
177
|
name: The name of the tool.
|
|
179
178
|
description: The description of the tool.
|
|
180
|
-
return_direct: Whether to return the output directly.
|
|
181
|
-
args_schema: The schema of the tool's input arguments.
|
|
182
|
-
coroutine: The asynchronous version of the function.
|
|
183
|
-
kwargs: Additional arguments to pass to the tool.
|
|
179
|
+
return_direct: Whether to return the output directly.
|
|
180
|
+
args_schema: The schema of the tool's input arguments.
|
|
181
|
+
coroutine: The asynchronous version of the function.
|
|
182
|
+
**kwargs: Additional arguments to pass to the tool.
|
|
184
183
|
|
|
185
184
|
Returns:
|
|
186
185
|
The tool.
|