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.

Files changed (165) hide show
  1. langchain_core/__init__.py +1 -1
  2. langchain_core/_api/__init__.py +3 -4
  3. langchain_core/_api/beta_decorator.py +23 -26
  4. langchain_core/_api/deprecation.py +52 -65
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +19 -19
  8. langchain_core/caches.py +53 -63
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +323 -334
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +441 -507
  13. langchain_core/callbacks/stdout.py +29 -30
  14. langchain_core/callbacks/streaming_stdout.py +32 -32
  15. langchain_core/callbacks/usage.py +60 -57
  16. langchain_core/chat_history.py +48 -63
  17. langchain_core/document_loaders/base.py +23 -23
  18. langchain_core/document_loaders/langsmith.py +37 -37
  19. langchain_core/documents/__init__.py +0 -1
  20. langchain_core/documents/base.py +62 -65
  21. langchain_core/documents/compressor.py +4 -4
  22. langchain_core/documents/transformers.py +28 -29
  23. langchain_core/embeddings/fake.py +50 -54
  24. langchain_core/example_selectors/length_based.py +1 -1
  25. langchain_core/example_selectors/semantic_similarity.py +21 -25
  26. langchain_core/exceptions.py +10 -11
  27. langchain_core/globals.py +3 -151
  28. langchain_core/indexing/api.py +61 -66
  29. langchain_core/indexing/base.py +58 -58
  30. langchain_core/indexing/in_memory.py +3 -3
  31. langchain_core/language_models/__init__.py +14 -27
  32. langchain_core/language_models/_utils.py +270 -84
  33. langchain_core/language_models/base.py +55 -162
  34. langchain_core/language_models/chat_models.py +442 -402
  35. langchain_core/language_models/fake.py +11 -11
  36. langchain_core/language_models/fake_chat_models.py +61 -39
  37. langchain_core/language_models/llms.py +123 -231
  38. langchain_core/load/dump.py +4 -5
  39. langchain_core/load/load.py +18 -28
  40. langchain_core/load/mapping.py +2 -4
  41. langchain_core/load/serializable.py +39 -40
  42. langchain_core/messages/__init__.py +61 -22
  43. langchain_core/messages/ai.py +368 -163
  44. langchain_core/messages/base.py +214 -43
  45. langchain_core/messages/block_translators/__init__.py +111 -0
  46. langchain_core/messages/block_translators/anthropic.py +470 -0
  47. langchain_core/messages/block_translators/bedrock.py +94 -0
  48. langchain_core/messages/block_translators/bedrock_converse.py +297 -0
  49. langchain_core/messages/block_translators/google_genai.py +530 -0
  50. langchain_core/messages/block_translators/google_vertexai.py +21 -0
  51. langchain_core/messages/block_translators/groq.py +143 -0
  52. langchain_core/messages/block_translators/langchain_v0.py +301 -0
  53. langchain_core/messages/block_translators/openai.py +1010 -0
  54. langchain_core/messages/chat.py +2 -6
  55. langchain_core/messages/content.py +1423 -0
  56. langchain_core/messages/function.py +6 -10
  57. langchain_core/messages/human.py +41 -38
  58. langchain_core/messages/modifier.py +2 -2
  59. langchain_core/messages/system.py +38 -28
  60. langchain_core/messages/tool.py +96 -103
  61. langchain_core/messages/utils.py +478 -504
  62. langchain_core/output_parsers/__init__.py +1 -14
  63. langchain_core/output_parsers/base.py +58 -61
  64. langchain_core/output_parsers/json.py +7 -8
  65. langchain_core/output_parsers/list.py +5 -7
  66. langchain_core/output_parsers/openai_functions.py +49 -47
  67. langchain_core/output_parsers/openai_tools.py +14 -19
  68. langchain_core/output_parsers/pydantic.py +12 -13
  69. langchain_core/output_parsers/string.py +2 -2
  70. langchain_core/output_parsers/transform.py +15 -17
  71. langchain_core/output_parsers/xml.py +8 -10
  72. langchain_core/outputs/__init__.py +1 -1
  73. langchain_core/outputs/chat_generation.py +18 -18
  74. langchain_core/outputs/chat_result.py +1 -3
  75. langchain_core/outputs/generation.py +8 -8
  76. langchain_core/outputs/llm_result.py +10 -10
  77. langchain_core/prompt_values.py +12 -12
  78. langchain_core/prompts/__init__.py +3 -27
  79. langchain_core/prompts/base.py +45 -55
  80. langchain_core/prompts/chat.py +254 -313
  81. langchain_core/prompts/dict.py +5 -5
  82. langchain_core/prompts/few_shot.py +81 -88
  83. langchain_core/prompts/few_shot_with_templates.py +11 -13
  84. langchain_core/prompts/image.py +12 -14
  85. langchain_core/prompts/loading.py +6 -8
  86. langchain_core/prompts/message.py +3 -3
  87. langchain_core/prompts/prompt.py +24 -39
  88. langchain_core/prompts/string.py +4 -4
  89. langchain_core/prompts/structured.py +42 -50
  90. langchain_core/rate_limiters.py +51 -60
  91. langchain_core/retrievers.py +49 -190
  92. langchain_core/runnables/base.py +1484 -1709
  93. langchain_core/runnables/branch.py +45 -61
  94. langchain_core/runnables/config.py +80 -88
  95. langchain_core/runnables/configurable.py +117 -134
  96. langchain_core/runnables/fallbacks.py +83 -79
  97. langchain_core/runnables/graph.py +85 -95
  98. langchain_core/runnables/graph_ascii.py +27 -28
  99. langchain_core/runnables/graph_mermaid.py +38 -50
  100. langchain_core/runnables/graph_png.py +15 -16
  101. langchain_core/runnables/history.py +135 -148
  102. langchain_core/runnables/passthrough.py +124 -150
  103. langchain_core/runnables/retry.py +46 -51
  104. langchain_core/runnables/router.py +25 -30
  105. langchain_core/runnables/schema.py +79 -74
  106. langchain_core/runnables/utils.py +62 -68
  107. langchain_core/stores.py +81 -115
  108. langchain_core/structured_query.py +8 -8
  109. langchain_core/sys_info.py +27 -29
  110. langchain_core/tools/__init__.py +1 -14
  111. langchain_core/tools/base.py +179 -187
  112. langchain_core/tools/convert.py +131 -139
  113. langchain_core/tools/render.py +10 -10
  114. langchain_core/tools/retriever.py +11 -11
  115. langchain_core/tools/simple.py +19 -24
  116. langchain_core/tools/structured.py +30 -39
  117. langchain_core/tracers/__init__.py +1 -9
  118. langchain_core/tracers/base.py +97 -99
  119. langchain_core/tracers/context.py +29 -52
  120. langchain_core/tracers/core.py +50 -60
  121. langchain_core/tracers/evaluation.py +11 -11
  122. langchain_core/tracers/event_stream.py +115 -70
  123. langchain_core/tracers/langchain.py +21 -21
  124. langchain_core/tracers/log_stream.py +43 -43
  125. langchain_core/tracers/memory_stream.py +3 -3
  126. langchain_core/tracers/root_listeners.py +16 -16
  127. langchain_core/tracers/run_collector.py +2 -4
  128. langchain_core/tracers/schemas.py +0 -129
  129. langchain_core/tracers/stdout.py +3 -3
  130. langchain_core/utils/__init__.py +1 -4
  131. langchain_core/utils/_merge.py +46 -8
  132. langchain_core/utils/aiter.py +57 -61
  133. langchain_core/utils/env.py +9 -9
  134. langchain_core/utils/function_calling.py +89 -191
  135. langchain_core/utils/html.py +7 -8
  136. langchain_core/utils/input.py +6 -6
  137. langchain_core/utils/interactive_env.py +1 -1
  138. langchain_core/utils/iter.py +37 -42
  139. langchain_core/utils/json.py +4 -3
  140. langchain_core/utils/json_schema.py +8 -8
  141. langchain_core/utils/mustache.py +9 -11
  142. langchain_core/utils/pydantic.py +33 -35
  143. langchain_core/utils/strings.py +5 -5
  144. langchain_core/utils/usage.py +1 -1
  145. langchain_core/utils/utils.py +80 -54
  146. langchain_core/vectorstores/base.py +129 -164
  147. langchain_core/vectorstores/in_memory.py +99 -174
  148. langchain_core/vectorstores/utils.py +5 -5
  149. langchain_core/version.py +1 -1
  150. {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/METADATA +28 -27
  151. langchain_core-1.0.0.dist-info/RECORD +172 -0
  152. {langchain_core-0.3.79.dist-info → langchain_core-1.0.0.dist-info}/WHEEL +1 -1
  153. langchain_core/beta/__init__.py +0 -1
  154. langchain_core/beta/runnables/__init__.py +0 -1
  155. langchain_core/beta/runnables/context.py +0 -447
  156. langchain_core/memory.py +0 -120
  157. langchain_core/messages/content_blocks.py +0 -176
  158. langchain_core/prompts/pipeline.py +0 -138
  159. langchain_core/pydantic_v1/__init__.py +0 -30
  160. langchain_core/pydantic_v1/dataclasses.py +0 -23
  161. langchain_core/pydantic_v1/main.py +0 -23
  162. langchain_core/tracers/langchain_v1.py +0 -31
  163. langchain_core/utils/loading.py +0 -35
  164. langchain_core-0.3.79.dist-info/RECORD +0 -174
  165. langchain_core-0.3.79.dist-info/entry_points.txt +0 -4
@@ -5,8 +5,9 @@ from __future__ import annotations
5
5
  import ast
6
6
  import asyncio
7
7
  import inspect
8
+ import sys
8
9
  import textwrap
9
- from collections.abc import Mapping, Sequence
10
+ from collections.abc import Callable, Mapping, Sequence
10
11
  from contextvars import Context
11
12
  from functools import lru_cache
12
13
  from inspect import signature
@@ -14,15 +15,13 @@ from itertools import groupby
14
15
  from typing import (
15
16
  TYPE_CHECKING,
16
17
  Any,
17
- Callable,
18
18
  NamedTuple,
19
- Optional,
20
19
  Protocol,
20
+ TypeGuard,
21
21
  TypeVar,
22
- Union,
23
22
  )
24
23
 
25
- from typing_extensions import TypeGuard, override
24
+ from typing_extensions import override
26
25
 
27
26
  # Re-export create-model for backwards compatibility
28
27
  from langchain_core.utils.pydantic import create_model # noqa: F401
@@ -57,7 +56,7 @@ async def gated_coro(semaphore: asyncio.Semaphore, coro: Coroutine) -> Any:
57
56
  return await coro
58
57
 
59
58
 
60
- async def gather_with_concurrency(n: Union[int, None], *coros: Coroutine) -> list:
59
+ async def gather_with_concurrency(n: int | None, *coros: Coroutine) -> list:
61
60
  """Gather coroutines with a limit on the number of concurrent coroutines.
62
61
 
63
62
  Args:
@@ -82,7 +81,7 @@ def accepts_run_manager(callable: Callable[..., Any]) -> bool: # noqa: A002
82
81
  callable: The callable to check.
83
82
 
84
83
  Returns:
85
- bool: True if the callable accepts a run_manager argument, False otherwise.
84
+ `True` if the callable accepts a run_manager argument, `False` otherwise.
86
85
  """
87
86
  try:
88
87
  return signature(callable).parameters.get("run_manager") is not None
@@ -97,7 +96,7 @@ def accepts_config(callable: Callable[..., Any]) -> bool: # noqa: A002
97
96
  callable: The callable to check.
98
97
 
99
98
  Returns:
100
- bool: True if the callable accepts a config argument, False otherwise.
99
+ `True` if the callable accepts a config argument, `False` otherwise.
101
100
  """
102
101
  try:
103
102
  return signature(callable).parameters.get("config") is not None
@@ -112,7 +111,7 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
112
111
  callable: The callable to check.
113
112
 
114
113
  Returns:
115
- bool: True if the callable accepts a context argument, False otherwise.
114
+ `True` if the callable accepts a context argument, `False` otherwise.
116
115
  """
117
116
  try:
118
117
  return signature(callable).parameters.get("context") is not None
@@ -120,15 +119,13 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
120
119
  return False
121
120
 
122
121
 
123
- @lru_cache(maxsize=1)
124
122
  def asyncio_accepts_context() -> bool:
125
- """Cache the result of checking if asyncio.create_task accepts a ``context`` arg.
123
+ """Check if asyncio.create_task accepts a `context` arg.
126
124
 
127
125
  Returns:
128
- bool: True if ``asyncio.create_task`` accepts a context argument, False
129
- otherwise.
126
+ True if `asyncio.create_task` accepts a context argument, `False` otherwise.
130
127
  """
131
- return accepts_context(asyncio.create_task)
128
+ return sys.version_info >= (3, 11)
132
129
 
133
130
 
134
131
  def coro_with_context(
@@ -139,7 +136,7 @@ def coro_with_context(
139
136
  Args:
140
137
  coro: The coroutine to await.
141
138
  context: The context to use.
142
- create_task: Whether to create a task. Defaults to False.
139
+ create_task: Whether to create a task.
143
140
 
144
141
  Returns:
145
142
  The coroutine with the context.
@@ -343,7 +340,7 @@ class GetLambdaSource(ast.NodeVisitor):
343
340
 
344
341
  def __init__(self) -> None:
345
342
  """Initialize the visitor."""
346
- self.source: Optional[str] = None
343
+ self.source: str | None = None
347
344
  self.count = 0
348
345
 
349
346
  @override
@@ -358,15 +355,14 @@ class GetLambdaSource(ast.NodeVisitor):
358
355
  self.source = ast.unparse(node)
359
356
 
360
357
 
361
- def get_function_first_arg_dict_keys(func: Callable) -> Optional[list[str]]:
358
+ def get_function_first_arg_dict_keys(func: Callable) -> list[str] | None:
362
359
  """Get the keys of the first argument of a function if it is a dict.
363
360
 
364
361
  Args:
365
362
  func: The function to check.
366
363
 
367
364
  Returns:
368
- Optional[list[str]]: The keys of the first argument if it is a dict,
369
- None otherwise.
365
+ The keys of the first argument if it is a dict, None otherwise.
370
366
  """
371
367
  try:
372
368
  code = inspect.getsource(func)
@@ -378,14 +374,14 @@ def get_function_first_arg_dict_keys(func: Callable) -> Optional[list[str]]:
378
374
  return None
379
375
 
380
376
 
381
- def get_lambda_source(func: Callable) -> Optional[str]:
377
+ def get_lambda_source(func: Callable) -> str | None:
382
378
  """Get the source code of a lambda function.
383
379
 
384
380
  Args:
385
381
  func: a Callable that can be a lambda function.
386
382
 
387
383
  Returns:
388
- str: the source code of the lambda function.
384
+ the source code of the lambda function.
389
385
  """
390
386
  try:
391
387
  name = func.__name__ if func.__name__ != "<lambda>" else None
@@ -409,7 +405,7 @@ def get_function_nonlocals(func: Callable) -> list[Any]:
409
405
  func: The function to check.
410
406
 
411
407
  Returns:
412
- list[Any]: The nonlocal variables accessed by the function.
408
+ The nonlocal variables accessed by the function.
413
409
  """
414
410
  try:
415
411
  code = inspect.getsource(func)
@@ -452,7 +448,7 @@ def indent_lines_after_first(text: str, prefix: str) -> str:
452
448
  prefix: Used to determine the number of spaces to indent.
453
449
 
454
450
  Returns:
455
- str: The indented text.
451
+ The indented text.
456
452
  """
457
453
  n_spaces = len(prefix)
458
454
  spaces = " " * n_spaces
@@ -520,31 +516,31 @@ class SupportsAdd(Protocol[_T_contra, _T_co]):
520
516
  Addable = TypeVar("Addable", bound=SupportsAdd[Any, Any])
521
517
 
522
518
 
523
- def add(addables: Iterable[Addable]) -> Optional[Addable]:
519
+ def add(addables: Iterable[Addable]) -> Addable | None:
524
520
  """Add a sequence of addable objects together.
525
521
 
526
522
  Args:
527
523
  addables: The addable objects to add.
528
524
 
529
525
  Returns:
530
- Optional[Addable]: The result of adding the addable objects.
526
+ The result of adding the addable objects.
531
527
  """
532
- final: Optional[Addable] = None
528
+ final: Addable | None = None
533
529
  for chunk in addables:
534
530
  final = chunk if final is None else final + chunk
535
531
  return final
536
532
 
537
533
 
538
- async def aadd(addables: AsyncIterable[Addable]) -> Optional[Addable]:
534
+ async def aadd(addables: AsyncIterable[Addable]) -> Addable | None:
539
535
  """Asynchronously add a sequence of addable objects together.
540
536
 
541
537
  Args:
542
538
  addables: The addable objects to add.
543
539
 
544
540
  Returns:
545
- Optional[Addable]: The result of adding the addable objects.
541
+ The result of adding the addable objects.
546
542
  """
547
- final: Optional[Addable] = None
543
+ final: Addable | None = None
548
544
  async for chunk in addables:
549
545
  final = chunk if final is None else final + chunk
550
546
  return final
@@ -555,14 +551,14 @@ class ConfigurableField(NamedTuple):
555
551
 
556
552
  id: str
557
553
  """The unique identifier of the field."""
558
- name: Optional[str] = None
559
- """The name of the field. Defaults to None."""
560
- description: Optional[str] = None
561
- """The description of the field. Defaults to None."""
562
- annotation: Optional[Any] = None
563
- """The annotation of the field. Defaults to None."""
554
+ name: str | None = None
555
+ """The name of the field. """
556
+ description: str | None = None
557
+ """The description of the field. """
558
+ annotation: Any | None = None
559
+ """The annotation of the field. """
564
560
  is_shared: bool = False
565
- """Whether the field is shared. Defaults to False."""
561
+ """Whether the field is shared."""
566
562
 
567
563
  @override
568
564
  def __hash__(self) -> int:
@@ -578,12 +574,12 @@ class ConfigurableFieldSingleOption(NamedTuple):
578
574
  """The options for the field."""
579
575
  default: str
580
576
  """The default value for the field."""
581
- name: Optional[str] = None
582
- """The name of the field. Defaults to None."""
583
- description: Optional[str] = None
584
- """The description of the field. Defaults to None."""
577
+ name: str | None = None
578
+ """The name of the field. """
579
+ description: str | None = None
580
+ """The description of the field. """
585
581
  is_shared: bool = False
586
- """Whether the field is shared. Defaults to False."""
582
+ """Whether the field is shared."""
587
583
 
588
584
  @override
589
585
  def __hash__(self) -> int:
@@ -599,21 +595,21 @@ class ConfigurableFieldMultiOption(NamedTuple):
599
595
  """The options for the field."""
600
596
  default: Sequence[str]
601
597
  """The default values for the field."""
602
- name: Optional[str] = None
603
- """The name of the field. Defaults to None."""
604
- description: Optional[str] = None
605
- """The description of the field. Defaults to None."""
598
+ name: str | None = None
599
+ """The name of the field. """
600
+ description: str | None = None
601
+ """The description of the field. """
606
602
  is_shared: bool = False
607
- """Whether the field is shared. Defaults to False."""
603
+ """Whether the field is shared."""
608
604
 
609
605
  @override
610
606
  def __hash__(self) -> int:
611
607
  return hash((self.id, tuple(self.options.keys()), tuple(self.default)))
612
608
 
613
609
 
614
- AnyConfigurableField = Union[
615
- ConfigurableField, ConfigurableFieldSingleOption, ConfigurableFieldMultiOption
616
- ]
610
+ AnyConfigurableField = (
611
+ ConfigurableField | ConfigurableFieldSingleOption | ConfigurableFieldMultiOption
612
+ )
617
613
 
618
614
 
619
615
  class ConfigurableFieldSpec(NamedTuple):
@@ -623,16 +619,16 @@ class ConfigurableFieldSpec(NamedTuple):
623
619
  """The unique identifier of the field."""
624
620
  annotation: Any
625
621
  """The annotation of the field."""
626
- name: Optional[str] = None
627
- """The name of the field. Defaults to None."""
628
- description: Optional[str] = None
629
- """The description of the field. Defaults to None."""
622
+ name: str | None = None
623
+ """The name of the field. """
624
+ description: str | None = None
625
+ """The description of the field. """
630
626
  default: Any = None
631
- """The default value for the field. Defaults to None."""
627
+ """The default value for the field. """
632
628
  is_shared: bool = False
633
- """Whether the field is shared. Defaults to False."""
634
- dependencies: Optional[list[str]] = None
635
- """The dependencies of the field. Defaults to None."""
629
+ """Whether the field is shared."""
630
+ dependencies: list[str] | None = None
631
+ """The dependencies of the field. """
636
632
 
637
633
 
638
634
  def get_unique_config_specs(
@@ -644,7 +640,7 @@ def get_unique_config_specs(
644
640
  specs: The config specs.
645
641
 
646
642
  Returns:
647
- list[ConfigurableFieldSpec]: The unique config specs.
643
+ The unique config specs.
648
644
 
649
645
  Raises:
650
646
  ValueError: If the runnable sequence contains conflicting config specs.
@@ -671,12 +667,12 @@ class _RootEventFilter:
671
667
  def __init__(
672
668
  self,
673
669
  *,
674
- include_names: Optional[Sequence[str]] = None,
675
- include_types: Optional[Sequence[str]] = None,
676
- include_tags: Optional[Sequence[str]] = None,
677
- exclude_names: Optional[Sequence[str]] = None,
678
- exclude_types: Optional[Sequence[str]] = None,
679
- exclude_tags: Optional[Sequence[str]] = None,
670
+ include_names: Sequence[str] | None = None,
671
+ include_types: Sequence[str] | None = None,
672
+ include_tags: Sequence[str] | None = None,
673
+ exclude_names: Sequence[str] | None = None,
674
+ exclude_types: Sequence[str] | None = None,
675
+ exclude_tags: Sequence[str] | None = None,
680
676
  ) -> None:
681
677
  """Utility to filter the root event in the astream_events implementation.
682
678
 
@@ -731,8 +727,7 @@ def is_async_generator(
731
727
  func: The function to check.
732
728
 
733
729
  Returns:
734
- TypeGuard[Callable[..., AsyncIterator]: True if the function is
735
- an async generator, False otherwise.
730
+ `True` if the function is an async generator, `False` otherwise.
736
731
  """
737
732
  return inspect.isasyncgenfunction(func) or (
738
733
  hasattr(func, "__call__") # noqa: B004
@@ -749,8 +744,7 @@ def is_async_callable(
749
744
  func: The function to check.
750
745
 
751
746
  Returns:
752
- TypeGuard[Callable[..., Awaitable]: True if the function is async,
753
- False otherwise.
747
+ `True` if the function is async, `False` otherwise.
754
748
  """
755
749
  return asyncio.iscoroutinefunction(func) or (
756
750
  hasattr(func, "__call__") # noqa: B004
langchain_core/stores.py CHANGED
@@ -11,9 +11,7 @@ from collections.abc import AsyncIterator, Iterator, Sequence
11
11
  from typing import (
12
12
  Any,
13
13
  Generic,
14
- Optional,
15
14
  TypeVar,
16
- Union,
17
15
  )
18
16
 
19
17
  from typing_extensions import override
@@ -49,55 +47,53 @@ class BaseStore(ABC, Generic[K, V]):
49
47
  which will usually be more efficient by saving on round trips to the store.
50
48
 
51
49
  Examples:
52
-
53
- .. code-block:: python
54
-
55
- from langchain.storage import BaseStore
56
-
57
-
58
- class MyInMemoryStore(BaseStore[str, int]):
59
- def __init__(self) -> None:
60
- self.store: dict[str, int] = {}
61
-
62
- def mget(self, keys: Sequence[str]) -> list[int | None]:
63
- return [self.store.get(key) for key in keys]
64
-
65
- def mset(self, key_value_pairs: Sequence[tuple[str, int]]) -> None:
66
- for key, value in key_value_pairs:
67
- self.store[key] = value
68
-
69
- def mdelete(self, keys: Sequence[str]) -> None:
70
- for key in keys:
71
- if key in self.store:
72
- del self.store[key]
73
-
74
- def yield_keys(self, prefix: str | None = None) -> Iterator[str]:
75
- if prefix is None:
76
- yield from self.store.keys()
77
- else:
78
- for key in self.store.keys():
79
- if key.startswith(prefix):
80
- yield key
81
-
50
+ ```python
51
+ from langchain.storage import BaseStore
52
+
53
+
54
+ class MyInMemoryStore(BaseStore[str, int]):
55
+ def __init__(self) -> None:
56
+ self.store: dict[str, int] = {}
57
+
58
+ def mget(self, keys: Sequence[str]) -> list[int | None]:
59
+ return [self.store.get(key) for key in keys]
60
+
61
+ def mset(self, key_value_pairs: Sequence[tuple[str, int]]) -> None:
62
+ for key, value in key_value_pairs:
63
+ self.store[key] = value
64
+
65
+ def mdelete(self, keys: Sequence[str]) -> None:
66
+ for key in keys:
67
+ if key in self.store:
68
+ del self.store[key]
69
+
70
+ def yield_keys(self, prefix: str | None = None) -> Iterator[str]:
71
+ if prefix is None:
72
+ yield from self.store.keys()
73
+ else:
74
+ for key in self.store.keys():
75
+ if key.startswith(prefix):
76
+ yield key
77
+ ```
82
78
  """
83
79
 
84
80
  @abstractmethod
85
- def mget(self, keys: Sequence[K]) -> list[Optional[V]]:
81
+ def mget(self, keys: Sequence[K]) -> list[V | None]:
86
82
  """Get the values associated with the given keys.
87
83
 
88
84
  Args:
89
- keys (Sequence[K]): A sequence of keys.
85
+ keys: A sequence of keys.
90
86
 
91
87
  Returns:
92
88
  A sequence of optional values associated with the keys.
93
89
  If a key is not found, the corresponding value will be None.
94
90
  """
95
91
 
96
- async def amget(self, keys: Sequence[K]) -> list[Optional[V]]:
92
+ async def amget(self, keys: Sequence[K]) -> list[V | None]:
97
93
  """Async get the values associated with the given keys.
98
94
 
99
95
  Args:
100
- keys (Sequence[K]): A sequence of keys.
96
+ keys: A sequence of keys.
101
97
 
102
98
  Returns:
103
99
  A sequence of optional values associated with the keys.
@@ -110,14 +106,14 @@ class BaseStore(ABC, Generic[K, V]):
110
106
  """Set the values for the given keys.
111
107
 
112
108
  Args:
113
- key_value_pairs (Sequence[tuple[K, V]]): A sequence of key-value pairs.
109
+ key_value_pairs: A sequence of key-value pairs.
114
110
  """
115
111
 
116
112
  async def amset(self, key_value_pairs: Sequence[tuple[K, V]]) -> None:
117
113
  """Async set the values for the given keys.
118
114
 
119
115
  Args:
120
- key_value_pairs (Sequence[tuple[K, V]]): A sequence of key-value pairs.
116
+ key_value_pairs: A sequence of key-value pairs.
121
117
  """
122
118
  return await run_in_executor(None, self.mset, key_value_pairs)
123
119
 
@@ -126,42 +122,40 @@ class BaseStore(ABC, Generic[K, V]):
126
122
  """Delete the given keys and their associated values.
127
123
 
128
124
  Args:
129
- keys (Sequence[K]): A sequence of keys to delete.
125
+ keys: A sequence of keys to delete.
130
126
  """
131
127
 
132
128
  async def amdelete(self, keys: Sequence[K]) -> None:
133
129
  """Async delete the given keys and their associated values.
134
130
 
135
131
  Args:
136
- keys (Sequence[K]): A sequence of keys to delete.
132
+ keys: A sequence of keys to delete.
137
133
  """
138
134
  return await run_in_executor(None, self.mdelete, keys)
139
135
 
140
136
  @abstractmethod
141
- def yield_keys(
142
- self, *, prefix: Optional[str] = None
143
- ) -> Union[Iterator[K], Iterator[str]]:
137
+ def yield_keys(self, *, prefix: str | None = None) -> Iterator[K] | Iterator[str]:
144
138
  """Get an iterator over keys that match the given prefix.
145
139
 
146
140
  Args:
147
- prefix (str): The prefix to match.
141
+ prefix: The prefix to match.
148
142
 
149
143
  Yields:
150
- Iterator[K | str]: An iterator over keys that match the given prefix.
144
+ An iterator over keys that match the given prefix.
151
145
  This method is allowed to return an iterator over either K or str
152
146
  depending on what makes more sense for the given store.
153
147
  """
154
148
 
155
149
  async def ayield_keys(
156
- self, *, prefix: Optional[str] = None
157
- ) -> Union[AsyncIterator[K], AsyncIterator[str]]:
150
+ self, *, prefix: str | None = None
151
+ ) -> AsyncIterator[K] | AsyncIterator[str]:
158
152
  """Async get an iterator over keys that match the given prefix.
159
153
 
160
154
  Args:
161
- prefix (str): The prefix to match.
155
+ prefix: The prefix to match.
162
156
 
163
157
  Yields:
164
- Iterator[K | str]: An iterator over keys that match the given prefix.
158
+ The keys that match the given prefix.
165
159
  This method is allowed to return an iterator over either K or str
166
160
  depending on what makes more sense for the given store.
167
161
  """
@@ -184,28 +178,12 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
184
178
  """Initialize an empty store."""
185
179
  self.store: dict[str, V] = {}
186
180
 
187
- def mget(self, keys: Sequence[str]) -> list[Optional[V]]:
188
- """Get the values associated with the given keys.
189
-
190
- Args:
191
- keys (Sequence[str]): A sequence of keys.
192
-
193
- Returns:
194
- A sequence of optional values associated with the keys.
195
- If a key is not found, the corresponding value will be None.
196
- """
181
+ @override
182
+ def mget(self, keys: Sequence[str]) -> list[V | None]:
197
183
  return [self.store.get(key) for key in keys]
198
184
 
199
- async def amget(self, keys: Sequence[str]) -> list[Optional[V]]:
200
- """Async get the values associated with the given keys.
201
-
202
- Args:
203
- keys (Sequence[str]): A sequence of keys.
204
-
205
- Returns:
206
- A sequence of optional values associated with the keys.
207
- If a key is not found, the corresponding value will be None.
208
- """
185
+ @override
186
+ async def amget(self, keys: Sequence[str]) -> list[V | None]:
209
187
  return self.mget(keys)
210
188
 
211
189
  @override
@@ -217,32 +195,24 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
217
195
  async def amset(self, key_value_pairs: Sequence[tuple[str, V]]) -> None:
218
196
  return self.mset(key_value_pairs)
219
197
 
198
+ @override
220
199
  def mdelete(self, keys: Sequence[str]) -> None:
221
- """Delete the given keys and their associated values.
222
-
223
- Args:
224
- keys (Sequence[str]): A sequence of keys to delete.
225
- """
226
200
  for key in keys:
227
201
  if key in self.store:
228
202
  del self.store[key]
229
203
 
204
+ @override
230
205
  async def amdelete(self, keys: Sequence[str]) -> None:
231
- """Async delete the given keys and their associated values.
232
-
233
- Args:
234
- keys (Sequence[str]): A sequence of keys to delete.
235
- """
236
206
  self.mdelete(keys)
237
207
 
238
- def yield_keys(self, prefix: Optional[str] = None) -> Iterator[str]:
208
+ def yield_keys(self, prefix: str | None = None) -> Iterator[str]:
239
209
  """Get an iterator over keys that match the given prefix.
240
210
 
241
211
  Args:
242
- prefix (str, optional): The prefix to match. Defaults to None.
212
+ prefix: The prefix to match.
243
213
 
244
214
  Yields:
245
- Iterator[str]: An iterator over keys that match the given prefix.
215
+ The keys that match the given prefix.
246
216
  """
247
217
  if prefix is None:
248
218
  yield from self.store.keys()
@@ -251,14 +221,14 @@ class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
251
221
  if key.startswith(prefix):
252
222
  yield key
253
223
 
254
- async def ayield_keys(self, prefix: Optional[str] = None) -> AsyncIterator[str]:
224
+ async def ayield_keys(self, prefix: str | None = None) -> AsyncIterator[str]:
255
225
  """Async get an async iterator over keys that match the given prefix.
256
226
 
257
227
  Args:
258
- prefix (str, optional): The prefix to match. Defaults to None.
228
+ prefix: The prefix to match.
259
229
 
260
230
  Yields:
261
- AsyncIterator[str]: An async iterator over keys that match the given prefix.
231
+ The keys that match the given prefix.
262
232
  """
263
233
  if prefix is None:
264
234
  for key in self.store:
@@ -277,21 +247,19 @@ class InMemoryStore(InMemoryBaseStore[Any]):
277
247
  the key-value pairs.
278
248
 
279
249
  Examples:
280
-
281
- .. code-block:: python
282
-
283
- from langchain.storage import InMemoryStore
284
-
285
- store = InMemoryStore()
286
- store.mset([("key1", "value1"), ("key2", "value2")])
287
- store.mget(["key1", "key2"])
288
- # ['value1', 'value2']
289
- store.mdelete(["key1"])
290
- list(store.yield_keys())
291
- # ['key2']
292
- list(store.yield_keys(prefix="k"))
293
- # ['key2']
294
-
250
+ ```python
251
+ from langchain.storage import InMemoryStore
252
+
253
+ store = InMemoryStore()
254
+ store.mset([("key1", "value1"), ("key2", "value2")])
255
+ store.mget(["key1", "key2"])
256
+ # ['value1', 'value2']
257
+ store.mdelete(["key1"])
258
+ list(store.yield_keys())
259
+ # ['key2']
260
+ list(store.yield_keys(prefix="k"))
261
+ # ['key2']
262
+ ```
295
263
  """
296
264
 
297
265
 
@@ -303,21 +271,19 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]):
303
271
  the key-value pairs.
304
272
 
305
273
  Examples:
306
-
307
- .. code-block:: python
308
-
309
- from langchain.storage import InMemoryByteStore
310
-
311
- store = InMemoryByteStore()
312
- store.mset([("key1", b"value1"), ("key2", b"value2")])
313
- store.mget(["key1", "key2"])
314
- # [b'value1', b'value2']
315
- store.mdelete(["key1"])
316
- list(store.yield_keys())
317
- # ['key2']
318
- list(store.yield_keys(prefix="k"))
319
- # ['key2']
320
-
274
+ ```python
275
+ from langchain.storage import InMemoryByteStore
276
+
277
+ store = InMemoryByteStore()
278
+ store.mset([("key1", b"value1"), ("key2", b"value2")])
279
+ store.mget(["key1", "key2"])
280
+ # [b'value1', b'value2']
281
+ store.mdelete(["key1"])
282
+ list(store.yield_keys())
283
+ # ['key2']
284
+ list(store.yield_keys(prefix="k"))
285
+ # ['key2']
286
+ ```
321
287
  """
322
288
 
323
289