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
@@ -4,8 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import warnings
6
6
  from abc import ABC
7
+ from collections.abc import Callable, Sequence
7
8
  from string import Formatter
8
- from typing import Any, Callable, Literal
9
+ from typing import Any, Literal
9
10
 
10
11
  from pydantic import BaseModel, create_model
11
12
 
@@ -121,13 +122,16 @@ def mustache_formatter(template: str, /, **kwargs: Any) -> str:
121
122
  def mustache_template_vars(
122
123
  template: str,
123
124
  ) -> set[str]:
124
- """Get the variables from a mustache template.
125
+ """Get the top-level variables from a mustache template.
126
+
127
+ For nested variables like `{{person.name}}`, only the top-level
128
+ key (`person`) is returned.
125
129
 
126
130
  Args:
127
131
  template: The template string.
128
132
 
129
133
  Returns:
130
- The variables from the template.
134
+ The top-level variables from the template.
131
135
  """
132
136
  variables: set[str] = set()
133
137
  section_depth = 0
@@ -148,9 +152,7 @@ def mustache_template_vars(
148
152
  Defs = dict[str, "Defs"]
149
153
 
150
154
 
151
- def mustache_schema(
152
- template: str,
153
- ) -> type[BaseModel]:
155
+ def mustache_schema(template: str) -> type[BaseModel]:
154
156
  """Get the variables from a mustache template.
155
157
 
156
158
  Args:
@@ -174,6 +176,11 @@ def mustache_schema(
174
176
  fields[prefix] = False
175
177
  elif type_ in {"variable", "no escape"}:
176
178
  fields[prefix + tuple(key.split("."))] = True
179
+
180
+ for fkey, fval in fields.items():
181
+ fields[fkey] = fval and not any(
182
+ is_subsequence(fkey, k) for k in fields if k != fkey
183
+ )
177
184
  defs: Defs = {} # None means leaf node
178
185
  while fields:
179
186
  field, is_leaf = fields.popitem()
@@ -272,10 +279,10 @@ class StringPromptTemplate(BasePromptTemplate, ABC):
272
279
 
273
280
  @classmethod
274
281
  def get_lc_namespace(cls) -> list[str]:
275
- """Get the namespace of the langchain object.
282
+ """Get the namespace of the LangChain object.
276
283
 
277
284
  Returns:
278
- ``["langchain", "prompts", "base"]``
285
+ `["langchain", "prompts", "base"]`
279
286
  """
280
287
  return ["langchain", "prompts", "base"]
281
288
 
@@ -283,7 +290,7 @@ class StringPromptTemplate(BasePromptTemplate, ABC):
283
290
  """Format the prompt with the inputs.
284
291
 
285
292
  Args:
286
- kwargs: Any arguments to be passed to the prompt template.
293
+ **kwargs: Any arguments to be passed to the prompt template.
287
294
 
288
295
  Returns:
289
296
  A formatted string.
@@ -294,7 +301,7 @@ class StringPromptTemplate(BasePromptTemplate, ABC):
294
301
  """Async format the prompt with the inputs.
295
302
 
296
303
  Args:
297
- kwargs: Any arguments to be passed to the prompt template.
304
+ **kwargs: Any arguments to be passed to the prompt template.
298
305
 
299
306
  Returns:
300
307
  A formatted string.
@@ -326,3 +333,12 @@ class StringPromptTemplate(BasePromptTemplate, ABC):
326
333
  def pretty_print(self) -> None:
327
334
  """Print a pretty representation of the prompt."""
328
335
  print(self.pretty_repr(html=is_interactive_env())) # noqa: T201
336
+
337
+
338
+ def is_subsequence(child: Sequence, parent: Sequence) -> bool:
339
+ """Return True if child is subsequence of parent."""
340
+ if len(child) == 0 or len(parent) == 0:
341
+ return False
342
+ if len(parent) < len(child):
343
+ return False
344
+ return all(child[i] == parent[i] for i in range(len(child)))
@@ -1,11 +1,8 @@
1
1
  """Structured prompt template for a language model."""
2
2
 
3
- from collections.abc import AsyncIterator, Iterator, Mapping, Sequence
3
+ from collections.abc import AsyncIterator, Callable, Iterator, Mapping, Sequence
4
4
  from typing import (
5
5
  Any,
6
- Callable,
7
- Optional,
8
- Union,
9
6
  )
10
7
 
11
8
  from pydantic import BaseModel, Field
@@ -31,16 +28,16 @@ from langchain_core.utils import get_pydantic_field_names
31
28
  class StructuredPrompt(ChatPromptTemplate):
32
29
  """Structured prompt template for a language model."""
33
30
 
34
- schema_: Union[dict, type]
31
+ schema_: dict | type
35
32
  """Schema for the structured prompt."""
36
33
  structured_output_kwargs: dict[str, Any] = Field(default_factory=dict)
37
34
 
38
35
  def __init__(
39
36
  self,
40
37
  messages: Sequence[MessageLikeRepresentation],
41
- schema_: Optional[Union[dict, type[BaseModel]]] = None,
38
+ schema_: dict | type[BaseModel] | None = None,
42
39
  *,
43
- structured_output_kwargs: Optional[dict[str, Any]] = None,
40
+ structured_output_kwargs: dict[str, Any] | None = None,
44
41
  template_format: PromptTemplateFormat = "f-string",
45
42
  **kwargs: Any,
46
43
  ) -> None:
@@ -66,13 +63,13 @@ class StructuredPrompt(ChatPromptTemplate):
66
63
 
67
64
  @classmethod
68
65
  def get_lc_namespace(cls) -> list[str]:
69
- """Get the namespace of the langchain object.
66
+ """Get the namespace of the LangChain object.
70
67
 
71
- For example, if the class is ``langchain.llms.openai.OpenAI``, then the
72
- namespace is ``["langchain", "llms", "openai"]``
68
+ For example, if the class is `langchain.llms.openai.OpenAI`, then the
69
+ namespace is `["langchain", "llms", "openai"]`
73
70
 
74
71
  Returns:
75
- The namespace of the langchain object.
72
+ The namespace of the LangChain object.
76
73
  """
77
74
  return cls.__module__.split(".")
78
75
 
@@ -80,7 +77,7 @@ class StructuredPrompt(ChatPromptTemplate):
80
77
  def from_messages_and_schema(
81
78
  cls,
82
79
  messages: Sequence[MessageLikeRepresentation],
83
- schema: Union[dict, type],
80
+ schema: dict | type,
84
81
  **kwargs: Any,
85
82
  ) -> ChatPromptTemplate:
86
83
  """Create a chat prompt template from a variety of message formats.
@@ -88,71 +85,70 @@ class StructuredPrompt(ChatPromptTemplate):
88
85
  Examples:
89
86
  Instantiation from a list of message templates:
90
87
 
91
- .. code-block:: python
88
+ ```python
89
+ from langchain_core.prompts import StructuredPrompt
92
90
 
93
- from langchain_core.prompts import StructuredPrompt
94
91
 
92
+ class OutputSchema(BaseModel):
93
+ name: str
94
+ value: int
95
95
 
96
- class OutputSchema(BaseModel):
97
- name: str
98
- value: int
99
96
 
97
+ template = StructuredPrompt(
98
+ [
99
+ ("human", "Hello, how are you?"),
100
+ ("ai", "I'm doing well, thanks!"),
101
+ ("human", "That's good to hear."),
102
+ ],
103
+ OutputSchema,
104
+ )
105
+ ```
106
+ Args:
107
+ messages: Sequence of message representations.
100
108
 
101
- template = StructuredPrompt(
102
- [
103
- ("human", "Hello, how are you?"),
104
- ("ai", "I'm doing well, thanks!"),
105
- ("human", "That's good to hear."),
106
- ],
107
- OutputSchema,
108
- )
109
+ A message can be represented using the following formats:
109
110
 
110
- Args:
111
- messages: sequence of message representations.
112
- A message can be represented using the following formats:
113
- (1) BaseMessagePromptTemplate, (2) BaseMessage, (3) 2-tuple of
114
- (message type, template); e.g., ("human", "{user_input}"),
115
- (4) 2-tuple of (message class, template), (5) a string which is
116
- shorthand for ("human", template); e.g., "{user_input}"
117
- schema: a dictionary representation of function call, or a Pydantic model.
118
- kwargs: Any additional kwargs to pass through to
119
- ``ChatModel.with_structured_output(schema, **kwargs)``.
111
+ 1. `BaseMessagePromptTemplate`
112
+ 2. `BaseMessage`
113
+ 3. 2-tuple of `(message type, template)`; e.g.,
114
+ `("human", "{user_input}")`
115
+ 4. 2-tuple of `(message class, template)`
116
+ 5. A string which is shorthand for `("human", template)`; e.g.,
117
+ `"{user_input}"`
118
+ schema: A dictionary representation of function call, or a Pydantic model.
119
+ **kwargs: Any additional kwargs to pass through to
120
+ `ChatModel.with_structured_output(schema, **kwargs)`.
120
121
 
121
122
  Returns:
122
- a structured prompt template
123
-
123
+ A structured prompt template
124
124
  """
125
125
  return cls(messages, schema, **kwargs)
126
126
 
127
127
  @override
128
128
  def __or__(
129
129
  self,
130
- other: Union[
131
- Runnable[Any, Other],
132
- Callable[[Iterator[Any]], Iterator[Other]],
133
- Callable[[AsyncIterator[Any]], AsyncIterator[Other]],
134
- Callable[[Any], Other],
135
- Mapping[str, Union[Runnable[Any, Other], Callable[[Any], Other], Any]],
136
- ],
130
+ other: Runnable[Any, Other]
131
+ | Callable[[Iterator[Any]], Iterator[Other]]
132
+ | Callable[[AsyncIterator[Any]], AsyncIterator[Other]]
133
+ | Callable[[Any], Other]
134
+ | Mapping[str, Runnable[Any, Other] | Callable[[Any], Other] | Any],
137
135
  ) -> RunnableSerializable[dict, Other]:
138
136
  return self.pipe(other)
139
137
 
140
138
  def pipe(
141
139
  self,
142
- *others: Union[
143
- Runnable[Any, Other],
144
- Callable[[Iterator[Any]], Iterator[Other]],
145
- Callable[[AsyncIterator[Any]], AsyncIterator[Other]],
146
- Callable[[Any], Other],
147
- Mapping[str, Union[Runnable[Any, Other], Callable[[Any], Other], Any]],
148
- ],
149
- name: Optional[str] = None,
140
+ *others: Runnable[Any, Other]
141
+ | Callable[[Iterator[Any]], Iterator[Other]]
142
+ | Callable[[AsyncIterator[Any]], AsyncIterator[Other]]
143
+ | Callable[[Any], Other]
144
+ | Mapping[str, Runnable[Any, Other] | Callable[[Any], Other] | Any],
145
+ name: str | None = None,
150
146
  ) -> RunnableSerializable[dict, Other]:
151
147
  """Pipe the structured prompt to a language model.
152
148
 
153
149
  Args:
154
150
  others: The language model to pipe the structured prompt to.
155
- name: The name of the pipeline. Defaults to None.
151
+ name: The name of the pipeline.
156
152
 
157
153
  Returns:
158
154
  A RunnableSequence object.
@@ -6,7 +6,6 @@ import abc
6
6
  import asyncio
7
7
  import threading
8
8
  import time
9
- from typing import Optional
10
9
 
11
10
 
12
11
  class BaseRateLimiter(abc.ABC):
@@ -22,11 +21,8 @@ class BaseRateLimiter(abc.ABC):
22
21
  Current limitations:
23
22
 
24
23
  - Rate limiting information is not surfaced in tracing or callbacks. This means
25
- that the total time it takes to invoke a chat model will encompass both
26
- the time spent waiting for tokens and the time spent making the request.
27
-
28
-
29
- .. versionadded:: 0.2.24
24
+ that the total time it takes to invoke a chat model will encompass both
25
+ the time spent waiting for tokens and the time spent making the request.
30
26
  """
31
27
 
32
28
  @abc.abstractmethod
@@ -34,18 +30,18 @@ class BaseRateLimiter(abc.ABC):
34
30
  """Attempt to acquire the necessary tokens for the rate limiter.
35
31
 
36
32
  This method blocks until the required tokens are available if `blocking`
37
- is set to True.
33
+ is set to `True`.
38
34
 
39
- If `blocking` is set to False, the method will immediately return the result
35
+ If `blocking` is set to `False`, the method will immediately return the result
40
36
  of the attempt to acquire the tokens.
41
37
 
42
38
  Args:
43
- blocking: If True, the method will block until the tokens are available.
44
- If False, the method will return immediately with the result of
45
- the attempt. Defaults to True.
39
+ blocking: If `True`, the method will block until the tokens are available.
40
+ If `False`, the method will return immediately with the result of
41
+ the attempt.
46
42
 
47
43
  Returns:
48
- True if the tokens were successfully acquired, False otherwise.
44
+ `True` if the tokens were successfully acquired, `False` otherwise.
49
45
  """
50
46
 
51
47
  @abc.abstractmethod
@@ -53,18 +49,18 @@ class BaseRateLimiter(abc.ABC):
53
49
  """Attempt to acquire the necessary tokens for the rate limiter.
54
50
 
55
51
  This method blocks until the required tokens are available if `blocking`
56
- is set to True.
52
+ is set to `True`.
57
53
 
58
- If `blocking` is set to False, the method will immediately return the result
54
+ If `blocking` is set to `False`, the method will immediately return the result
59
55
  of the attempt to acquire the tokens.
60
56
 
61
57
  Args:
62
- blocking: If True, the method will block until the tokens are available.
63
- If False, the method will return immediately with the result of
64
- the attempt. Defaults to True.
58
+ blocking: If `True`, the method will block until the tokens are available.
59
+ If `False`, the method will return immediately with the result of
60
+ the attempt.
65
61
 
66
62
  Returns:
67
- True if the tokens were successfully acquired, False otherwise.
63
+ `True` if the tokens were successfully acquired, `False` otherwise.
68
64
  """
69
65
 
70
66
 
@@ -85,45 +81,40 @@ class InMemoryRateLimiter(BaseRateLimiter):
85
81
  not enough tokens in the bucket, the request is blocked until there are
86
82
  enough tokens.
87
83
 
88
- These *tokens* have NOTHING to do with LLM tokens. They are just
84
+ These tokens have nothing to do with LLM tokens. They are just
89
85
  a way to keep track of how many requests can be made at a given time.
90
86
 
91
87
  Current limitations:
92
88
 
93
89
  - The rate limiter is not designed to work across different processes. It is
94
- an in-memory rate limiter, but it is thread safe.
90
+ an in-memory rate limiter, but it is thread safe.
95
91
  - The rate limiter only supports time-based rate limiting. It does not take
96
- into account the size of the request or any other factors.
92
+ into account the size of the request or any other factors.
97
93
 
98
94
  Example:
95
+ ```python
96
+ import time
99
97
 
100
- .. code-block:: python
101
-
102
- import time
103
-
104
- from langchain_core.rate_limiters import InMemoryRateLimiter
105
-
106
- rate_limiter = InMemoryRateLimiter(
107
- requests_per_second=0.1, # <-- Can only make a request once every 10 seconds!!
108
- check_every_n_seconds=0.1, # Wake up every 100 ms to check whether allowed to make a request,
109
- max_bucket_size=10, # Controls the maximum burst size.
110
- )
111
-
112
- from langchain_anthropic import ChatAnthropic
113
-
114
- model = ChatAnthropic(
115
- model_name="claude-3-opus-20240229", rate_limiter=rate_limiter
116
- )
98
+ from langchain_core.rate_limiters import InMemoryRateLimiter
117
99
 
118
- for _ in range(5):
119
- tic = time.time()
120
- model.invoke("hello")
121
- toc = time.time()
122
- print(toc - tic)
100
+ rate_limiter = InMemoryRateLimiter(
101
+ requests_per_second=0.1, # <-- Can only make a request once every 10 seconds!!
102
+ check_every_n_seconds=0.1, # Wake up every 100 ms to check whether allowed to make a request,
103
+ max_bucket_size=10, # Controls the maximum burst size.
104
+ )
123
105
 
106
+ from langchain_anthropic import ChatAnthropic
124
107
 
125
- .. versionadded:: 0.2.24
108
+ model = ChatAnthropic(
109
+ model_name="claude-sonnet-4-5-20250929", rate_limiter=rate_limiter
110
+ )
126
111
 
112
+ for _ in range(5):
113
+ tic = time.time()
114
+ model.invoke("hello")
115
+ toc = time.time()
116
+ print(toc - tic)
117
+ ```
127
118
  """ # noqa: E501
128
119
 
129
120
  def __init__(
@@ -135,7 +126,7 @@ class InMemoryRateLimiter(BaseRateLimiter):
135
126
  ) -> None:
136
127
  """A rate limiter based on a token bucket.
137
128
 
138
- These *tokens* have NOTHING to do with LLM tokens. They are just
129
+ These tokens have nothing to do with LLM tokens. They are just
139
130
  a way to keep track of how many requests can be made at a given time.
140
131
 
141
132
  This rate limiter is designed to work in a threaded environment.
@@ -148,11 +139,11 @@ class InMemoryRateLimiter(BaseRateLimiter):
148
139
  Args:
149
140
  requests_per_second: The number of tokens to add per second to the bucket.
150
141
  The tokens represent "credit" that can be used to make requests.
151
- check_every_n_seconds: check whether the tokens are available
142
+ check_every_n_seconds: Check whether the tokens are available
152
143
  every this many seconds. Can be a float to represent
153
144
  fractions of a second.
154
145
  max_bucket_size: The maximum number of tokens that can be in the bucket.
155
- Must be at least 1. Used to prevent bursts of requests.
146
+ Must be at least `1`. Used to prevent bursts of requests.
156
147
  """
157
148
  # Number of requests that we can make per second.
158
149
  self.requests_per_second = requests_per_second
@@ -163,7 +154,7 @@ class InMemoryRateLimiter(BaseRateLimiter):
163
154
  # at a given time.
164
155
  self._consume_lock = threading.Lock()
165
156
  # The last time we tried to consume tokens.
166
- self.last: Optional[float] = None
157
+ self.last: float | None = None
167
158
  self.check_every_n_seconds = check_every_n_seconds
168
159
 
169
160
  def _consume(self) -> bool:
@@ -202,18 +193,18 @@ class InMemoryRateLimiter(BaseRateLimiter):
202
193
  """Attempt to acquire a token from the rate limiter.
203
194
 
204
195
  This method blocks until the required tokens are available if `blocking`
205
- is set to True.
196
+ is set to `True`.
206
197
 
207
- If `blocking` is set to False, the method will immediately return the result
198
+ If `blocking` is set to `False`, the method will immediately return the result
208
199
  of the attempt to acquire the tokens.
209
200
 
210
201
  Args:
211
- blocking: If True, the method will block until the tokens are available.
212
- If False, the method will return immediately with the result of
213
- the attempt. Defaults to True.
202
+ blocking: If `True`, the method will block until the tokens are available.
203
+ If `False`, the method will return immediately with the result of
204
+ the attempt.
214
205
 
215
206
  Returns:
216
- True if the tokens were successfully acquired, False otherwise.
207
+ `True` if the tokens were successfully acquired, `False` otherwise.
217
208
  """
218
209
  if not blocking:
219
210
  return self._consume()
@@ -226,18 +217,18 @@ class InMemoryRateLimiter(BaseRateLimiter):
226
217
  """Attempt to acquire a token from the rate limiter. Async version.
227
218
 
228
219
  This method blocks until the required tokens are available if `blocking`
229
- is set to True.
220
+ is set to `True`.
230
221
 
231
- If `blocking` is set to False, the method will immediately return the result
222
+ If `blocking` is set to `False`, the method will immediately return the result
232
223
  of the attempt to acquire the tokens.
233
224
 
234
225
  Args:
235
- blocking: If True, the method will block until the tokens are available.
236
- If False, the method will return immediately with the result of
237
- the attempt. Defaults to True.
226
+ blocking: If `True`, the method will block until the tokens are available.
227
+ If `False`, the method will return immediately with the result of
228
+ the attempt.
238
229
 
239
230
  Returns:
240
- True if the tokens were successfully acquired, False otherwise.
231
+ `True` if the tokens were successfully acquired, `False` otherwise.
241
232
  """
242
233
  if not blocking:
243
234
  return self._consume()