langchain-core 1.0.0a6__py3-none-any.whl → 1.0.3__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.
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 +51 -64
  5. langchain_core/_api/path.py +3 -6
  6. langchain_core/_import_utils.py +3 -4
  7. langchain_core/agents.py +20 -22
  8. langchain_core/caches.py +65 -66
  9. langchain_core/callbacks/__init__.py +1 -8
  10. langchain_core/callbacks/base.py +321 -336
  11. langchain_core/callbacks/file.py +44 -44
  12. langchain_core/callbacks/manager.py +436 -513
  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 +53 -68
  17. langchain_core/document_loaders/base.py +27 -25
  18. langchain_core/document_loaders/blob_loaders.py +1 -1
  19. langchain_core/document_loaders/langsmith.py +44 -48
  20. langchain_core/documents/__init__.py +23 -3
  21. langchain_core/documents/base.py +98 -90
  22. langchain_core/documents/compressor.py +10 -10
  23. langchain_core/documents/transformers.py +34 -35
  24. langchain_core/embeddings/fake.py +50 -54
  25. langchain_core/example_selectors/length_based.py +1 -1
  26. langchain_core/example_selectors/semantic_similarity.py +28 -32
  27. langchain_core/exceptions.py +21 -20
  28. langchain_core/globals.py +3 -151
  29. langchain_core/indexing/__init__.py +1 -1
  30. langchain_core/indexing/api.py +121 -126
  31. langchain_core/indexing/base.py +73 -75
  32. langchain_core/indexing/in_memory.py +4 -6
  33. langchain_core/language_models/__init__.py +14 -29
  34. langchain_core/language_models/_utils.py +58 -61
  35. langchain_core/language_models/base.py +53 -162
  36. langchain_core/language_models/chat_models.py +298 -387
  37. langchain_core/language_models/fake.py +11 -11
  38. langchain_core/language_models/fake_chat_models.py +42 -36
  39. langchain_core/language_models/llms.py +125 -235
  40. langchain_core/load/dump.py +9 -12
  41. langchain_core/load/load.py +18 -28
  42. langchain_core/load/mapping.py +2 -4
  43. langchain_core/load/serializable.py +42 -40
  44. langchain_core/messages/__init__.py +10 -16
  45. langchain_core/messages/ai.py +148 -148
  46. langchain_core/messages/base.py +53 -51
  47. langchain_core/messages/block_translators/__init__.py +19 -22
  48. langchain_core/messages/block_translators/anthropic.py +6 -6
  49. langchain_core/messages/block_translators/bedrock_converse.py +5 -5
  50. langchain_core/messages/block_translators/google_genai.py +10 -7
  51. langchain_core/messages/block_translators/google_vertexai.py +4 -32
  52. langchain_core/messages/block_translators/groq.py +117 -21
  53. langchain_core/messages/block_translators/langchain_v0.py +5 -5
  54. langchain_core/messages/block_translators/openai.py +11 -11
  55. langchain_core/messages/chat.py +2 -6
  56. langchain_core/messages/content.py +337 -328
  57. langchain_core/messages/function.py +6 -10
  58. langchain_core/messages/human.py +24 -31
  59. langchain_core/messages/modifier.py +2 -2
  60. langchain_core/messages/system.py +19 -29
  61. langchain_core/messages/tool.py +74 -90
  62. langchain_core/messages/utils.py +474 -504
  63. langchain_core/output_parsers/__init__.py +13 -10
  64. langchain_core/output_parsers/base.py +61 -61
  65. langchain_core/output_parsers/format_instructions.py +9 -4
  66. langchain_core/output_parsers/json.py +12 -10
  67. langchain_core/output_parsers/list.py +21 -23
  68. langchain_core/output_parsers/openai_functions.py +49 -47
  69. langchain_core/output_parsers/openai_tools.py +16 -21
  70. langchain_core/output_parsers/pydantic.py +13 -14
  71. langchain_core/output_parsers/string.py +5 -5
  72. langchain_core/output_parsers/transform.py +15 -17
  73. langchain_core/output_parsers/xml.py +35 -34
  74. langchain_core/outputs/__init__.py +1 -1
  75. langchain_core/outputs/chat_generation.py +18 -18
  76. langchain_core/outputs/chat_result.py +1 -3
  77. langchain_core/outputs/generation.py +10 -11
  78. langchain_core/outputs/llm_result.py +10 -10
  79. langchain_core/prompt_values.py +11 -17
  80. langchain_core/prompts/__init__.py +3 -27
  81. langchain_core/prompts/base.py +48 -56
  82. langchain_core/prompts/chat.py +275 -325
  83. langchain_core/prompts/dict.py +5 -5
  84. langchain_core/prompts/few_shot.py +81 -88
  85. langchain_core/prompts/few_shot_with_templates.py +11 -13
  86. langchain_core/prompts/image.py +12 -14
  87. langchain_core/prompts/loading.py +4 -6
  88. langchain_core/prompts/message.py +3 -3
  89. langchain_core/prompts/prompt.py +24 -39
  90. langchain_core/prompts/string.py +26 -10
  91. langchain_core/prompts/structured.py +49 -53
  92. langchain_core/rate_limiters.py +51 -60
  93. langchain_core/retrievers.py +61 -198
  94. langchain_core/runnables/base.py +1476 -1626
  95. langchain_core/runnables/branch.py +53 -57
  96. langchain_core/runnables/config.py +72 -89
  97. langchain_core/runnables/configurable.py +120 -137
  98. langchain_core/runnables/fallbacks.py +83 -79
  99. langchain_core/runnables/graph.py +91 -97
  100. langchain_core/runnables/graph_ascii.py +27 -28
  101. langchain_core/runnables/graph_mermaid.py +38 -50
  102. langchain_core/runnables/graph_png.py +15 -16
  103. langchain_core/runnables/history.py +135 -148
  104. langchain_core/runnables/passthrough.py +124 -150
  105. langchain_core/runnables/retry.py +46 -51
  106. langchain_core/runnables/router.py +25 -30
  107. langchain_core/runnables/schema.py +75 -80
  108. langchain_core/runnables/utils.py +60 -67
  109. langchain_core/stores.py +85 -121
  110. langchain_core/structured_query.py +8 -8
  111. langchain_core/sys_info.py +27 -29
  112. langchain_core/tools/__init__.py +1 -14
  113. langchain_core/tools/base.py +284 -229
  114. langchain_core/tools/convert.py +160 -155
  115. langchain_core/tools/render.py +10 -10
  116. langchain_core/tools/retriever.py +12 -11
  117. langchain_core/tools/simple.py +19 -24
  118. langchain_core/tools/structured.py +32 -39
  119. langchain_core/tracers/__init__.py +1 -9
  120. langchain_core/tracers/base.py +97 -99
  121. langchain_core/tracers/context.py +29 -52
  122. langchain_core/tracers/core.py +49 -53
  123. langchain_core/tracers/evaluation.py +11 -11
  124. langchain_core/tracers/event_stream.py +65 -64
  125. langchain_core/tracers/langchain.py +21 -21
  126. langchain_core/tracers/log_stream.py +45 -45
  127. langchain_core/tracers/memory_stream.py +3 -3
  128. langchain_core/tracers/root_listeners.py +16 -16
  129. langchain_core/tracers/run_collector.py +2 -4
  130. langchain_core/tracers/schemas.py +0 -129
  131. langchain_core/tracers/stdout.py +3 -3
  132. langchain_core/utils/__init__.py +1 -4
  133. langchain_core/utils/_merge.py +2 -2
  134. langchain_core/utils/aiter.py +57 -61
  135. langchain_core/utils/env.py +9 -9
  136. langchain_core/utils/function_calling.py +89 -186
  137. langchain_core/utils/html.py +7 -8
  138. langchain_core/utils/input.py +6 -6
  139. langchain_core/utils/interactive_env.py +1 -1
  140. langchain_core/utils/iter.py +36 -40
  141. langchain_core/utils/json.py +4 -3
  142. langchain_core/utils/json_schema.py +9 -9
  143. langchain_core/utils/mustache.py +8 -10
  144. langchain_core/utils/pydantic.py +33 -35
  145. langchain_core/utils/strings.py +6 -9
  146. langchain_core/utils/usage.py +1 -1
  147. langchain_core/utils/utils.py +66 -62
  148. langchain_core/vectorstores/base.py +182 -216
  149. langchain_core/vectorstores/in_memory.py +101 -176
  150. langchain_core/vectorstores/utils.py +5 -5
  151. langchain_core/version.py +1 -1
  152. langchain_core-1.0.3.dist-info/METADATA +69 -0
  153. langchain_core-1.0.3.dist-info/RECORD +172 -0
  154. {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.3.dist-info}/WHEEL +1 -1
  155. langchain_core/memory.py +0 -120
  156. langchain_core/messages/block_translators/ollama.py +0 -47
  157. langchain_core/prompts/pipeline.py +0 -138
  158. langchain_core/pydantic_v1/__init__.py +0 -30
  159. langchain_core/pydantic_v1/dataclasses.py +0 -23
  160. langchain_core/pydantic_v1/main.py +0 -23
  161. langchain_core/tracers/langchain_v1.py +0 -31
  162. langchain_core/utils/loading.py +0 -35
  163. langchain_core-1.0.0a6.dist-info/METADATA +0 -67
  164. langchain_core-1.0.0a6.dist-info/RECORD +0 -181
  165. langchain_core-1.0.0a6.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,13 +15,10 @@ 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,
