mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-21 14:43:07 +00:00
.
This commit is contained in:
@@ -65,6 +65,7 @@ class InputTokenDetails(TypedDict, total=False):
|
||||
|
||||
Since there was a cache hit, the tokens were read from the cache. More precisely,
|
||||
the model state given these tokens was read from the cache.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -92,6 +93,7 @@ class OutputTokenDetails(TypedDict, total=False):
|
||||
|
||||
Tokens generated by the model in a chain of thought process (i.e. by OpenAI's o1
|
||||
models) that are not returned as part of model output.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -139,6 +141,7 @@ class UsageMetadata(TypedDict):
|
||||
"""Breakdown of output token counts.
|
||||
|
||||
Does *not* need to sum to full output token count. Does *not* need to have all keys.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -150,12 +153,14 @@ class AIMessage(BaseMessage):
|
||||
This message represents the output of the model and consists of both
|
||||
the raw output as returned by the model together standardized fields
|
||||
(e.g., tool calls, usage metadata) added by the LangChain framework.
|
||||
|
||||
"""
|
||||
|
||||
example: bool = False
|
||||
"""Use to denote that a message is part of an example conversation.
|
||||
|
||||
At the moment, this is ignored by most models. Usage is discouraged.
|
||||
|
||||
"""
|
||||
|
||||
tool_calls: list[ToolCall] = []
|
||||
@@ -166,6 +171,7 @@ class AIMessage(BaseMessage):
|
||||
"""If provided, usage metadata for a message, such as token counts.
|
||||
|
||||
This is a standard representation of token usage that is consistent across models.
|
||||
|
||||
"""
|
||||
|
||||
type: Literal["ai"] = "ai"
|
||||
@@ -178,35 +184,12 @@ class AIMessage(BaseMessage):
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
Args:
|
||||
content: The content of the message.
|
||||
kwargs: Additional arguments to pass to the parent class.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Specify ``content`` as positional arg or ``content_blocks`` for typing."""
|
||||
if content_blocks is not None:
|
||||
# If there are tool calls in content_blocks, but not in tool_calls, add them
|
||||
content_tool_calls = [
|
||||
block for block in content_blocks if block.get("type") == "tool_call"
|
||||
]
|
||||
if content_tool_calls and "tool_calls" not in kwargs:
|
||||
kwargs["tool_calls"] = content_tool_calls
|
||||
|
||||
super().__init__(
|
||||
content=cast("Union[str, list[Union[str, dict]]]", content_blocks),
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
super().__init__(content=content, **kwargs)
|
||||
"""
|
||||
super().__init__(content=content, **kwargs)
|
||||
|
||||
@property
|
||||
def lc_attributes(self) -> dict:
|
||||
@@ -316,6 +299,7 @@ class AIMessage(BaseMessage):
|
||||
|
||||
Returns:
|
||||
A pretty representation of the message.
|
||||
|
||||
"""
|
||||
base = super().pretty_repr(html=html)
|
||||
lines = []
|
||||
@@ -355,7 +339,10 @@ class AIMessageChunk(AIMessage, BaseMessageChunk):
|
||||
# non-chunk variant.
|
||||
type: Literal["AIMessageChunk"] = "AIMessageChunk" # type: ignore[assignment]
|
||||
"""The type of the message (used for deserialization).
|
||||
Defaults to "AIMessageChunk"."""
|
||||
|
||||
Defaults to ``AIMessageChunk``.
|
||||
|
||||
"""
|
||||
|
||||
tool_call_chunks: list[ToolCallChunk] = []
|
||||
"""If provided, tool call chunks associated with the message."""
|
||||
@@ -419,6 +406,7 @@ class AIMessageChunk(AIMessage, BaseMessageChunk):
|
||||
|
||||
Raises:
|
||||
ValueError: If the tool call chunks are malformed.
|
||||
|
||||
"""
|
||||
if not self.tool_call_chunks:
|
||||
if self.tool_calls:
|
||||
@@ -632,9 +620,9 @@ def add_usage(
|
||||
def subtract_usage(
|
||||
left: Optional[UsageMetadata], right: Optional[UsageMetadata]
|
||||
) -> UsageMetadata:
|
||||
"""Recursively subtract two UsageMetadata objects.
|
||||
"""Recursively subtract two ``UsageMetadata`` objects.
|
||||
|
||||
Token counts cannot be negative so the actual operation is max(left - right, 0).
|
||||
Token counts cannot be negative so the actual operation is ``max(left - right, 0)``.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
@@ -58,8 +58,11 @@ class BaseMessage(Serializable):
|
||||
"""
|
||||
|
||||
id: Optional[str] = Field(default=None, coerce_numbers_to_str=True)
|
||||
"""An optional unique identifier for the message. This should ideally be
|
||||
provided by the provider/model which created the message."""
|
||||
"""An optional unique identifier for the message.
|
||||
|
||||
This should ideally be provided by the provider/model which created the message.
|
||||
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(
|
||||
extra="allow",
|
||||
@@ -72,25 +75,11 @@ class BaseMessage(Serializable):
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
Args:
|
||||
content: The string contents of the message.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Specify ``content`` as positional arg or ``content_blocks`` for typing."""
|
||||
if content_blocks is not None:
|
||||
super().__init__(content=content_blocks, **kwargs)
|
||||
else:
|
||||
super().__init__(content=content, **kwargs)
|
||||
"""
|
||||
super().__init__(content=content, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def is_lc_serializable(cls) -> bool:
|
||||
@@ -106,6 +95,7 @@ class BaseMessage(Serializable):
|
||||
"""Get the namespace of the langchain object.
|
||||
|
||||
Default is ``['langchain', 'schema', 'messages']``.
|
||||
|
||||
"""
|
||||
return ["langchain", "schema", "messages"]
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@ class ChatMessageChunk(ChatMessage, BaseMessageChunk):
|
||||
# non-chunk variant.
|
||||
type: Literal["ChatMessageChunk"] = "ChatMessageChunk" # type: ignore[assignment]
|
||||
"""The type of the message (used during serialization).
|
||||
Defaults to "ChatMessageChunk"."""
|
||||
|
||||
Defaults to ``ChatMessageChunk``.
|
||||
|
||||
"""
|
||||
|
||||
@override
|
||||
def __add__(self, other: Any) -> BaseMessageChunk: # type: ignore[override]
|
||||
|
||||
@@ -15,19 +15,20 @@ from langchain_core.utils._merge import merge_dicts
|
||||
class FunctionMessage(BaseMessage):
|
||||
"""Message for passing the result of executing a tool back to a model.
|
||||
|
||||
FunctionMessage are an older version of the ToolMessage schema, and
|
||||
do not contain the tool_call_id field.
|
||||
``FunctionMessage`` are an older version of the ``ToolMessage`` schema, and
|
||||
do not contain the ``tool_call_id`` field.
|
||||
|
||||
The tool_call_id field is used to associate the tool call request with the
|
||||
The ``tool_call_id`` field is used to associate the tool call request with the
|
||||
tool call response. This is useful in situations where a chat model is able
|
||||
to request multiple tool calls in parallel.
|
||||
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""The name of the function that was executed."""
|
||||
|
||||
type: Literal["function"] = "function"
|
||||
"""The type of the message (used for serialization). Defaults to "function"."""
|
||||
"""The type of the message (used for serialization). Defaults to ``'function'``."""
|
||||
|
||||
|
||||
class FunctionMessageChunk(FunctionMessage, BaseMessageChunk):
|
||||
@@ -38,7 +39,10 @@ class FunctionMessageChunk(FunctionMessage, BaseMessageChunk):
|
||||
# non-chunk variant.
|
||||
type: Literal["FunctionMessageChunk"] = "FunctionMessageChunk" # type: ignore[assignment]
|
||||
"""The type of the message (used for serialization).
|
||||
Defaults to "FunctionMessageChunk"."""
|
||||
|
||||
Defaults to ``FunctionMessageChunk``.
|
||||
|
||||
"""
|
||||
|
||||
@override
|
||||
def __add__(self, other: Any) -> BaseMessageChunk: # type: ignore[override]
|
||||
|
||||
@@ -9,7 +9,7 @@ from langchain_core.messages.base import BaseMessage, BaseMessageChunk
|
||||
class HumanMessage(BaseMessage):
|
||||
"""Message from a human.
|
||||
|
||||
HumanMessages are messages that are passed in from a human to the model.
|
||||
``HumanMessage``s are messages that are passed in from a human to the model.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -37,10 +37,15 @@ class HumanMessage(BaseMessage):
|
||||
|
||||
At the moment, this is ignored by most models. Usage is discouraged.
|
||||
Defaults to False.
|
||||
|
||||
"""
|
||||
|
||||
type: Literal["human"] = "human"
|
||||
"""The type of the message (used for serialization). Defaults to "human"."""
|
||||
"""The type of the message (used for serialization).
|
||||
|
||||
Defaults to ``'human'``.
|
||||
|
||||
"""
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
@@ -49,28 +54,12 @@ class HumanMessage(BaseMessage):
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
Args:
|
||||
content: The string contents of the message.
|
||||
kwargs: Additional fields to pass to the message.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Specify ``content`` as positional arg or ``content_blocks`` for typing."""
|
||||
if content_blocks is not None:
|
||||
super().__init__(
|
||||
content=cast("Union[str, list[Union[str, dict]]]", content_blocks),
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
super().__init__(content=content, **kwargs)
|
||||
"""
|
||||
super().__init__(content=content, **kwargs)
|
||||
|
||||
|
||||
class HumanMessageChunk(HumanMessage, BaseMessageChunk):
|
||||
|
||||
@@ -24,6 +24,7 @@ class RemoveMessage(BaseMessage):
|
||||
|
||||
Raises:
|
||||
ValueError: If the 'content' field is passed in kwargs.
|
||||
|
||||
"""
|
||||
if kwargs.pop("content", None):
|
||||
msg = "RemoveMessage does not support 'content' field."
|
||||
|
||||
@@ -33,7 +33,11 @@ class SystemMessage(BaseMessage):
|
||||
"""
|
||||
|
||||
type: Literal["system"] = "system"
|
||||
"""The type of the message (used for serialization). Defaults to "system"."""
|
||||
"""The type of the message (used for serialization).
|
||||
|
||||
Defaults to ``'system'``.
|
||||
|
||||
"""
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
@@ -74,4 +78,7 @@ class SystemMessageChunk(SystemMessage, BaseMessageChunk):
|
||||
# non-chunk variant.
|
||||
type: Literal["SystemMessageChunk"] = "SystemMessageChunk" # type: ignore[assignment]
|
||||
"""The type of the message (used for serialization).
|
||||
Defaults to "SystemMessageChunk"."""
|
||||
|
||||
Defaults to ``'SystemMessageChunk'``.
|
||||
|
||||
"""
|
||||
|
||||
@@ -16,19 +16,20 @@ from langchain_core.utils._merge import merge_dicts, merge_obj
|
||||
class ToolOutputMixin:
|
||||
"""Mixin for objects that tools can return directly.
|
||||
|
||||
If a custom BaseTool is invoked with a ToolCall and the output of custom code is
|
||||
not an instance of ToolOutputMixin, the output will automatically be coerced to a
|
||||
string and wrapped in a ToolMessage.
|
||||
If a custom BaseTool is invoked with a ``ToolCall`` and the output of custom code is
|
||||
not an instance of ``ToolOutputMixin``, the output will automatically be coerced to
|
||||
a string and wrapped in a ``ToolMessage``.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
"""Message for passing the result of executing a tool back to a model.
|
||||
|
||||
ToolMessages contain the result of a tool invocation. Typically, the result
|
||||
is encoded inside the `content` field.
|
||||
``ToolMessage``s contain the result of a tool invocation. Typically, the result
|
||||
is encoded inside the ``content`` field.
|
||||
|
||||
Example: A ToolMessage representing a result of 42 from a tool call with id
|
||||
Example: A ``ToolMessage`` representing a result of ``42`` from a tool call with id
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -37,7 +38,7 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
ToolMessage(content='42', tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL')
|
||||
|
||||
|
||||
Example: A ToolMessage where only part of the tool output is sent to the model
|
||||
Example: A ``ToolMessage`` where only part of the tool output is sent to the model
|
||||
and the full output is passed in to artifact.
|
||||
|
||||
.. versionadded:: 0.2.17
|
||||
@@ -58,7 +59,7 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
tool_call_id='call_Jja7J89XsjrOLA5r!MEOW!SL',
|
||||
)
|
||||
|
||||
The tool_call_id field is used to associate the tool call request with the
|
||||
The ``tool_call_id`` field is used to associate the tool call request with the
|
||||
tool call response. This is useful in situations where a chat model is able
|
||||
to request multiple tool calls in parallel.
|
||||
|
||||
@@ -68,7 +69,11 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
"""Tool call that this message is responding to."""
|
||||
|
||||
type: Literal["tool"] = "tool"
|
||||
"""The type of the message (used for serialization). Defaults to "tool"."""
|
||||
"""The type of the message (used for serialization).
|
||||
|
||||
Defaults to ``'tool'``.
|
||||
|
||||
"""
|
||||
|
||||
artifact: Any = None
|
||||
"""Artifact of the Tool execution which is not meant to be sent to the model.
|
||||
@@ -78,12 +83,14 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
output is needed in other parts of the code.
|
||||
|
||||
.. versionadded:: 0.2.17
|
||||
|
||||
"""
|
||||
|
||||
status: Literal["success", "error"] = "success"
|
||||
"""Status of the tool invocation.
|
||||
|
||||
.. versionadded:: 0.2.24
|
||||
|
||||
"""
|
||||
|
||||
additional_kwargs: dict = Field(default_factory=dict, repr=False)
|
||||
@@ -98,6 +105,7 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
|
||||
Args:
|
||||
values: The model arguments.
|
||||
|
||||
"""
|
||||
content = values["content"]
|
||||
if isinstance(content, tuple):
|
||||
@@ -142,28 +150,12 @@ class ToolMessage(BaseMessage, ToolOutputMixin):
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None: ...
|
||||
Args:
|
||||
content: The string contents of the message.
|
||||
**kwargs: Additional fields.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
content: Optional[Union[str, list[Union[str, dict]]]] = None,
|
||||
content_blocks: Optional[list[types.ContentBlock]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Specify ``content`` as positional arg or ``content_blocks`` for typing."""
|
||||
if content_blocks is not None:
|
||||
super().__init__(
|
||||
content=cast("Union[str, list[Union[str, dict]]]", content_blocks),
|
||||
**kwargs,
|
||||
)
|
||||
else:
|
||||
super().__init__(content=content, **kwargs)
|
||||
"""
|
||||
super().__init__(content=content, **kwargs)
|
||||
|
||||
|
||||
class ToolMessageChunk(ToolMessage, BaseMessageChunk):
|
||||
@@ -211,8 +203,8 @@ class ToolCall(TypedDict):
|
||||
"id": "123"
|
||||
}
|
||||
|
||||
This represents a request to call the tool named "foo" with arguments {"a": 1}
|
||||
and an identifier of "123".
|
||||
This represents a request to call the tool named ``'foo'`` with arguments
|
||||
``{"a": 1}`` and an identifier of ``'123'``.
|
||||
|
||||
"""
|
||||
|
||||
@@ -225,6 +217,7 @@ class ToolCall(TypedDict):
|
||||
|
||||
An identifier is needed to associate a tool call request with a tool
|
||||
call result in events when multiple concurrent tool calls are made.
|
||||
|
||||
"""
|
||||
type: NotRequired[Literal["tool_call"]]
|
||||
|
||||
@@ -241,6 +234,7 @@ def tool_call(
|
||||
name: The name of the tool to be called.
|
||||
args: The arguments to the tool call.
|
||||
id: An identifier associated with the tool call.
|
||||
|
||||
"""
|
||||
return ToolCall(name=name, args=args, id=id, type="tool_call")
|
||||
|
||||
@@ -248,9 +242,9 @@ def tool_call(
|
||||
class ToolCallChunk(TypedDict):
|
||||
"""A chunk of a tool call (e.g., as part of a stream).
|
||||
|
||||
When merging ToolCallChunks (e.g., via AIMessageChunk.__add__),
|
||||
When merging ``ToolCallChunk``s (e.g., via ``AIMessageChunk.__add__``),
|
||||
all string attributes are concatenated. Chunks are only merged if their
|
||||
values of `index` are equal and not None.
|
||||
values of ``index`` are equal and not None.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -291,12 +285,32 @@ def tool_call_chunk(
|
||||
args: The arguments to the tool call.
|
||||
id: An identifier associated with the tool call.
|
||||
index: The index of the tool call in a sequence.
|
||||
|
||||
"""
|
||||
return ToolCallChunk(
|
||||
name=name, args=args, id=id, index=index, type="tool_call_chunk"
|
||||
)
|
||||
|
||||
|
||||
class InvalidToolCall(TypedDict):
|
||||
"""Allowance for errors made by LLM.
|
||||
|
||||
Here we add an ``error`` key to surface errors made during generation
|
||||
(e.g., invalid JSON arguments.)
|
||||
|
||||
"""
|
||||
|
||||
name: Optional[str]
|
||||
"""The name of the tool to be called."""
|
||||
args: Optional[str]
|
||||
"""The arguments to the tool call."""
|
||||
id: Optional[str]
|
||||
"""An identifier associated with the tool call."""
|
||||
error: Optional[str]
|
||||
"""An error message associated with the tool call."""
|
||||
type: NotRequired[Literal["invalid_tool_call"]]
|
||||
|
||||
|
||||
def invalid_tool_call(
|
||||
*,
|
||||
name: Optional[str] = None,
|
||||
@@ -311,6 +325,7 @@ def invalid_tool_call(
|
||||
args: The arguments to the tool call.
|
||||
id: An identifier associated with the tool call.
|
||||
error: An error message associated with the tool call.
|
||||
|
||||
"""
|
||||
return InvalidToolCall(
|
||||
name=name, args=args, id=id, error=error, type="invalid_tool_call"
|
||||
|
||||
@@ -5,6 +5,7 @@ Some examples of what you can do with these functions include:
|
||||
* Convert messages to strings (serialization)
|
||||
* Convert messages from dicts to Message objects (deserialization)
|
||||
* Filter messages from a list of messages based on name, type or id etc.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -89,13 +90,13 @@ AnyMessage = Annotated[
|
||||
def get_buffer_string(
|
||||
messages: Sequence[BaseMessage], human_prefix: str = "Human", ai_prefix: str = "AI"
|
||||
) -> str:
|
||||
r"""Convert a sequence of Messages to strings and concatenate them into one string.
|
||||
r"""Convert a sequence of messages to strings and concatenate them into one string.
|
||||
|
||||
Args:
|
||||
messages: Messages to be converted to strings.
|
||||
human_prefix: The prefix to prepend to contents of HumanMessages.
|
||||
human_prefix: The prefix to prepend to contents of ``HumanMessage``s.
|
||||
Default is "Human".
|
||||
ai_prefix: THe prefix to prepend to contents of AIMessages. Default is "AI".
|
||||
ai_prefix: The prefix to prepend to contents of AIMessages. Default is ``'AI'``.
|
||||
|
||||
Returns:
|
||||
A single string concatenation of all input messages.
|
||||
@@ -174,19 +175,20 @@ def _message_from_dict(message: dict) -> BaseMessage:
|
||||
|
||||
|
||||
def messages_from_dict(messages: Sequence[dict]) -> list[BaseMessage]:
|
||||
"""Convert a sequence of messages from dicts to Message objects.
|
||||
"""Convert a sequence of messages from dicts to ``Message`` objects.
|
||||
|
||||
Args:
|
||||
messages: Sequence of messages (as dicts) to convert.
|
||||
|
||||
Returns:
|
||||
list of messages (BaseMessages).
|
||||
|
||||
"""
|
||||
return [_message_from_dict(m) for m in messages]
|
||||
|
||||
|
||||
def message_chunk_to_message(chunk: BaseMessageChunk) -> BaseMessage:
|
||||
"""Convert a message chunk to a message.
|
||||
"""Convert a message chunk to a ``Message``.
|
||||
|
||||
Args:
|
||||
chunk: Message chunk to convert.
|
||||
@@ -219,10 +221,10 @@ def _create_message_from_message_type(
|
||||
id: Optional[str] = None,
|
||||
**additional_kwargs: Any,
|
||||
) -> BaseMessage:
|
||||
"""Create a message from a message type and content string.
|
||||
"""Create a message from a ``Message`` type and content string.
|
||||
|
||||
Args:
|
||||
message_type: (str) the type of the message (e.g., "human", "ai", etc.).
|
||||
message_type: (str) the type of the message (e.g., ``'human'``, ``'ai'``, etc.).
|
||||
content: (str) the content string.
|
||||
name: (str) the name of the message. Default is None.
|
||||
tool_call_id: (str) the tool call id. Default is None.
|
||||
@@ -234,8 +236,9 @@ def _create_message_from_message_type(
|
||||
a message of the appropriate type.
|
||||
|
||||
Raises:
|
||||
ValueError: if the message type is not one of "human", "user", "ai",
|
||||
"assistant", "function", "tool", "system", or "developer".
|
||||
ValueError: if the message type is not one of ``'human'``, ``'user'``, ``'ai'``,
|
||||
``'assistant'``, ``'function'``, ``'tool'``, ``'system'``, or
|
||||
``'developer'``.
|
||||
"""
|
||||
kwargs: dict[str, Any] = {}
|
||||
if name is not None:
|
||||
@@ -298,15 +301,15 @@ def _create_message_from_message_type(
|
||||
|
||||
|
||||
def _convert_to_message(message: MessageLikeRepresentation) -> BaseMessage:
|
||||
"""Instantiate a message from a variety of message formats.
|
||||
"""Instantiate a ``Message`` from a variety of message formats.
|
||||
|
||||
The message format can be one of the following:
|
||||
|
||||
- BaseMessagePromptTemplate
|
||||
- BaseMessage
|
||||
- 2-tuple of (role string, template); e.g., ("human", "{user_input}")
|
||||
- ``BaseMessagePromptTemplate``
|
||||
- ``BaseMessage``
|
||||
- 2-tuple of (role string, template); e.g., (``'human'``, ``'{user_input}'``)
|
||||
- dict: a message dict with role and content keys
|
||||
- string: shorthand for ("human", template); e.g., "{user_input}"
|
||||
- string: shorthand for (``'human'``, template); e.g., ``'{user_input}'``
|
||||
|
||||
Args:
|
||||
message: a representation of a message in one of the supported formats.
|
||||
@@ -317,6 +320,7 @@ def _convert_to_message(message: MessageLikeRepresentation) -> BaseMessage:
|
||||
Raises:
|
||||
NotImplementedError: if the message type is not supported.
|
||||
ValueError: if the message dict does not contain the required keys.
|
||||
|
||||
"""
|
||||
if isinstance(message, BaseMessage):
|
||||
message_ = message
|
||||
@@ -362,6 +366,7 @@ def convert_to_messages(
|
||||
|
||||
Returns:
|
||||
list of messages (BaseMessages).
|
||||
|
||||
"""
|
||||
# Import here to avoid circular imports
|
||||
from langchain_core.prompt_values import PromptValue
|
||||
@@ -411,31 +416,31 @@ def filter_messages(
|
||||
exclude_ids: Optional[Sequence[str]] = None,
|
||||
exclude_tool_calls: Optional[Sequence[str] | bool] = None,
|
||||
) -> list[BaseMessage]:
|
||||
"""Filter messages based on name, type or id.
|
||||
"""Filter messages based on ``name``, ``type`` or ``id``.
|
||||
|
||||
Args:
|
||||
messages: Sequence Message-like objects to filter.
|
||||
include_names: Message names to include. Default is None.
|
||||
exclude_names: Messages names to exclude. Default is None.
|
||||
include_types: Message types to include. Can be specified as string names (e.g.
|
||||
"system", "human", "ai", ...) or as BaseMessage classes (e.g.
|
||||
SystemMessage, HumanMessage, AIMessage, ...). Default is None.
|
||||
``'system'``, ``'human'``, ``'ai'``, ...) or as ``BaseMessage`` classes (e.g.
|
||||
``SystemMessage``, ``HumanMessage``, ``AIMessage``, ...). Default is None.
|
||||
exclude_types: Message types to exclude. Can be specified as string names (e.g.
|
||||
"system", "human", "ai", ...) or as BaseMessage classes (e.g.
|
||||
SystemMessage, HumanMessage, AIMessage, ...). Default is None.
|
||||
``'system'``, ``'human'``, ``'ai'``, ...) or as ``BaseMessage`` classes (e.g.
|
||||
``SystemMessage``, ``HumanMessage``, ``AIMessage``, ...). Default is None.
|
||||
include_ids: Message IDs to include. Default is None.
|
||||
exclude_ids: Message IDs to exclude. Default is None.
|
||||
exclude_tool_calls: Tool call IDs to exclude. Default is None.
|
||||
Can be one of the following:
|
||||
- `True`: all AIMessages with tool calls and all ToolMessages will be excluded.
|
||||
- ``True``: all ``AIMessage``s with tool calls and all ``ToolMessage``s will be excluded.
|
||||
- a sequence of tool call IDs to exclude:
|
||||
- ToolMessages with the corresponding tool call ID will be excluded.
|
||||
- The `tool_calls` in the AIMessage will be updated to exclude matching tool calls.
|
||||
If all tool_calls are filtered from an AIMessage, the whole message is excluded.
|
||||
- ``ToolMessage``s with the corresponding tool call ID will be excluded.
|
||||
- The ``tool_calls`` in the AIMessage will be updated to exclude matching tool calls.
|
||||
If all ``tool_calls`` are filtered from an AIMessage, the whole message is excluded.
|
||||
|
||||
Returns:
|
||||
A list of Messages that meets at least one of the incl_* conditions and none
|
||||
of the excl_* conditions. If not incl_* conditions are specified then
|
||||
A list of Messages that meets at least one of the ``incl_*`` conditions and none
|
||||
of the ``excl_*`` conditions. If not ``incl_*`` conditions are specified then
|
||||
anything that is not explicitly excluded will be included.
|
||||
|
||||
Raises:
|
||||
@@ -536,13 +541,14 @@ def merge_message_runs(
|
||||
) -> list[BaseMessage]:
|
||||
r"""Merge consecutive Messages of the same type.
|
||||
|
||||
**NOTE**: ToolMessages are not merged, as each has a distinct tool call id that
|
||||
can't be merged.
|
||||
.. note::
|
||||
ToolMessages are not merged, as each has a distinct tool call id that can't be
|
||||
merged.
|
||||
|
||||
Args:
|
||||
messages: Sequence Message-like objects to merge.
|
||||
chunk_separator: Specify the string to be inserted between message chunks.
|
||||
Default is "\n".
|
||||
Default is ``'\n'``.
|
||||
|
||||
Returns:
|
||||
list of BaseMessages with consecutive runs of message types merged into single
|
||||
@@ -651,22 +657,22 @@ def trim_messages(
|
||||
) -> list[BaseMessage]:
|
||||
r"""Trim messages to be below a token count.
|
||||
|
||||
trim_messages can be used to reduce the size of a chat history to a specified token
|
||||
count or specified message count.
|
||||
``trim_messages`` can be used to reduce the size of a chat history to a specified
|
||||
token count or specified message count.
|
||||
|
||||
In either case, if passing the trimmed chat history back into a chat model
|
||||
directly, the resulting chat history should usually satisfy the following
|
||||
properties:
|
||||
|
||||
1. The resulting chat history should be valid. Most chat models expect that chat
|
||||
history starts with either (1) a ``HumanMessage`` or (2) a ``SystemMessage`` followed
|
||||
by a ``HumanMessage``. To achieve this, set ``start_on="human"``.
|
||||
history starts with either (1) a ``HumanMessage`` or (2) a ``SystemMessage``
|
||||
followed by a ``HumanMessage``. To achieve this, set ``start_on='human'``.
|
||||
In addition, generally a ``ToolMessage`` can only appear after an ``AIMessage``
|
||||
that involved a tool call.
|
||||
Please see the following link for more information about messages:
|
||||
https://python.langchain.com/docs/concepts/#messages
|
||||
2. It includes recent messages and drops old messages in the chat history.
|
||||
To achieve this set the ``strategy="last"``.
|
||||
To achieve this set the ``strategy='last'``.
|
||||
3. Usually, the new chat history should include the ``SystemMessage`` if it
|
||||
was present in the original chat history since the ``SystemMessage`` includes
|
||||
special instructions to the chat model. The ``SystemMessage`` is almost always
|
||||
@@ -680,65 +686,66 @@ def trim_messages(
|
||||
Args:
|
||||
messages: Sequence of Message-like objects to trim.
|
||||
max_tokens: Max token count of trimmed messages.
|
||||
token_counter: Function or llm for counting tokens in a BaseMessage or a list of
|
||||
BaseMessage. If a BaseLanguageModel is passed in then
|
||||
BaseLanguageModel.get_num_tokens_from_messages() will be used.
|
||||
Set to `len` to count the number of **messages** in the chat history.
|
||||
token_counter: Function or llm for counting tokens in a ``BaseMessage`` or a
|
||||
list of ``BaseMessage``. If a ``BaseLanguageModel`` is passed in then
|
||||
``BaseLanguageModel.get_num_tokens_from_messages()`` will be used.
|
||||
Set to ``len`` to count the number of **messages** in the chat history.
|
||||
|
||||
.. note::
|
||||
Use `count_tokens_approximately` to get fast, approximate token counts.
|
||||
This is recommended for using `trim_messages` on the hot path, where
|
||||
Use ``count_tokens_approximately`` to get fast, approximate token counts.
|
||||
This is recommended for using ``trim_messages`` on the hot path, where
|
||||
exact token counting is not necessary.
|
||||
|
||||
strategy: Strategy for trimming.
|
||||
- "first": Keep the first <= n_count tokens of the messages.
|
||||
- "last": Keep the last <= n_count tokens of the messages.
|
||||
Default is "last".
|
||||
- ``'first'``: Keep the first ``<= n_count`` tokens of the messages.
|
||||
- ``'last'``: Keep the last ``<= n_count`` tokens of the messages.
|
||||
Default is ``'last'``.
|
||||
allow_partial: Whether to split a message if only part of the message can be
|
||||
included. If ``strategy="last"`` then the last partial contents of a message
|
||||
are included. If ``strategy="first"`` then the first partial contents of a
|
||||
included. If ``strategy='last'`` then the last partial contents of a message
|
||||
are included. If ``strategy='first'`` then the first partial contents of a
|
||||
message are included.
|
||||
Default is False.
|
||||
end_on: The message type to end on. If specified then every message after the
|
||||
last occurrence of this type is ignored. If ``strategy=="last"`` then this
|
||||
last occurrence of this type is ignored. If ``strategy='last'`` then this
|
||||
is done before we attempt to get the last ``max_tokens``. If
|
||||
``strategy=="first"`` then this is done after we get the first
|
||||
``max_tokens``. Can be specified as string names (e.g. "system", "human",
|
||||
"ai", ...) or as BaseMessage classes (e.g. SystemMessage, HumanMessage,
|
||||
AIMessage, ...). Can be a single type or a list of types.
|
||||
``strategy='first'`` then this is done after we get the first
|
||||
``max_tokens``. Can be specified as string names (e.g. ``'system'``,
|
||||
``'human'``, ``'ai'``, ...) or as ``BaseMessage`` classes (e.g.
|
||||
``SystemMessage``, ``HumanMessage``, ``AIMessage``, ...). Can be a single
|
||||
type or a list of types.
|
||||
Default is None.
|
||||
start_on: The message type to start on. Should only be specified if
|
||||
``strategy="last"``. If specified then every message before
|
||||
``strategy='last'``. If specified then every message before
|
||||
the first occurrence of this type is ignored. This is done after we trim
|
||||
the initial messages to the last ``max_tokens``. Does not
|
||||
apply to a SystemMessage at index 0 if ``include_system=True``. Can be
|
||||
specified as string names (e.g. "system", "human", "ai", ...) or as
|
||||
BaseMessage classes (e.g. SystemMessage, HumanMessage, AIMessage, ...). Can
|
||||
be a single type or a list of types.
|
||||
apply to a ``SystemMessage`` at index 0 if ``include_system=True``. Can be
|
||||
specified as string names (e.g. ``'system'``, ``'human'``, ``'ai'``, ...) or
|
||||
as ``BaseMessage`` classes (e.g. ``SystemMessage``, ``HumanMessage``,
|
||||
``AIMessage``, ...). Can be a single type or a list of types.
|
||||
Default is None.
|
||||
include_system: Whether to keep the SystemMessage if there is one at index 0.
|
||||
Should only be specified if ``strategy="last"``.
|
||||
Default is False.
|
||||
text_splitter: Function or ``langchain_text_splitters.TextSplitter`` for
|
||||
splitting the string contents of a message. Only used if
|
||||
``allow_partial=True``. If ``strategy="last"`` then the last split tokens
|
||||
from a partial message will be included. if ``strategy=="first"`` then the
|
||||
``allow_partial=True``. If ``strategy='last'`` then the last split tokens
|
||||
from a partial message will be included. if ``strategy='first'`` then the
|
||||
first split tokens from a partial message will be included. Token splitter
|
||||
assumes that separators are kept, so that split contents can be directly
|
||||
concatenated to recreate the original text. Defaults to splitting on
|
||||
newlines.
|
||||
|
||||
Returns:
|
||||
list of trimmed BaseMessages.
|
||||
list of trimmed ``BaseMessage``.
|
||||
|
||||
Raises:
|
||||
ValueError: if two incompatible arguments are specified or an unrecognized
|
||||
``strategy`` is specified.
|
||||
|
||||
Example:
|
||||
Trim chat history based on token count, keeping the SystemMessage if
|
||||
present, and ensuring that the chat history starts with a HumanMessage (
|
||||
or a SystemMessage followed by a HumanMessage).
|
||||
Trim chat history based on token count, keeping the ``SystemMessage`` if
|
||||
present, and ensuring that the chat history starts with a ``HumanMessage`` (
|
||||
or a ``SystemMessage`` followed by a ``HumanMessage``).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -787,9 +794,9 @@ def trim_messages(
|
||||
HumanMessage(content='what do you call a speechless parrot'),
|
||||
]
|
||||
|
||||
Trim chat history based on the message count, keeping the SystemMessage if
|
||||
present, and ensuring that the chat history starts with a HumanMessage (
|
||||
or a SystemMessage followed by a HumanMessage).
|
||||
Trim chat history based on the message count, keeping the ``SystemMessage`` if
|
||||
present, and ensuring that the chat history starts with a ``HumanMessage`` (
|
||||
or a ``SystemMessage`` followed by a ``HumanMessage``).
|
||||
|
||||
trim_messages(
|
||||
messages,
|
||||
@@ -955,16 +962,16 @@ def convert_to_openai_messages(
|
||||
in OpenAI, Anthropic, Bedrock Converse, or VertexAI formats.
|
||||
text_format: How to format string or text block contents:
|
||||
|
||||
- "string":
|
||||
- ``'string'``:
|
||||
If a message has a string content, this is left as a string. If
|
||||
a message has content blocks that are all of type 'text', these are
|
||||
joined with a newline to make a single string. If a message has
|
||||
content blocks and at least one isn't of type 'text', then
|
||||
a message has content blocks that are all of type ``'text'``, these
|
||||
are joined with a newline to make a single string. If a message has
|
||||
content blocks and at least one isn't of type ``'text'``, then
|
||||
all blocks are left as dicts.
|
||||
- "block":
|
||||
If a message has a string content, this is turned into a list
|
||||
with a single content block of type 'text'. If a message has content
|
||||
blocks these are left as is.
|
||||
with a single content block of type ``'text'``. If a message has
|
||||
content blocks these are left as is.
|
||||
|
||||
Returns:
|
||||
The return type depends on the input type:
|
||||
|
||||
Reference in New Issue
Block a user