diff --git a/libs/core/langchain_core/agents.py b/libs/core/langchain_core/agents.py index 8ea46fb79ea..4a020a99c95 100644 --- a/libs/core/langchain_core/agents.py +++ b/libs/core/langchain_core/agents.py @@ -52,31 +52,33 @@ class AgentAction(Serializable): """The input to pass in to the Tool.""" log: str """Additional information to log about the action. - This log can be used in a few ways. First, it can be used to audit - what exactly the LLM predicted to lead to this (tool, tool_input). - Second, it can be used in future iterations to show the LLMs prior - thoughts. This is useful when (tool, tool_input) does not contain - full information about the LLM prediction (for example, any `thought` - before the tool/tool_input).""" + + This log can be used in a few ways. First, it can be used to audit what exactly the + LLM predicted to lead to this `(tool, tool_input)`. + + Second, it can be used in future iterations to show the LLMs prior thoughts. This is + useful when `(tool, tool_input)` does not contain full information about the LLM + prediction (for example, any `thought` before the tool/tool_input). + """ type: Literal["AgentAction"] = "AgentAction" # Override init to support instantiation by position for backward compat. def __init__(self, tool: str, tool_input: str | dict, log: str, **kwargs: Any): - """Create an AgentAction. + """Create an `AgentAction`. Args: tool: The name of the tool to execute. - tool_input: The input to pass in to the Tool. + tool_input: The input to pass in to the `Tool`. log: Additional information to log about the action. """ super().__init__(tool=tool, tool_input=tool_input, log=log, **kwargs) @classmethod def is_lc_serializable(cls) -> bool: - """AgentAction is serializable. + """`AgentAction` is serializable. Returns: - True + `True` """ return True @@ -98,19 +100,23 @@ class AgentAction(Serializable): class AgentActionMessageLog(AgentAction): """Representation of an action to be executed by an agent. - This is similar to AgentAction, but includes a message log consisting of - chat messages. This is useful when working with ChatModels, and is used - to reconstruct conversation history from the agent's perspective. + This is similar to `AgentAction`, but includes a message log consisting of + chat messages. + + This is useful when working with `ChatModels`, and is used to reconstruct + conversation history from the agent's perspective. """ message_log: Sequence[BaseMessage] - """Similar to log, this can be used to pass along extra - information about what exact messages were predicted by the LLM - before parsing out the (tool, tool_input). This is again useful - if (tool, tool_input) cannot be used to fully recreate the LLM - prediction, and you need that LLM prediction (for future agent iteration). + """Similar to log, this can be used to pass along extra information about what exact + messages were predicted by the LLM before parsing out the `(tool, tool_input)`. + + This is again useful if `(tool, tool_input)` cannot be used to fully recreate the + LLM prediction, and you need that LLM prediction (for future agent iteration). + Compared to `log`, this is useful when the underlying LLM is a - chat model (and therefore returns messages rather than a string).""" + chat model (and therefore returns messages rather than a string). + """ # Ignoring type because we're overriding the type from AgentAction. # And this is the correct thing to do in this case. # The type literal is used for serialization purposes. @@ -132,19 +138,22 @@ class AgentStep(Serializable): class AgentFinish(Serializable): - """Final return value of an ActionAgent. + """Final return value of an `ActionAgent`. - Agents return an AgentFinish when they have reached a stopping condition. + Agents return an `AgentFinish` when they have reached a stopping condition. """ return_values: dict """Dictionary of return values.""" log: str """Additional information to log about the return value. + This is used to pass along the full LLM prediction, not just the parsed out - return value. For example, if the full LLM prediction was - `Final Answer: 2` you may want to just return `2` as a return value, but pass - along the full string as a `log` (for debugging or observability purposes). + return value. + + For example, if the full LLM prediction was `Final Answer: 2` you may want to just + return `2` as a return value, but pass along the full string as a `log` (for + debugging or observability purposes). """ type: Literal["AgentFinish"] = "AgentFinish" @@ -154,7 +163,7 @@ class AgentFinish(Serializable): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -202,7 +211,7 @@ def _convert_agent_observation_to_messages( observation: Observation to convert to a message. Returns: - AIMessage that corresponds to the original tool invocation. + `AIMessage` that corresponds to the original tool invocation. """ if isinstance(agent_action, AgentActionMessageLog): return [_create_function_message(agent_action, observation)] @@ -225,7 +234,7 @@ def _create_function_message( observation: the result of the tool invocation. Returns: - FunctionMessage that corresponds to the original tool invocation. + `FunctionMessage` that corresponds to the original tool invocation. """ if not isinstance(observation, str): try: diff --git a/libs/core/langchain_core/documents/base.py b/libs/core/langchain_core/documents/base.py index f049a9897bc..0341c8c184e 100644 --- a/libs/core/langchain_core/documents/base.py +++ b/libs/core/langchain_core/documents/base.py @@ -114,11 +114,11 @@ class Blob(BaseMedia): data: bytes | str | None = None """Raw data associated with the `Blob`.""" mimetype: str | None = None - """MimeType not to be confused with a file extension.""" + """MIME type, not to be confused with a file extension.""" encoding: str = "utf-8" """Encoding to use if decoding the bytes into a string. - Use `utf-8` as default encoding, if decoding to string. + Uses `utf-8` as default encoding if decoding to string. """ path: PathLike | None = None """Location where the original content was found.""" @@ -134,7 +134,7 @@ class Blob(BaseMedia): If a path is associated with the `Blob`, it will default to the path location. - Unless explicitly set via a metadata field called `"source"`, in which + Unless explicitly set via a metadata field called `'source'`, in which case that value will be used instead. """ if self.metadata and "source" in self.metadata: @@ -309,7 +309,7 @@ class Document(BaseMedia): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -322,10 +322,10 @@ class Document(BaseMedia): return ["langchain", "schema", "document"] def __str__(self) -> str: - """Override __str__ to restrict it to page_content and metadata. + """Override `__str__` to restrict it to page_content and metadata. Returns: - A string representation of the Document. + A string representation of the `Document`. """ # The format matches pydantic format for __str__. # diff --git a/libs/core/langchain_core/outputs/generation.py b/libs/core/langchain_core/outputs/generation.py index c250c3173aa..5fbd9c7e1b0 100644 --- a/libs/core/langchain_core/outputs/generation.py +++ b/libs/core/langchain_core/outputs/generation.py @@ -20,8 +20,7 @@ class Generation(Serializable): LangChain users working with chat models will usually access information via `AIMessage` (returned from runnable interfaces) or `LLMResult` (available - via callbacks). Please refer the `AIMessage` and `LLMResult` schema documentation - for more information. + via callbacks). Please refer to `AIMessage` and `LLMResult` for more information. """ text: str @@ -34,11 +33,13 @@ class Generation(Serializable): """ type: Literal["Generation"] = "Generation" """Type is used exclusively for serialization purposes. - Set to "Generation" for this class.""" + + Set to "Generation" for this class. + """ @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -52,7 +53,7 @@ class Generation(Serializable): class GenerationChunk(Generation): - """Generation chunk, which can be concatenated with other Generation chunks.""" + """`GenerationChunk`, which can be concatenated with other Generation chunks.""" def __add__(self, other: GenerationChunk) -> GenerationChunk: """Concatenate two `GenerationChunk`s. diff --git a/libs/core/langchain_core/prompt_values.py b/libs/core/langchain_core/prompt_values.py index 731941514fd..cb29070fa65 100644 --- a/libs/core/langchain_core/prompt_values.py +++ b/libs/core/langchain_core/prompt_values.py @@ -30,7 +30,7 @@ class PromptValue(Serializable, ABC): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -48,7 +48,7 @@ class PromptValue(Serializable, ABC): @abstractmethod def to_messages(self) -> list[BaseMessage]: - """Return prompt as a list of Messages.""" + """Return prompt as a list of messages.""" class StringPromptValue(PromptValue): diff --git a/libs/core/langchain_core/prompts/base.py b/libs/core/langchain_core/prompts/base.py index ed322080c93..f4cd86fb5cc 100644 --- a/libs/core/langchain_core/prompts/base.py +++ b/libs/core/langchain_core/prompts/base.py @@ -46,23 +46,27 @@ class BasePromptTemplate( input_variables: list[str] """A list of the names of the variables whose values are required as inputs to the - prompt.""" + prompt. + """ optional_variables: list[str] = Field(default=[]) """A list of the names of the variables for placeholder or `MessagePlaceholder` that are optional. - These variables are auto inferred from the prompt and user need not provide them.""" + These variables are auto inferred from the prompt and user need not provide them. + """ input_types: typing.Dict[str, Any] = Field(default_factory=dict, exclude=True) # noqa: UP006 """A dictionary of the types of the variables the prompt template expects. - If not provided, all variables are assumed to be strings.""" + If not provided, all variables are assumed to be strings. + """ output_parser: BaseOutputParser | None = None """How to parse the output of calling an LLM on this formatted prompt.""" partial_variables: Mapping[str, Any] = Field(default_factory=dict) """A dictionary of the partial variables the prompt template carries. - Partial variables populate the template so that you don't need to - pass them in every time you call the prompt.""" + Partial variables populate the template so that you don't need to pass them in every + time you call the prompt. + """ metadata: typing.Dict[str, Any] | None = None # noqa: UP006 """Metadata to be used for tracing.""" tags: list[str] | None = None @@ -107,7 +111,7 @@ class BasePromptTemplate( @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True model_config = ConfigDict( @@ -129,7 +133,7 @@ class BasePromptTemplate( """Get the input schema for the prompt. Args: - config: configuration for the prompt. + config: Configuration for the prompt. Returns: The input schema for the prompt. @@ -197,8 +201,8 @@ class BasePromptTemplate( """Invoke the prompt. Args: - input: Dict, input to the prompt. - config: RunnableConfig, configuration for the prompt. + input: Input to the prompt. + config: Configuration for the prompt. Returns: The output of the prompt. @@ -223,8 +227,8 @@ class BasePromptTemplate( """Async invoke the prompt. Args: - input: Dict, input to the prompt. - config: RunnableConfig, configuration for the prompt. + input: Input to the prompt. + config: Configuration for the prompt. Returns: The output of the prompt. @@ -244,7 +248,7 @@ class BasePromptTemplate( @abstractmethod def format_prompt(self, **kwargs: Any) -> PromptValue: - """Create Prompt Value. + """Create `PromptValue`. Args: **kwargs: Any arguments to be passed to the prompt template. @@ -254,7 +258,7 @@ class BasePromptTemplate( """ async def aformat_prompt(self, **kwargs: Any) -> PromptValue: - """Async create Prompt Value. + """Async create `PromptValue`. Args: **kwargs: Any arguments to be passed to the prompt template. @@ -268,7 +272,7 @@ class BasePromptTemplate( """Return a partial of the prompt template. Args: - **kwargs: partial variables to set. + **kwargs: Partial variables to set. Returns: A partial of the prompt template. @@ -298,9 +302,9 @@ class BasePromptTemplate( A formatted string. Example: - ```python - prompt.format(variable1="foo") - ``` + ```python + prompt.format(variable1="foo") + ``` """ async def aformat(self, **kwargs: Any) -> FormatOutputType: @@ -313,9 +317,9 @@ class BasePromptTemplate( A formatted string. Example: - ```python - await prompt.aformat(variable1="foo") - ``` + ```python + await prompt.aformat(variable1="foo") + ``` """ return self.format(**kwargs) @@ -350,9 +354,9 @@ class BasePromptTemplate( NotImplementedError: If the prompt type is not implemented. Example: - ```python - prompt.save(file_path="path/prompt.yaml") - ``` + ```python + prompt.save(file_path="path/prompt.yaml") + ``` """ if self.partial_variables: msg = "Cannot save prompt with partial variables." @@ -404,23 +408,23 @@ def format_document(doc: Document, prompt: BasePromptTemplate[str]) -> str: First, this pulls information from the document from two sources: - 1. page_content: - This takes the information from the `document.page_content` - and assigns it to a variable named `page_content`. - 2. metadata: - This takes information from `document.metadata` and assigns - it to variables of the same name. + 1. `page_content`: + This takes the information from the `document.page_content` and assigns it to a + variable named `page_content`. + 2. `metadata`: + This takes information from `document.metadata` and assigns it to variables of + the same name. Those variables are then passed into the `prompt` to produce a formatted string. Args: - doc: Document, the page_content and metadata will be used to create + doc: `Document`, the `page_content` and `metadata` will be used to create the final string. - prompt: BasePromptTemplate, will be used to format the page_content - and metadata into the final string. + prompt: `BasePromptTemplate`, will be used to format the `page_content` + and `metadata` into the final string. Returns: - string of the document formatted. + String of the document formatted. Example: ```python @@ -431,7 +435,6 @@ def format_document(doc: Document, prompt: BasePromptTemplate[str]) -> str: prompt = PromptTemplate.from_template("Page {page}: {page_content}") format_document(doc, prompt) >>> "Page 1: This is a joke" - ``` """ return prompt.format(**_get_document_info(doc, prompt)) @@ -442,22 +445,22 @@ async def aformat_document(doc: Document, prompt: BasePromptTemplate[str]) -> st First, this pulls information from the document from two sources: - 1. page_content: - This takes the information from the `document.page_content` - and assigns it to a variable named `page_content`. - 2. metadata: - This takes information from `document.metadata` and assigns - it to variables of the same name. + 1. `page_content`: + This takes the information from the `document.page_content` and assigns it to a + variable named `page_content`. + 2. `metadata`: + This takes information from `document.metadata` and assigns it to variables of + the same name. Those variables are then passed into the `prompt` to produce a formatted string. Args: - doc: Document, the page_content and metadata will be used to create + doc: `Document`, the `page_content` and `metadata` will be used to create the final string. - prompt: BasePromptTemplate, will be used to format the page_content - and metadata into the final string. + prompt: `BasePromptTemplate`, will be used to format the `page_content` + and `metadata` into the final string. Returns: - string of the document formatted. + String of the document formatted. """ return await prompt.aformat(**_get_document_info(doc, prompt)) diff --git a/libs/core/langchain_core/prompts/dict.py b/libs/core/langchain_core/prompts/dict.py index b8e3a49c052..1d6f76384ed 100644 --- a/libs/core/langchain_core/prompts/dict.py +++ b/libs/core/langchain_core/prompts/dict.py @@ -69,7 +69,7 @@ class DictPromptTemplate(RunnableSerializable[dict, dict]): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod diff --git a/libs/core/langchain_core/prompts/message.py b/libs/core/langchain_core/prompts/message.py index 9ae86ab0596..bf52af49590 100644 --- a/libs/core/langchain_core/prompts/message.py +++ b/libs/core/langchain_core/prompts/message.py @@ -18,7 +18,7 @@ class BaseMessagePromptTemplate(Serializable, ABC): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -32,13 +32,13 @@ class BaseMessagePromptTemplate(Serializable, ABC): @abstractmethod def format_messages(self, **kwargs: Any) -> list[BaseMessage]: - """Format messages from kwargs. Should return a list of BaseMessages. + """Format messages from kwargs. Should return a list of `BaseMessage` objects. Args: **kwargs: Keyword arguments to use for formatting. Returns: - List of BaseMessages. + List of `BaseMessage` objects. """ async def aformat_messages(self, **kwargs: Any) -> list[BaseMessage]: @@ -48,7 +48,7 @@ class BaseMessagePromptTemplate(Serializable, ABC): **kwargs: Keyword arguments to use for formatting. Returns: - List of BaseMessages. + List of `BaseMessage` objects. """ return self.format_messages(**kwargs) diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index 733e31b68b7..e40cb275715 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -2859,7 +2859,7 @@ class RunnableSequence(RunnableSerializable[Input, Output]): name: The name of the `Runnable`. first: The first `Runnable` in the sequence. middle: The middle `Runnable` objects in the sequence. - last: The last Runnable in the sequence. + last: The last `Runnable` in the sequence. Raises: ValueError: If the sequence has less than 2 steps. @@ -2904,7 +2904,7 @@ class RunnableSequence(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True model_config = ConfigDict( @@ -3610,7 +3610,7 @@ class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -5139,7 +5139,7 @@ class RunnableEachBase(RunnableSerializable[list[Input], list[Output]]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -5322,7 +5322,7 @@ class RunnableEach(RunnableEachBase[Input, Output]): class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[no-redef] - """`Runnable` that delegates calls to another `Runnable` with a set of kwargs. + """`Runnable` that delegates calls to another `Runnable` with a set of `**kwargs`. Use only if creating a new `RunnableBinding` subclass with different `__init__` args. @@ -5462,7 +5462,7 @@ class RunnableBindingBase(RunnableSerializable[Input, Output]): # type: ignore[ @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod diff --git a/libs/core/langchain_core/runnables/branch.py b/libs/core/langchain_core/runnables/branch.py index e7d40151f11..5da2e422f15 100644 --- a/libs/core/langchain_core/runnables/branch.py +++ b/libs/core/langchain_core/runnables/branch.py @@ -38,9 +38,9 @@ from langchain_core.runnables.utils import ( class RunnableBranch(RunnableSerializable[Input, Output]): - """Runnable that selects which branch to run based on a condition. + """`Runnable` that selects which branch to run based on a condition. - The Runnable is initialized with a list of `(condition, Runnable)` pairs and + The `Runnable` is initialized with a list of `(condition, Runnable)` pairs and a default branch. When operating on an input, the first condition that evaluates to True is @@ -86,10 +86,10 @@ class RunnableBranch(RunnableSerializable[Input, Output]): Defaults a `Runnable` to run if no condition is met. Raises: - ValueError: If the number of branches is less than 2. + ValueError: If the number of branches is less than `2`. TypeError: If the default branch is not `Runnable`, `Callable` or `Mapping`. - TypeError: If a branch is not a tuple or list. - ValueError: If a branch is not of length 2. + TypeError: If a branch is not a `tuple` or `list`. + ValueError: If a branch is not of length `2`. """ if len(branches) < 2: msg = "RunnableBranch requires at least two branches" @@ -140,7 +140,7 @@ class RunnableBranch(RunnableSerializable[Input, Output]): @classmethod def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -187,12 +187,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]): def invoke( self, input: Input, config: RunnableConfig | None = None, **kwargs: Any ) -> Output: - """First evaluates the condition, then delegate to true or false branch. + """First evaluates the condition, then delegate to `True` or `False` branch. Args: - input: The input to the Runnable. - config: The configuration for the Runnable. - **kwargs: Additional keyword arguments to pass to the Runnable. + input: The input to the `Runnable`. + config: The configuration for the `Runnable`. + **kwargs: Additional keyword arguments to pass to the `Runnable`. Returns: The output of the branch that was run. @@ -297,12 +297,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]): config: RunnableConfig | None = None, **kwargs: Any | None, ) -> Iterator[Output]: - """First evaluates the condition, then delegate to true or false branch. + """First evaluates the condition, then delegate to `True` or `False` branch. Args: - input: The input to the Runnable. - config: The configuration for the Runnable. - **kwargs: Additional keyword arguments to pass to the Runnable. + input: The input to the `Runnable`. + config: The configuration for the Runna`ble. + **kwargs: Additional keyword arguments to pass to the `Runnable`. Yields: The output of the branch that was run. @@ -381,12 +381,12 @@ class RunnableBranch(RunnableSerializable[Input, Output]): config: RunnableConfig | None = None, **kwargs: Any | None, ) -> AsyncIterator[Output]: - """First evaluates the condition, then delegate to true or false branch. + """First evaluates the condition, then delegate to `True` or `False` branch. Args: - input: The input to the Runnable. - config: The configuration for the Runnable. - **kwargs: Additional keyword arguments to pass to the Runnable. + input: The input to the `Runnable`. + config: The configuration for the `Runnable`. + **kwargs: Additional keyword arguments to pass to the `Runnable`. Yields: The output of the branch that was run. diff --git a/libs/core/langchain_core/runnables/configurable.py b/libs/core/langchain_core/runnables/configurable.py index 693c68b7f37..5552fa620ea 100644 --- a/libs/core/langchain_core/runnables/configurable.py +++ b/libs/core/langchain_core/runnables/configurable.py @@ -1,4 +1,4 @@ -"""Runnables that can be dynamically configured.""" +"""`Runnable` objects that can be dynamically configured.""" from __future__ import annotations @@ -47,14 +47,14 @@ if TYPE_CHECKING: class DynamicRunnable(RunnableSerializable[Input, Output]): - """Serializable Runnable that can be dynamically configured. + """Serializable `Runnable` that can be dynamically configured. - A DynamicRunnable should be initiated using the `configurable_fields` or - `configurable_alternatives` method of a Runnable. + A `DynamicRunnable` should be initiated using the `configurable_fields` or + `configurable_alternatives` method of a `Runnable`. """ default: RunnableSerializable[Input, Output] - """The default Runnable to use.""" + """The default `Runnable` to use.""" config: RunnableConfig | None = None """The configuration to use.""" @@ -66,7 +66,7 @@ class DynamicRunnable(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -120,13 +120,13 @@ class DynamicRunnable(RunnableSerializable[Input, Output]): def prepare( self, config: RunnableConfig | None = None ) -> tuple[Runnable[Input, Output], RunnableConfig]: - """Prepare the Runnable for invocation. + """Prepare the `Runnable` for invocation. Args: config: The configuration to use. Returns: - The prepared Runnable and configuration. + The prepared `Runnable` and configuration. """ runnable: Runnable[Input, Output] = self while isinstance(runnable, DynamicRunnable): @@ -316,12 +316,12 @@ class DynamicRunnable(RunnableSerializable[Input, Output]): class RunnableConfigurableFields(DynamicRunnable[Input, Output]): - """Runnable that can be dynamically configured. + """`Runnable` that can be dynamically configured. - A RunnableConfigurableFields should be initiated using the - `configurable_fields` method of a Runnable. + A `RunnableConfigurableFields` should be initiated using the + `configurable_fields` method of a `Runnable`. - Here is an example of using a RunnableConfigurableFields with LLMs: + Here is an example of using a `RunnableConfigurableFields` with LLMs: ```python from langchain_core.prompts import PromptTemplate @@ -348,7 +348,7 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]): chain.invoke({"x": 0}, config={"configurable": {"temperature": 0.9}}) ``` - Here is an example of using a RunnableConfigurableFields with HubRunnables: + Here is an example of using a `RunnableConfigurableFields` with `HubRunnables`: ```python from langchain_core.prompts import PromptTemplate @@ -380,7 +380,7 @@ class RunnableConfigurableFields(DynamicRunnable[Input, Output]): @property def config_specs(self) -> list[ConfigurableFieldSpec]: - """Get the configuration specs for the RunnableConfigurableFields. + """Get the configuration specs for the `RunnableConfigurableFields`. Returns: The configuration specs. @@ -473,10 +473,10 @@ _enums_for_spec_lock = threading.Lock() class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): - """Runnable that can be dynamically configured. + """`Runnable` that can be dynamically configured. A `RunnableConfigurableAlternatives` should be initiated using the - `configurable_alternatives` method of a Runnable or can be + `configurable_alternatives` method of a `Runnable` or can be initiated directly as well. Here is an example of using a `RunnableConfigurableAlternatives` that uses @@ -531,7 +531,7 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): """ which: ConfigurableField - """The ConfigurableField to use to choose between alternatives.""" + """The `ConfigurableField` to use to choose between alternatives.""" alternatives: dict[ str, @@ -544,8 +544,9 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): prefix_keys: bool """Whether to prefix configurable fields of each alternative with a namespace - of the form ==, eg. a key named "temperature" used by - the alternative named "gpt3" becomes "model==gpt3/temperature".""" + of the form ==, e.g. a key named "temperature" used by + the alternative named "gpt3" becomes "model==gpt3/temperature". + """ @property @override @@ -638,24 +639,24 @@ class RunnableConfigurableAlternatives(DynamicRunnable[Input, Output]): def _strremoveprefix(s: str, prefix: str) -> str: - """str.removeprefix() is only available in Python 3.9+.""" + """`str.removeprefix()` is only available in Python 3.9+.""" return s.replace(prefix, "", 1) if s.startswith(prefix) else s def prefix_config_spec( spec: ConfigurableFieldSpec, prefix: str ) -> ConfigurableFieldSpec: - """Prefix the id of a ConfigurableFieldSpec. + """Prefix the id of a `ConfigurableFieldSpec`. - This is useful when a RunnableConfigurableAlternatives is used as a - ConfigurableField of another RunnableConfigurableAlternatives. + This is useful when a `RunnableConfigurableAlternatives` is used as a + `ConfigurableField` of another `RunnableConfigurableAlternatives`. Args: - spec: The ConfigurableFieldSpec to prefix. + spec: The `ConfigurableFieldSpec` to prefix. prefix: The prefix to add. Returns: - The prefixed ConfigurableFieldSpec. + The prefixed `ConfigurableFieldSpec`. """ return ( ConfigurableFieldSpec( @@ -677,15 +678,15 @@ def make_options_spec( ) -> ConfigurableFieldSpec: """Make options spec. - Make a ConfigurableFieldSpec for a ConfigurableFieldSingleOption or - ConfigurableFieldMultiOption. + Make a `ConfigurableFieldSpec` for a `ConfigurableFieldSingleOption` or + `ConfigurableFieldMultiOption`. Args: - spec: The ConfigurableFieldSingleOption or ConfigurableFieldMultiOption. + spec: The `ConfigurableFieldSingleOption` or `ConfigurableFieldMultiOption`. description: The description to use if the spec does not have one. Returns: - The ConfigurableFieldSpec. + The `ConfigurableFieldSpec`. """ with _enums_for_spec_lock: if enum := _enums_for_spec.get(spec): diff --git a/libs/core/langchain_core/runnables/fallbacks.py b/libs/core/langchain_core/runnables/fallbacks.py index 9de53995d83..0584d64e60c 100644 --- a/libs/core/langchain_core/runnables/fallbacks.py +++ b/libs/core/langchain_core/runnables/fallbacks.py @@ -35,20 +35,20 @@ if TYPE_CHECKING: class RunnableWithFallbacks(RunnableSerializable[Input, Output]): - """Runnable that can fallback to other Runnables if it fails. + """`Runnable` that can fallback to other `Runnable`s if it fails. External APIs (e.g., APIs for a language model) may at times experience degraded performance or even downtime. - In these cases, it can be useful to have a fallback Runnable that can be - used in place of the original Runnable (e.g., fallback to another LLM provider). + In these cases, it can be useful to have a fallback `Runnable` that can be + used in place of the original `Runnable` (e.g., fallback to another LLM provider). - Fallbacks can be defined at the level of a single Runnable, or at the level - of a chain of Runnables. Fallbacks are tried in order until one succeeds or + Fallbacks can be defined at the level of a single `Runnable`, or at the level + of a chain of `Runnable`s. Fallbacks are tried in order until one succeeds or all fail. While you can instantiate a `RunnableWithFallbacks` directly, it is usually - more convenient to use the `with_fallbacks` method on a Runnable. + more convenient to use the `with_fallbacks` method on a `Runnable`. Example: ```python @@ -87,7 +87,7 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): """ runnable: Runnable[Input, Output] - """The Runnable to run first.""" + """The `Runnable` to run first.""" fallbacks: Sequence[Runnable[Input, Output]] """A sequence of fallbacks to try.""" exceptions_to_handle: tuple[type[BaseException], ...] = (Exception,) @@ -97,9 +97,12 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): """ exception_key: str | None = None """If `string` is specified then handled exceptions will be passed to fallbacks as - part of the input under the specified key. If `None`, exceptions - will not be passed to fallbacks. If used, the base Runnable and its fallbacks - must accept a dictionary as input.""" + part of the input under the specified key. + + If `None`, exceptions will not be passed to fallbacks. + + If used, the base `Runnable` and its fallbacks must accept a dictionary as input. + """ model_config = ConfigDict( arbitrary_types_allowed=True, @@ -137,7 +140,7 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -152,10 +155,10 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): @property def runnables(self) -> Iterator[Runnable[Input, Output]]: - """Iterator over the Runnable and its fallbacks. + """Iterator over the `Runnable` and its fallbacks. Yields: - The Runnable then its fallbacks. + The `Runnable` then its fallbacks. """ yield self.runnable yield from self.fallbacks @@ -589,14 +592,14 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): await run_manager.on_chain_end(output) def __getattr__(self, name: str) -> Any: - """Get an attribute from the wrapped Runnable and its fallbacks. + """Get an attribute from the wrapped `Runnable` and its fallbacks. Returns: - If the attribute is anything other than a method that outputs a Runnable, - returns getattr(self.runnable, name). If the attribute is a method that - does return a new Runnable (e.g. model.bind_tools([...]) outputs a new - RunnableBinding) then self.runnable and each of the runnables in - self.fallbacks is replaced with getattr(x, name). + If the attribute is anything other than a method that outputs a `Runnable`, + returns `getattr(self.runnable, name)`. If the attribute is a method that + does return a new `Runnable` (e.g. `model.bind_tools([...])` outputs a new + `RunnableBinding`) then `self.runnable` and each of the runnables in + `self.fallbacks` is replaced with `getattr(x, name)`. Example: ```python @@ -618,7 +621,6 @@ class RunnableWithFallbacks(RunnableSerializable[Input, Output]): runnable=RunnableBinding(bound=ChatOpenAI(...), kwargs={"tools": [...]}), fallbacks=[RunnableBinding(bound=ChatAnthropic(...), kwargs={"tools": [...]})], ) - ``` """ # noqa: E501 attr = getattr(self.runnable, name) diff --git a/libs/core/langchain_core/runnables/history.py b/libs/core/langchain_core/runnables/history.py index bfe1ab34de4..aed93030563 100644 --- a/libs/core/langchain_core/runnables/history.py +++ b/libs/core/langchain_core/runnables/history.py @@ -36,23 +36,23 @@ GetSessionHistoryCallable = Callable[..., BaseChatMessageHistory] class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] - """Runnable that manages chat message history for another Runnable. + """`Runnable` that manages chat message history for another `Runnable`. A chat message history is a sequence of messages that represent a conversation. - RunnableWithMessageHistory wraps another Runnable and manages the chat message + `RunnableWithMessageHistory` wraps another `Runnable` and manages the chat message history for it; it is responsible for reading and updating the chat message history. - The formats supported for the inputs and outputs of the wrapped Runnable + The formats supported for the inputs and outputs of the wrapped `Runnable` are described below. - RunnableWithMessageHistory must always be called with a config that contains + `RunnableWithMessageHistory` must always be called with a config that contains the appropriate parameters for the chat message history factory. - By default, the Runnable is expected to take a single configuration parameter + By default, the `Runnable` is expected to take a single configuration parameter called `session_id` which is a string. This parameter is used to create a new - or look up an existing chat message history that matches the given session_id. + or look up an existing chat message history that matches the given `session_id`. In this case, the invocation would look like this: @@ -117,7 +117,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] ``` - Example where the wrapped Runnable takes a dictionary input: + Example where the wrapped `Runnable` takes a dictionary input: ```python from typing import Optional @@ -166,7 +166,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] print(store) # noqa: T201 ``` - Example where the session factory takes two keys, user_id and conversation id): + Example where the session factory takes two keys (`user_id` and `conversation_id`): ```python store = {} @@ -223,21 +223,28 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] """ get_session_history: GetSessionHistoryCallable - """Function that returns a new BaseChatMessageHistory. + """Function that returns a new `BaseChatMessageHistory`. + This function should either take a single positional argument `session_id` of type - string and return a corresponding chat message history instance""" + string and return a corresponding chat message history instance + """ input_messages_key: str | None = None - """Must be specified if the base runnable accepts a dict as input. - The key in the input dict that contains the messages.""" + """Must be specified if the base `Runnable` accepts a `dict` as input. + The key in the input `dict` that contains the messages. + """ output_messages_key: str | None = None - """Must be specified if the base Runnable returns a dict as output. - The key in the output dict that contains the messages.""" + """Must be specified if the base `Runnable` returns a `dict` as output. + The key in the output `dict` that contains the messages. + """ history_messages_key: str | None = None - """Must be specified if the base runnable accepts a dict as input and expects a - separate key for historical messages.""" + """Must be specified if the base `Runnable` accepts a `dict` as input and expects a + separate key for historical messages. + """ history_factory_config: Sequence[ConfigurableFieldSpec] """Configure fields that should be passed to the chat history factory. - See `ConfigurableFieldSpec` for more details.""" + + See `ConfigurableFieldSpec` for more details. + """ def __init__( self, @@ -254,15 +261,16 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] history_factory_config: Sequence[ConfigurableFieldSpec] | None = None, **kwargs: Any, ) -> None: - """Initialize RunnableWithMessageHistory. + """Initialize `RunnableWithMessageHistory`. Args: - runnable: The base Runnable to be wrapped. + runnable: The base `Runnable` to be wrapped. + Must take as input one of: 1. A list of `BaseMessage` - 2. A dict with one key for all messages - 3. A dict with one key for the current input string/message(s) and + 2. A `dict` with one key for all messages + 3. A `dict` with one key for the current input string/message(s) and a separate key for historical messages. If the input key points to a string, it will be treated as a `HumanMessage` in history. @@ -270,13 +278,15 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] 1. A string which can be treated as an `AIMessage` 2. A `BaseMessage` or sequence of `BaseMessage` - 3. A dict with a key for a `BaseMessage` or sequence of + 3. A `dict` with a key for a `BaseMessage` or sequence of `BaseMessage` - get_session_history: Function that returns a new BaseChatMessageHistory. + get_session_history: Function that returns a new `BaseChatMessageHistory`. + This function should either take a single positional argument `session_id` of type string and return a corresponding chat message history instance. + ```python def get_session_history( session_id: str, *, user_id: str | None = None @@ -295,16 +305,17 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] ) -> BaseChatMessageHistory: ... ``` - input_messages_key: Must be specified if the base runnable accepts a dict + input_messages_key: Must be specified if the base runnable accepts a `dict` as input. - output_messages_key: Must be specified if the base runnable returns a dict + output_messages_key: Must be specified if the base runnable returns a `dict` as output. - history_messages_key: Must be specified if the base runnable accepts a dict - as input and expects a separate key for historical messages. + history_messages_key: Must be specified if the base runnable accepts a + `dict` as input and expects a separate key for historical messages. history_factory_config: Configure fields that should be passed to the chat history factory. See `ConfigurableFieldSpec` for more details. - Specifying these allows you to pass multiple config keys - into the get_session_history factory. + + Specifying these allows you to pass multiple config keys into the + `get_session_history` factory. **kwargs: Arbitrary additional kwargs to pass to parent class `RunnableBindingBase` init. @@ -364,7 +375,7 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] @property @override def config_specs(self) -> list[ConfigurableFieldSpec]: - """Get the configuration specs for the RunnableWithMessageHistory.""" + """Get the configuration specs for the `RunnableWithMessageHistory`.""" return get_unique_config_specs( super().config_specs + list(self.history_factory_config) ) @@ -606,6 +617,6 @@ class RunnableWithMessageHistory(RunnableBindingBase): # type: ignore[no-redef] def _get_parameter_names(callable_: GetSessionHistoryCallable) -> list[str]: - """Get the parameter names of the callable.""" + """Get the parameter names of the `Callable`.""" sig = inspect.signature(callable_) return list(sig.parameters.keys()) diff --git a/libs/core/langchain_core/runnables/passthrough.py b/libs/core/langchain_core/runnables/passthrough.py index 329e3a17484..69264d33647 100644 --- a/libs/core/langchain_core/runnables/passthrough.py +++ b/libs/core/langchain_core/runnables/passthrough.py @@ -51,10 +51,10 @@ def identity(x: Other) -> Other: """Identity function. Args: - x: input. + x: Input. Returns: - output. + Output. """ return x @@ -63,10 +63,10 @@ async def aidentity(x: Other) -> Other: """Async identity function. Args: - x: input. + x: Input. Returns: - output. + Output. """ return x @@ -74,11 +74,11 @@ async def aidentity(x: Other) -> Other: class RunnablePassthrough(RunnableSerializable[Other, Other]): """Runnable to passthrough inputs unchanged or with additional keys. - This Runnable behaves almost like the identity function, except that it + This `Runnable` behaves almost like the identity function, except that it can be configured to add additional keys to the output, if the input is a dict. - The examples below demonstrate this Runnable works using a few simple + The examples below demonstrate this `Runnable` works using a few simple chains. The chains rely on simple lambdas to make the examples easy to execute and experiment with. @@ -164,7 +164,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): input_type: type[Other] | None = None, **kwargs: Any, ) -> None: - """Create e RunnablePassthrough. + """Create a `RunnablePassthrough`. Args: func: Function to be called with the input. @@ -180,7 +180,7 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -213,11 +213,11 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]): """Merge the Dict input with the output produced by the mapping argument. Args: - **kwargs: Runnable, Callable or a Mapping from keys to Runnables - or Callables. + **kwargs: `Runnable`, `Callable` or a `Mapping` from keys to `Runnable` + objects or `Callable`s. Returns: - A Runnable that merges the Dict input with the output produced by the + A `Runnable` that merges the `dict` input with the output produced by the mapping argument. """ return RunnableAssign(RunnableParallel[dict[str, Any]](kwargs)) @@ -350,7 +350,7 @@ _graph_passthrough: RunnablePassthrough = RunnablePassthrough() class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): - """Runnable that assigns key-value pairs to dict[str, Any] inputs. + """Runnable that assigns key-value pairs to `dict[str, Any]` inputs. The `RunnableAssign` class takes input dictionaries and, through a `RunnableParallel` instance, applies transformations, then combines @@ -392,7 +392,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): mapper: RunnableParallel def __init__(self, mapper: RunnableParallel[dict[str, Any]], **kwargs: Any) -> None: - """Create a RunnableAssign. + """Create a `RunnableAssign`. Args: mapper: A `RunnableParallel` instance that will be used to transform the @@ -403,7 +403,7 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod @@ -669,9 +669,9 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]): class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): - """Runnable that picks keys from dict[str, Any] inputs. + """`Runnable` that picks keys from `dict[str, Any]` inputs. - RunnablePick class represents a Runnable that selectively picks keys from a + `RunnablePick` class represents a `Runnable` that selectively picks keys from a dictionary input. It allows you to specify one or more keys to extract from the input dictionary. It returns a new dictionary containing only the selected keys. @@ -698,7 +698,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): keys: str | list[str] def __init__(self, keys: str | list[str], **kwargs: Any) -> None: - """Create a RunnablePick. + """Create a `RunnablePick`. Args: keys: A single key or a list of keys to pick from the input dictionary. @@ -708,7 +708,7 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod diff --git a/libs/core/langchain_core/runnables/router.py b/libs/core/langchain_core/runnables/router.py index e32c21519b4..d9b4d44b8c3 100644 --- a/libs/core/langchain_core/runnables/router.py +++ b/libs/core/langchain_core/runnables/router.py @@ -40,11 +40,11 @@ class RouterInput(TypedDict): key: str """The key to route on.""" input: Any - """The input to pass to the selected Runnable.""" + """The input to pass to the selected `Runnable`.""" class RouterRunnable(RunnableSerializable[RouterInput, Output]): - """Runnable that routes to a set of Runnables based on Input['key']. + """`Runnable` that routes to a set of `Runnable` based on `Input['key']`. Returns the output of the selected Runnable. @@ -74,10 +74,10 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]): self, runnables: Mapping[str, Runnable[Any, Output] | Callable[[Any], Output]], ) -> None: - """Create a RouterRunnable. + """Create a `RouterRunnable`. Args: - runnables: A mapping of keys to Runnables. + runnables: A mapping of keys to `Runnable` objects. """ super().__init__( runnables={key: coerce_to_runnable(r) for key, r in runnables.items()} @@ -90,7 +90,7 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]): @classmethod @override def is_lc_serializable(cls) -> bool: - """Return True as this class is serializable.""" + """Return `True` as this class is serializable.""" return True @classmethod diff --git a/libs/langchain/langchain_classic/chains/combine_documents/reduce.py b/libs/langchain/langchain_classic/chains/combine_documents/reduce.py index 6f546702dae..c90eae53ee6 100644 --- a/libs/langchain/langchain_classic/chains/combine_documents/reduce.py +++ b/libs/langchain/langchain_classic/chains/combine_documents/reduce.py @@ -33,17 +33,18 @@ def split_list_of_docs( token_max: int, **kwargs: Any, ) -> list[list[Document]]: - """Split Documents into subsets that each meet a cumulative length constraint. + """Split `Document` objects to subsets that each meet a cumulative len. constraint. Args: - docs: The full list of Documents. - length_func: Function for computing the cumulative length of a set of Documents. - token_max: The maximum cumulative length of any subset of Documents. + docs: The full list of `Document` objects. + length_func: Function for computing the cumulative length of a set of `Document` + objects. + token_max: The maximum cumulative length of any subset of `Document` objects. **kwargs: Arbitrary additional keyword params to pass to each call of the - length_func. + `length_func`. Returns: - A List[List[Document]]. + A `list[list[Document]]`. """ new_result_doc_list = [] _sub_result_docs = [] @@ -71,18 +72,18 @@ def collapse_docs( """Execute a collapse function on a set of documents and merge their metadatas. Args: - docs: A list of Documents to combine. - combine_document_func: A function that takes in a list of Documents and + docs: A list of `Document` objects to combine. + combine_document_func: A function that takes in a list of `Document` objects and optionally addition keyword parameters and combines them into a single string. **kwargs: Arbitrary additional keyword params to pass to the - combine_document_func. + `combine_document_func`. Returns: - A single Document with the output of combine_document_func for the page content - and the combined metadata's of all the input documents. All metadata values - are strings, and where there are overlapping keys across documents the - values are joined by ", ". + A single `Document` with the output of `combine_document_func` for the page + content and the combined metadata's of all the input documents. All metadata + values are strings, and where there are overlapping keys across documents + the values are joined by `', '`. """ result = combine_document_func(docs, **kwargs) combined_metadata = {k: str(v) for k, v in docs[0].metadata.items()} @@ -103,18 +104,18 @@ async def acollapse_docs( """Execute a collapse function on a set of documents and merge their metadatas. Args: - docs: A list of Documents to combine. - combine_document_func: A function that takes in a list of Documents and + docs: A list of `Document` objects to combine. + combine_document_func: A function that takes in a list of `Document` objects and optionally addition keyword parameters and combines them into a single string. **kwargs: Arbitrary additional keyword params to pass to the - combine_document_func. + `combine_document_func`. Returns: - A single Document with the output of combine_document_func for the page content - and the combined metadata's of all the input documents. All metadata values - are strings, and where there are overlapping keys across documents the - values are joined by ", ". + A single `Document` with the output of `combine_document_func` for the page + content and the combined metadata's of all the input documents. All metadata + values are strings, and where there are overlapping keys across documents + the values are joined by `', '`. """ result = await combine_document_func(docs, **kwargs) combined_metadata = {k: str(v) for k, v in docs[0].metadata.items()} @@ -141,11 +142,11 @@ class ReduceDocumentsChain(BaseCombineDocumentsChain): This involves - - combine_documents_chain - - - collapse_documents_chain + - `combine_documents_chain` + - `collapse_documents_chain` `combine_documents_chain` is ALWAYS provided. This is final chain that is called. + We pass all previous results to this chain, and the output of this chain is returned as a final result. @@ -203,19 +204,28 @@ class ReduceDocumentsChain(BaseCombineDocumentsChain): combine_documents_chain: BaseCombineDocumentsChain """Final chain to call to combine documents. - This is typically a StuffDocumentsChain.""" + + This is typically a `StuffDocumentsChain`. + """ collapse_documents_chain: BaseCombineDocumentsChain | None = None """Chain to use to collapse documents if needed until they can all fit. - If `None`, will use the combine_documents_chain. - This is typically a StuffDocumentsChain.""" + If `None`, will use the `combine_documents_chain`. + + This is typically a `StuffDocumentsChain`. + """ token_max: int = 3000 - """The maximum number of tokens to group documents into. For example, if - set to 3000 then documents will be grouped into chunks of no greater than - 3000 tokens before trying to combine them into a smaller chunk.""" + """The maximum number of tokens to group documents into. + + For example, if set to 3000 then documents will be grouped into chunks of no greater + than 3000 tokens before trying to combine them into a smaller chunk. + """ collapse_max_retries: int | None = None - """The maximum number of retries to collapse documents to fit token_max. - If `None`, it will keep trying to collapse documents to fit token_max. - Otherwise, after it reaches the max number, it will throw an error""" + """The maximum number of retries to collapse documents to fit `token_max`. + + If `None`, it will keep trying to collapse documents to fit `token_max`. + + Otherwise, after it reaches the max number, it will throw an error. + """ model_config = ConfigDict( arbitrary_types_allowed=True, @@ -248,7 +258,7 @@ class ReduceDocumentsChain(BaseCombineDocumentsChain): Returns: The first element returned is the single string output. The second - element returned is a dictionary of other keys to return. + element returned is a dictionary of other keys to return. """ result_docs, _ = self._collapse( docs, @@ -282,7 +292,7 @@ class ReduceDocumentsChain(BaseCombineDocumentsChain): Returns: The first element returned is the single string output. The second - element returned is a dictionary of other keys to return. + element returned is a dictionary of other keys to return. """ result_docs, _ = await self._acollapse( docs, diff --git a/libs/langchain/langchain_classic/chains/conversational_retrieval/base.py b/libs/langchain/langchain_classic/chains/conversational_retrieval/base.py index f327a9d407a..64c30ead607 100644 --- a/libs/langchain/langchain_classic/chains/conversational_retrieval/base.py +++ b/libs/langchain/langchain_classic/chains/conversational_retrieval/base.py @@ -337,17 +337,17 @@ class ConversationalRetrievalChain(BaseConversationalRetrievalChain): The algorithm for this chain consists of three parts: 1. Use the chat history and the new question to create a "standalone question". - This is done so that this question can be passed into the retrieval step to fetch - relevant documents. If only the new question was passed in, then relevant context - may be lacking. If the whole conversation was passed into retrieval, there may - be unnecessary information there that would distract from retrieval. + This is done so that this question can be passed into the retrieval step to + fetch relevant documents. If only the new question was passed in, then relevant + context may be lacking. If the whole conversation was passed into retrieval, + there may be unnecessary information there that would distract from retrieval. 2. This new question is passed to the retriever and relevant documents are - returned. + returned. 3. The retrieved documents are passed to an LLM along with either the new question - (default behavior) or the original question and chat history to generate a final - response. + (default behavior) or the original question and chat history to generate a final + response. Example: ```python diff --git a/libs/langchain/langchain_classic/chains/history_aware_retriever.py b/libs/langchain/langchain_classic/chains/history_aware_retriever.py index 9d193adf52e..3d14b5ad286 100644 --- a/libs/langchain/langchain_classic/chains/history_aware_retriever.py +++ b/libs/langchain/langchain_classic/chains/history_aware_retriever.py @@ -20,14 +20,14 @@ def create_history_aware_retriever( Args: llm: Language model to use for generating a search term given chat history - retriever: RetrieverLike object that takes a string as input and outputs - a list of Documents. + retriever: `RetrieverLike` object that takes a string as input and outputs + a list of `Document` objects. prompt: The prompt used to generate the search query for the retriever. Returns: An LCEL Runnable. The runnable input must take in `input`, and if there is chat history should take it in the form of `chat_history`. - The Runnable output is a list of Documents + The `Runnable` output is a list of `Document` objects Example: ```python diff --git a/libs/partners/chroma/langchain_chroma/vectorstores.py b/libs/partners/chroma/langchain_chroma/vectorstores.py index e100743a7f5..106c5451f7d 100644 --- a/libs/partners/chroma/langchain_chroma/vectorstores.py +++ b/libs/partners/chroma/langchain_chroma/vectorstores.py @@ -1142,7 +1142,7 @@ class Chroma(VectorStore): ids: List of ids to retrieve. Returns: - List of Documents. + List of `Document` objects. !!! version-added "Added in 0.2.1" """ diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index 7b11cd29219..0447f49366d 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -3601,7 +3601,8 @@ def _get_last_messages( ) -> tuple[Sequence[BaseMessage], str | None]: """Get the last part of the conversation after the last `AIMessage` with an `id`. - Return: + Will return: + 1. Every message after the most-recent `AIMessage` that has a non-empty `response_metadata["id"]` (may be an empty list), 2. That `id`. diff --git a/libs/partners/xai/tests/integration_tests/test_chat_models.py b/libs/partners/xai/tests/integration_tests/test_chat_models.py index 049f51e59bc..72d17fc9d19 100644 --- a/libs/partners/xai/tests/integration_tests/test_chat_models.py +++ b/libs/partners/xai/tests/integration_tests/test_chat_models.py @@ -16,8 +16,9 @@ MODEL_NAME = "grok-4-fast-reasoning" def test_reasoning(output_version: Literal["", "v1"]) -> None: """Test reasoning features. - Note: `grok-4` does not return `reasoning_content`, but may optionally return - encrypted reasoning content if `use_encrypted_content` is set to True. + !!! note + `grok-4` does not return `reasoning_content`, but may optionally return + encrypted reasoning content if `use_encrypted_content` is set to `True`. """ # Test reasoning effort if output_version: diff --git a/libs/standard-tests/langchain_tests/integration_tests/base_store.py b/libs/standard-tests/langchain_tests/integration_tests/base_store.py index f4b64c59c7a..391433925e5 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/base_store.py +++ b/libs/standard-tests/langchain_tests/integration_tests/base_store.py @@ -1,6 +1,7 @@ -"""Standard tests for the BaseStore abstraction. +"""Standard tests for the `BaseStore` abstraction. -We don't recommend implementing externally managed BaseStore abstractions at this time. +We don't recommend implementing externally managed `BaseStore` abstractions at this +time. """ from abc import abstractmethod @@ -16,9 +17,9 @@ V = TypeVar("V") class BaseStoreSyncTests(BaseStandardTests, Generic[V]): - """Test suite for checking the key-value API of a BaseStore. + """Test suite for checking the key-value API of a `BaseStore`. - This test suite verifies the basic key-value API of a BaseStore. + This test suite verifies the basic key-value API of a `BaseStore`. The test suite is designed for synchronous key-value stores. @@ -162,9 +163,9 @@ class BaseStoreSyncTests(BaseStandardTests, Generic[V]): class BaseStoreAsyncTests(BaseStandardTests, Generic[V]): - """Test suite for checking the key-value API of a BaseStore. + """Test suite for checking the key-value API of a `BaseStore`. - This test suite verifies the basic key-value API of a BaseStore. + This test suite verifies the basic key-value API of a `BaseStore`. The test suite is designed for synchronous key-value stores. diff --git a/libs/standard-tests/langchain_tests/integration_tests/cache.py b/libs/standard-tests/langchain_tests/integration_tests/cache.py index ea2b6a3ff60..9bb5343aa7b 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/cache.py +++ b/libs/standard-tests/langchain_tests/integration_tests/cache.py @@ -1,6 +1,7 @@ -"""Standard tests for the BaseCache abstraction. +"""Standard tests for the `BaseCache` abstraction. -We don't recommend implementing externally managed BaseCache abstractions at this time. +We don't recommend implementing externally managed `BaseCache` abstractions at this +time. """ from abc import abstractmethod @@ -13,7 +14,7 @@ from langchain_tests.base import BaseStandardTests class SyncCacheTestSuite(BaseStandardTests): - """Test suite for checking the BaseCache API of a caching layer for LLMs. + """Test suite for checking the `BaseCache` API of a caching layer for LLMs. This test suite verifies the basic caching API of a caching layer for LLMs. @@ -106,9 +107,9 @@ class SyncCacheTestSuite(BaseStandardTests): class AsyncCacheTestSuite(BaseStandardTests): - """Test suite for checking the BaseCache API of a caching layer for LLMs. + """Test suite for checking the `BaseCache` API of a caching layer for LLMs. - This test suite verifies the basic caching API of a caching layer for LLMs. + Verifies the basic caching API of a caching layer for LLMs. The test suite is designed for synchronous caching layers. diff --git a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py index 332237349ff..90ea6f7e5f9 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py @@ -292,7 +292,9 @@ class ChatModelIntegrationTests(ChatModelTests): ??? info "`structured_output_kwargs`" Dict property that can be used to specify additional kwargs for - `with_structured_output`. Useful for testing different models. + `with_structured_output`. + + Useful for testing different models. ```python @property @@ -436,7 +438,9 @@ class ChatModelIntegrationTests(ChatModelTests): Boolean property indicating whether the chat model supports image inputs. - Defaults to `False`. No current tests are written for this feature. + Defaults to `False`. + + No current tests are written for this feature. ??? info "`returns_usage_metadata`" @@ -504,7 +508,7 @@ class ChatModelIntegrationTests(ChatModelTests): ) ``` - as well as the LangChain `ImageContentBlock` format: + ...as well as the LangChain `ImageContentBlock` format: ```python ToolMessage( @@ -688,7 +692,7 @@ class ChatModelIntegrationTests(ChatModelTests): gunzip -k /path/to/tests/cassettes/TestClass_test.yaml.gz ``` - or by using the serializer: + ...or by using the serializer: ```python from langchain_tests.conftest import ( @@ -766,7 +770,7 @@ class ChatModelIntegrationTests(ChatModelTests): because `ainvoke` has a default implementation that calls `invoke` in an async context. - If that test passes but not this one, you should make sure your _agenerate + If that test passes but not this one, you should make sure your `_agenerate` method does not raise any exceptions, and that it returns a valid `langchain_core.outputs.chat_result.ChatResult` like so: @@ -876,7 +880,7 @@ class ChatModelIntegrationTests(ChatModelTests): If that test passes but not this one, you should make sure your `batch` method does not raise any exceptions, and that it returns a list of valid - `langchain_core.messages.AIMessage` objects. + `AIMessage` objects. """ batch_results = model.batch(["Hello", "Hey"]) @@ -906,7 +910,7 @@ class ChatModelIntegrationTests(ChatModelTests): If those tests pass but not this one, you should make sure your `abatch` method does not raise any exceptions, and that it returns a list of valid - `langchain_core.messages.AIMessage` objects. + `AIMessage` objects. """ batch_results = await model.abatch(["Hello", "Hey"]) @@ -923,8 +927,8 @@ class ChatModelIntegrationTests(ChatModelTests): """Test to verify that the model can handle multi-turn conversations. This should pass for all integrations. Tests the model's ability to process - a sequence of alternating human and AI messages as context for generating - the next response. + a sequence of alternating `HumanMessage` and `AIMessage` objects as context for + generating the next response. ??? question "Troubleshooting" @@ -933,6 +937,7 @@ class ChatModelIntegrationTests(ChatModelTests): because this test also uses `model.invoke`. If that test passes but not this one, you should verify that: + 1. Your model correctly processes the message history 2. The model maintains appropriate context from previous messages 3. The response is a valid `langchain_core.messages.AIMessage` @@ -968,8 +973,9 @@ class ChatModelIntegrationTests(ChatModelTests): because this test is the "basic case" without double messages. If that test passes those but not this one, you should verify that: + 1. Your model API can handle double messages, or the integration should - merge messages before sending them to the API. + merge messages before sending them to the API. 2. The response is a valid `langchain_core.messages.AIMessage` """ @@ -993,7 +999,7 @@ class ChatModelIntegrationTests(ChatModelTests): """Test to verify that the model returns correct usage metadata. This test is optional and should be skipped if the model does not return - usage metadata (see Configuration below). + usage metadata (see configuration below). !!! warning "Behavior changed in 0.3.17" Additionally check for the presence of `model_name` in the response @@ -1014,9 +1020,10 @@ class ChatModelIntegrationTests(ChatModelTests): ``` This test can also check the format of specific kinds of usage metadata - based on the `supported_usage_metadata_details` property. This property - should be configured as follows with the types of tokens that the model - supports tracking: + based on the `supported_usage_metadata_details` property. + + This property should be configured as follows with the types of tokens that + the model supports tracking: ```python class TestMyChatModelIntegration(ChatModelIntegrationTests): @@ -1186,9 +1193,10 @@ class ChatModelIntegrationTests(ChatModelTests): ``` This test can also check the format of specific kinds of usage metadata - based on the `supported_usage_metadata_details` property. This property - should be configured as follows with the types of tokens that the model - supports tracking: + based on the `supported_usage_metadata_details` property. + + This property should be configured as follows with the types of tokens that + the model supports tracking: ```python class TestMyChatModelIntegration(ChatModelIntegrationTests): @@ -1370,11 +1378,11 @@ class ChatModelIntegrationTests(ChatModelTests): set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1432,11 +1440,11 @@ class ChatModelIntegrationTests(ChatModelTests): set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1495,11 +1503,11 @@ class ChatModelIntegrationTests(ChatModelTests): on the test class is set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1565,11 +1573,11 @@ class ChatModelIntegrationTests(ChatModelTests): with messages generated from providers following OpenAI format. This test should be skipped if the model does not support tool calling - (see Configuration below). + (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1654,11 +1662,11 @@ class ChatModelIntegrationTests(ChatModelTests): ``` This test should be skipped if the model does not support tool calling - (see Configuration below). + (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1734,11 +1742,11 @@ class ChatModelIntegrationTests(ChatModelTests): test class is set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_choice` to False in your + To disable tool calling tests, set `has_tool_choice` to `False` in your test class: ```python @@ -1786,11 +1794,11 @@ class ChatModelIntegrationTests(ChatModelTests): is set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1859,11 +1867,11 @@ class ChatModelIntegrationTests(ChatModelTests): to the model. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1920,11 +1928,11 @@ class ChatModelIntegrationTests(ChatModelTests): - `HumanMessage` with string content (a follow-up question). This test should be skipped if the model does not support tool calling - (see Configuration below). + (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python @@ -1981,7 +1989,7 @@ class ChatModelIntegrationTests(ChatModelTests): """Test to verify structured output is generated both on invoke and stream. This test is optional and should be skipped if the model does not support - structured output (see Configuration below). + structured output (see configuration below). ??? note "Configuration" @@ -2064,7 +2072,7 @@ class ChatModelIntegrationTests(ChatModelTests): """Test to verify structured output is generated both on invoke and stream. This test is optional and should be skipped if the model does not support - structured output (see Configuration below). + structured output (see configuration below). ??? note "Configuration" @@ -2146,7 +2154,7 @@ class ChatModelIntegrationTests(ChatModelTests): `pydantic.v1.BaseModel` is available in the Pydantic 2 package. This test is optional and should be skipped if the model does not support - structured output (see Configuration below). + structured output (see configuration below). ??? note "Configuration" @@ -2212,7 +2220,7 @@ class ChatModelIntegrationTests(ChatModelTests): parameters. This test is optional and should be skipped if the model does not support - structured output (see Configuration below). + structured output (see configuration below). ??? note "Configuration" @@ -2284,11 +2292,11 @@ class ChatModelIntegrationTests(ChatModelTests): """Test structured output via [JSON mode.](https://python.langchain.com/docs/concepts/structured_outputs/#json-mode). This test is optional and should be skipped if the model does not support - the JSON mode feature (see Configuration below). + the JSON mode feature (see configuration below). ??? note "Configuration" - To disable this test, set `supports_json_mode` to False in your + To disable this test, set `supports_json_mode` to `False` in your test class: ```python @@ -2343,7 +2351,7 @@ class ChatModelIntegrationTests(ChatModelTests): def test_pdf_inputs(self, model: BaseChatModel) -> None: """Test that the model can process PDF inputs. - This test should be skipped (see Configuration below) if the model does not + This test should be skipped (see configuration below) if the model does not support PDF inputs. These will take the shape of the LangChain `FileContentBlock`: @@ -2372,7 +2380,7 @@ class ChatModelIntegrationTests(ChatModelTests): ??? note "Configuration" - To disable this test, set `supports_pdf_inputs` to False in your + To disable this test, set `supports_pdf_inputs` to `False` in your test class: ```python @@ -2386,7 +2394,7 @@ class ChatModelIntegrationTests(ChatModelTests): If this test fails, check that the model can correctly handle messages with pdf content blocks, including base64-encoded files. Otherwise, set - the `supports_pdf_inputs` property to False. + the `supports_pdf_inputs` property to `False`. """ if not self.supports_pdf_inputs: @@ -2431,7 +2439,7 @@ class ChatModelIntegrationTests(ChatModelTests): def test_audio_inputs(self, model: BaseChatModel) -> None: """Test that the model can process audio inputs. - This test should be skipped (see Configuration below) if the model does not + This test should be skipped (see configuration below) if the model does not support audio inputs. These will take the shape of the LangChain `AudioContentBlock`: @@ -2468,7 +2476,7 @@ class ChatModelIntegrationTests(ChatModelTests): ??? note "Configuration" - To disable this test, set `supports_audio_inputs` to False in your + To disable this test, set `supports_audio_inputs` to `False` in your test class: ```python @@ -2482,7 +2490,7 @@ class ChatModelIntegrationTests(ChatModelTests): If this test fails, check that the model can correctly handle messages with audio content blocks, specifically base64-encoded files. Otherwise, - set the `supports_audio_inputs` property to False. + set the `supports_audio_inputs` property to `False`. """ # noqa: E501 if not self.supports_audio_inputs: @@ -2526,7 +2534,7 @@ class ChatModelIntegrationTests(ChatModelTests): def test_image_inputs(self, model: BaseChatModel) -> None: """Test that the model can process image inputs. - This test should be skipped (see Configuration below) if the model does not + This test should be skipped (see configuration below) if the model does not support image inputs. These will take the shape of the LangChain `ImageContentBlock`: @@ -2553,7 +2561,7 @@ class ChatModelIntegrationTests(ChatModelTests): See https://python.langchain.com/docs/concepts/multimodality/ - If the property `supports_image_urls` is set to True, the test will also + If the property `supports_image_urls` is set to `True`, the test will also check that we can process content blocks of the form: ```python @@ -2565,7 +2573,7 @@ class ChatModelIntegrationTests(ChatModelTests): ??? note "Configuration" - To disable this test, set `supports_image_inputs` to False in your + To disable this test, set `supports_image_inputs` to `False` in your test class: ```python @@ -2584,7 +2592,7 @@ class ChatModelIntegrationTests(ChatModelTests): If this test fails, check that the model can correctly handle messages with image content blocks, including base64-encoded images. Otherwise, set - the `supports_image_inputs` property to False. + the `supports_image_inputs` property to `False`. """ if not self.supports_image_inputs: @@ -2671,11 +2679,11 @@ class ChatModelIntegrationTests(ChatModelTests): ``` This test can be skipped by setting the `supports_image_tool_message` property - to False (see Configuration below). + to False (see configuration below). ??? note "Configuration" - To disable this test, set `supports_image_tool_message` to False in your + To disable this test, set `supports_image_tool_message` to `False` in your test class: ```python @@ -2771,11 +2779,11 @@ class ChatModelIntegrationTests(ChatModelTests): ``` This test can be skipped by setting the `supports_pdf_tool_message` property - to False (see Configuration below). + to False (see configuration below). ??? note "Configuration" - To disable this test, set `supports_pdf_tool_message` to False in your + To disable this test, set `supports_pdf_tool_message` to `False` in your test class: ```python @@ -2854,7 +2862,7 @@ class ChatModelIntegrationTests(ChatModelTests): ) ``` - as well as `HumanMessage` objects containing `tool_result` content blocks: + ...as well as `HumanMessage` objects containing `tool_result` content blocks: ```python HumanMessage( @@ -2881,7 +2889,7 @@ class ChatModelIntegrationTests(ChatModelTests): ??? note "Configuration" - To disable this test, set `supports_anthropic_inputs` to False in your + To disable this test, set `supports_anthropic_inputs` to `False` in your test class: ```python @@ -2903,7 +2911,7 @@ class ChatModelIntegrationTests(ChatModelTests): handled. Otherwise, if Anthropic tool call and result formats are not supported, - set the `supports_anthropic_inputs` property to False. + set the `supports_anthropic_inputs` property to `False`. """ if not self.supports_anthropic_inputs: @@ -3047,11 +3055,11 @@ class ChatModelIntegrationTests(ChatModelTests): set to `False`. This test is optional and should be skipped if the model does not support - tool calling (see Configuration below). + tool calling (see configuration below). ??? note "Configuration" - To disable tool calling tests, set `has_tool_calling` to False in your + To disable tool calling tests, set `has_tool_calling` to `False` in your test class: ```python diff --git a/libs/standard-tests/langchain_tests/integration_tests/embeddings.py b/libs/standard-tests/langchain_tests/integration_tests/embeddings.py index 9d556a21581..06e5c799c6b 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/embeddings.py +++ b/libs/standard-tests/langchain_tests/integration_tests/embeddings.py @@ -65,7 +65,7 @@ class EmbeddingsIntegrationTests(EmbeddingsTests): If this test fails, check that: 1. The model will generate a list of lists of floats when calling - `.embed_documents` on a list of strings. + `embed_documents` on a list of strings. 2. The length of each list is the same. """ documents = ["foo", "bar", "baz"] @@ -84,7 +84,7 @@ class EmbeddingsIntegrationTests(EmbeddingsTests): If this test fails, check that: - 1. The model will generate a list of floats when calling `.aembed_query` + 1. The model will generate a list of floats when calling `aembed_query` on a string. 2. The length of the list is consistent across different inputs. """ @@ -106,7 +106,7 @@ class EmbeddingsIntegrationTests(EmbeddingsTests): If this test fails, check that: 1. The model will generate a list of lists of floats when calling - `.aembed_documents` on a list of strings. + `aembed_documents` on a list of strings. 2. The length of each list is the same. """ documents = ["foo", "bar", "baz"] diff --git a/libs/standard-tests/langchain_tests/integration_tests/retrievers.py b/libs/standard-tests/langchain_tests/integration_tests/retrievers.py index 1736045cca0..00ed2b04146 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/retrievers.py +++ b/libs/standard-tests/langchain_tests/integration_tests/retrievers.py @@ -72,13 +72,13 @@ class RetrieversIntegrationTests(BaseStandardTests): of documents ( of the one set in `num_results_arg_name`) when it is set. - For example, a retriever like + For example, a retriever like... ```python MyRetriever(k=3).invoke("query") ``` - should return 3 documents when invoked with a query. + ...should return 3 documents when invoked with a query. """ params = { @@ -128,13 +128,13 @@ class RetrieversIntegrationTests(BaseStandardTests): of documents (`k` of the one set in `num_results_arg_name`) when it is set. - For example, a retriever like + For example, a retriever like... ```python MyRetriever().invoke("query", k=3) ``` - should return 3 documents when invoked with a query. + ...should return 3 documents when invoked with a query. """ result_1 = retriever.invoke( @@ -169,8 +169,8 @@ class RetrieversIntegrationTests(BaseStandardTests): async def test_ainvoke_returns_documents(self, retriever: BaseRetriever) -> None: """Test ainvoke returns documents. - If ainvoked with the example params, the retriever should return a list of - Documents. + If `ainvoke`'d with the example params, the retriever should return a list of + `Document` objects. See `test_invoke_returns_documents` for more information on troubleshooting. diff --git a/libs/standard-tests/langchain_tests/integration_tests/tools.py b/libs/standard-tests/langchain_tests/integration_tests/tools.py index 8c65f37dab9..6e45a9b055d 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/tools.py +++ b/libs/standard-tests/langchain_tests/integration_tests/tools.py @@ -16,12 +16,12 @@ class ToolsIntegrationTests(ToolsTests): content. If you have followed the [custom tool guide](https://python.langchain.com/docs/how_to/custom_tools/), - this test should always pass because ToolCall inputs are handled by the + this test should always pass because `ToolCall` inputs are handled by the `langchain_core.tools.BaseTool` class. If you have not followed this guide, you should ensure that your tool's `invoke` method returns a valid ToolMessage content when it receives - a dict representing a ToolCall as input (as opposed to distinct args). + a `dict` representing a `ToolCall` as input (as opposed to distinct args). """ tool_call = ToolCall( name=tool.name, @@ -79,7 +79,7 @@ class ToolsIntegrationTests(ToolsTests): in `tool_invoke_params_example` correctly, and it's throwing an error. This test doesn't have any checks. It's just to ensure that the tool - doesn't throw an error when invoked with a dictionary of kwargs. + doesn't throw an error when invoked with a `dict` of `**kwargs`. """ tool.invoke(self.tool_invoke_params_example) diff --git a/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py b/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py index 490648e565e..fc529866f19 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py +++ b/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py @@ -101,9 +101,9 @@ class VectorStoreIntegrationTests(BaseStandardTests): @abstractmethod @pytest.fixture def vectorstore(self) -> VectorStore: - """Get the VectorStore class to test. + """Get the `VectorStore` class to test. - The returned VectorStore should be empty. + The returned `VectorStore` should be empty. """ @property @@ -118,7 +118,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): @property def has_get_by_ids(self) -> bool: - """Whether the vector store supports get_by_ids.""" + """Whether the `VectorStore` supports `get_by_ids`.""" return True @staticmethod @@ -137,7 +137,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): ) def test_vectorstore_is_empty(self, vectorstore: VectorStore) -> None: - """Test that the VectorStore is empty. + """Test that the `VectorStore` is empty. ??? note "Troubleshooting" @@ -159,7 +159,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): 1. We correctly initialize an empty vector store in the `vectorestore` fixture. - 2. Calling `.similarity_search` for the top `k` similar documents does + 2. Calling `similarity_search` for the top `k` similar documents does not threshold by score. 3. We do not mutate the original document object when adding it to the vector store (e.g., by adding an ID). @@ -185,7 +185,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): ] def test_vectorstore_still_empty(self, vectorstore: VectorStore) -> None: - """Test that the VectorStore is still empty. + """Test that the `VectorStore` is still empty. This test should follow a test that adds documents. @@ -288,7 +288,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): ] def test_add_documents_by_id_with_mutation(self, vectorstore: VectorStore) -> None: - """Test that we can overwrite by ID using add_documents. + """Test that we can overwrite by ID using `add_documents`. ??? note "Troubleshooting" @@ -485,7 +485,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): ) async def test_vectorstore_is_empty_async(self, vectorstore: VectorStore) -> None: - """Test that the VectorStore is empty. + """Test that the `VectorStore` is empty. ??? note "Troubleshooting" @@ -536,7 +536,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): async def test_vectorstore_still_empty_async( self, vectorstore: VectorStore ) -> None: - """Test that the VectorStore is still empty. + """Test that the `VectorStore` is still empty. This test should follow a test that adds documents. @@ -643,7 +643,7 @@ class VectorStoreIntegrationTests(BaseStandardTests): async def test_add_documents_by_id_with_mutation_async( self, vectorstore: VectorStore ) -> None: - """Test that we can overwrite by ID using add_documents. + """Test that we can overwrite by ID using `add_documents`. ??? note "Troubleshooting" diff --git a/libs/standard-tests/langchain_tests/unit_tests/chat_models.py b/libs/standard-tests/langchain_tests/unit_tests/chat_models.py index 4ac585c27bd..1a73ffd84f1 100644 --- a/libs/standard-tests/langchain_tests/unit_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/unit_tests/chat_models.py @@ -185,7 +185,6 @@ class ChatModelTests(BaseStandardTests): Whether the chat model supports video inputs, defaults to `False`. No current tests are written for this feature. - """ return False @@ -210,7 +209,6 @@ class ChatModelTests(BaseStandardTests): Whether the chat model supports `ToolMessage` objects that include image content. - """ return False @@ -220,7 +218,6 @@ class ChatModelTests(BaseStandardTests): Whether the chat model supports `ToolMessage` objects that include PDF content. - """ return False @@ -231,7 +228,6 @@ class ChatModelTests(BaseStandardTests): !!! warning See `enable_vcr_tests` dropdown `above ` for more information. - """ return False @@ -382,7 +378,9 @@ class ChatModelUnitTests(ChatModelTests): ??? info "`structured_output_kwargs`" Dict property that can be used to specify additional kwargs for - `with_structured_output`. Useful for testing different models. + `with_structured_output`. + + Useful for testing different models. ```python @property @@ -529,7 +527,9 @@ class ChatModelUnitTests(ChatModelTests): Boolean property indicating whether the chat model supports image inputs. - Defaults to `False`. No current tests are written for this feature. + Defaults to `False`. + + No current tests are written for this feature. ??? info "`returns_usage_metadata`" @@ -786,7 +786,7 @@ class ChatModelUnitTests(ChatModelTests): gunzip -k /path/to/tests/cassettes/TestClass_test.yaml.gz ``` - or by using the serializer: + ...or by using the serializer: ```python from langchain_tests.conftest import (