21
20
  TypeGuard,
22
21
  TypeVar,
23
- Union,
24
22
  )
25
23
 
26
24
  from typing_extensions import override
@@ -58,7 +56,7 @@ async def gated_coro(semaphore: asyncio.Semaphore, coro: Coroutine) -> Any:
58
56
  return await coro
59
57
 
60
58
 
61
- async def gather_with_concurrency(n: Union[int, None], *coros: Coroutine) -> list:
59
+ async def gather_with_concurrency(n: int | None, *coros: Coroutine) -> list:
62
60
  """Gather coroutines with a limit on the number of concurrent coroutines.
63
61
 
64
62
  Args:
@@ -83,7 +81,7 @@ def accepts_run_manager(callable: Callable[..., Any]) -> bool: # noqa: A002
83
81
  callable: The callable to check.
84
82
 
85
83
  Returns:
86
- bool: True if the callable accepts a run_manager argument, False otherwise.
84
+ `True` if the callable accepts a run_manager argument, `False` otherwise.
87
85
  """
88
86
  try:
89
87
  return signature(callable).parameters.get("run_manager") is not None
@@ -98,7 +96,7 @@ def accepts_config(callable: Callable[..., Any]) -> bool: # noqa: A002
98
96
  callable: The callable to check.
99
97
 
