langchain-core 0.3.79__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langchain-core might be problematic. Click here for more details.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +23 -26
- langchain_core/_api/deprecation.py +52 -65
- langchain_core/_api/path.py +3 -6
- langchain_core/_import_utils.py +3 -4
- langchain_core/agents.py +19 -19
- langchain_core/caches.py +53 -63
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +323 -334
- langchain_core/callbacks/file.py +44 -44
- langchain_core/callbacks/manager.py +441 -507
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +32 -32
- langchain_core/callbacks/usage.py +60 -57
- langchain_core/chat_history.py +48 -63
- langchain_core/document_loaders/base.py +23 -23
- langchain_core/document_loaders/langsmith.py +37 -37
- langchain_core/documents/__init__.py +0 -1
- langchain_core/documents/base.py +62 -65
- langchain_core/documents/compressor.py +4 -4
- langchain_core/documents/transformers.py +28 -29
- langchain_core/embeddings/fake.py +50 -54
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +21 -25
- langchain_core/exceptions.py +10 -11
- langchain_core/globals.py +3 -151
- langchain_core/indexing/api.py +61 -66
- langchain_core/indexing/base.py +58 -58
- langchain_core/indexing/in_memory.py +3 -3
- langchain_core/language_models/__init__.py +14 -27
- langchain_core/language_models/_utils.py +270 -84
- langchain_core/language_models/base.py +55 -162
- langchain_core/language_models/chat_models.py +442 -402
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +61 -39
- langchain_core/language_models/llms.py +123 -231
- langchain_core/load/dump.py +4 -5
- langchain_core/load/load.py +18 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +39 -40
- langchain_core/messages/__init__.py +61 -22
- langchain_core/messages/ai.py +368 -163
- langchain_core/messages/base.py +214 -43
- langchain_core/messages/block_translators/__init__.py +111 -0
- langchain_core/messages/block_translators/anthropic.py +470 -0
- langchain_core/messages/block_translators/bedrock.py +94 -0
- langchain_core/messages/block_translators/bedrock_converse.py +297 -0
- langchain_core/messages/block_translators/google_genai.py +530 -0
- langchain_core/messages/block_translators/google_vertexai.py +21 -0
- langchain_core/messages/block_translators/groq.py +143 -0
- langchain_core/messages/block_translators/langchain_v0.py +301 -0
- langchain_core/messages/block_translators/openai.py +1010 -0
- langchain_core/messages/chat.py +2 -6
- langchain_core/messages/content.py +1423 -0
- langchain_core/messages/function.py +6 -10
- langchain_core/messages/human.py +41 -38
- langchain_core/messages/modifier.py +2 -2
- langchain_core/messages/system.py +38 -28
- langchain_core/messages/tool.py +96 -103
- langchain_core/messages/utils.py +478 -504
- langchain_core/output_parsers/__init__.py +1 -14
- langchain_core/output_parsers/base.py +58 -61
- langchain_core/output_parsers/json.py +7 -8
- langchain_core/output_parsers/list.py +5 -7
- langchain_core/output_parsers/openai_functions.py +49 -47
- langchain_core/output_parsers/openai_tools.py +14 -19
- langchain_core/output_parsers/pydantic.py +12 -13
- langchain_core/output_parsers/string.py +2 -2
- langchain_core/output_parsers/transform.py +15 -17
- langchain_core/output_parsers/xml.py +8 -10
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +18 -18
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +8 -8
- langchain_core/outputs/llm_result.py +10 -10
- langchain_core/prompt_values.py +12 -12
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +45 -55
- langchain_core/prompts/chat.py +254 -313
- langchain_core/prompts/dict.py +5 -5
- langchain_core/prompts/few_shot.py +81 -88
- langchain_core/prompts/few_shot_with_templates.py +11 -13
- langchain_core/prompts/image.py +12 -14
- langchain_core/prompts/loading.py +6 -8
- langchain_core/prompts/message.py +3 -3
- langchain_core/prompts/prompt.py +24 -39
- langchain_core/prompts/string.py +4 -4
- langchain_core/prompts/structured.py +42 -50
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +49 -190
- langchain_core/runnables/base.py +1484 -1709
- langchain_core/runnables/branch.py +45 -61
- langchain_core/runnables/config.py +80 -88
- langchain_core/runnables/configurable.py +117 -134
- langchain_core/runnables/fallbacks.py +83 -79
- langchain_core/runnables/graph.py +85 -95
- langchain_core/runnables/graph_ascii.py +27 -28
- langchain_core/runnables/graph_mermaid.py +38 -50
- langchain_core/runnables/graph_png.py +15 -16
- langchain_core/runnables/history.py +135 -148
- langchain_core/runnables/passthrough.py +124 -150
- langchain_core/runnables/retry.py +46 -51
- langchain_core/runnables/router.py +25 -30
- langchain_core/runnables/schema.py +79 -74
- langchain_core/runnables/utils.py +62 -68
- langchain_core/stores.py +81 -115
- langchain_core/structured_query.py +8 -8
- langchain_core/sys_info.py +27 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +179 -187
- langchain_core/tools/convert.py +131 -139
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +11 -11
- langchain_core/tools/simple.py +19 -24
- langchain_core/tools/structured.py +30 -39
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/base.py +97 -99
- langchain_core/tracers/context.py +29 -52
- langchain_core/tracers/core.py +50 -60
- langchain_core/tracers/evaluation.py +11 -11
- langchain_core/tracers/event_stream.py +115 -70
- langchain_core/tracers/langchain.py +21 -21
- langchain_core/tracers/log_stream.py +43 -43
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +16 -16
- langchain_core/tracers/run_collector.py +2 -4
- langchain_core/tracers/schemas.py +0 -129
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +46 -8
- langchain_core/utils/aiter.py +57 -61
- langchain_core/utils/env.py +9 -9
- langchain_core/utils/function_calling.py +89 -191
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +1 -1
- langchain_core/utils/iter.py +37 -42
- langchain_core/utils/json.py +4 -3
- langchain_core/utils/json_schema.py +8 -8
- langchain_core/utils/mustache.py +9 -11
- langchain_core/utils/pydantic.py +33 -35
- langchain_core/utils/strings.py +5 -5
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +80 -54
- langchain_core/vectorstores/base.py +129 -164
- langchain_core/vectorstores/in_memory.py +99 -174
- langchain_core/vectorstores/utils.py +5 -5
- langchain_core/version.py +1 -1
- {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/METADATA +28 -27
- langchain_core-1.0.0.dist-info/RECORD +172 -0
- {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
- langchain_core/beta/__init__.py +0 -1
- langchain_core/beta/runnables/__init__.py +0 -1
- langchain_core/beta/runnables/context.py +0 -447
- langchain_core/memory.py +0 -120
- langchain_core/messages/content_blocks.py +0 -176
- langchain_core/prompts/pipeline.py +0 -138
- langchain_core/pydantic_v1/__init__.py +0 -30
- langchain_core/pydantic_v1/dataclasses.py +0 -23
- langchain_core/pydantic_v1/main.py +0 -23
- langchain_core/tracers/langchain_v1.py +0 -31
- langchain_core/utils/loading.py +0 -35
- langchain_core-0.3.79.dist-info/RECORD +0 -174
- langchain_core-0.3.79.dist-info/entry_points.txt +0 -4
langchain_core/tools/base.py
CHANGED
|
@@ -8,16 +8,14 @@ import json
|
|
|
8
8
|
import typing
|
|
9
9
|
import warnings
|
|
10
10
|
from abc import ABC, abstractmethod
|
|
11
|
+
from collections.abc import Callable
|
|
11
12
|
from inspect import signature
|
|
12
13
|
from typing import (
|
|
13
14
|
TYPE_CHECKING,
|
|
14
15
|
Annotated,
|
|
15
16
|
Any,
|
|
16
|
-
Callable,
|
|
17
17
|
Literal,
|
|
18
|
-
Optional,
|
|
19
18
|
TypeVar,
|
|
20
|
-
Union,
|
|
21
19
|
cast,
|
|
22
20
|
get_args,
|
|
23
21
|
get_origin,
|
|
@@ -31,7 +29,6 @@ from pydantic import (
|
|
|
31
29
|
PydanticDeprecationWarning,
|
|
32
30
|
SkipValidation,
|
|
33
31
|
ValidationError,
|
|
34
|
-
model_validator,
|
|
35
32
|
validate_arguments,
|
|
36
33
|
)
|
|
37
34
|
from pydantic.v1 import BaseModel as BaseModelV1
|
|
@@ -39,10 +36,8 @@ from pydantic.v1 import ValidationError as ValidationErrorV1
|
|
|
39
36
|
from pydantic.v1 import validate_arguments as validate_arguments_v1
|
|
40
37
|
from typing_extensions import override
|
|
41
38
|
|
|
42
|
-
from langchain_core._api import deprecated
|
|
43
39
|
from langchain_core.callbacks import (
|
|
44
40
|
AsyncCallbackManager,
|
|
45
|
-
BaseCallbackManager,
|
|
46
41
|
CallbackManager,
|
|
47
42
|
Callbacks,
|
|
48
43
|
)
|
|
@@ -97,7 +92,7 @@ def _is_annotated_type(typ: type[Any]) -> bool:
|
|
|
97
92
|
typ: The type to check.
|
|
98
93
|
|
|
99
94
|
Returns:
|
|
100
|
-
True if the type is an Annotated type, False otherwise.
|
|
95
|
+
`True` if the type is an Annotated type, `False` otherwise.
|
|
101
96
|
"""
|
|
102
97
|
return get_origin(typ) is typing.Annotated
|
|
103
98
|
|
|
@@ -231,7 +226,7 @@ def _is_pydantic_annotation(annotation: Any, pydantic_version: str = "v2") -> bo
|
|
|
231
226
|
pydantic_version: The Pydantic version to check against ("v1" or "v2").
|
|
232
227
|
|
|
233
228
|
Returns:
|
|
234
|
-
True if the annotation is a Pydantic model, False otherwise.
|
|
229
|
+
`True` if the annotation is a Pydantic model, `False` otherwise.
|
|
235
230
|
"""
|
|
236
231
|
base_model_class = BaseModelV1 if pydantic_version == "v1" else BaseModel
|
|
237
232
|
try:
|
|
@@ -250,7 +245,7 @@ def _function_annotations_are_pydantic_v1(
|
|
|
250
245
|
func: The function being checked.
|
|
251
246
|
|
|
252
247
|
Returns:
|
|
253
|
-
True if all Pydantic annotations are from V1, False otherwise.
|
|
248
|
+
True if all Pydantic annotations are from V1, `False` otherwise.
|
|
254
249
|
|
|
255
250
|
Raises:
|
|
256
251
|
NotImplementedError: If the function contains mixed V1 and V2 annotations.
|
|
@@ -285,29 +280,28 @@ def create_schema_from_function(
|
|
|
285
280
|
model_name: str,
|
|
286
281
|
func: Callable,
|
|
287
282
|
*,
|
|
288
|
-
filter_args:
|
|
283
|
+
filter_args: Sequence[str] | None = None,
|
|
289
284
|
parse_docstring: bool = False,
|
|
290
285
|
error_on_invalid_docstring: bool = False,
|
|
291
286
|
include_injected: bool = True,
|
|
292
287
|
) -> type[BaseModel]:
|
|
293
|
-
"""Create a
|
|
288
|
+
"""Create a Pydantic schema from a function's signature.
|
|
294
289
|
|
|
295
290
|
Args:
|
|
296
|
-
model_name: Name to assign to the generated
|
|
291
|
+
model_name: Name to assign to the generated Pydantic schema.
|
|
297
292
|
func: Function to generate the schema from.
|
|
298
293
|
filter_args: Optional list of arguments to exclude from the schema.
|
|
299
|
-
Defaults to FILTERED_ARGS
|
|
294
|
+
Defaults to `FILTERED_ARGS`.
|
|
300
295
|
parse_docstring: Whether to parse the function's docstring for descriptions
|
|
301
|
-
for each argument.
|
|
302
|
-
error_on_invalid_docstring: if
|
|
303
|
-
whether to raise ValueError on invalid Google Style docstrings.
|
|
304
|
-
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.
|
|
305
299
|
include_injected: Whether to include injected arguments in the schema.
|
|
306
|
-
Defaults to True
|
|
300
|
+
Defaults to `True`, since we want to include them in the schema
|
|
307
301
|
when *validating* tool inputs.
|
|
308
302
|
|
|
309
303
|
Returns:
|
|
310
|
-
A
|
|
304
|
+
A Pydantic model with the same arguments as the function.
|
|
311
305
|
"""
|
|
312
306
|
sig = inspect.signature(func)
|
|
313
307
|
|
|
@@ -317,7 +311,7 @@ def create_schema_from_function(
|
|
|
317
311
|
# https://docs.pydantic.dev/latest/usage/validation_decorator/
|
|
318
312
|
with warnings.catch_warnings():
|
|
319
313
|
# We are using deprecated functionality here.
|
|
320
|
-
# This code should be re-written to simply construct a
|
|
314
|
+
# This code should be re-written to simply construct a Pydantic model
|
|
321
315
|
# using inspect.signature and create_model.
|
|
322
316
|
warnings.simplefilter("ignore", category=PydanticDeprecationWarning)
|
|
323
317
|
validated = validate_arguments(func, config=_SchemaConfig) # type: ignore[operator]
|
|
@@ -390,10 +384,10 @@ class ToolException(Exception): # noqa: N818
|
|
|
390
384
|
"""
|
|
391
385
|
|
|
392
386
|
|
|
393
|
-
ArgsSchema =
|
|
387
|
+
ArgsSchema = TypeBaseModel | dict[str, Any]
|
|
394
388
|
|
|
395
389
|
|
|
396
|
-
class BaseTool(RunnableSerializable[
|
|
390
|
+
class BaseTool(RunnableSerializable[str | dict | ToolCall, Any]):
|
|
397
391
|
"""Base class for all LangChain tools.
|
|
398
392
|
|
|
399
393
|
This abstract class defines the interface that all LangChain tools must implement.
|
|
@@ -441,7 +435,7 @@ class ChildTool(BaseTool):
|
|
|
441
435
|
You can provide few-shot examples as a part of the description.
|
|
442
436
|
"""
|
|
443
437
|
|
|
444
|
-
args_schema: Annotated[
|
|
438
|
+
args_schema: Annotated[ArgsSchema | None, SkipValidation()] = Field(
|
|
445
439
|
default=None, description="The tool schema."
|
|
446
440
|
)
|
|
447
441
|
"""Pydantic model class to validate and parse the tool's input arguments.
|
|
@@ -464,51 +458,40 @@ class ChildTool(BaseTool):
|
|
|
464
458
|
callbacks: Callbacks = Field(default=None, exclude=True)
|
|
465
459
|
"""Callbacks to be called during tool execution."""
|
|
466
460
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
)(
|
|
470
|
-
Field(
|
|
471
|
-
default=None,
|
|
472
|
-
exclude=True,
|
|
473
|
-
description="Callback manager to add to the run trace.",
|
|
474
|
-
)
|
|
475
|
-
)
|
|
476
|
-
tags: Optional[list[str]] = None
|
|
477
|
-
"""Optional list of tags associated with the tool. Defaults to None.
|
|
461
|
+
tags: list[str] | None = None
|
|
462
|
+
"""Optional list of tags associated with the tool.
|
|
478
463
|
These tags will be associated with each call to this tool,
|
|
479
464
|
and passed as arguments to the handlers defined in `callbacks`.
|
|
480
465
|
You can use these to eg identify a specific instance of a tool with its use case.
|
|
481
466
|
"""
|
|
482
|
-
metadata:
|
|
483
|
-
"""Optional metadata associated with the tool.
|
|
467
|
+
metadata: dict[str, Any] | None = None
|
|
468
|
+
"""Optional metadata associated with the tool.
|
|
484
469
|
This metadata will be associated with each call to this tool,
|
|
485
470
|
and passed as arguments to the handlers defined in `callbacks`.
|
|
486
471
|
You can use these to eg identify a specific instance of a tool with its use case.
|
|
487
472
|
"""
|
|
488
473
|
|
|
489
|
-
handle_tool_error:
|
|
490
|
-
False
|
|
491
|
-
)
|
|
474
|
+
handle_tool_error: bool | str | Callable[[ToolException], str] | None = False
|
|
492
475
|
"""Handle the content of the ToolException thrown."""
|
|
493
476
|
|
|
494
|
-
handle_validation_error:
|
|
495
|
-
|
|
496
|
-
|
|
477
|
+
handle_validation_error: (
|
|
478
|
+
bool | str | Callable[[ValidationError | ValidationErrorV1], str] | None
|
|
479
|
+
) = False
|
|
497
480
|
"""Handle the content of the ValidationError thrown."""
|
|
498
481
|
|
|
499
482
|
response_format: Literal["content", "content_and_artifact"] = "content"
|
|
500
|
-
"""The tool response format.
|
|
483
|
+
"""The tool response format.
|
|
501
484
|
|
|
502
|
-
If "content" then the output of the tool is interpreted as the contents of a
|
|
503
|
-
ToolMessage. If "content_and_artifact" then the output is expected to be a
|
|
504
|
-
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`.
|
|
505
488
|
"""
|
|
506
489
|
|
|
507
490
|
def __init__(self, **kwargs: Any) -> None:
|
|
508
491
|
"""Initialize the tool.
|
|
509
492
|
|
|
510
493
|
Raises:
|
|
511
|
-
TypeError: If
|
|
494
|
+
TypeError: If `args_schema` is not a subclass of pydantic `BaseModel` or
|
|
512
495
|
dict.
|
|
513
496
|
"""
|
|
514
497
|
if (
|
|
@@ -533,7 +516,7 @@ class ChildTool(BaseTool):
|
|
|
533
516
|
"""Check if the tool accepts only a single input argument.
|
|
534
517
|
|
|
535
518
|
Returns:
|
|
536
|
-
True if the tool has only one input argument, False otherwise.
|
|
519
|
+
`True` if the tool has only one input argument, `False` otherwise.
|
|
537
520
|
"""
|
|
538
521
|
keys = {k for k in self.args if k != "kwargs"}
|
|
539
522
|
return len(keys) == 1
|
|
@@ -582,9 +565,7 @@ class ChildTool(BaseTool):
|
|
|
582
565
|
# --- Runnable ---
|
|
583
566
|
|
|
584
567
|
@override
|
|
585
|
-
def get_input_schema(
|
|
586
|
-
self, config: Optional[RunnableConfig] = None
|
|
587
|
-
) -> type[BaseModel]:
|
|
568
|
+
def get_input_schema(self, config: RunnableConfig | None = None) -> type[BaseModel]:
|
|
588
569
|
"""The tool's input schema.
|
|
589
570
|
|
|
590
571
|
Args:
|
|
@@ -602,8 +583,8 @@ class ChildTool(BaseTool):
|
|
|
602
583
|
@override
|
|
603
584
|
def invoke(
|
|
604
585
|
self,
|
|
605
|
-
input:
|
|
606
|
-
config:
|
|
586
|
+
input: str | dict | ToolCall,
|
|
587
|
+
config: RunnableConfig | None = None,
|
|
607
588
|
**kwargs: Any,
|
|
608
589
|
) -> Any:
|
|
609
590
|
tool_input, kwargs = _prep_run_args(input, config, **kwargs)
|
|
@@ -612,8 +593,8 @@ class ChildTool(BaseTool):
|
|
|
612
593
|
@override
|
|
613
594
|
async def ainvoke(
|
|
614
595
|
self,
|
|
615
|
-
input:
|
|
616
|
-
config:
|
|
596
|
+
input: str | dict | ToolCall,
|
|
597
|
+
config: RunnableConfig | None = None,
|
|
617
598
|
**kwargs: Any,
|
|
618
599
|
) -> Any:
|
|
619
600
|
tool_input, kwargs = _prep_run_args(input, config, **kwargs)
|
|
@@ -622,8 +603,8 @@ class ChildTool(BaseTool):
|
|
|
622
603
|
# --- Tool ---
|
|
623
604
|
|
|
624
605
|
def _parse_input(
|
|
625
|
-
self, tool_input:
|
|
626
|
-
) ->
|
|
606
|
+
self, tool_input: str | dict, tool_call_id: str | None
|
|
607
|
+
) -> str | dict[str, Any]:
|
|
627
608
|
"""Parse and validate tool input using the args schema.
|
|
628
609
|
|
|
629
610
|
Args:
|
|
@@ -634,10 +615,10 @@ class ChildTool(BaseTool):
|
|
|
634
615
|
The parsed and validated input.
|
|
635
616
|
|
|
636
617
|
Raises:
|
|
637
|
-
ValueError: If string input is provided with JSON schema
|
|
638
|
-
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
|
|
639
620
|
provided.
|
|
640
|
-
TypeError: If args_schema is not a Pydantic
|
|
621
|
+
TypeError: If args_schema is not a Pydantic `BaseModel` or dict.
|
|
641
622
|
"""
|
|
642
623
|
input_args = self.args_schema
|
|
643
624
|
if isinstance(tool_input, str):
|
|
@@ -700,32 +681,12 @@ class ChildTool(BaseTool):
|
|
|
700
681
|
}
|
|
701
682
|
return tool_input
|
|
702
683
|
|
|
703
|
-
@model_validator(mode="before")
|
|
704
|
-
@classmethod
|
|
705
|
-
def raise_deprecation(cls, values: dict) -> Any:
|
|
706
|
-
"""Raise deprecation warning if callback_manager is used.
|
|
707
|
-
|
|
708
|
-
Args:
|
|
709
|
-
values: The values to validate.
|
|
710
|
-
|
|
711
|
-
Returns:
|
|
712
|
-
The validated values.
|
|
713
|
-
"""
|
|
714
|
-
if values.get("callback_manager") is not None:
|
|
715
|
-
warnings.warn(
|
|
716
|
-
"callback_manager is deprecated. Please use callbacks instead.",
|
|
717
|
-
DeprecationWarning,
|
|
718
|
-
stacklevel=6,
|
|
719
|
-
)
|
|
720
|
-
values["callbacks"] = values.pop("callback_manager", None)
|
|
721
|
-
return values
|
|
722
|
-
|
|
723
684
|
@abstractmethod
|
|
724
685
|
def _run(self, *args: Any, **kwargs: Any) -> Any:
|
|
725
686
|
"""Use the tool.
|
|
726
687
|
|
|
727
|
-
Add run_manager:
|
|
728
|
-
|
|
688
|
+
Add `run_manager: CallbackManagerForToolRun | None = None` to child
|
|
689
|
+
implementations to enable tracing.
|
|
729
690
|
|
|
730
691
|
Returns:
|
|
731
692
|
The result of the tool execution.
|
|
@@ -734,8 +695,8 @@ class ChildTool(BaseTool):
|
|
|
734
695
|
async def _arun(self, *args: Any, **kwargs: Any) -> Any:
|
|
735
696
|
"""Use the tool asynchronously.
|
|
736
697
|
|
|
737
|
-
Add run_manager:
|
|
738
|
-
|
|
698
|
+
Add `run_manager: AsyncCallbackManagerForToolRun | None = None` to child
|
|
699
|
+
implementations to enable tracing.
|
|
739
700
|
|
|
740
701
|
Returns:
|
|
741
702
|
The result of the tool execution.
|
|
@@ -747,7 +708,7 @@ class ChildTool(BaseTool):
|
|
|
747
708
|
return await run_in_executor(None, self._run, *args, **kwargs)
|
|
748
709
|
|
|
749
710
|
def _to_args_and_kwargs(
|
|
750
|
-
self, tool_input:
|
|
711
|
+
self, tool_input: str | dict, tool_call_id: str | None
|
|
751
712
|
) -> tuple[tuple, dict]:
|
|
752
713
|
"""Convert tool input to positional and keyword arguments.
|
|
753
714
|
|
|
@@ -787,35 +748,35 @@ class ChildTool(BaseTool):
|
|
|
787
748
|
|
|
788
749
|
def run(
|
|
789
750
|
self,
|
|
790
|
-
tool_input:
|
|
791
|
-
verbose:
|
|
792
|
-
start_color:
|
|
793
|
-
color:
|
|
751
|
+
tool_input: str | dict[str, Any],
|
|
752
|
+
verbose: bool | None = None, # noqa: FBT001
|
|
753
|
+
start_color: str | None = "green",
|
|
754
|
+
color: str | None = "green",
|
|
794
755
|
callbacks: Callbacks = None,
|
|
795
756
|
*,
|
|
796
|
-
tags:
|
|
797
|
-
metadata:
|
|
798
|
-
run_name:
|
|
799
|
-
run_id:
|
|
800
|
-
config:
|
|
801
|
-
tool_call_id:
|
|
757
|
+
tags: list[str] | None = None,
|
|
758
|
+
metadata: dict[str, Any] | None = None,
|
|
759
|
+
run_name: str | None = None,
|
|
760
|
+
run_id: uuid.UUID | None = None,
|
|
761
|
+
config: RunnableConfig | None = None,
|
|
762
|
+
tool_call_id: str | None = None,
|
|
802
763
|
**kwargs: Any,
|
|
803
764
|
) -> Any:
|
|
804
765
|
"""Run the tool.
|
|
805
766
|
|
|
806
767
|
Args:
|
|
807
768
|
tool_input: The input to the tool.
|
|
808
|
-
verbose: Whether to log the tool's progress.
|
|
809
|
-
start_color: The color to use when starting the tool.
|
|
810
|
-
color: The color to use when ending the tool.
|
|
811
|
-
callbacks: Callbacks to be called during tool execution.
|
|
812
|
-
tags: Optional list of tags associated with the tool.
|
|
813
|
-
metadata: Optional metadata associated with the tool.
|
|
814
|
-
run_name: The name of the run.
|
|
815
|
-
run_id: The id of the run.
|
|
816
|
-
config: The configuration for the tool.
|
|
817
|
-
tool_call_id: The id of the tool call.
|
|
818
|
-
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)
|
|
819
780
|
|
|
820
781
|
Returns:
|
|
821
782
|
The output of the tool.
|
|
@@ -850,7 +811,7 @@ class ChildTool(BaseTool):
|
|
|
850
811
|
content = None
|
|
851
812
|
artifact = None
|
|
852
813
|
status = "success"
|
|
853
|
-
error_to_raise:
|
|
814
|
+
error_to_raise: Exception | KeyboardInterrupt | None = None
|
|
854
815
|
try:
|
|
855
816
|
child_config = patch_config(config, callbacks=run_manager.get_child())
|
|
856
817
|
with set_config_context(child_config) as context:
|
|
@@ -899,35 +860,35 @@ class ChildTool(BaseTool):
|
|
|
899
860
|
|
|
900
861
|
async def arun(
|
|
901
862
|
self,
|
|
902
|
-
tool_input:
|
|
903
|
-
verbose:
|
|
904
|
-
start_color:
|
|
905
|
-
color:
|
|
863
|
+
tool_input: str | dict,
|
|
864
|
+
verbose: bool | None = None, # noqa: FBT001
|
|
865
|
+
start_color: str | None = "green",
|
|
866
|
+
color: str | None = "green",
|
|
906
867
|
callbacks: Callbacks = None,
|
|
907
868
|
*,
|
|
908
|
-
tags:
|
|
909
|
-
metadata:
|
|
910
|
-
run_name:
|
|
911
|
-
run_id:
|
|
912
|
-
config:
|
|
913
|
-
tool_call_id:
|
|
869
|
+
tags: list[str] | None = None,
|
|
870
|
+
metadata: dict[str, Any] | None = None,
|
|
871
|
+
run_name: str | None = None,
|
|
872
|
+
run_id: uuid.UUID | None = None,
|
|
873
|
+
config: RunnableConfig | None = None,
|
|
874
|
+
tool_call_id: str | None = None,
|
|
914
875
|
**kwargs: Any,
|
|
915
876
|
) -> Any:
|
|
916
877
|
"""Run the tool asynchronously.
|
|
917
878
|
|
|
918
879
|
Args:
|
|
919
880
|
tool_input: The input to the tool.
|
|
920
|
-
verbose: Whether to log the tool's progress.
|
|
921
|
-
start_color: The color to use when starting the tool.
|
|
922
|
-
color: The color to use when ending the tool.
|
|
923
|
-
callbacks: Callbacks to be called during tool execution.
|
|
924
|
-
tags: Optional list of tags associated with the tool.
|
|
925
|
-
metadata: Optional metadata associated with the tool.
|
|
926
|
-
run_name: The name of the run.
|
|
927
|
-
run_id: The id of the run.
|
|
928
|
-
config: The configuration for the tool.
|
|
929
|
-
tool_call_id: The id of the tool call.
|
|
930
|
-
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
|
|
931
892
|
|
|
932
893
|
Returns:
|
|
933
894
|
The output of the tool.
|
|
@@ -960,7 +921,7 @@ class ChildTool(BaseTool):
|
|
|
960
921
|
content = None
|
|
961
922
|
artifact = None
|
|
962
923
|
status = "success"
|
|
963
|
-
error_to_raise:
|
|
924
|
+
error_to_raise: Exception | KeyboardInterrupt | None = None
|
|
964
925
|
try:
|
|
965
926
|
tool_args, tool_kwargs = self._to_args_and_kwargs(tool_input, tool_call_id)
|
|
966
927
|
child_config = patch_config(config, callbacks=run_manager.get_child())
|
|
@@ -1011,19 +972,6 @@ class ChildTool(BaseTool):
|
|
|
1011
972
|
await run_manager.on_tool_end(output, color=color, name=self.name, **kwargs)
|
|
1012
973
|
return output
|
|
1013
974
|
|
|
1014
|
-
@deprecated("0.1.47", alternative="invoke", removal="1.0")
|
|
1015
|
-
def __call__(self, tool_input: str, callbacks: Callbacks = None) -> str:
|
|
1016
|
-
"""Make tool callable (deprecated).
|
|
1017
|
-
|
|
1018
|
-
Args:
|
|
1019
|
-
tool_input: The input to the tool.
|
|
1020
|
-
callbacks: Callbacks to use during execution.
|
|
1021
|
-
|
|
1022
|
-
Returns:
|
|
1023
|
-
The tool's output.
|
|
1024
|
-
"""
|
|
1025
|
-
return self.run(tool_input, callbacks=callbacks)
|
|
1026
|
-
|
|
1027
975
|
|
|
1028
976
|
def _is_tool_call(x: Any) -> bool:
|
|
1029
977
|
"""Check if the input is a tool call dictionary.
|
|
@@ -1032,17 +980,15 @@ def _is_tool_call(x: Any) -> bool:
|
|
|
1032
980
|
x: The input to check.
|
|
1033
981
|
|
|
1034
982
|
Returns:
|
|
1035
|
-
True if the input is a tool call, False otherwise.
|
|
983
|
+
`True` if the input is a tool call, `False` otherwise.
|
|
1036
984
|
"""
|
|
1037
985
|
return isinstance(x, dict) and x.get("type") == "tool_call"
|
|
1038
986
|
|
|
1039
987
|
|
|
1040
988
|
def _handle_validation_error(
|
|
1041
|
-
e:
|
|
989
|
+
e: ValidationError | ValidationErrorV1,
|
|
1042
990
|
*,
|
|
1043
|
-
flag:
|
|
1044
|
-
Literal[True], str, Callable[[Union[ValidationError, ValidationErrorV1]], str]
|
|
1045
|
-
],
|
|
991
|
+
flag: Literal[True] | str | Callable[[ValidationError | ValidationErrorV1], str],
|
|
1046
992
|
) -> str:
|
|
1047
993
|
"""Handle validation errors based on the configured flag.
|
|
1048
994
|
|
|
@@ -1074,7 +1020,7 @@ def _handle_validation_error(
|
|
|
1074
1020
|
def _handle_tool_error(
|
|
1075
1021
|
e: ToolException,
|
|
1076
1022
|
*,
|
|
1077
|
-
flag:
|
|
1023
|
+
flag: Literal[True] | str | Callable[[ToolException], str] | None,
|
|
1078
1024
|
) -> str:
|
|
1079
1025
|
"""Handle tool execution errors based on the configured flag.
|
|
1080
1026
|
|
|
@@ -1104,10 +1050,10 @@ def _handle_tool_error(
|
|
|
1104
1050
|
|
|
1105
1051
|
|
|
1106
1052
|
def _prep_run_args(
|
|
1107
|
-
value:
|
|
1108
|
-
config:
|
|
1053
|
+
value: str | dict | ToolCall,
|
|
1054
|
+
config: RunnableConfig | None,
|
|
1109
1055
|
**kwargs: Any,
|
|
1110
|
-
) -> tuple[
|
|
1056
|
+
) -> tuple[str | dict, dict]:
|
|
1111
1057
|
"""Prepare arguments for tool execution.
|
|
1112
1058
|
|
|
1113
1059
|
Args:
|
|
@@ -1120,11 +1066,11 @@ def _prep_run_args(
|
|
|
1120
1066
|
"""
|
|
1121
1067
|
config = ensure_config(config)
|
|
1122
1068
|
if _is_tool_call(value):
|
|
1123
|
-
tool_call_id:
|
|
1124
|
-
tool_input:
|
|
1069
|
+
tool_call_id: str | None = cast("ToolCall", value)["id"]
|
|
1070
|
+
tool_input: str | dict = cast("ToolCall", value)["args"].copy()
|
|
1125
1071
|
else:
|
|
1126
1072
|
tool_call_id = None
|
|
1127
|
-
tool_input = cast("
|
|
1073
|
+
tool_input = cast("str | dict", value)
|
|
1128
1074
|
return (
|
|
1129
1075
|
tool_input,
|
|
1130
1076
|
dict(
|
|
@@ -1143,10 +1089,10 @@ def _prep_run_args(
|
|
|
1143
1089
|
def _format_output(
|
|
1144
1090
|
content: Any,
|
|
1145
1091
|
artifact: Any,
|
|
1146
|
-
tool_call_id:
|
|
1092
|
+
tool_call_id: str | None,
|
|
1147
1093
|
name: str,
|
|
1148
1094
|
status: str,
|
|
1149
|
-
) ->
|
|
1095
|
+
) -> ToolOutputMixin | Any:
|
|
1150
1096
|
"""Format tool output as a ToolMessage if appropriate.
|
|
1151
1097
|
|
|
1152
1098
|
Args:
|
|
@@ -1181,7 +1127,7 @@ def _is_message_content_type(obj: Any) -> bool:
|
|
|
1181
1127
|
obj: The object to check.
|
|
1182
1128
|
|
|
1183
1129
|
Returns:
|
|
1184
|
-
True if the object is valid message content, False otherwise.
|
|
1130
|
+
`True` if the object is valid message content, `False` otherwise.
|
|
1185
1131
|
"""
|
|
1186
1132
|
return isinstance(obj, str) or (
|
|
1187
1133
|
isinstance(obj, list) and all(_is_message_content_block(e) for e in obj)
|
|
@@ -1197,7 +1143,7 @@ def _is_message_content_block(obj: Any) -> bool:
|
|
|
1197
1143
|
obj: The object to check.
|
|
1198
1144
|
|
|
1199
1145
|
Returns:
|
|
1200
|
-
True if the object is a valid content block, False otherwise.
|
|
1146
|
+
`True` if the object is a valid content block, `False` otherwise.
|
|
1201
1147
|
"""
|
|
1202
1148
|
if isinstance(obj, str):
|
|
1203
1149
|
return True
|
|
@@ -1221,7 +1167,7 @@ def _stringify(content: Any) -> str:
|
|
|
1221
1167
|
return str(content)
|
|
1222
1168
|
|
|
1223
1169
|
|
|
1224
|
-
def _get_type_hints(func: Callable) ->
|
|
1170
|
+
def _get_type_hints(func: Callable) -> dict[str, type] | None:
|
|
1225
1171
|
"""Get type hints from a function, handling partial functions.
|
|
1226
1172
|
|
|
1227
1173
|
Args:
|
|
@@ -1238,7 +1184,7 @@ def _get_type_hints(func: Callable) -> Optional[dict[str, type]]:
|
|
|
1238
1184
|
return None
|
|
1239
1185
|
|
|
1240
1186
|
|
|
1241
|
-
def _get_runnable_config_param(func: Callable) ->
|
|
1187
|
+
def _get_runnable_config_param(func: Callable) -> str | None:
|
|
1242
1188
|
"""Find the parameter name for RunnableConfig in a function.
|
|
1243
1189
|
|
|
1244
1190
|
Args:
|
|
@@ -1264,35 +1210,73 @@ class InjectedToolArg:
|
|
|
1264
1210
|
"""
|
|
1265
1211
|
|
|
1266
1212
|
|
|
1213
|
+
class _DirectlyInjectedToolArg:
|
|
1214
|
+
"""Annotation for tool arguments that are injected at runtime.
|
|
1215
|
+
|
|
1216
|
+
Injected via direct type annotation, rather than annotated metadata.
|
|
1217
|
+
|
|
1218
|
+
For example, ToolRuntime is a directly injected argument.
|
|
1219
|
+
Note the direct annotation rather than the verbose alternative:
|
|
1220
|
+
Annotated[ToolRuntime, InjectedRuntime]
|
|
1221
|
+
```python
|
|
1222
|
+
from langchain_core.tools import tool, ToolRuntime
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
@tool
|
|
1226
|
+
def foo(x: int, runtime: ToolRuntime) -> str:
|
|
1227
|
+
# use runtime.state, runtime.context, runtime.store, etc.
|
|
1228
|
+
...
|
|
1229
|
+
```
|
|
1230
|
+
"""
|
|
1231
|
+
|
|
1232
|
+
|
|
1267
1233
|
class InjectedToolCallId(InjectedToolArg):
|
|
1268
1234
|
"""Annotation for injecting the tool call ID.
|
|
1269
1235
|
|
|
1270
1236
|
This annotation is used to mark a tool parameter that should receive
|
|
1271
1237
|
the tool call ID at runtime.
|
|
1272
1238
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
)
|
|
1239
|
+
```python
|
|
1240
|
+
from typing import Annotated
|
|
1241
|
+
from langchain_core.messages import ToolMessage
|
|
1242
|
+
from langchain_core.tools import tool, InjectedToolCallId
|
|
1243
|
+
|
|
1244
|
+
@tool
|
|
1245
|
+
def foo(
|
|
1246
|
+
x: int, tool_call_id: Annotated[str, InjectedToolCallId]
|
|
1247
|
+
) -> ToolMessage:
|
|
1248
|
+
\"\"\"Return x.\"\"\"
|
|
1249
|
+
return ToolMessage(
|
|
1250
|
+
str(x),
|
|
1251
|
+
artifact=x,
|
|
1252
|
+
name="foo",
|
|
1253
|
+
tool_call_id=tool_call_id
|
|
1254
|
+
)
|
|
1290
1255
|
|
|
1256
|
+
```
|
|
1291
1257
|
"""
|
|
1292
1258
|
|
|
1293
1259
|
|
|
1260
|
+
def _is_directly_injected_arg_type(type_: Any) -> bool:
|
|
1261
|
+
"""Check if a type annotation indicates a directly injected argument.
|
|
1262
|
+
|
|
1263
|
+
This is currently only used for ToolRuntime.
|
|
1264
|
+
Checks if either the annotation itself is a subclass of _DirectlyInjectedToolArg
|
|
1265
|
+
or the origin of the annotation is a subclass of _DirectlyInjectedToolArg.
|
|
1266
|
+
|
|
1267
|
+
Ex: ToolRuntime or ToolRuntime[ContextT, StateT] would both return True.
|
|
1268
|
+
"""
|
|
1269
|
+
return (
|
|
1270
|
+
isinstance(type_, type) and issubclass(type_, _DirectlyInjectedToolArg)
|
|
1271
|
+
) or (
|
|
1272
|
+
(origin := get_origin(type_)) is not None
|
|
1273
|
+
and isinstance(origin, type)
|
|
1274
|
+
and issubclass(origin, _DirectlyInjectedToolArg)
|
|
1275
|
+
)
|
|
1276
|
+
|
|
1277
|
+
|
|
1294
1278
|
def _is_injected_arg_type(
|
|
1295
|
-
type_:
|
|
1279
|
+
type_: type | TypeVar, injected_type: type[InjectedToolArg] | None = None
|
|
1296
1280
|
) -> bool:
|
|
1297
1281
|
"""Check if a type annotation indicates an injected argument.
|
|
1298
1282
|
|
|
@@ -1301,9 +1285,17 @@ def _is_injected_arg_type(
|
|
|
1301
1285
|
injected_type: The specific injected type to check for.
|
|
1302
1286
|
|
|
1303
1287
|
Returns:
|
|
1304
|
-
True if the type is an injected argument, False otherwise.
|
|
1288
|
+
`True` if the type is an injected argument, `False` otherwise.
|
|
1305
1289
|
"""
|
|
1306
|
-
|
|
1290
|
+
if injected_type is None:
|
|
1291
|
+
# if no injected type is specified,
|
|
1292
|
+
# check if the type is a directly injected argument
|
|
1293
|
+
if _is_directly_injected_arg_type(type_):
|
|
1294
|
+
return True
|
|
1295
|
+
injected_type = InjectedToolArg
|
|
1296
|
+
|
|
1297
|
+
# if the type is an Annotated type, check if annotated metadata
|
|
1298
|
+
# is an intance or subclass of the injected type
|
|
1307
1299
|
return any(
|
|
1308
1300
|
isinstance(arg, injected_type)
|
|
1309
1301
|
or (isinstance(arg, type) and issubclass(arg, injected_type))
|
|
@@ -1312,8 +1304,8 @@ def _is_injected_arg_type(
|
|
|
1312
1304
|
|
|
1313
1305
|
|
|
1314
1306
|
def get_all_basemodel_annotations(
|
|
1315
|
-
cls:
|
|
1316
|
-
) -> dict[str,
|
|
1307
|
+
cls: TypeBaseModel | Any, *, default_to_bound: bool = True
|
|
1308
|
+
) -> dict[str, type | TypeVar]:
|
|
1317
1309
|
"""Get all annotations from a Pydantic BaseModel and its parents.
|
|
1318
1310
|
|
|
1319
1311
|
Args:
|
|
@@ -1328,7 +1320,7 @@ def get_all_basemodel_annotations(
|
|
|
1328
1320
|
fields = get_fields(cls)
|
|
1329
1321
|
alias_map = {field.alias: name for name, field in fields.items() if field.alias}
|
|
1330
1322
|
|
|
1331
|
-
annotations: dict[str,
|
|
1323
|
+
annotations: dict[str, type | TypeVar] = {}
|
|
1332
1324
|
for name, param in inspect.signature(cls).parameters.items():
|
|
1333
1325
|
# Exclude hidden init args added by pydantic Config. For example if
|
|
1334
1326
|
# BaseModel(extra="allow") then "extra_data" will part of init sig.
|
|
@@ -1369,7 +1361,7 @@ def get_all_basemodel_annotations(
|
|
|
1369
1361
|
# generic_type_vars = (type vars in Baz)
|
|
1370
1362
|
# generic_map = {type var in Baz: str}
|
|
1371
1363
|
generic_type_vars: tuple = getattr(parent_origin, "__parameters__", ())
|
|
1372
|
-
generic_map = dict(zip(generic_type_vars, get_args(parent)))
|
|
1364
|
+
generic_map = dict(zip(generic_type_vars, get_args(parent), strict=False))
|
|
1373
1365
|
for field in getattr(parent_origin, "__annotations__", {}):
|
|
1374
1366
|
annotations[field] = _replace_type_vars(
|
|
1375
1367
|
annotations[field], generic_map, default_to_bound=default_to_bound
|
|
@@ -1382,11 +1374,11 @@ def get_all_basemodel_annotations(
|
|
|
1382
1374
|
|
|
1383
1375
|
|
|
1384
1376
|
def _replace_type_vars(
|
|
1385
|
-
type_:
|
|
1386
|
-
generic_map:
|
|
1377
|
+
type_: type | TypeVar,
|
|
1378
|
+
generic_map: dict[TypeVar, type] | None = None,
|
|
1387
1379
|
*,
|
|
1388
1380
|
default_to_bound: bool = True,
|
|
1389
|
-
) ->
|
|
1381
|
+
) -> type | TypeVar:
|
|
1390
1382
|
"""Replace TypeVars in a type annotation with concrete types.
|
|
1391
1383
|
|
|
1392
1384
|
Args:
|