langchain-core 1.0.0rc2__py3-none-any.whl → 1.0.1__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/caches.py +3 -1
- langchain_core/callbacks/base.py +0 -4
- langchain_core/callbacks/manager.py +0 -11
- langchain_core/document_loaders/langsmith.py +0 -3
- langchain_core/documents/base.py +0 -2
- langchain_core/documents/transformers.py +4 -4
- langchain_core/indexing/base.py +4 -6
- langchain_core/indexing/in_memory.py +0 -2
- langchain_core/language_models/base.py +5 -6
- langchain_core/language_models/chat_models.py +86 -79
- langchain_core/language_models/llms.py +16 -12
- langchain_core/load/dump.py +5 -7
- langchain_core/messages/block_translators/google_genai.py +1 -1
- langchain_core/messages/utils.py +4 -4
- langchain_core/prompts/string.py +5 -2
- langchain_core/rate_limiters.py +1 -3
- langchain_core/runnables/base.py +17 -21
- langchain_core/runnables/branch.py +9 -9
- langchain_core/runnables/config.py +8 -10
- langchain_core/runnables/fallbacks.py +1 -1
- langchain_core/runnables/retry.py +1 -1
- langchain_core/runnables/schema.py +2 -5
- langchain_core/runnables/utils.py +3 -3
- langchain_core/stores.py +4 -6
- langchain_core/tools/base.py +49 -3
- langchain_core/tools/convert.py +0 -2
- langchain_core/tracers/event_stream.py +4 -1
- langchain_core/tracers/log_stream.py +4 -1
- langchain_core/utils/function_calling.py +8 -0
- langchain_core/utils/json_schema.py +1 -1
- langchain_core/vectorstores/base.py +59 -63
- langchain_core/vectorstores/in_memory.py +2 -2
- langchain_core/vectorstores/utils.py +1 -1
- langchain_core/version.py +1 -1
- {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/METADATA +8 -7
- {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/RECORD +37 -37
- {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/WHEEL +0 -0
langchain_core/runnables/base.py
CHANGED
|
@@ -860,7 +860,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
860
860
|
|
|
861
861
|
The default implementation of batch works well for IO bound runnables.
|
|
862
862
|
|
|
863
|
-
Subclasses
|
|
863
|
+
Subclasses must override this method if they can batch more efficiently;
|
|
864
864
|
e.g., if the underlying `Runnable` uses an API which supports a batch mode.
|
|
865
865
|
|
|
866
866
|
Args:
|
|
@@ -992,7 +992,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
992
992
|
|
|
993
993
|
The default implementation of `batch` works well for IO bound runnables.
|
|
994
994
|
|
|
995
|
-
Subclasses
|
|
995
|
+
Subclasses must override this method if they can batch more efficiently;
|
|
996
996
|
e.g., if the underlying `Runnable` uses an API which supports a batch mode.
|
|
997
997
|
|
|
998
998
|
Args:
|
|
@@ -1112,7 +1112,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1112
1112
|
) -> Iterator[Output]:
|
|
1113
1113
|
"""Default implementation of `stream`, which calls `invoke`.
|
|
1114
1114
|
|
|
1115
|
-
Subclasses
|
|
1115
|
+
Subclasses must override this method if they support streaming output.
|
|
1116
1116
|
|
|
1117
1117
|
Args:
|
|
1118
1118
|
input: The input to the `Runnable`.
|
|
@@ -1133,7 +1133,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1133
1133
|
) -> AsyncIterator[Output]:
|
|
1134
1134
|
"""Default implementation of `astream`, which calls `ainvoke`.
|
|
1135
1135
|
|
|
1136
|
-
Subclasses
|
|
1136
|
+
Subclasses must override this method if they support streaming output.
|
|
1137
1137
|
|
|
1138
1138
|
Args:
|
|
1139
1139
|
input: The input to the `Runnable`.
|
|
@@ -1367,8 +1367,8 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1367
1367
|
|
|
1368
1368
|
events = [event async for event in chain.astream_events("hello", version="v2")]
|
|
1369
1369
|
|
|
1370
|
-
#
|
|
1371
|
-
# has been omitted for brevity):
|
|
1370
|
+
# Will produce the following events
|
|
1371
|
+
# (run_id, and parent_ids has been omitted for brevity):
|
|
1372
1372
|
[
|
|
1373
1373
|
{
|
|
1374
1374
|
"data": {"input": "hello"},
|
|
@@ -1423,7 +1423,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1423
1423
|
|
|
1424
1424
|
async for event in slow_thing.astream_events("some_input", version="v2"):
|
|
1425
1425
|
print(event)
|
|
1426
|
-
|
|
1426
|
+
```
|
|
1427
1427
|
|
|
1428
1428
|
Args:
|
|
1429
1429
|
input: The input to the `Runnable`.
|
|
@@ -1497,7 +1497,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1497
1497
|
|
|
1498
1498
|
Default implementation of transform, which buffers input and calls `astream`.
|
|
1499
1499
|
|
|
1500
|
-
Subclasses
|
|
1500
|
+
Subclasses must override this method if they can start producing output while
|
|
1501
1501
|
input is still being generated.
|
|
1502
1502
|
|
|
1503
1503
|
Args:
|
|
@@ -1542,7 +1542,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1542
1542
|
|
|
1543
1543
|
Default implementation of atransform, which buffers input and calls `astream`.
|
|
1544
1544
|
|
|
1545
|
-
Subclasses
|
|
1545
|
+
Subclasses must override this method if they can start producing output while
|
|
1546
1546
|
input is still being generated.
|
|
1547
1547
|
|
|
1548
1548
|
Args:
|
|
@@ -1813,7 +1813,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1813
1813
|
output_type: The output type to bind to the `Runnable`.
|
|
1814
1814
|
|
|
1815
1815
|
Returns:
|
|
1816
|
-
A new Runnable with the types bound.
|
|
1816
|
+
A new `Runnable` with the types bound.
|
|
1817
1817
|
"""
|
|
1818
1818
|
return RunnableBinding(
|
|
1819
1819
|
bound=self,
|
|
@@ -1840,7 +1840,7 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1840
1840
|
giving up.
|
|
1841
1841
|
exponential_jitter_params: Parameters for
|
|
1842
1842
|
`tenacity.wait_exponential_jitter`. Namely: `initial`, `max`,
|
|
1843
|
-
`exp_base`, and `jitter` (all float values).
|
|
1843
|
+
`exp_base`, and `jitter` (all `float` values).
|
|
1844
1844
|
|
|
1845
1845
|
Returns:
|
|
1846
1846
|
A new Runnable that retries the original Runnable on exceptions.
|
|
@@ -1925,15 +1925,15 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1925
1925
|
fallbacks: A sequence of runnables to try if the original `Runnable`
|
|
1926
1926
|
fails.
|
|
1927
1927
|
exceptions_to_handle: A tuple of exception types to handle.
|
|
1928
|
-
exception_key: If string is specified then handled exceptions will be
|
|
1929
|
-
to fallbacks as part of the input under the specified key.
|
|
1928
|
+
exception_key: If `string` is specified then handled exceptions will be
|
|
1929
|
+
passed to fallbacks as part of the input under the specified key.
|
|
1930
1930
|
If `None`, exceptions will not be passed to fallbacks.
|
|
1931
1931
|
If used, the base `Runnable` and its fallbacks must accept a
|
|
1932
1932
|
dictionary as input.
|
|
1933
1933
|
|
|
1934
1934
|
Returns:
|
|
1935
1935
|
A new `Runnable` that will try the original `Runnable`, and then each
|
|
1936
|
-
|
|
1936
|
+
Fallback in order, upon failures.
|
|
1937
1937
|
|
|
1938
1938
|
Example:
|
|
1939
1939
|
```python
|
|
@@ -1961,16 +1961,15 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
1961
1961
|
fallbacks: A sequence of runnables to try if the original `Runnable`
|
|
1962
1962
|
fails.
|
|
1963
1963
|
exceptions_to_handle: A tuple of exception types to handle.
|
|
1964
|
-
exception_key: If string is specified then handled exceptions will be
|
|
1965
|
-
to fallbacks as part of the input under the specified key.
|
|
1964
|
+
exception_key: If `string` is specified then handled exceptions will be
|
|
1965
|
+
passed to fallbacks as part of the input under the specified key.
|
|
1966
1966
|
If `None`, exceptions will not be passed to fallbacks.
|
|
1967
1967
|
If used, the base `Runnable` and its fallbacks must accept a
|
|
1968
1968
|
dictionary as input.
|
|
1969
1969
|
|
|
1970
1970
|
Returns:
|
|
1971
1971
|
A new `Runnable` that will try the original `Runnable`, and then each
|
|
1972
|
-
|
|
1973
|
-
|
|
1972
|
+
Fallback in order, upon failures.
|
|
1974
1973
|
"""
|
|
1975
1974
|
# Import locally to prevent circular import
|
|
1976
1975
|
from langchain_core.runnables.fallbacks import ( # noqa: PLC0415
|
|
@@ -2520,9 +2519,6 @@ class Runnable(ABC, Generic[Input, Output]):
|
|
|
2520
2519
|
as_tool = runnable.as_tool()
|
|
2521
2520
|
as_tool.invoke("b")
|
|
2522
2521
|
```
|
|
2523
|
-
|
|
2524
|
-
!!! version-added "Added in version 0.2.14"
|
|
2525
|
-
|
|
2526
2522
|
"""
|
|
2527
2523
|
# Avoid circular import
|
|
2528
2524
|
from langchain_core.tools import convert_runnable_to_tool # noqa: PLC0415
|
|
@@ -40,13 +40,13 @@ from langchain_core.runnables.utils import (
|
|
|
40
40
|
class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
41
41
|
"""Runnable that selects which branch to run based on a condition.
|
|
42
42
|
|
|
43
|
-
The Runnable is initialized with a list of (condition, Runnable) pairs and
|
|
43
|
+
The Runnable is initialized with a list of `(condition, Runnable)` pairs and
|
|
44
44
|
a default branch.
|
|
45
45
|
|
|
46
46
|
When operating on an input, the first condition that evaluates to True is
|
|
47
|
-
selected, and the corresponding Runnable is run on the input.
|
|
47
|
+
selected, and the corresponding `Runnable` is run on the input.
|
|
48
48
|
|
|
49
|
-
If no condition evaluates to True
|
|
49
|
+
If no condition evaluates to `True`, the default branch is run on the input.
|
|
50
50
|
|
|
51
51
|
Examples:
|
|
52
52
|
```python
|
|
@@ -65,9 +65,9 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
67
|
branches: Sequence[tuple[Runnable[Input, bool], Runnable[Input, Output]]]
|
|
68
|
-
"""A list of (condition, Runnable) pairs."""
|
|
68
|
+
"""A list of `(condition, Runnable)` pairs."""
|
|
69
69
|
default: Runnable[Input, Output]
|
|
70
|
-
"""A Runnable to run if no condition is met."""
|
|
70
|
+
"""A `Runnable` to run if no condition is met."""
|
|
71
71
|
|
|
72
72
|
def __init__(
|
|
73
73
|
self,
|
|
@@ -79,15 +79,15 @@ class RunnableBranch(RunnableSerializable[Input, Output]):
|
|
|
79
79
|
]
|
|
80
80
|
| RunnableLike,
|
|
81
81
|
) -> None:
|
|
82
|
-
"""A Runnable that runs one of two branches based on a condition.
|
|
82
|
+
"""A `Runnable` that runs one of two branches based on a condition.
|
|
83
83
|
|
|
84
84
|
Args:
|
|
85
|
-
*branches: A list of (condition, Runnable) pairs.
|
|
86
|
-
Defaults a Runnable to run if no condition is met.
|
|
85
|
+
*branches: A list of `(condition, Runnable)` pairs.
|
|
86
|
+
Defaults a `Runnable` to run if no condition is met.
|
|
87
87
|
|
|
88
88
|
Raises:
|
|
89
89
|
ValueError: If the number of branches is less than 2.
|
|
90
|
-
TypeError: If the default branch is not Runnable
|
|
90
|
+
TypeError: If the default branch is not `Runnable`, `Callable` or `Mapping`.
|
|
91
91
|
TypeError: If a branch is not a tuple or list.
|
|
92
92
|
ValueError: If a branch is not of length 2.
|
|
93
93
|
"""
|
|
@@ -75,26 +75,26 @@ class RunnableConfig(TypedDict, total=False):
|
|
|
75
75
|
max_concurrency: int | None
|
|
76
76
|
"""
|
|
77
77
|
Maximum number of parallel calls to make. If not provided, defaults to
|
|
78
|
-
ThreadPoolExecutor's default.
|
|
78
|
+
`ThreadPoolExecutor`'s default.
|
|
79
79
|
"""
|
|
80
80
|
|
|
81
81
|
recursion_limit: int
|
|
82
82
|
"""
|
|
83
|
-
Maximum number of times a call can recurse. If not provided, defaults to 25
|
|
83
|
+
Maximum number of times a call can recurse. If not provided, defaults to `25`.
|
|
84
84
|
"""
|
|
85
85
|
|
|
86
86
|
configurable: dict[str, Any]
|
|
87
87
|
"""
|
|
88
|
-
Runtime values for attributes previously made configurable on this Runnable
|
|
89
|
-
or sub-Runnables, through
|
|
90
|
-
Check
|
|
88
|
+
Runtime values for attributes previously made configurable on this `Runnable`,
|
|
89
|
+
or sub-Runnables, through `configurable_fields` or `configurable_alternatives`.
|
|
90
|
+
Check `output_schema` for a description of the attributes that have been made
|
|
91
91
|
configurable.
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
94
|
run_id: uuid.UUID | None
|
|
95
95
|
"""
|
|
96
96
|
Unique identifier for the tracer run for this call. If not provided, a new UUID
|
|
97
|
-
|
|
97
|
+
will be generated.
|
|
98
98
|
"""
|
|
99
99
|
|
|
100
100
|
|
|
@@ -527,8 +527,7 @@ class ContextThreadPoolExecutor(ThreadPoolExecutor):
|
|
|
527
527
|
self,
|
|
528
528
|
fn: Callable[..., T],
|
|
529
529
|
*iterables: Iterable[Any],
|
|
530
|
-
|
|
531
|
-
chunksize: int = 1,
|
|
530
|
+
**kwargs: Any,
|
|
532
531
|
) -> Iterator[T]:
|
|
533
532
|
"""Map a function to multiple iterables.
|
|
534
533
|
|
|
@@ -549,8 +548,7 @@ class ContextThreadPoolExecutor(ThreadPoolExecutor):
|
|
|
549
548
|
return super().map(
|
|
550
549
|
_wrapped_fn,
|
|
551
550
|
*iterables,
|
|
552
|
-
|
|
553
|
-
chunksize=chunksize,
|
|
551
|
+
**kwargs,
|
|
554
552
|
)
|
|
555
553
|
|
|
556
554
|
|
|
@@ -96,7 +96,7 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]):
|
|
|
96
96
|
Any exception that is not a subclass of these exceptions will be raised immediately.
|
|
97
97
|
"""
|
|
98
98
|
exception_key: str | None = None
|
|
99
|
-
"""If string is specified then handled exceptions will be passed to fallbacks as
|
|
99
|
+
"""If `string` is specified then handled exceptions will be passed to fallbacks as
|
|
100
100
|
part of the input under the specified key. If `None`, exceptions
|
|
101
101
|
will not be passed to fallbacks. If used, the base Runnable and its fallbacks
|
|
102
102
|
must accept a dictionary as input."""
|
|
@@ -126,7 +126,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-rede
|
|
|
126
126
|
|
|
127
127
|
exponential_jitter_params: ExponentialJitterParams | None = None
|
|
128
128
|
"""Parameters for `tenacity.wait_exponential_jitter`. Namely: `initial`,
|
|
129
|
-
`max`, `exp_base`, and `jitter` (all float values).
|
|
129
|
+
`max`, `exp_base`, and `jitter` (all `float` values).
|
|
130
130
|
"""
|
|
131
131
|
|
|
132
132
|
max_attempt_number: int = 3
|
|
@@ -65,7 +65,7 @@ class BaseStreamEvent(TypedDict):
|
|
|
65
65
|
|
|
66
66
|
events = [event async for event in chain.astream_events("hello")]
|
|
67
67
|
|
|
68
|
-
#
|
|
68
|
+
# Will produce the following events
|
|
69
69
|
# (where some fields have been omitted for brevity):
|
|
70
70
|
[
|
|
71
71
|
{
|
|
@@ -168,10 +168,7 @@ class StandardStreamEvent(BaseStreamEvent):
|
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
class CustomStreamEvent(BaseStreamEvent):
|
|
171
|
-
"""Custom stream event created by the user.
|
|
172
|
-
|
|
173
|
-
!!! version-added "Added in version 0.2.15"
|
|
174
|
-
"""
|
|
171
|
+
"""Custom stream event created by the user."""
|
|
175
172
|
|
|
176
173
|
# Overwrite the event field to be more specific.
|
|
177
174
|
event: Literal["on_custom_event"] # type: ignore[misc]
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import ast
|
|
6
6
|
import asyncio
|
|
7
7
|
import inspect
|
|
8
|
+
import sys
|
|
8
9
|
import textwrap
|
|
9
10
|
from collections.abc import Callable, Mapping, Sequence
|
|
10
11
|
from contextvars import Context
|
|
@@ -118,14 +119,13 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
|
|
|
118
119
|
return False
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
@lru_cache(maxsize=1)
|
|
122
122
|
def asyncio_accepts_context() -> bool:
|
|
123
|
-
"""
|
|
123
|
+
"""Check if asyncio.create_task accepts a `context` arg.
|
|
124
124
|
|
|
125
125
|
Returns:
|
|
126
126
|
True if `asyncio.create_task` accepts a context argument, `False` otherwise.
|
|
127
127
|
"""
|
|
128
|
-
return
|
|
128
|
+
return sys.version_info >= (3, 11)
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
def coro_with_context(
|
langchain_core/stores.py
CHANGED
|
@@ -86,7 +86,7 @@ class BaseStore(ABC, Generic[K, V]):
|
|
|
86
86
|
|
|
87
87
|
Returns:
|
|
88
88
|
A sequence of optional values associated with the keys.
|
|
89
|
-
If a key is not found, the corresponding value will be None
|
|
89
|
+
If a key is not found, the corresponding value will be `None`.
|
|
90
90
|
"""
|
|
91
91
|
|
|
92
92
|
async def amget(self, keys: Sequence[K]) -> list[V | None]:
|
|
@@ -97,7 +97,7 @@ class BaseStore(ABC, Generic[K, V]):
|
|
|
97
97
|
|
|
98
98
|
Returns:
|
|
99
99
|
A sequence of optional values associated with the keys.
|
|
100
|
-
If a key is not found, the corresponding value will be None
|
|
100
|
+
If a key is not found, the corresponding value will be `None`.
|
|
101
101
|
"""
|
|
102
102
|
return await run_in_executor(None, self.mget, keys)
|
|
103
103
|
|
|
@@ -243,8 +243,7 @@ class InMemoryStore(InMemoryBaseStore[Any]):
|
|
|
243
243
|
"""In-memory store for any type of data.
|
|
244
244
|
|
|
245
245
|
Attributes:
|
|
246
|
-
store
|
|
247
|
-
the key-value pairs.
|
|
246
|
+
store: The underlying dictionary that stores the key-value pairs.
|
|
248
247
|
|
|
249
248
|
Examples:
|
|
250
249
|
```python
|
|
@@ -267,8 +266,7 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]):
|
|
|
267
266
|
"""In-memory store for bytes.
|
|
268
267
|
|
|
269
268
|
Attributes:
|
|
270
|
-
store
|
|
271
|
-
the key-value pairs.
|
|
269
|
+
store: The underlying dictionary that stores the key-value pairs.
|
|
272
270
|
|
|
273
271
|
Examples:
|
|
274
272
|
```python
|
langchain_core/tools/base.py
CHANGED
|
@@ -483,7 +483,7 @@ class ChildTool(BaseTool):
|
|
|
483
483
|
"""The tool response format.
|
|
484
484
|
|
|
485
485
|
If `"content"` then the output of the tool is interpreted as the contents of a
|
|
486
|
-
ToolMessage
|
|
486
|
+
`ToolMessage`. If `"content_and_artifact"` then the output is expected to be a
|
|
487
487
|
two-tuple corresponding to the (content, artifact) of a `ToolMessage`.
|
|
488
488
|
"""
|
|
489
489
|
|
|
@@ -615,7 +615,7 @@ class ChildTool(BaseTool):
|
|
|
615
615
|
The parsed and validated input.
|
|
616
616
|
|
|
617
617
|
Raises:
|
|
618
|
-
ValueError: If string input is provided with JSON schema `args_schema`.
|
|
618
|
+
ValueError: If `string` input is provided with JSON schema `args_schema`.
|
|
619
619
|
ValueError: If InjectedToolCallId is required but `tool_call_id` is not
|
|
620
620
|
provided.
|
|
621
621
|
TypeError: If args_schema is not a Pydantic `BaseModel` or dict.
|
|
@@ -1210,6 +1210,26 @@ class InjectedToolArg:
|
|
|
1210
1210
|
"""
|
|
1211
1211
|
|
|
1212
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
|
+
|
|
1213
1233
|
class InjectedToolCallId(InjectedToolArg):
|
|
1214
1234
|
"""Annotation for injecting the tool call ID.
|
|
1215
1235
|
|
|
@@ -1237,6 +1257,24 @@ class InjectedToolCallId(InjectedToolArg):
|
|
|
1237
1257
|
"""
|
|
1238
1258
|
|
|
1239
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
|
+
|
|
1240
1278
|
def _is_injected_arg_type(
|
|
1241
1279
|
type_: type | TypeVar, injected_type: type[InjectedToolArg] | None = None
|
|
1242
1280
|
) -> bool:
|
|
@@ -1249,7 +1287,15 @@ def _is_injected_arg_type(
|
|
|
1249
1287
|
Returns:
|
|
1250
1288
|
`True` if the type is an injected argument, `False` otherwise.
|
|
1251
1289
|
"""
|
|
1252
|
-
|
|
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
|
|
1253
1299
|
return any(
|
|
1254
1300
|
isinstance(arg, injected_type)
|
|
1255
1301
|
or (isinstance(arg, type) and issubclass(arg, injected_type))
|
langchain_core/tools/convert.py
CHANGED
|
@@ -128,7 +128,10 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand
|
|
|
128
128
|
exclude_tags=exclude_tags,
|
|
129
129
|
)
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
try:
|
|
132
|
+
loop = asyncio.get_event_loop()
|
|
133
|
+
except RuntimeError:
|
|
134
|
+
loop = asyncio.new_event_loop()
|
|
132
135
|
memory_stream = _MemoryStream[StreamEvent](loop)
|
|
133
136
|
self.send_stream = memory_stream.get_send_stream()
|
|
134
137
|
self.receive_stream = memory_stream.get_receive_stream()
|
|
@@ -264,7 +264,10 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler):
|
|
|
264
264
|
self.exclude_types = exclude_types
|
|
265
265
|
self.exclude_tags = exclude_tags
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
try:
|
|
268
|
+
loop = asyncio.get_event_loop()
|
|
269
|
+
except RuntimeError:
|
|
270
|
+
loop = asyncio.new_event_loop()
|
|
268
271
|
memory_stream = _MemoryStream[RunLogPatch](loop)
|
|
269
272
|
self.lock = threading.Lock()
|
|
270
273
|
self.send_stream = memory_stream.get_send_stream()
|
|
@@ -425,6 +425,14 @@ def convert_to_openai_function(
|
|
|
425
425
|
oai_function["parameters"] = _recursive_set_additional_properties_false(
|
|
426
426
|
oai_function["parameters"]
|
|
427
427
|
)
|
|
428
|
+
# All fields must be `required`
|
|
429
|
+
parameters = oai_function.get("parameters")
|
|
430
|
+
if isinstance(parameters, dict):
|
|
431
|
+
fields = parameters.get("properties")
|
|
432
|
+
if isinstance(fields, dict) and fields:
|
|
433
|
+
parameters = dict(parameters)
|
|
434
|
+
parameters["required"] = list(fields.keys())
|
|
435
|
+
oai_function["parameters"] = parameters
|
|
428
436
|
return oai_function
|
|
429
437
|
|
|
430
438
|
|
|
@@ -226,7 +226,7 @@ def dereference_refs(
|
|
|
226
226
|
... }
|
|
227
227
|
>>> result = dereference_refs(schema) # Won't cause infinite recursion
|
|
228
228
|
|
|
229
|
-
|
|
229
|
+
!!! note
|
|
230
230
|
- Circular references are handled gracefully by breaking cycles
|
|
231
231
|
- Mixed $ref objects (with both $ref and other properties) are supported
|
|
232
232
|
- Additional properties in mixed $refs override resolved properties
|