100
98
  Returns:
101
- bool: True if the callable accepts a config argument, False otherwise.
99
+ `True` if the callable accepts a config argument, `False` otherwise.
102
100
  """
103
101
  try:
104
102
  return signature(callable).parameters.get("config") is not None
@@ -113,7 +111,7 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
113
111
  callable: The callable to check.
114
112
 
115
113
  Returns:
116
- bool: True if the callable accepts a context argument, False otherwise.
114
+ `True` if the callable accepts a context argument, `False` otherwise.
117
115
  """
118
116
  try:
119
117
  return signature(callable).parameters.get("context") is not None
@@ -121,15 +119,13 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
121
119
  return False
122
120
 
123
121
 
124
- @lru_cache(maxsize=1)
125
122
  def asyncio_accepts_context() -> bool:
126
- """Cache the result of checking if asyncio.create_task accepts a ``context`` arg.
123
+ """Check if asyncio.create_task accepts a `context` arg.
127
124
 
128
125
  Returns:
129
- bool: True if ``asyncio.create_task`` accepts a context argument, False
130
- otherwise.
126
+ True if `asyncio.create_task` accepts a context argument, `False` otherwise.
131
127
  """
132
- return accepts_context(asyncio.create_task)
128
+ return sys.version_info >= (3, 11)
133
129
 
134
130
 
135
131
  def coro_with_context(
@@ -140,7 +136,7 @@ def coro_with_context(
140
136
  Args:
141
137
  coro: The coroutine to await.
142
138
  context: The context to use.
143
- create_task: Whether to create a task. Defaults to False.
139
+ create_task: Whether to create a task.
144
140
 
145
141
  Returns:
146
142
  The coroutine with the context.
@@ -344,7 +340,7 @@ class GetLambdaSource(ast.NodeVisitor):
344
340
 
345
341
  def __init__(self) -> None:
346
342
  """Initialize the visitor."""
347
- self.source: Optional[str] = None
343
+ self.source: str | None = None
348
344
  self.count = 0
349
345
 
350
346
  @override
@@ -359,15 +355,14 @@ class GetLambdaSource(ast.NodeVisitor):
359
355
  self.source = ast.unparse(node)
360
356
 
361
357
 
362
- 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:
363
359
  """Get the keys of the first argument of a function if it is a dict.
