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
@@ -6,22 +6,20 @@ import asyncio
6
6
  import inspect
7
7
  import json
8
8
  import typing
9
- import warnings
10
9
  from abc import ABC, abstractmethod
11
- from collections.abc import AsyncIterator, Iterator, Sequence
10
+ from collections.abc import AsyncIterator, Callable, Iterator, Sequence
12
11
  from functools import cached_property
13
12
  from operator import itemgetter
14
- from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Union, cast
13
+ from typing import TYPE_CHECKING, Any, Literal, cast
15
14
 
16
- from pydantic import BaseModel, ConfigDict, Field, model_validator
15
+ from pydantic import BaseModel, ConfigDict, Field
17
16
  from typing_extensions import override
18
17
 
19
- from langchain_core._api import deprecated
18
+ from langchain_core._api.beta_decorator import beta
20
19
  from langchain_core.caches import BaseCache
21
20
  from langchain_core.callbacks import (
22
21
  AsyncCallbackManager,
23
22
  AsyncCallbackManagerForLLMRun,
24
- BaseCallbackManager,
25
23
  CallbackManager,
26
24
  CallbackManagerForLLMRun,
27
25
  Callbacks,
@@ -42,11 +40,11 @@ from langchain_core.messages import (
42
40
  AIMessageChunk,
43
41
  AnyMessage,
44
42
  BaseMessage,
45
- HumanMessage,
46
43
  convert_to_messages,
47
44
  is_data_content_block,
48
45
  message_chunk_to_message,
49
46
  )
47
+ from langchain_core.messages import content as types
50
48
  from langchain_core.messages.block_translators.openai import (
51
49
  convert_to_openai_image_block,
52
50
  )
@@ -78,6 +76,8 @@ from langchain_core.utils.utils import LC_ID_PREFIX, from_env
78
76
  if TYPE_CHECKING:
79
77
  import uuid
80
78
 
79
+ from langchain_model_profiles import ModelProfile # type: ignore[import-untyped]
80
+
81
81
  from langchain_core.output_parsers.base import OutputParserLike
82
82
  from langchain_core.runnables import Runnable, RunnableConfig
83
83
  from langchain_core.tools import BaseTool
@@ -111,11 +111,11 @@ def _generate_response_from_error(error: BaseException) -> list[ChatGeneration]:
111
111
 
112
112
 
113
113
  def _format_for_tracing(messages: list[BaseMessage]) -> list[BaseMessage]:
114
- """Format messages for tracing in ``on_chat_model_start``.
114
+ """Format messages for tracing in `on_chat_model_start`.
115
115
 
116
116
  - Update image content blocks to OpenAI Chat Completions format (backward
117
117
  compatibility).
118
- - Add ``type`` key to content blocks that have a single key.
118
+ - Add `type` key to content blocks that have a single key.
119
119
 
120
120
  Args:
121
121
  messages: List of messages to format.
@@ -182,13 +182,13 @@ def generate_from_stream(stream: Iterator[ChatGenerationChunk]) -> ChatResult:
182
182
  """Generate from a stream.
183
183
 
184
184
  Args:
185
- stream: Iterator of ``ChatGenerationChunk``.
185
+ stream: Iterator of `ChatGenerationChunk`.
186
186
 
187
187
  Raises:
188
188
  ValueError: If no generations are found in the stream.
189
189
 
190
190
  Returns:
191
- ChatResult: Chat result.
191
+ Chat result.
192
192
 
193
193
  """
194
194
  generation = next(stream, None)
@@ -213,17 +213,17 @@ async def agenerate_from_stream(
213
213
  """Async generate from a stream.
214
214
 
215
215
  Args:
216
- stream: Iterator of ``ChatGenerationChunk``.
216
+ stream: Iterator of `ChatGenerationChunk`.
217
217
 
218
218
  Returns:
219
- ChatResult: Chat result.
219
+ Chat result.
220
220
 
221
221
  """
222
222
  chunks = [chunk async for chunk in stream]
223
223
  return await run_in_executor(None, generate_from_stream, iter(chunks))
224
224
 
225
225
 
226
- def _format_ls_structured_output(ls_structured_output_format: Optional[dict]) -> dict:
226
+ def _format_ls_structured_output(ls_structured_output_format: dict | None) -> dict:
227
227
  if ls_structured_output_format:
228
228
  try:
229
229
  ls_structured_output_format_dict = {
@@ -243,157 +243,99 @@ def _format_ls_structured_output(ls_structured_output_format: Optional[dict]) ->
243
243
 
244
244
 
245
245
  class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
246
- """Base class for chat models.
246
+ r"""Base class for chat models.
247
247
 
248
248
  Key imperative methods:
249
249
  Methods that actually call the underlying model.
250
250
 
251
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
252
- | Method | Input | Output | Description |
253
- +===========================+================================================================+=====================================================================+==================================================================================================+
254
- | `invoke` | str | list[dict | tuple | BaseMessage] | PromptValue | BaseMessage | A single chat model call. |
255
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
256
- | `ainvoke` | ''' | BaseMessage | Defaults to running invoke in an async executor. |
257
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
258
- | `stream` | ''' | Iterator[BaseMessageChunk] | Defaults to yielding output of invoke. |
259
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
260
- | `astream` | ''' | AsyncIterator[BaseMessageChunk] | Defaults to yielding output of ainvoke. |
261
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
262
- | `astream_events` | ''' | AsyncIterator[StreamEvent] | Event types: 'on_chat_model_start', 'on_chat_model_stream', 'on_chat_model_end'. |
263
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
264
- | `batch` | list['''] | list[BaseMessage] | Defaults to running invoke in concurrent threads. |
265
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
266
- | `abatch` | list['''] | list[BaseMessage] | Defaults to running ainvoke in concurrent threads. |
267
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
268
- | `batch_as_completed` | list['''] | Iterator[tuple[int, Union[BaseMessage, Exception]]] | Defaults to running invoke in concurrent threads. |
269
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
270
- | `abatch_as_completed` | list['''] | AsyncIterator[tuple[int, Union[BaseMessage, Exception]]] | Defaults to running ainvoke in concurrent threads. |
271
- +---------------------------+----------------------------------------------------------------+---------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
272
-
273
- This table provides a brief overview of the main imperative methods. Please see the base Runnable reference for full documentation.
251
+ This table provides a brief overview of the main imperative methods. Please see the base `Runnable` reference for full documentation.
252
+
253
+ | Method | Input | Output | Description |
254
+ | ---------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------------------------------- |
255
+ | `invoke` | `str` \| `list[dict | tuple | BaseMessage]` \| `PromptValue` | `BaseMessage` | A single chat model call. |
256
+ | `ainvoke` | `'''` | `BaseMessage` | Defaults to running `invoke` in an async executor. |
257
+ | `stream` | `'''` | `Iterator[BaseMessageChunk]` | Defaults to yielding output of `invoke`. |
258
+ | `astream` | `'''` | `AsyncIterator[BaseMessageChunk]` | Defaults to yielding output of `ainvoke`. |
259
+ | `astream_events` | `'''` | `AsyncIterator[StreamEvent]` | Event types: `on_chat_model_start`, `on_chat_model_stream`, `on_chat_model_end`. |
260
+ | `batch` | `list[''']` | `list[BaseMessage]` | Defaults to running `invoke` in concurrent threads. |
261
+ | `abatch` | `list[''']` | `list[BaseMessage]` | Defaults to running `ainvoke` in concurrent threads. |
262
+ | `batch_as_completed` | `list[''']` | `Iterator[tuple[int, Union[BaseMessage, Exception]]]` | Defaults to running `invoke` in concurrent threads. |
263
+ | `abatch_as_completed` | `list[''']` | `AsyncIterator[tuple[int, Union[BaseMessage, Exception]]]` | Defaults to running `ainvoke` in concurrent threads. |
274
264
 
275
265
  Key declarative methods:
276
- Methods for creating another Runnable using the ChatModel.
277
-
278
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
279
- | Method | Description |
280
- +==================================+===========================================================================================================+
281
- | `bind_tools` | Create ChatModel that can call tools. |
282
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
283
- | `with_structured_output` | Create wrapper that structures model output using schema. |
284
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
285
- | `with_retry` | Create wrapper that retries model calls on failure. |
286
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
287
- | `with_fallbacks` | Create wrapper that falls back to other models on failure. |
288
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
289
- | `configurable_fields` | Specify init args of the model that can be configured at runtime via the RunnableConfig. |
290
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
291
- | `configurable_alternatives` | Specify alternative models which can be swapped in at runtime via the RunnableConfig. |
292
- +----------------------------------+-----------------------------------------------------------------------------------------------------------+
266
+ Methods for creating another `Runnable` using the chat model.
293
267
 
294
268
  This table provides a brief overview of the main declarative methods. Please see the reference for each method for full documentation.
295
269
 
270
+ | Method | Description |
271
+ | ---------------------------- | ------------------------------------------------------------------------------------------ |
272
+ | `bind_tools` | Create chat model that can call tools. |
273
+ | `with_structured_output` | Create wrapper that structures model output using schema. |
274
+ | `with_retry` | Create wrapper that retries model calls on failure. |
275
+ | `with_fallbacks` | Create wrapper that falls back to other models on failure. |
276
+ | `configurable_fields` | Specify init args of the model that can be configured at runtime via the `RunnableConfig`. |
277
+ | `configurable_alternatives` | Specify alternative models which can be swapped in at runtime via the `RunnableConfig`. |
278
+
296
279
  Creating custom chat model:
297
280
  Custom chat model implementations should inherit from this class.
298
281
  Please reference the table below for information about which
299
282
  methods and properties are required or optional for implementations.
300
283
 
301
- +----------------------------------+--------------------------------------------------------------------+-------------------+
302
- | Method/Property | Description | Required/Optional |
303
- +==================================+====================================================================+===================+
284
+ | Method/Property | Description | Required |
285
+ | -------------------------------- | ------------------------------------------------------------------ | ----------------- |
304
286
  | `_generate` | Use to generate a chat result from a prompt | Required |
305
- +----------------------------------+--------------------------------------------------------------------+-------------------+
306
287
  | `_llm_type` (property) | Used to uniquely identify the type of the model. Used for logging. | Required |
307
- +----------------------------------+--------------------------------------------------------------------+-------------------+
308
288
  | `_identifying_params` (property) | Represent model parameterization for tracing purposes. | Optional |
309
- +----------------------------------+--------------------------------------------------------------------+-------------------+
310
289
  | `_stream` | Use to implement streaming | Optional |
311
- +----------------------------------+--------------------------------------------------------------------+-------------------+
312
290
  | `_agenerate` | Use to implement a native async method | Optional |
313
- +----------------------------------+--------------------------------------------------------------------+-------------------+
314
291
  | `_astream` | Use to implement async version of `_stream` | Optional |
315
- +----------------------------------+--------------------------------------------------------------------+-------------------+
316
-
317
- Follow the guide for more information on how to implement a custom Chat Model:
318
- [Guide](https://python.langchain.com/docs/how_to/custom_chat_model/).
319
292
 
320
293
  """ # noqa: E501
321
294
 
322
- callback_manager: Optional[BaseCallbackManager] = deprecated(
323
- name="callback_manager", since="0.1.7", removal="1.0", alternative="callbacks"
324
- )(
325
- Field(
326
- default=None,
327
- exclude=True,
328
- description="Callback manager to add to the run trace.",
329
- )
330
- )
331
-
332
- rate_limiter: Optional[BaseRateLimiter] = Field(default=None, exclude=True)
295
+ rate_limiter: BaseRateLimiter | None = Field(default=None, exclude=True)
333
296
  "An optional rate limiter to use for limiting the number of requests."
334
297
 
335
- disable_streaming: Union[bool, Literal["tool_calling"]] = False
298
+ disable_streaming: bool | Literal["tool_calling"] = False
336
299
  """Whether to disable streaming for this model.
337
300
 
338
- If streaming is bypassed, then ``stream()``/``astream()``/``astream_events()`` will
339
- defer to ``invoke()``/``ainvoke()``.
301
+ If streaming is bypassed, then `stream`/`astream`/`astream_events` will
302
+ defer to `invoke`/`ainvoke`.
340
303
 
341
- - If True, will always bypass streaming case.
342
- - If ``'tool_calling'``, will bypass streaming case only when the model is called
343
- with a ``tools`` keyword argument. In other words, LangChain will automatically
344
- switch to non-streaming behavior (``invoke()``) only when the tools argument is
345
- provided. This offers the best of both worlds.
346
- - If False (default), will always use streaming case if available.
304
+ - If `True`, will always bypass streaming case.
305
+ - If `'tool_calling'`, will bypass streaming case only when the model is called
306
+ with a `tools` keyword argument. In other words, LangChain will automatically
307
+ switch to non-streaming behavior (`invoke`) only when the tools argument is
308
+ provided. This offers the best of both worlds.
309
+ - If `False` (Default), will always use streaming case if available.
347
310
 
348
- The main reason for this flag is that code might be written using ``stream()`` and
311
+ The main reason for this flag is that code might be written using `stream` and
349
312
  a user may want to swap out a given model for another model whose the implementation
350
313
  does not properly support streaming.
351
-
352
314
  """
353
315
 
354
- output_version: Optional[str] = Field(
316
+ output_version: str | None = Field(
355
317
  default_factory=from_env("LC_OUTPUT_VERSION", default=None)
356
318
  )
357
- """Version of ``AIMessage`` output format to store in message content.
319
+ """Version of `AIMessage` output format to store in message content.
358
320
 
359
- ``AIMessage.content_blocks`` will lazily parse the contents of ``content`` into a
321
+ `AIMessage.content_blocks` will lazily parse the contents of `content` into a
360
322
  standard format. This flag can be used to additionally store the standard format
361
323
  in message content, e.g., for serialization purposes.
362
324
 
363
325
  Supported values:
364
326
 
365
- - ``"v0"``: provider-specific format in content (can lazily-parse with
366
- ``.content_blocks``)
367
- - ``"v1"``: standardized format in content (consistent with ``.content_blocks``)
327
+ - `'v0'`: provider-specific format in content (can lazily-parse with
328
+ `content_blocks`)
329
+ - `'v1'`: standardized format in content (consistent with `content_blocks`)
368
330
 
369
- Partner packages (e.g., ``langchain-openai``) can also use this field to roll out
370
- new content formats in a backward-compatible way.
331
+ Partner packages (e.g.,
332
+ [`langchain-openai`](https://pypi.org/project/langchain-openai)) can also use this
333
+ field to roll out new content formats in a backward-compatible way.
371
334
 
372
- .. versionadded:: 1.0
335
+ !!! version-added "Added in version 1.0"
373
336
 
374
337
  """
375
338
 
376
- @model_validator(mode="before")
377
- @classmethod
378
- def raise_deprecation(cls, values: dict) -> Any:
379
- """Emit deprecation warning if ``callback_manager`` is used.
380
-
381
- Args:
382
- values (Dict): Values to validate.
383
-
384
- Returns:
385
- Dict: Validated values.
386
-
387
- """
388
- if values.get("callback_manager") is not None:
389
- warnings.warn(
390
- "callback_manager is deprecated. Please use callbacks instead.",
391
- DeprecationWarning,
392
- stacklevel=5,
393
- )
394
- values["callbacks"] = values.pop("callback_manager", None)
395
- return values
396
-
397
339
  model_config = ConfigDict(
398
340
  arbitrary_types_allowed=True,
399
341
  )
@@ -407,7 +349,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
407
349
  @property
408
350
  @override
409
351
  def OutputType(self) -> Any:
410
- """Get the output type for this runnable."""
352
+ """Get the output type for this `Runnable`."""
411
353
  return AnyMessage
412
354
 
413
355
  def _convert_input(self, model_input: LanguageModelInput) -> PromptValue:
@@ -427,9 +369,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
427
369
  def invoke(
428
370
  self,
429
371
  input: LanguageModelInput,
430
- config: Optional[RunnableConfig] = None,
372
+ config: RunnableConfig | None = None,
431
373
  *,
432
- stop: Optional[list[str]] = None,
374
+ stop: list[str] | None = None,
433
375
  **kwargs: Any,
434
376
  ) -> AIMessage:
435
377
  config = ensure_config(config)
@@ -454,9 +396,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
454
396
  async def ainvoke(
455
397
  self,
456
398
  input: LanguageModelInput,
457
- config: Optional[RunnableConfig] = None,
399
+ config: RunnableConfig | None = None,
458
400
  *,
459
- stop: Optional[list[str]] = None,
401
+ stop: list[str] | None = None,
460
402
  **kwargs: Any,
461
403
  ) -> AIMessage:
462
404
  config = ensure_config(config)
@@ -478,9 +420,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
478
420
  self,
479
421
  *,
480
422
  async_api: bool,
481
- run_manager: Optional[
482
- Union[CallbackManagerForLLMRun, AsyncCallbackManagerForLLMRun]
483
- ] = None,
423
+ run_manager: CallbackManagerForLLMRun
424
+ | AsyncCallbackManagerForLLMRun
425
+ | None = None,
484
426
  **kwargs: Any,
485
427
  ) -> bool:
486
428
  """Determine if a given model call should hit the streaming API."""
@@ -505,6 +447,11 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
505
447
  if "stream" in kwargs:
506
448
  return kwargs["stream"]
507
449
 
450
+ if "streaming" in self.model_fields_set:
451
+ streaming_value = getattr(self, "streaming", None)
452
+ if isinstance(streaming_value, bool):
453
+ return streaming_value
454
+
508
455
  # Check if any streaming callback handlers have been passed in.
509
456
  handlers = run_manager.handlers if run_manager else []
510
457
  return any(isinstance(h, _StreamingCallbackHandler) for h in handlers)
@@ -513,9 +460,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
513
460
  def stream(
514
461
  self,
515
462
  input: LanguageModelInput,
516
- config: Optional[RunnableConfig] = None,
463
+ config: RunnableConfig | None = None,
517
464
  *,
518
- stop: Optional[list[str]] = None,
465
+ stop: list[str] | None = None,
519
466
  **kwargs: Any,
520
467
  ) -> Iterator[AIMessageChunk]:
521
468
  if not self._should_stream(async_api=False, **{**kwargs, "stream": True}):
@@ -568,6 +515,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
568
515
  input_messages = _normalize_messages(messages)
569
516
  run_id = "-".join((LC_ID_PREFIX, str(run_manager.run_id)))
570
517
  yielded = False
518
+ index = -1
519
+ index_type = ""
571
520
  for chunk in self._stream(input_messages, stop=stop, **kwargs):
572
521
  if chunk.message.id is None:
573
522
  chunk.message.id = run_id
@@ -577,6 +526,14 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
577
526
  chunk.message = _update_message_content_to_blocks(
578
527
  chunk.message, "v1"
579
528
  )
529
+ for block in cast(
530
+ "list[types.ContentBlock]", chunk.message.content
531
+ ):
532
+ if block["type"] != index_type:
533
+ index_type = block["type"]
534
+ index = index + 1
535
+ if "index" not in block:
536
+ block["index"] = index
580
537
  run_manager.on_llm_new_token(
581
538
  cast("str", chunk.message.content), chunk=chunk
582
539
  )
@@ -591,7 +548,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
591
548
  and isinstance(chunk.message, AIMessageChunk)
592
549
  and not chunk.message.chunk_position
593
550
  ):
594
- empty_content: Union[str, list] = (
551
+ empty_content: str | list = (
595
552
  "" if isinstance(chunk.message.content, str) else []
596
553
  )
597
554
  msg_chunk = AIMessageChunk(
@@ -629,9 +586,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
629
586
  async def astream(
630
587
  self,
631
588
  input: LanguageModelInput,
632
- config: Optional[RunnableConfig] = None,
589
+ config: RunnableConfig | None = None,
633
590
  *,
634
- stop: Optional[list[str]] = None,
591
+ stop: list[str] | None = None,
635
592
  **kwargs: Any,
636
593
  ) -> AsyncIterator[AIMessageChunk]:
637
594
  if not self._should_stream(async_api=True, **{**kwargs, "stream": True}):
@@ -686,6 +643,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
686
643
  input_messages = _normalize_messages(messages)
687
644
  run_id = "-".join((LC_ID_PREFIX, str(run_manager.run_id)))
688
645
  yielded = False
646
+ index = -1
647
+ index_type = ""
689
648
  async for chunk in self._astream(
690
649
  input_messages,
691
650
  stop=stop,
@@ -699,6 +658,14 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
699
658
  chunk.message = _update_message_content_to_blocks(
700
659
  chunk.message, "v1"
701
660
  )
661
+ for block in cast(
662
+ "list[types.ContentBlock]", chunk.message.content
663
+ ):
664
+ if block["type"] != index_type:
665
+ index_type = block["type"]
666
+ index = index + 1
667
+ if "index" not in block:
668
+ block["index"] = index
702
669
  await run_manager.on_llm_new_token(
703
670
  cast("str", chunk.message.content), chunk=chunk
704
671
  )
@@ -712,7 +679,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
712
679
  and isinstance(chunk.message, AIMessageChunk)
713
680
  and not chunk.message.chunk_position
714
681
  ):
715
- empty_content: Union[str, list] = (
682
+ empty_content: str | list = (
716
683
  "" if isinstance(chunk.message.content, str) else []
717
684
  )
718
685
  msg_chunk = AIMessageChunk(
@@ -747,7 +714,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
747
714
 
748
715
  # --- Custom methods ---
749
716
 
750
- def _combine_llm_outputs(self, llm_outputs: list[Optional[dict]]) -> dict: # noqa: ARG002
717
+ def _combine_llm_outputs(self, llm_outputs: list[dict | None]) -> dict: # noqa: ARG002
751
718
  return {}
752
719
 
753
720
  def _convert_cached_generations(self, cache_val: list) -> list[ChatGeneration]:
@@ -791,7 +758,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
791
758
 
792
759
  def _get_invocation_params(
793
760
  self,
794
- stop: Optional[list[str]] = None,
761
+ stop: list[str] | None = None,
795
762
  **kwargs: Any,
796
763
  ) -> dict:
797
764
  params = self.dict()
@@ -800,7 +767,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
800
767
 
801
768
  def _get_ls_params(
802
769
  self,
803
- stop: Optional[list[str]] = None,
770
+ stop: list[str] | None = None,
804
771
  **kwargs: Any,
805
772
  ) -> LangSmithParams:
806
773
  """Get standard params for tracing."""
@@ -838,7 +805,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
838
805
 
839
806
  return ls_params
840
807
 
841
- def _get_llm_string(self, stop: Optional[list[str]] = None, **kwargs: Any) -> str:
808
+ def _get_llm_string(self, stop: list[str] | None = None, **kwargs: Any) -> str:
842
809
  if self.is_lc_serializable():
843
810
  params = {**kwargs, "stop": stop}
844
811
  param_string = str(sorted(params.items()))
@@ -855,13 +822,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
855
822
  def generate(
856
823
  self,
857
824
  messages: list[list[BaseMessage]],
858
- stop: Optional[list[str]] = None,
825
+ stop: list[str] | None = None,
859
826
  callbacks: Callbacks = None,
860
827
  *,
861
- tags: Optional[list[str]] = None,
862
- metadata: Optional[dict[str, Any]] = None,
863
- run_name: Optional[str] = None,
864
- run_id: Optional[uuid.UUID] = None,
828
+ tags: list[str] | None = None,
829
+ metadata: dict[str, Any] | None = None,
830
+ run_name: str | None = None,
831
+ run_id: uuid.UUID | None = None,
865
832
  **kwargs: Any,
866
833
  ) -> LLMResult:
867
834
  """Pass a sequence of prompts to the model and return model generations.
@@ -874,13 +841,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
874
841
  1. Take advantage of batched calls,
875
842
  2. Need more output from the model than just the top generated value,
876
843
  3. Are building chains that are agnostic to the underlying language model
877
- type (e.g., pure text completion models vs chat models).
844
+ type (e.g., pure text completion models vs chat models).
878
845
 
879
846
  Args:
880
847
  messages: List of list of messages.
881
848
  stop: Stop words to use when generating. Model output is cut off at the
882
849
  first occurrence of any of these substrings.
883
- callbacks: Callbacks to pass through. Used for executing additional
850
+ callbacks: `Callbacks` to pass through. Used for executing additional
884
851
  functionality, such as logging or streaming, throughout generation.
885
852
  tags: The tags to apply.
886
853
  metadata: The metadata to apply.
@@ -890,8 +857,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
890
857
  to the model provider API call.
891
858
 
892
859
  Returns:
893
- An LLMResult, which contains a list of candidate Generations for each input
894
- prompt and additional model provider-specific output.
860
+ An `LLMResult`, which contains a list of candidate `Generations` for each
861
+ input prompt and additional model provider-specific output.
895
862
 
896
863
  """
897
864
  ls_structured_output_format = kwargs.pop(
@@ -962,7 +929,9 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
962
929
  output = LLMResult(generations=generations, llm_output=llm_output)
963
930
  if run_managers:
964
931
  run_infos = []
965
- for manager, flattened_output in zip(run_managers, flattened_outputs):
932
+ for manager, flattened_output in zip(
933
+ run_managers, flattened_outputs, strict=False
934
+ ):
966
935
  manager.on_llm_end(flattened_output)
967
936
  run_infos.append(RunInfo(run_id=manager.run_id))
968
937
  output.run = run_infos
@@ -971,13 +940,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
971
940
  async def agenerate(
972
941
  self,
973
942
  messages: list[list[BaseMessage]],
974
- stop: Optional[list[str]] = None,
943
+ stop: list[str] | None = None,
975
944
  callbacks: Callbacks = None,
976
945
  *,
977
- tags: Optional[list[str]] = None,
978
- metadata: Optional[dict[str, Any]] = None,
979
- run_name: Optional[str] = None,
980
- run_id: Optional[uuid.UUID] = None,
946
+ tags: list[str] | None = None,
947
+ metadata: dict[str, Any] | None = None,
948
+ run_name: str | None = None,
949
+ run_id: uuid.UUID | None = None,
981
950
  **kwargs: Any,
982
951
  ) -> LLMResult:
983
952
  """Asynchronously pass a sequence of prompts to a model and return generations.
@@ -990,13 +959,13 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
990
959
  1. Take advantage of batched calls,
991
960
  2. Need more output from the model than just the top generated value,
992
961
  3. Are building chains that are agnostic to the underlying language model
993
- type (e.g., pure text completion models vs chat models).
962
+ type (e.g., pure text completion models vs chat models).
994
963
 
995
964
  Args:
996
965
  messages: List of list of messages.
997
966
  stop: Stop words to use when generating. Model output is cut off at the
998
967
  first occurrence of any of these substrings.
999
- callbacks: Callbacks to pass through. Used for executing additional
968
+ callbacks: `Callbacks` to pass through. Used for executing additional
1000
969
  functionality, such as logging or streaming, throughout generation.
1001
970
  tags: The tags to apply.
1002
971
  metadata: The metadata to apply.
@@ -1006,8 +975,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1006
975
  to the model provider API call.
1007
976
 
1008
977
  Returns:
1009
- An LLMResult, which contains a list of candidate Generations for each input
1010
- prompt and additional model provider-specific output.
978
+ An `LLMResult`, which contains a list of candidate `Generations` for each
979
+ input prompt and additional model provider-specific output.
1011
980
 
1012
981
  """
1013
982
  ls_structured_output_format = kwargs.pop(
@@ -1084,7 +1053,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1084
1053
  llm_output=res.llm_output, # type: ignore[union-attr]
1085
1054
  )
1086
1055
  )
1087
- for run_manager, res in zip(run_managers, results)
1056
+ for run_manager, res in zip(run_managers, results, strict=False)
1088
1057
  if not isinstance(res, Exception)
1089
1058
  ]
1090
1059
  )
@@ -1100,7 +1069,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1100
1069
  *[
1101
1070
  run_manager.on_llm_end(flattened_output)
1102
1071
  for run_manager, flattened_output in zip(
1103
- run_managers, flattened_outputs
1072
+ run_managers, flattened_outputs, strict=False
1104
1073
  )
1105
1074
  ]
1106
1075
  )
@@ -1114,7 +1083,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1114
1083
  def generate_prompt(
1115
1084
  self,
1116
1085
  prompts: list[PromptValue],
1117
- stop: Optional[list[str]] = None,
1086
+ stop: list[str] | None = None,
1118
1087
  callbacks: Callbacks = None,
1119
1088
  **kwargs: Any,
1120
1089
  ) -> LLMResult:
@@ -1125,7 +1094,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1125
1094
  async def agenerate_prompt(
1126
1095
  self,
1127
1096
  prompts: list[PromptValue],
1128
- stop: Optional[list[str]] = None,
1097
+ stop: list[str] | None = None,
1129
1098
  callbacks: Callbacks = None,
1130
1099
  **kwargs: Any,
1131
1100
  ) -> LLMResult:
@@ -1137,8 +1106,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1137
1106
  def _generate_with_cache(
1138
1107
  self,
1139
1108
  messages: list[BaseMessage],
1140
- stop: Optional[list[str]] = None,
1141
- run_manager: Optional[CallbackManagerForLLMRun] = None,
1109
+ stop: list[str] | None = None,
1110
+ run_manager: CallbackManagerForLLMRun | None = None,
1142
1111
  **kwargs: Any,
1143
1112
  ) -> ChatResult:
1144
1113
  llm_cache = self.cache if isinstance(self.cache, BaseCache) else get_llm_cache()
@@ -1174,10 +1143,12 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1174
1143
  **kwargs,
1175
1144
  ):
1176
1145
  chunks: list[ChatGenerationChunk] = []
1177
- run_id: Optional[str] = (
1146
+ run_id: str | None = (
1178
1147
  f"{LC_ID_PREFIX}-{run_manager.run_id}" if run_manager else None
1179
1148
  )
1180
1149
  yielded = False
1150
+ index = -1
1151
+ index_type = ""
1181
1152
  for chunk in self._stream(messages, stop=stop, **kwargs):
1182
1153
  chunk.message.response_metadata = _gen_info_and_msg_metadata(chunk)
1183
1154
  if self.output_version == "v1":
@@ -1185,6 +1156,14 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1185
1156
  chunk.message = _update_message_content_to_blocks(
1186
1157
  chunk.message, "v1"
1187
1158
  )
1159
+ for block in cast(
1160
+ "list[types.ContentBlock]", chunk.message.content
1161
+ ):
1162
+ if block["type"] != index_type:
1163
+ index_type = block["type"]
1164
+ index = index + 1
1165
+ if "index" not in block:
1166
+ block["index"] = index
1188
1167
  if run_manager:
1189
1168
  if chunk.message.id is None:
1190
1169
  chunk.message.id = run_id
@@ -1200,7 +1179,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1200
1179
  and isinstance(chunk.message, AIMessageChunk)
1201
1180
  and not chunk.message.chunk_position
1202
1181
  ):
1203
- empty_content: Union[str, list] = (
1182
+ empty_content: str | list = (
1204
1183
  "" if isinstance(chunk.message.content, str) else []
1205
1184
  )
1206
1185
  chunk = ChatGenerationChunk(
@@ -1245,8 +1224,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1245
1224
  async def _agenerate_with_cache(
1246
1225
  self,
1247
1226
  messages: list[BaseMessage],
1248
- stop: Optional[list[str]] = None,
1249
- run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
1227
+ stop: list[str] | None = None,
1228
+ run_manager: AsyncCallbackManagerForLLMRun | None = None,
1250
1229
  **kwargs: Any,
1251
1230
  ) -> ChatResult:
1252
1231
  llm_cache = self.cache if isinstance(self.cache, BaseCache) else get_llm_cache()
@@ -1282,10 +1261,12 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1282
1261
  **kwargs,
1283
1262
  ):
1284
1263
  chunks: list[ChatGenerationChunk] = []
1285
- run_id: Optional[str] = (
1264
+ run_id: str | None = (
1286
1265
  f"{LC_ID_PREFIX}-{run_manager.run_id}" if run_manager else None
1287
1266
  )
1288
1267
  yielded = False
1268
+ index = -1
1269
+ index_type = ""
1289
1270
  async for chunk in self._astream(messages, stop=stop, **kwargs):
1290
1271
  chunk.message.response_metadata = _gen_info_and_msg_metadata(chunk)
1291
1272
  if self.output_version == "v1":
@@ -1293,6 +1274,14 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1293
1274
  chunk.message = _update_message_content_to_blocks(
1294
1275
  chunk.message, "v1"
1295
1276
  )
1277
+ for block in cast(
1278
+ "list[types.ContentBlock]", chunk.message.content
1279
+ ):
1280
+ if block["type"] != index_type:
1281
+ index_type = block["type"]
1282
+ index = index + 1
1283
+ if "index" not in block:
1284
+ block["index"] = index
1296
1285
  if run_manager:
1297
1286
  if chunk.message.id is None:
1298
1287
  chunk.message.id = run_id
@@ -1308,7 +1297,7 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1308
1297
  and isinstance(chunk.message, AIMessageChunk)
1309
1298
  and not chunk.message.chunk_position
1310
1299
  ):
1311
- empty_content: Union[str, list] = (
1300
+ empty_content: str | list = (
1312
1301
  "" if isinstance(chunk.message.content, str) else []
1313
1302
  )
1314
1303
  chunk = ChatGenerationChunk(
@@ -1354,8 +1343,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1354
1343
  def _generate(
1355
1344
  self,
1356
1345
  messages: list[BaseMessage],
1357
- stop: Optional[list[str]] = None,
1358
- run_manager: Optional[CallbackManagerForLLMRun] = None,
1346
+ stop: list[str] | None = None,
1347
+ run_manager: CallbackManagerForLLMRun | None = None,
1359
1348
  **kwargs: Any,
1360
1349
  ) -> ChatResult:
1361
1350
  """Generate the result.
@@ -1373,8 +1362,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1373
1362
  async def _agenerate(
1374
1363
  self,
1375
1364
  messages: list[BaseMessage],
1376
- stop: Optional[list[str]] = None,
1377
- run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
1365
+ stop: list[str] | None = None,
1366
+ run_manager: AsyncCallbackManagerForLLMRun | None = None,
1378
1367
  **kwargs: Any,
1379
1368
  ) -> ChatResult:
1380
1369
  """Generate the result.
@@ -1400,8 +1389,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1400
1389
  def _stream(
1401
1390
  self,
1402
1391
  messages: list[BaseMessage],
1403
- stop: Optional[list[str]] = None,
1404
- run_manager: Optional[CallbackManagerForLLMRun] = None,
1392
+ stop: list[str] | None = None,
1393
+ run_manager: CallbackManagerForLLMRun | None = None,
1405
1394
  **kwargs: Any,
1406
1395
  ) -> Iterator[ChatGenerationChunk]:
1407
1396
  """Stream the output of the model.
@@ -1420,8 +1409,8 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1420
1409
  async def _astream(
1421
1410
  self,
1422
1411
  messages: list[BaseMessage],
1423
- stop: Optional[list[str]] = None,
1424
- run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
1412
+ stop: list[str] | None = None,
1413
+ run_manager: AsyncCallbackManagerForLLMRun | None = None,
1425
1414
  **kwargs: Any,
1426
1415
  ) -> AsyncIterator[ChatGenerationChunk]:
1427
1416
  """Stream the output of the model.
@@ -1455,44 +1444,10 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1455
1444
  break
1456
1445
  yield item # type: ignore[misc]
1457
1446
 
1458
- @deprecated("0.1.7", alternative="invoke", removal="1.0")
1459
- def __call__(
1460
- self,
1461
- messages: list[BaseMessage],
1462
- stop: Optional[list[str]] = None,
1463
- callbacks: Callbacks = None,
1464
- **kwargs: Any,
1465
- ) -> BaseMessage:
1466
- """Call the model.
1467
-
1468
- Args:
1469
- messages: List of messages.
1470
- stop: Stop words to use when generating. Model output is cut off at the
1471
- first occurrence of any of these substrings.
1472
- callbacks: Callbacks to pass through. Used for executing additional
1473
- functionality, such as logging or streaming, throughout generation.
1474
- **kwargs: Arbitrary additional keyword arguments. These are usually passed
1475
- to the model provider API call.
1476
-
1477
- Raises:
1478
- ValueError: If the generation is not a chat generation.
1479
-
1480
- Returns:
1481
- The model output message.
1482
-
1483
- """
1484
- generation = self.generate(
1485
- [messages], stop=stop, callbacks=callbacks, **kwargs
1486
- ).generations[0][0]
1487
- if isinstance(generation, ChatGeneration):
1488
- return generation.message
1489
- msg = "Unexpected generation type"
1490
- raise ValueError(msg)
1491
-
1492
1447
  async def _call_async(
1493
1448
  self,
1494
1449
  messages: list[BaseMessage],
1495
- stop: Optional[list[str]] = None,
1450
+ stop: list[str] | None = None,
1496
1451
  callbacks: Callbacks = None,
1497
1452
  **kwargs: Any,
1498
1453
  ) -> BaseMessage:
@@ -1505,91 +1460,6 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1505
1460
  msg = "Unexpected generation type"
1506
1461
  raise ValueError(msg)
1507
1462
 
1508
- @deprecated("0.1.7", alternative="invoke", removal="1.0")
1509
- def call_as_llm(
1510
- self, message: str, stop: Optional[list[str]] = None, **kwargs: Any
1511
- ) -> str:
1512
- """Call the model.
1513
-
1514
- Args:
1515
- message: The input message.
1516
- stop: Stop words to use when generating. Model output is cut off at the
1517
- first occurrence of any of these substrings.
1518
- **kwargs: Arbitrary additional keyword arguments. These are usually passed
1519
- to the model provider API call.
1520
-
1521
- Returns:
1522
- The model output string.
1523
-
1524
- """
1525
- return self.predict(message, stop=stop, **kwargs)
1526
-
1527
- @deprecated("0.1.7", alternative="invoke", removal="1.0")
1528
- @override
1529
- def predict(
1530
- self, text: str, *, stop: Optional[Sequence[str]] = None, **kwargs: Any
1531
- ) -> str:
1532
- """Predict the next message.
1533
-
1534
- Args:
1535
- text: The input message.
1536
- stop: Stop words to use when generating. Model output is cut off at the
1537
- first occurrence of any of these substrings.
1538
- **kwargs: Arbitrary additional keyword arguments. These are usually passed
1539
- to the model provider API call.
1540
-
1541
- Raises:
1542
- ValueError: If the output is not a string.
1543
-
1544
- Returns:
1545
- The predicted output string.
1546
-
1547
- """
1548
- stop_ = None if stop is None else list(stop)
1549
- result = self([HumanMessage(content=text)], stop=stop_, **kwargs)
1550
- if isinstance(result.content, str):
1551
- return result.content
1552
- msg = "Cannot use predict when output is not a string."
1553
- raise ValueError(msg)
1554
-
1555
- @deprecated("0.1.7", alternative="invoke", removal="1.0")
1556
- @override
1557
- def predict_messages(
1558
- self,
1559
- messages: list[BaseMessage],
1560
- *,
1561
- stop: Optional[Sequence[str]] = None,
1562
- **kwargs: Any,
1563
- ) -> BaseMessage:
1564
- stop_ = None if stop is None else list(stop)
1565
- return self(messages, stop=stop_, **kwargs)
1566
-
1567
- @deprecated("0.1.7", alternative="ainvoke", removal="1.0")
1568
- @override
1569
- async def apredict(
1570
- self, text: str, *, stop: Optional[Sequence[str]] = None, **kwargs: Any
1571
- ) -> str:
1572
- stop_ = None if stop is None else list(stop)
1573
- result = await self._call_async(
1574
- [HumanMessage(content=text)], stop=stop_, **kwargs
1575
- )
1576
- if isinstance(result.content, str):
1577
- return result.content
1578
- msg = "Cannot use predict when output is not a string."
1579
- raise ValueError(msg)
1580
-
1581
- @deprecated("0.1.7", alternative="ainvoke", removal="1.0")
1582
- @override
1583
- async def apredict_messages(
1584
- self,
1585
- messages: list[BaseMessage],
1586
- *,
1587
- stop: Optional[Sequence[str]] = None,
1588
- **kwargs: Any,
1589
- ) -> BaseMessage:
1590
- stop_ = None if stop is None else list(stop)
1591
- return await self._call_async(messages, stop=stop_, **kwargs)
1592
-
1593
1463
  @property
1594
1464
  @abstractmethod
1595
1465
  def _llm_type(self) -> str:
@@ -1605,10 +1475,10 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1605
1475
  def bind_tools(
1606
1476
  self,
1607
1477
  tools: Sequence[
1608
- Union[typing.Dict[str, Any], type, Callable, BaseTool] # noqa: UP006
1478
+ typing.Dict[str, Any] | type | Callable | BaseTool # noqa: UP006
1609
1479
  ],
1610
1480
  *,
1611
- tool_choice: Optional[Union[str]] = None,
1481
+ tool_choice: str | None = None,
1612
1482
  **kwargs: Any,
1613
1483
  ) -> Runnable[LanguageModelInput, AIMessage]:
1614
1484
  """Bind tools to the model.
@@ -1625,11 +1495,11 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1625
1495
 
1626
1496
  def with_structured_output(
1627
1497
  self,
1628
- schema: Union[typing.Dict, type], # noqa: UP006
1498
+ schema: typing.Dict | type, # noqa: UP006
1629
1499
  *,
1630
1500
  include_raw: bool = False,
1631
1501
  **kwargs: Any,
1632
- ) -> Runnable[LanguageModelInput, Union[typing.Dict, BaseModel]]: # noqa: UP006
1502
+ ) -> Runnable[LanguageModelInput, typing.Dict | BaseModel]: # noqa: UP006
1633
1503
  """Model wrapper that returns outputs formatted to match the given schema.
1634
1504
 
1635
1505
  Args:
@@ -1637,124 +1507,130 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1637
1507
 
1638
1508
  - an OpenAI function/tool schema,
1639
1509
  - a JSON Schema,
1640
- - a TypedDict class,
1510
+ - a `TypedDict` class,
1641
1511
  - or a Pydantic class.
1642
1512
 
1643
- If ``schema`` is a Pydantic class then the model output will be a
1513
+ If `schema` is a Pydantic class then the model output will be a
1644
1514
  Pydantic instance of that class, and the model-generated fields will be
1645
1515
  validated by the Pydantic class. Otherwise the model output will be a
1646
- dict and will not be validated. See :meth:`langchain_core.utils.function_calling.convert_to_openai_tool`
1647
- for more on how to properly specify types and descriptions of
1648
- schema fields when specifying a Pydantic or TypedDict class.
1516
+ dict and will not be validated.
1517
+
1518
+ See `langchain_core.utils.function_calling.convert_to_openai_tool` for
1519
+ more on how to properly specify types and descriptions of schema fields
1520
+ when specifying a Pydantic or `TypedDict` class.
1649
1521
 
1650
1522
  include_raw:
1651
- If False then only the parsed structured output is returned. If
1652
- an error occurs during model output parsing it will be raised. If True
1653
- then both the raw model response (a BaseMessage) and the parsed model
1523
+ If `False` then only the parsed structured output is returned. If
1524
+ an error occurs during model output parsing it will be raised. If `True`
1525
+ then both the raw model response (a `BaseMessage`) and the parsed model
1654
1526
  response will be returned. If an error occurs during output parsing it
1655
- will be caught and returned as well. The final output is always a dict
1656
- with keys ``'raw'``, ``'parsed'``, and ``'parsing_error'``.
1527
+ will be caught and returned as well.
1528
+
1529
+ The final output is always a `dict` with keys `'raw'`, `'parsed'`, and
1530
+ `'parsing_error'`.
1657
1531
 
1658
1532
  Raises:
1659
- ValueError: If there are any unsupported ``kwargs``.
1533
+ ValueError: If there are any unsupported `kwargs`.
1660
1534
  NotImplementedError: If the model does not implement
1661
- ``with_structured_output()``.
1535
+ `with_structured_output()`.
1662
1536
 
1663
1537
  Returns:
1664
- A Runnable that takes same inputs as a :class:`langchain_core.language_models.chat.BaseChatModel`.
1665
-
1666
- If ``include_raw`` is False and ``schema`` is a Pydantic class, Runnable outputs
1667
- an instance of ``schema`` (i.e., a Pydantic object).
1538
+ A `Runnable` that takes same inputs as a
1539
+ `langchain_core.language_models.chat.BaseChatModel`. If `include_raw` is
1540
+ `False` and `schema` is a Pydantic class, `Runnable` outputs an instance
1541
+ of `schema` (i.e., a Pydantic object). Otherwise, if `include_raw` is
1542
+ `False` then `Runnable` outputs a `dict`.
1668
1543
 
1669
- Otherwise, if ``include_raw`` is False then Runnable outputs a dict.
1544
+ If `include_raw` is `True`, then `Runnable` outputs a `dict` with keys:
1670
1545
 
1671
- If ``include_raw`` is True, then Runnable outputs a dict with keys:
1546
+ - `'raw'`: `BaseMessage`
1547
+ - `'parsed'`: `None` if there was a parsing error, otherwise the type
1548
+ depends on the `schema` as described above.
1549
+ - `'parsing_error'`: `BaseException | None`
1672
1550
 
1673
- - ``'raw'``: BaseMessage
1674
- - ``'parsed'``: None if there was a parsing error, otherwise the type depends on the ``schema`` as described above.
1675
- - ``'parsing_error'``: Optional[BaseException]
1551
+ Example: Pydantic schema (`include_raw=False`):
1676
1552
 
1677
- Example: Pydantic schema (include_raw=False):
1678
- .. code-block:: python
1553
+ ```python
1554
+ from pydantic import BaseModel
1679
1555
 
1680
- from pydantic import BaseModel
1681
1556
 
1557
+ class AnswerWithJustification(BaseModel):
1558
+ '''An answer to the user question along with justification for the answer.'''
1682
1559
 
1683
- class AnswerWithJustification(BaseModel):
1684
- '''An answer to the user question along with justification for the answer.'''
1560
+ answer: str
1561
+ justification: str
1685
1562
 
1686
- answer: str
1687
- justification: str
1688
1563
 
1564
+ model = ChatModel(model="model-name", temperature=0)
1565
+ structured_model = model.with_structured_output(AnswerWithJustification)
1689
1566
 
1690
- llm = ChatModel(model="model-name", temperature=0)
1691
- structured_llm = llm.with_structured_output(AnswerWithJustification)
1692
-
1693
- structured_llm.invoke(
1694
- "What weighs more a pound of bricks or a pound of feathers"
1695
- )
1567
+ structured_model.invoke(
1568
+ "What weighs more a pound of bricks or a pound of feathers"
1569
+ )
1696
1570
 
1697
- # -> AnswerWithJustification(
1698
- # answer='They weigh the same',
1699
- # justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
1700
- # )
1571
+ # -> AnswerWithJustification(
1572
+ # answer='They weigh the same',
1573
+ # justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
1574
+ # )
1575
+ ```
1701
1576
 
1702
- Example: Pydantic schema (include_raw=True):
1703
- .. code-block:: python
1577
+ Example: Pydantic schema (`include_raw=True`):
1704
1578
 
1705
- from pydantic import BaseModel
1579
+ ```python
1580
+ from pydantic import BaseModel
1706
1581
 
1707
1582
 
1708
- class AnswerWithJustification(BaseModel):
1709
- '''An answer to the user question along with justification for the answer.'''
1583
+ class AnswerWithJustification(BaseModel):
1584
+ '''An answer to the user question along with justification for the answer.'''
1710
1585
 
1711
- answer: str
1712
- justification: str
1586
+ answer: str
1587
+ justification: str
1713
1588
 
1714
1589
 
1715
- llm = ChatModel(model="model-name", temperature=0)
1716
- structured_llm = llm.with_structured_output(
1717
- AnswerWithJustification, include_raw=True
1718
- )
1719
-
1720
- structured_llm.invoke(
1721
- "What weighs more a pound of bricks or a pound of feathers"
1722
- )
1723
- # -> {
1724
- # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}),
1725
- # 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'),
1726
- # 'parsing_error': None
1727
- # }
1590
+ model = ChatModel(model="model-name", temperature=0)
1591
+ structured_model = model.with_structured_output(
1592
+ AnswerWithJustification, include_raw=True
1593
+ )
1728
1594
 
1729
- Example: Dict schema (include_raw=False):
1730
- .. code-block:: python
1595
+ structured_model.invoke(
1596
+ "What weighs more a pound of bricks or a pound of feathers"
1597
+ )
1598
+ # -> {
1599
+ # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}),
1600
+ # 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'),
1601
+ # 'parsing_error': None
1602
+ # }
1603
+ ```
1731
1604
 
1732
- from pydantic import BaseModel
1733
- from langchain_core.utils.function_calling import convert_to_openai_tool
1605
+ Example: `dict` schema (`include_raw=False`):
1734
1606
 
1607
+ ```python
1608
+ from pydantic import BaseModel
1609
+ from langchain_core.utils.function_calling import convert_to_openai_tool
1735
1610
 
1736
- class AnswerWithJustification(BaseModel):
1737
- '''An answer to the user question along with justification for the answer.'''
1738
1611
 
1739
- answer: str
1740
- justification: str
1612
+ class AnswerWithJustification(BaseModel):
1613
+ '''An answer to the user question along with justification for the answer.'''
1741
1614
 
1615
+ answer: str
1616
+ justification: str
1742
1617
 
1743
- dict_schema = convert_to_openai_tool(AnswerWithJustification)
1744
- llm = ChatModel(model="model-name", temperature=0)
1745
- structured_llm = llm.with_structured_output(dict_schema)
1746
1618
 
1747
- structured_llm.invoke(
1748
- "What weighs more a pound of bricks or a pound of feathers"
1749
- )
1750
- # -> {
1751
- # 'answer': 'They weigh the same',
1752
- # 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.'
1753
- # }
1619
+ dict_schema = convert_to_openai_tool(AnswerWithJustification)
1620
+ model = ChatModel(model="model-name", temperature=0)
1621
+ structured_model = model.with_structured_output(dict_schema)
1754
1622
 
1755
- .. versionchanged:: 0.2.26
1623
+ structured_model.invoke(
1624
+ "What weighs more a pound of bricks or a pound of feathers"
1625
+ )
1626
+ # -> {
1627
+ # 'answer': 'They weigh the same',
1628
+ # 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.'
1629
+ # }
1630
+ ```
1756
1631
 
1757
- Added support for TypedDict class.
1632
+ !!! warning "Behavior changed in 0.2.26"
1633
+ Added support for TypedDict class.
1758
1634
 
1759
1635
  """ # noqa: E501
1760
1636
  _ = kwargs.pop("method", None)
@@ -1795,21 +1671,56 @@ class BaseChatModel(BaseLanguageModel[AIMessage], ABC):
1795
1671
  return RunnableMap(raw=llm) | parser_with_fallback
1796
1672
  return llm | output_parser
1797
1673
 
1674
+ @property
1675
+ @beta()
1676
+ def profile(self) -> ModelProfile:
1677
+ """Return profiling information for the model.
1678
+
1679
+ This property will relies on the `langchain-model-profiles` package to
1680
+ retrieve chat model capabilities, such as context window sizes and supported
1681
+ features.
1682
+
1683
+ Raises:
1684
+ ImportError: If `langchain-model-profiles` is not installed.
1685
+
1686
+ Returns:
1687
+ A `ModelProfile` object containing profiling information for the model.
1688
+ """
1689
+ try:
1690
+ from langchain_model_profiles import get_model_profile # noqa: PLC0415
1691
+ except ImportError as err:
1692
+ informative_error_message = (
1693
+ "To access model profiling information, please install the "
1694
+ "`langchain-model-profiles` package: "
1695
+ "`pip install langchain-model-profiles`."
1696
+ )
1697
+ raise ImportError(informative_error_message) from err
1698
+
1699
+ provider_id = self._llm_type
1700
+ model_name = (
1701
+ # Model name is not standardized across integrations. New integrations
1702
+ # should prefer `model`.
1703
+ getattr(self, "model", None)
1704
+ or getattr(self, "model_name", None)
1705
+ or getattr(self, "model_id", "")
1706
+ )
1707
+ return get_model_profile(provider_id, model_name) or {}
1708
+
1798
1709
 
1799
1710
  class SimpleChatModel(BaseChatModel):
1800
1711
  """Simplified implementation for a chat model to inherit from.
1801
1712
 
1802
- .. note::
1713
+ !!! note
1803
1714
  This implementation is primarily here for backwards compatibility. For new
1804
- implementations, please use ``BaseChatModel`` directly.
1715
+ implementations, please use `BaseChatModel` directly.
1805
1716
 
1806
1717
  """
1807
1718
 
1808
1719
  def _generate(
1809
1720
  self,
1810
1721
  messages: list[BaseMessage],
1811
- stop: Optional[list[str]] = None,
1812
- run_manager: Optional[CallbackManagerForLLMRun] = None,
1722
+ stop: list[str] | None = None,
1723
+ run_manager: CallbackManagerForLLMRun | None = None,
1813
1724
  **kwargs: Any,
1814
1725
  ) -> ChatResult:
1815
1726
  output_str = self._call(messages, stop=stop, run_manager=run_manager, **kwargs)
@@ -1821,8 +1732,8 @@ class SimpleChatModel(BaseChatModel):
1821
1732
  def _call(
1822
1733
  self,
1823
1734
  messages: list[BaseMessage],
1824
- stop: Optional[list[str]] = None,
1825
- run_manager: Optional[CallbackManagerForLLMRun] = None,
1735
+ stop: list[str] | None = None,
1736
+ run_manager: CallbackManagerForLLMRun | None = None,
1826
1737
  **kwargs: Any,
1827
1738
  ) -> str:
1828
1739
  """Simpler interface."""
@@ -1830,8 +1741,8 @@ class SimpleChatModel(BaseChatModel):
1830
1741
  async def _agenerate(
1831
1742
  self,
1832
1743
  messages: list[BaseMessage],
1833
- stop: Optional[list[str]] = None,
1834
- run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
1744
+ stop: list[str] | None = None,
1745
+ run_manager: AsyncCallbackManagerForLLMRun | None = None,
1835
1746
  **kwargs: Any,
1836
1747
  ) -> ChatResult:
1837
1748
  return await run_in_executor(
@@ -1845,7 +1756,7 @@ class SimpleChatModel(BaseChatModel):
1845
1756
 
1846
1757
 
1847
1758
  def _gen_info_and_msg_metadata(
1848
- generation: Union[ChatGeneration, ChatGenerationChunk],
1759
+ generation: ChatGeneration | ChatGenerationChunk,
1849
1760
  ) -> dict:
1850
1761
  return {
1851
1762
  **(generation.generation_info or {}),