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.
- langchain_core/__init__.py +1 -1
- langchain_core/_api/__init__.py +3 -4
- langchain_core/_api/beta_decorator.py +23 -26
- langchain_core/_api/deprecation.py +51 -64
- langchain_core/_api/path.py +3 -6
- langchain_core/_import_utils.py +3 -4
- langchain_core/agents.py +20 -22
- langchain_core/caches.py +65 -66
- langchain_core/callbacks/__init__.py +1 -8
- langchain_core/callbacks/base.py +321 -336
- langchain_core/callbacks/file.py +44 -44
- langchain_core/callbacks/manager.py +436 -513
- langchain_core/callbacks/stdout.py +29 -30
- langchain_core/callbacks/streaming_stdout.py +32 -32
- langchain_core/callbacks/usage.py +60 -57
- langchain_core/chat_history.py +53 -68
- langchain_core/document_loaders/base.py +27 -25
- langchain_core/document_loaders/blob_loaders.py +1 -1
- langchain_core/document_loaders/langsmith.py +44 -48
- langchain_core/documents/__init__.py +23 -3
- langchain_core/documents/base.py +98 -90
- langchain_core/documents/compressor.py +10 -10
- langchain_core/documents/transformers.py +34 -35
- langchain_core/embeddings/fake.py +50 -54
- langchain_core/example_selectors/length_based.py +1 -1
- langchain_core/example_selectors/semantic_similarity.py +28 -32
- langchain_core/exceptions.py +21 -20
- langchain_core/globals.py +3 -151
- langchain_core/indexing/__init__.py +1 -1
- langchain_core/indexing/api.py +121 -126
- langchain_core/indexing/base.py +73 -75
- langchain_core/indexing/in_memory.py +4 -6
- langchain_core/language_models/__init__.py +14 -29
- langchain_core/language_models/_utils.py +58 -61
- langchain_core/language_models/base.py +53 -162
- langchain_core/language_models/chat_models.py +298 -387
- langchain_core/language_models/fake.py +11 -11
- langchain_core/language_models/fake_chat_models.py +42 -36
- langchain_core/language_models/llms.py +125 -235
- langchain_core/load/dump.py +9 -12
- langchain_core/load/load.py +18 -28
- langchain_core/load/mapping.py +2 -4
- langchain_core/load/serializable.py +42 -40
- langchain_core/messages/__init__.py +10 -16
- langchain_core/messages/ai.py +148 -148
- langchain_core/messages/base.py +53 -51
- langchain_core/messages/block_translators/__init__.py +19 -22
- langchain_core/messages/block_translators/anthropic.py +6 -6
- langchain_core/messages/block_translators/bedrock_converse.py +5 -5
- langchain_core/messages/block_translators/google_genai.py +10 -7
- langchain_core/messages/block_translators/google_vertexai.py +4 -32
- langchain_core/messages/block_translators/groq.py +117 -21
- langchain_core/messages/block_translators/langchain_v0.py +5 -5
- langchain_core/messages/block_translators/openai.py +11 -11
- langchain_core/messages/chat.py +2 -6
- langchain_core/messages/content.py +337 -328
- langchain_core/messages/function.py +6 -10
- langchain_core/messages/human.py +24 -31
- langchain_core/messages/modifier.py +2 -2
- langchain_core/messages/system.py +19 -29
- langchain_core/messages/tool.py +74 -90
- langchain_core/messages/utils.py +474 -504
- langchain_core/output_parsers/__init__.py +13 -10
- langchain_core/output_parsers/base.py +61 -61
- langchain_core/output_parsers/format_instructions.py +9 -4
- langchain_core/output_parsers/json.py +12 -10
- langchain_core/output_parsers/list.py +21 -23
- langchain_core/output_parsers/openai_functions.py +49 -47
- langchain_core/output_parsers/openai_tools.py +16 -21
- langchain_core/output_parsers/pydantic.py +13 -14
- langchain_core/output_parsers/string.py +5 -5
- langchain_core/output_parsers/transform.py +15 -17
- langchain_core/output_parsers/xml.py +35 -34
- langchain_core/outputs/__init__.py +1 -1
- langchain_core/outputs/chat_generation.py +18 -18
- langchain_core/outputs/chat_result.py +1 -3
- langchain_core/outputs/generation.py +10 -11
- langchain_core/outputs/llm_result.py +10 -10
- langchain_core/prompt_values.py +11 -17
- langchain_core/prompts/__init__.py +3 -27
- langchain_core/prompts/base.py +48 -56
- langchain_core/prompts/chat.py +275 -325
- langchain_core/prompts/dict.py +5 -5
- langchain_core/prompts/few_shot.py +81 -88
- langchain_core/prompts/few_shot_with_templates.py +11 -13
- langchain_core/prompts/image.py +12 -14
- langchain_core/prompts/loading.py +4 -6
- langchain_core/prompts/message.py +3 -3
- langchain_core/prompts/prompt.py +24 -39
- langchain_core/prompts/string.py +26 -10
- langchain_core/prompts/structured.py +49 -53
- langchain_core/rate_limiters.py +51 -60
- langchain_core/retrievers.py +61 -198
- langchain_core/runnables/base.py +1476 -1626
- langchain_core/runnables/branch.py +53 -57
- langchain_core/runnables/config.py +72 -89
- langchain_core/runnables/configurable.py +120 -137
- langchain_core/runnables/fallbacks.py +83 -79
- langchain_core/runnables/graph.py +91 -97
- langchain_core/runnables/graph_ascii.py +27 -28
- langchain_core/runnables/graph_mermaid.py +38 -50
- langchain_core/runnables/graph_png.py +15 -16
- langchain_core/runnables/history.py +135 -148
- langchain_core/runnables/passthrough.py +124 -150
- langchain_core/runnables/retry.py +46 -51
- langchain_core/runnables/router.py +25 -30
- langchain_core/runnables/schema.py +75 -80
- langchain_core/runnables/utils.py +60 -67
- langchain_core/stores.py +85 -121
- langchain_core/structured_query.py +8 -8
- langchain_core/sys_info.py +27 -29
- langchain_core/tools/__init__.py +1 -14
- langchain_core/tools/base.py +284 -229
- langchain_core/tools/convert.py +160 -155
- langchain_core/tools/render.py +10 -10
- langchain_core/tools/retriever.py +12 -11
- langchain_core/tools/simple.py +19 -24
- langchain_core/tools/structured.py +32 -39
- langchain_core/tracers/__init__.py +1 -9
- langchain_core/tracers/base.py +97 -99
- langchain_core/tracers/context.py +29 -52
- langchain_core/tracers/core.py +49 -53
- langchain_core/tracers/evaluation.py +11 -11
- langchain_core/tracers/event_stream.py +65 -64
- langchain_core/tracers/langchain.py +21 -21
- langchain_core/tracers/log_stream.py +45 -45
- langchain_core/tracers/memory_stream.py +3 -3
- langchain_core/tracers/root_listeners.py +16 -16
- langchain_core/tracers/run_collector.py +2 -4
- langchain_core/tracers/schemas.py +0 -129
- langchain_core/tracers/stdout.py +3 -3
- langchain_core/utils/__init__.py +1 -4
- langchain_core/utils/_merge.py +2 -2
- langchain_core/utils/aiter.py +57 -61
- langchain_core/utils/env.py +9 -9
- langchain_core/utils/function_calling.py +89 -186
- langchain_core/utils/html.py +7 -8
- langchain_core/utils/input.py +6 -6
- langchain_core/utils/interactive_env.py +1 -1
- langchain_core/utils/iter.py +36 -40
- langchain_core/utils/json.py +4 -3
- langchain_core/utils/json_schema.py +9 -9
- langchain_core/utils/mustache.py +8 -10
- langchain_core/utils/pydantic.py +33 -35
- langchain_core/utils/strings.py +6 -9
- langchain_core/utils/usage.py +1 -1
- langchain_core/utils/utils.py +66 -62
- langchain_core/vectorstores/base.py +182 -216
- langchain_core/vectorstores/in_memory.py +101 -176
- langchain_core/vectorstores/utils.py +5 -5
- langchain_core/version.py +1 -1
- langchain_core-1.0.3.dist-info/METADATA +69 -0
- langchain_core-1.0.3.dist-info/RECORD +172 -0
- {langchain_core-1.0.0a6.dist-info → langchain_core-1.0.3.dist-info}/WHEEL +1 -1
- langchain_core/memory.py +0 -120
- langchain_core/messages/block_translators/ollama.py +0 -47
- langchain_core/prompts/pipeline.py +0 -138
- langchain_core/pydantic_v1/__init__.py +0 -30
- langchain_core/pydantic_v1/dataclasses.py +0 -23
- langchain_core/pydantic_v1/main.py +0 -23
- langchain_core/tracers/langchain_v1.py +0 -31
- langchain_core/utils/loading.py +0 -35
- langchain_core-1.0.0a6.dist-info/METADATA +0 -67
- langchain_core-1.0.0a6.dist-info/RECORD +0 -181
- 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,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Literal, cast
|
|
15
14
|
|
|
16
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
15
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
17
16
|
from typing_extensions import override
|
|
18
17
|
|
|
19
|
-
from langchain_core._api import
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
216
|
+
stream: Iterator of `ChatGenerationChunk`.
|
|
217
217
|
|
|
218
218
|
Returns:
|
|
219
|
-
|
|
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:
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
|
255
|
-
|
|
256
|
-
| `ainvoke`
|
|
257
|
-
|
|
258
|
-
| `
|
|
259
|
-
|
|
260
|
-
| `
|
|
261
|
-
|
|
262
|
-
| `
|
|
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
|
|
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
|
-
|
|
|
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
|
-
|
|
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:
|
|
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
|
|
339
|
-
defer to
|
|
301
|
+
If streaming is bypassed, then `stream`/`astream`/`astream_events` will
|
|
302
|
+
defer to `invoke`/`ainvoke`.
|
|
340
303
|
|
|
341
|
-
- If True
|
|
342
|
-
- If
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
- If False (
|
|
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
|
|
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:
|
|
316
|
+
output_version: str | None = Field(
|
|
355
317
|
default_factory=from_env("LC_OUTPUT_VERSION", default=None)
|
|
356
318
|
)
|
|
357
|
-
"""Version of
|
|
319
|
+
"""Version of `AIMessage` output format to store in message content.
|
|
358
320
|
|
|
359
|
-
|
|
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
|
-
-
|
|
366
|
-
|
|
367
|
-
-
|
|
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.,
|
|
370
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
372
|
+
config: RunnableConfig | None = None,
|
|
431
373
|
*,
|
|
432
|
-
stop:
|
|
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:
|
|
399
|
+
config: RunnableConfig | None = None,
|
|
458
400
|
*,
|
|
459
|
-
stop:
|
|
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:
|
|
482
|
-
|
|
483
|
-
|
|
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:
|
|
463
|
+
config: RunnableConfig | None = None,
|
|
517
464
|
*,
|
|
518
|
-
stop:
|
|
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:
|
|
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:
|
|
589
|
+
config: RunnableConfig | None = None,
|
|
633
590
|
*,
|
|
634
|
-
stop:
|
|
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:
|
|
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[
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
825
|
+
stop: list[str] | None = None,
|
|
859
826
|
callbacks: Callbacks = None,
|
|
860
827
|
*,
|
|
861
|
-
tags:
|
|
862
|
-
metadata:
|
|
863
|
-
run_name:
|
|
864
|
-
run_id:
|
|
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
|
-
|
|
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
|
|
894
|
-
|
|
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(
|
|
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:
|
|
943
|
+
stop: list[str] | None = None,
|
|
975
944
|
callbacks: Callbacks = None,
|
|
976
945
|
*,
|
|
977
|
-
tags:
|
|
978
|
-
metadata:
|
|
979
|
-
run_name:
|
|
980
|
-
run_id:
|
|
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
|
-
|
|
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
|
|
1010
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
1141
|
-
run_manager:
|
|
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:
|
|
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:
|
|
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:
|
|
1249
|
-
run_manager:
|
|
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:
|
|
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:
|
|
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:
|
|
1358
|
-
run_manager:
|
|
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:
|
|
1377
|
-
run_manager:
|
|
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:
|
|
1404
|
-
run_manager:
|
|
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:
|
|
1424
|
-
run_manager:
|
|
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:
|
|
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
|
-
|
|
1478
|
+
typing.Dict[str, Any] | type | Callable | BaseTool # noqa: UP006
|
|
1609
1479
|
],
|
|
1610
1480
|
*,
|
|
1611
|
-
tool_choice:
|
|
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:
|
|
1498
|
+
schema: typing.Dict | type, # noqa: UP006
|
|
1629
1499
|
*,
|
|
1630
1500
|
include_raw: bool = False,
|
|
1631
1501
|
**kwargs: Any,
|
|
1632
|
-
) -> Runnable[LanguageModelInput,
|
|
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
|
|
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.
|
|
1647
|
-
|
|
1648
|
-
|
|
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.
|
|
1656
|
-
|
|
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
|
|
1533
|
+
ValueError: If there are any unsupported `kwargs`.
|
|
1660
1534
|
NotImplementedError: If the model does not implement
|
|
1661
|
-
|
|
1535
|
+
`with_structured_output()`.
|
|
1662
1536
|
|
|
1663
1537
|
Returns:
|
|
1664
|
-
A Runnable that takes same inputs as a
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
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
|
-
|
|
1544
|
+
If `include_raw` is `True`, then `Runnable` outputs a `dict` with keys:
|
|
1670
1545
|
|
|
1671
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1678
|
-
|
|
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
|
-
|
|
1684
|
-
|
|
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
|
-
|
|
1691
|
-
|
|
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
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
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
|
-
|
|
1579
|
+
```python
|
|
1580
|
+
from pydantic import BaseModel
|
|
1706
1581
|
|
|
1707
1582
|
|
|
1708
|
-
|
|
1709
|
-
|
|
1583
|
+
class AnswerWithJustification(BaseModel):
|
|
1584
|
+
'''An answer to the user question along with justification for the answer.'''
|
|
1710
1585
|
|
|
1711
|
-
|
|
1712
|
-
|
|
1586
|
+
answer: str
|
|
1587
|
+
justification: str
|
|
1713
1588
|
|
|
1714
1589
|
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
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
|
-
|
|
1730
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1740
|
-
|
|
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
|
-
|
|
1748
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1713
|
+
!!! note
|
|
1803
1714
|
This implementation is primarily here for backwards compatibility. For new
|
|
1804
|
-
implementations, please use
|
|
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:
|
|
1812
|
-
run_manager:
|
|
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:
|
|
1825
|
-
run_manager:
|
|
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:
|
|
1834
|
-
run_manager:
|
|
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:
|
|
1759
|
+
generation: ChatGeneration | ChatGenerationChunk,
|
|
1849
1760
|
) -> dict:
|
|
1850
1761
|
return {
|
|
1851
1762
|
**(generation.generation_info or {}),
|