364
360
 
365
361
  Args:
366
362
  func: The function to check.
367
363
 
368
364
  Returns:
369
- Optional[list[str]]: The keys of the first argument if it is a dict,
370
- None otherwise.
365
+ The keys of the first argument if it is a dict, None otherwise.
371
366
  """
372
367
  try:
373
368
  code = inspect.getsource(func)
@@ -379,14 +374,14 @@ def get_function_first_arg_dict_keys(func: Callable) -> Optional[list[str]]:
379
374
  return None
380
375
 
381
376
 
382
- def get_lambda_source(func: Callable) -> Optional[str]:
377
+ def get_lambda_source(func: Callable) -> str | None:
383
378
  """Get the source code of a lambda function.
384
379
 
385
380
  Args:
386
381
  func: a Callable that can be a lambda function.
387
382
 
388
383
  Returns:
389
- str: the source code of the lambda function.
384
+ the source code of the lambda function.
390
385
  """
391
386
  try:
392
387
  name = func.__name__ if func.__name__ != "<lambda>" else None
@@ -410,7 +405,7 @@ def get_function_nonlocals(func: Callable) -> list[Any]:
410
405
  func: The function to check.
411
406
 
412
407
  Returns:
413
- list[Any]: The nonlocal variables accessed by the function.
408
+ The nonlocal variables accessed by the function.
414
409
  """
415
410
  try:
416
411
  code = inspect.getsource(func)
@@ -453,7 +448,7 @@ def indent_lines_after_first(text: str, prefix: str) -> str:
453
448
  prefix: Used to determine the number of spaces to indent.
454
449
 
455
450
  Returns:
456
- str: The indented text.
451
+ The indented text.
457
452
  """
458
453
  n_spaces = len(prefix)
459
454
  spaces = " " * n_spaces
@@ -521,31 +516,31 @@ class SupportsAdd(Protocol[_T_contra, _T_co]):
521
516
  Addable = TypeVar("Addable", bound=SupportsAdd[Any, Any])
522
517
 
523
518
 
524
- def add(addables: Iterable[Addable]) -> Optional[Addable]:
519
+ def add(addables: Iterable[Addable]) -> Addable | None:
525
520
  """Add a sequence of addable objects together.
526
521
 
527
522
  Args:
528
523
  addables: The addable objects to add.
529
524
 
530
525
  Returns:
531
- Optional[Addable]: The result of adding the addable objects.
526
+ The result of adding the addable objects.
532
527
  """
533
- final: Optional[Addable] = None
528
+ final: Addable | None = None
534
529
  for chunk in addables:
535
530
  final = chunk if final is None else final + chunk
536
531
  return final
537
532
 
538
533
 
539
- async def aadd(addables: AsyncIterable[Addable]) -> Optional[Addable]:
534
+ async def aadd(addables: AsyncIterable[Addable]) -> Addable | None:
540
535
  """Asynchronously add a sequence of addable objects together.
541
536
 
542
537
  Args:
543
538
  addables: The addable objects to add.
544
539
 
545
540
  Returns:
546
- Optional[Addable]: The result of adding the addable objects.
541
+ The result of adding the addable objects.
547
542
  """
548
- final: Optional[Addable] = None
543
+ final: Addable | None = None
549
544
  async for chunk in addables:
550
545
  final = chunk if final is None else final + chunk
551
546
  return final
@@ -556,14 +551,14 @@ class ConfigurableField(NamedTuple):
556
551
 
557
552
  id: str
558
553
  """The unique identifier of the field."""
559
- name: Optional[str] = None
560
- """The name of the field. Defaults to None."""
561
- description: Optional[str] = None
562
- """The description of the field. Defaults to None."""
563
- annotation: Optional[Any] = None
564
- """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. """
565
560
  is_shared: bool = False
566
- """Whether the field is shared. Defaults to False."""
561
+ """Whether the field is shared."""
567
562
 
568
563
  @override
569
564
  def __hash__(self) -> int:
@@ -579,12 +574,12 @@ class ConfigurableFieldSingleOption(NamedTuple):
579
574
  """The options for the field."""
580
575
  default: str
581
576
  """The default value for the field."""
582
- name: Optional[str] = None
583
- """The name of the field. Defaults to None."""
584
- description: Optional[str] = None
585
- """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. """
586
581
  is_shared: bool = False
587
- """Whether the field is shared. Defaults to False."""
582
+ """Whether the field is shared."""
588
583
 
589
584
  @override
590
585
  def __hash__(self) -> int:
@@ -600,21 +595,21 @@ class ConfigurableFieldMultiOption(NamedTuple):
600
595
  """The options for the field."""
601
596
  default: Sequence[str]
602
597
  """The default values for the field."""
603
- name: Optional[str] = None
604
- """The name of the field. Defaults to None."""
605
- description: Optional[str] = None
606
- """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. """
607
602
  is_shared: bool = False
608
- """Whether the field is shared. Defaults to False."""
603
+ """Whether the field is shared."""
609
604
 
610
605
  @override
611
606
  def __hash__(self) -> int:
612
607
  return hash((self.id, tuple(self.options.keys()), tuple(self.default)))
613
608
 
614
609
 
615
- AnyConfigurableField = Union[
616
- ConfigurableField, ConfigurableFieldSingleOption, ConfigurableFieldMultiOption
617
- ]
610
+ AnyConfigurableField = (
611
+ ConfigurableField | ConfigurableFieldSingleOption | ConfigurableFieldMultiOption
612
+ )
618
613
 
619
614
 
620
615
  class ConfigurableFieldSpec(NamedTuple):
@@ -624,16 +619,16 @@ class ConfigurableFieldSpec(NamedTuple):
624
619
  """The unique identifier of the field."""
625
620
  annotation: Any
626
621
  """The annotation of the field."""
627
- name: Optional[str] = None
628
- """The name of the field. Defaults to None."""
629
- description: Optional[str] = None
630
- """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. """
631
626
  default: Any = None
632
- """The default value for the field. Defaults to None."""
627
+ """The default value for the field. """
633
628
  is_shared: bool = False
634
- """Whether the field is shared. Defaults to False."""
635
- dependencies: Optional[list[str]] = None
636
- """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. """
637
632
 
638
633
 
639
634
  def get_unique_config_specs(
@@ -645,7 +640,7 @@ def get_unique_config_specs(
645
640
  specs: The config specs.
646
641
 
647
642
  Returns:
648
- list[ConfigurableFieldSpec]: The unique config specs.
643
+ The unique config specs.
649
644
 
650
645
  Raises:
651
646
  ValueError: If the runnable sequence contains conflicting config specs.
@@ -672,12 +667,12 @@ class _RootEventFilter:
672
667
  def __init__(
673
668
  self,
674
669
  *,
675
- include_names: Optional[Sequence[str]] = None,
676
- include_types: Optional[Sequence[str]] = None,
677
- include_tags: Optional[Sequence[str]] = None,
678
- exclude_names: Optional[Sequence[str]] = None,
679
- exclude_types: Optional[Sequence[str]] = None,
680
- 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,
681
676
  ) -> None:
682
677
  """Utility to filter the root event in the astream_events implementation.
