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.

Files changed (37) hide show
  1. langchain_core/caches.py +3 -1
  2. langchain_core/callbacks/base.py +0 -4
  3. langchain_core/callbacks/manager.py +0 -11
  4. langchain_core/document_loaders/langsmith.py +0 -3
  5. langchain_core/documents/base.py +0 -2
  6. langchain_core/documents/transformers.py +4 -4
  7. langchain_core/indexing/base.py +4 -6
  8. langchain_core/indexing/in_memory.py +0 -2
  9. langchain_core/language_models/base.py +5 -6
  10. langchain_core/language_models/chat_models.py +86 -79
  11. langchain_core/language_models/llms.py +16 -12
  12. langchain_core/load/dump.py +5 -7
  13. langchain_core/messages/block_translators/google_genai.py +1 -1
  14. langchain_core/messages/utils.py +4 -4
  15. langchain_core/prompts/string.py +5 -2
  16. langchain_core/rate_limiters.py +1 -3
  17. langchain_core/runnables/base.py +17 -21
  18. langchain_core/runnables/branch.py +9 -9
  19. langchain_core/runnables/config.py +8 -10
  20. langchain_core/runnables/fallbacks.py +1 -1
  21. langchain_core/runnables/retry.py +1 -1
  22. langchain_core/runnables/schema.py +2 -5
  23. langchain_core/runnables/utils.py +3 -3
  24. langchain_core/stores.py +4 -6
  25. langchain_core/tools/base.py +49 -3
  26. langchain_core/tools/convert.py +0 -2
  27. langchain_core/tracers/event_stream.py +4 -1
  28. langchain_core/tracers/log_stream.py +4 -1
  29. langchain_core/utils/function_calling.py +8 -0
  30. langchain_core/utils/json_schema.py +1 -1
  31. langchain_core/vectorstores/base.py +59 -63
  32. langchain_core/vectorstores/in_memory.py +2 -2
  33. langchain_core/vectorstores/utils.py +1 -1
  34. langchain_core/version.py +1 -1
  35. {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/METADATA +8 -7
  36. {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/RECORD +37 -37
  37. {langchain_core-1.0.0rc2.dist-info → langchain_core-1.0.1.dist-info}/WHEEL +0 -0
@@ -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 should override this method if they can batch more efficiently;
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 should override this method if they can batch more efficiently;
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 should override this method if they support streaming output.
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 should override this method if they support streaming output.
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
- # will produce the following events (run_id, and parent_ids
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 should override this method if they can start producing output while
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 should override this method if they can start producing output while
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 passed
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
- Fallback in order, upon failures.
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 passed
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
- Fallback in order, upon failures.
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, the default branch is run on the input.
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, Callable or Mapping.
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 .configurable_fields() or .configurable_alternatives().
90
- Check .output_schema() for a description of the attributes that have been made
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
- will be generated.
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
- timeout: float | None = None,
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
- timeout=timeout,
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
- # will produce the following events
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
- """Cache the result of checking if asyncio.create_task accepts a `context` arg.
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 accepts_context(asyncio.create_task)
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 (dict[str, Any]): The underlying dictionary that stores
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 (dict[str, bytes]): The underlying dictionary that stores
271
- the key-value pairs.
269
+ store: The underlying dictionary that stores the key-value pairs.
272
270
 
273
271
  Examples:
274
272
  ```python
@@ -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. If `"content_and_artifact"` then the output is expected to be a
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
- injected_type = injected_type or InjectedToolArg
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))
@@ -151,8 +151,6 @@ def tool(
151
151
  return "partial json of results", {"full": "object of results"}
152
152
  ```
153
153
 
154
- !!! version-added "Added in version 0.2.14"
155
-
156
154
  Parse Google-style docstrings:
157
155
 
158
156
  ```python
@@ -128,7 +128,10 @@ class _AstreamEventsCallbackHandler(AsyncCallbackHandler, _StreamingCallbackHand
128
128
  exclude_tags=exclude_tags,
129
129
  )
130
130
 
131
- loop = asyncio.get_event_loop()
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
- loop = asyncio.get_event_loop()
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
- Note:
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