683
678
 
@@ -732,8 +727,7 @@ def is_async_generator(
732
727
  func: The function to check.
733
728
 
734
729
  Returns:
735
- TypeGuard[Callable[..., AsyncIterator]: True if the function is
736
- an async generator, False otherwise.
730
+ `True` if the function is an async generator, `False` otherwise.
737
731
  """
738
732
  return inspect.isasyncgenfunction(func) or (
739
733
  hasattr(func, "__call__") # noqa: B004
@@ -750,8 +744,7 @@ def is_async_callable(
750
744
  func: The function to check.
751
745
 
752
746
  Returns:
753
- TypeGuard[Callable[..., Awaitable]: True if the function is async,
754
- False otherwise.
747
+ `True` if the function is async, `False` otherwise.
755
748
  """
756
749
  return asyncio.iscoroutinefunction(func) or (
757
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,59 +47,57 @@ 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
- 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`.
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.
104
- 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`.
105
101
  """
106
102
  return await run_in_executor(None, self.mget, keys)
107
103
 
@@ -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:
@@ -273,25 +243,22 @@ class InMemoryStore(InMemoryBaseStore[Any]):
273
243
  """In-memory store for any type of data.
274
244
 
275
245
  Attributes:
276
- store (dict[str, Any]): The underlying dictionary that stores
277
- the key-value pairs.
246
+ store: The underlying dictionary that stores the key-value pairs.
278
247
 
279
248
  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
-
249
+ ```python
250
+ from langchain.storage import InMemoryStore
251
+
252
+ store = InMemoryStore()
253
+ store.mset([("key1", "value1"), ("key2", "value2")])
254
+ store.mget(["key1", "key2"])
255
+ # ['value1', 'value2']
256
+ store.mdelete(["key1"])
257
+ list(store.yield_keys())
258
+ # ['key2']
259
+ list(store.yield_keys(prefix="k"))
260
+ # ['key2']
261
+ ```
295
262
  """
296
263
 
297
264
 
@@ -299,25 +266,22 @@ class InMemoryByteStore(InMemoryBaseStore[bytes]):
299
266
  """In-memory store for bytes.
300
267
 
301
268
  Attributes:
302
- store (dict[str, bytes]): The underlying dictionary that stores
303
- the key-value pairs.
269
+ store: The underlying dictionary that stores the key-value pairs.
304
270
 
305
271
  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
-
272
+ ```python
273
+ from langchain.storage import InMemoryByteStore
274
+
275
+ store = InMemoryByteStore()
276
+ store.mset([("key1", b"value1"), ("key2", b"value2")])
277
+ store.mget(["key1", "key2"])
278
+ # [b'value1', b'value2']
279
+ store.mdelete(["key1"])
280
+ list(store.yield_keys())
281
+ # ['key2']
282
+ list(store.yield_keys(prefix="k"))
283
+ # ['key2']
284
+ ```
321
285
  """
322
286
 
323
287