diff --git a/libs/langchain_v1/langchain/agents/interrupt.py b/libs/langchain_v1/langchain/agents/interrupt.py index 593b3cefe11..cbba63b51f5 100644 --- a/libs/langchain_v1/langchain/agents/interrupt.py +++ b/libs/langchain_v1/langchain/agents/interrupt.py @@ -74,15 +74,20 @@ class HumanInterrupt(TypedDict): class HumanResponse(TypedDict): - """The response provided by a human to an interrupt, which is returned when graph execution resumes. + """Human response. + + The response provided by a human to an interrupt, + which is returned when graph execution resumes. Attributes: type: The type of response: + - "accept": Approves the current state without changes - "ignore": Skips/ignores the current step - "response": Provides text feedback or instructions - "edit": Modifies the current state/content args: The response payload: + - None: For ignore/accept actions - str: For text responses - ActionRequest: For edit actions with updated content diff --git a/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py b/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py index b2ed04867cf..4718e704685 100644 --- a/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py +++ b/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py @@ -65,7 +65,10 @@ class HumanInTheLoopMiddleware(AgentMiddleware): # Right now, we do not support multiple tool calls with interrupts if len(interrupt_tool_calls) > 1: tool_names = [t["name"] for t in interrupt_tool_calls] - msg = f"Called the following tools which require interrupts: {tool_names}\n\nYou may only call ONE tool that requires an interrupt at a time" + msg = ( + f"Called the following tools which require interrupts: {tool_names}\n\n" + "You may only call ONE tool that requires an interrupt at a time" + ) return { "messages": _generate_correction_tool_messages(msg, last_message.tool_calls), "jump_to": "model", @@ -74,7 +77,11 @@ class HumanInTheLoopMiddleware(AgentMiddleware): # Right now, we do not support interrupting a tool call if other tool calls exist if auto_approved_tool_calls: tool_names = [t["name"] for t in interrupt_tool_calls] - msg = f"Called the following tools which require interrupts: {tool_names}. You also called other tools that do not require interrupts. If you call a tool that requires and interrupt, you may ONLY call that tool." + msg = ( + f"Called the following tools which require interrupts: {tool_names}. " + "You also called other tools that do not require interrupts. " + "If you call a tool that requires and interrupt, you may ONLY call that tool." + ) return { "messages": _generate_correction_tool_messages(msg, last_message.tool_calls), "jump_to": "model", diff --git a/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py b/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py index 52eb2c147de..2f7a1817995 100644 --- a/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py +++ b/libs/langchain_v1/langchain/agents/middleware/prompt_caching.py @@ -6,9 +6,12 @@ from langchain.agents.middleware.types import AgentMiddleware, AgentState, Model class AnthropicPromptCachingMiddleware(AgentMiddleware): - """Prompt Caching Middleware - Optimizes API usage by caching conversation prefixes for Anthropic models. + """Prompt Caching Middleware. - Learn more about anthropic prompt caching [here](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching). + Optimizes API usage by caching conversation prefixes for Anthropic models. + + Learn more about Anthropic prompt caching + `here `__. """ def __init__( @@ -22,7 +25,8 @@ class AnthropicPromptCachingMiddleware(AgentMiddleware): Args: type: The type of cache to use, only "ephemeral" is supported. ttl: The time to live for the cache, only "5m" and "1h" are supported. - min_messages_to_cache: The minimum number of messages until the cache is used, default is 0. + min_messages_to_cache: The minimum number of messages until the cache is used, + default is 0. """ self.type = type self.ttl = ttl @@ -34,15 +38,16 @@ class AnthropicPromptCachingMiddleware(AgentMiddleware): from langchain_anthropic import ChatAnthropic except ImportError: msg = ( - "AnthropicPromptCachingMiddleware caching middleware only supports Anthropic models." + "AnthropicPromptCachingMiddleware caching middleware only supports " + "Anthropic models." "Please install langchain-anthropic." ) raise ValueError(msg) if not isinstance(request.model, ChatAnthropic): msg = ( - "AnthropicPromptCachingMiddleware caching middleware only supports Anthropic models, " - f"not instances of {type(request.model)}" + "AnthropicPromptCachingMiddleware caching middleware only supports " + f"Anthropic models, not instances of {type(request.model)}" ) raise ValueError(msg) diff --git a/libs/langchain_v1/langchain/agents/middleware/summarization.py b/libs/langchain_v1/langchain/agents/middleware/summarization.py index 04274b14c87..c716e2c2dec 100644 --- a/libs/langchain_v1/langchain/agents/middleware/summarization.py +++ b/libs/langchain_v1/langchain/agents/middleware/summarization.py @@ -48,7 +48,7 @@ Respond ONLY with the extracted context. Do not include any additional informati Messages to summarize: {messages} -""" +""" # noqa: E501 SUMMARY_PREFIX = "## Previous conversation summary:" diff --git a/libs/langchain_v1/langchain/agents/middleware/types.py b/libs/langchain_v1/langchain/agents/middleware/types.py index 976d0c323b0..c84f4954ed1 100644 --- a/libs/langchain_v1/langchain/agents/middleware/types.py +++ b/libs/langchain_v1/langchain/agents/middleware/types.py @@ -58,7 +58,8 @@ StateT = TypeVar("StateT", bound=AgentState) class AgentMiddleware(Generic[StateT]): """Base middleware class for an agent. - Subclass this and implement any of the defined methods to customize agent behavior between steps in the main agent loop. + Subclass this and implement any of the defined methods to customize agent behavior + between steps in the main agent loop. """ state_schema: type[StateT] = cast("type[StateT]", AgentState) diff --git a/libs/langchain_v1/langchain/agents/react_agent.py b/libs/langchain_v1/langchain/agents/react_agent.py index 96fbd30407c..d9392c47527 100644 --- a/libs/langchain_v1/langchain/agents/react_agent.py +++ b/libs/langchain_v1/langchain/agents/react_agent.py @@ -176,8 +176,9 @@ def _validate_chat_history( error_message = create_error_message( message="Found AIMessages with tool_calls that do not have a corresponding ToolMessage. " f"Here are the first few of those tool calls: {tool_calls_without_results[:3]}.\n\n" - "Every tool call (LLM requesting to call a tool) in the message history MUST have a corresponding ToolMessage " - "(result of a tool invocation to return to the LLM) - this is required by most LLM providers.", + "Every tool call (LLM requesting to call a tool) in the message history " + "MUST have a corresponding ToolMessage (result of a tool invocation to return to the LLM) -" + " this is required by most LLM providers.", error_code=ErrorCode.INVALID_CHAT_HISTORY, ) raise ValueError(error_message) @@ -216,7 +217,8 @@ class _AgentBuilder(Generic[StateT, ContextT, StructuredResponseT]): if isinstance(model, Runnable) and not isinstance(model, BaseChatModel): msg = ( "Expected `model` to be a BaseChatModel or a string, got {type(model)}." - "The `model` parameter should not have pre-bound tools, simply pass the model and tools separately." + "The `model` parameter should not have pre-bound tools, " + "simply pass the model and tools separately." ) raise ValueError(msg) @@ -308,7 +310,8 @@ class _AgentBuilder(Generic[StateT, ContextT, StructuredResponseT]): Command with structured response update if found, None otherwise Raises: - MultipleStructuredOutputsError: If multiple structured responses are returned and error handling is disabled + MultipleStructuredOutputsError: If multiple structured responses are returned + and error handling is disabled StructuredOutputParsingError: If parsing fails and error handling is disabled """ if not isinstance(self.response_format, ToolStrategy) or not response.tool_calls: @@ -452,7 +455,11 @@ class _AgentBuilder(Generic[StateT, ContextT, StructuredResponseT]): return model.bind(**kwargs) def _handle_structured_response_native(self, response: AIMessage) -> Command | None: - """If native output is configured and there are no tool calls, parse using ProviderStrategyBinding.""" + """Handle structured output using the native output. + + If native output is configured and there are no tool calls, + parse using ProviderStrategyBinding. + """ if self.native_output_binding is None: return None if response.tool_calls: @@ -922,7 +929,8 @@ def create_agent( # noqa: D417 ) -> CompiledStateGraph[StateT, ContextT]: """Creates an agent graph that calls tools in a loop until a stopping condition is met. - For more details on using `create_agent`, visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation. + For more details on using `create_agent`, + visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation. Args: model: The language model for the agent. Supports static and dynamic @@ -969,25 +977,35 @@ def create_agent( # noqa: D417 must be a subset of those specified in the `tools` parameter. tools: A list of tools or a ToolNode instance. - If an empty list is provided, the agent will consist of a single LLM node without tool calling. + If an empty list is provided, the agent will consist of a single LLM node + without tool calling. prompt: An optional prompt for the LLM. Can take a few different forms: - - str: This is converted to a SystemMessage and added to the beginning of the list of messages in state["messages"]. - - SystemMessage: this is added to the beginning of the list of messages in state["messages"]. - - Callable: This function should take in full graph state and the output is then passed to the language model. - - Runnable: This runnable should take in full graph state and the output is then passed to the language model. + - str: This is converted to a SystemMessage and added to the beginning + of the list of messages in state["messages"]. + - SystemMessage: this is added to the beginning of the list of messages + in state["messages"]. + - Callable: This function should take in full graph state and the output is then passed + to the language model. + - Runnable: This runnable should take in full graph state and the output is then passed + to the language model. response_format: An optional UsingToolStrategy configuration for structured responses. - If provided, the agent will handle structured output via tool calls during the normal conversation flow. - When the model calls a structured output tool, the response will be captured and returned in the 'structured_response' state key. + If provided, the agent will handle structured output via tool calls + during the normal conversation flow. + When the model calls a structured output tool, the response will be captured + and returned in the 'structured_response' state key. If not provided, `structured_response` will not be present in the output state. The UsingToolStrategy should contain: - - schemas: A sequence of ResponseSchema objects that define the structured output format + + - schemas: A sequence of ResponseSchema objects that define + the structured output format - tool_choice: Either "required" or "auto" to control when structured output is used Each ResponseSchema contains: + - schema: A Pydantic model that defines the structure - name: Optional custom name for the tool (defaults to model name) - description: Optional custom description (defaults to model docstring) @@ -997,11 +1015,15 @@ def create_agent( # noqa: D417 `response_format` requires the model to support tool calling !!! Note - Structured responses are handled directly in the model call node via tool calls, eliminating the need for separate structured response nodes. + Structured responses are handled directly in the model call node via tool calls, + eliminating the need for separate structured response nodes. - pre_model_hook: An optional node to add before the `agent` node (i.e., the node that calls the LLM). - Useful for managing long message histories (e.g., message trimming, summarization, etc.). - Pre-model hook must be a callable or a runnable that takes in current graph state and returns a state update in the form of + pre_model_hook: An optional node to add before the `agent` node + (i.e., the node that calls the LLM). + Useful for managing long message histories + (e.g., message trimming, summarization, etc.). + Pre-model hook must be a callable or a runnable that takes in current + graph state and returns a state update in the form of ```python # At least one of `messages` or `llm_input_messages` MUST be provided { @@ -1016,11 +1038,13 @@ def create_agent( # noqa: D417 ``` !!! Important - At least one of `messages` or `llm_input_messages` MUST be provided and will be used as an input to the `agent` node. + At least one of `messages` or `llm_input_messages` MUST be provided + and will be used as an input to the `agent` node. The rest of the keys will be added to the graph state. !!! Warning - If you are returning `messages` in the pre-model hook, you should OVERWRITE the `messages` key by doing the following: + If you are returning `messages` in the pre-model hook, + you should OVERWRITE the `messages` key by doing the following: ```python { @@ -1028,9 +1052,12 @@ def create_agent( # noqa: D417 ... } ``` - post_model_hook: An optional node to add after the `agent` node (i.e., the node that calls the LLM). - Useful for implementing human-in-the-loop, guardrails, validation, or other post-processing. - Post-model hook must be a callable or a runnable that takes in current graph state and returns a state update. + post_model_hook: An optional node to add after the `agent` node + (i.e., the node that calls the LLM). + Useful for implementing human-in-the-loop, guardrails, validation, + or other post-processing. + Post-model hook must be a callable or a runnable that takes in + current graph state and returns a state update. !!! Note Only available with `version="v2"`. @@ -1039,12 +1066,14 @@ def create_agent( # noqa: D417 Defaults to `AgentState` that defines those two keys. context_schema: An optional schema for runtime context. checkpointer: An optional checkpoint saver object. This is used for persisting - the state of the graph (e.g., as chat memory) for a single thread (e.g., a single conversation). + the state of the graph (e.g., as chat memory) for a single thread + (e.g., a single conversation). store: An optional store object. This is used for persisting data across multiple threads (e.g., multiple conversations / users). interrupt_before: An optional list of node names to interrupt before. Should be one of the following: "agent", "tools". - This is useful if you want to add a user confirmation or other interrupt before taking an action. + This is useful if you want to add a user confirmation or other interrupt + before taking an action. interrupt_after: An optional list of node names to interrupt after. Should be one of the following: "agent", "tools". This is useful if you want to return directly or run additional processing on an output. @@ -1059,7 +1088,8 @@ def create_agent( # noqa: D417 node using the [Send](https://langchain-ai.github.io/langgraph/concepts/low_level/#send) API. name: An optional name for the CompiledStateGraph. - This name will be automatically used when adding ReAct agent graph to another graph as a subgraph node - + This name will be automatically used when adding ReAct agent graph to + another graph as a subgraph node - particularly useful for building multi-agent systems. !!! warning "`config_schema` Deprecated" @@ -1071,9 +1101,11 @@ def create_agent( # noqa: D417 A compiled LangChain runnable that can be used for chat interactions. The "agent" node calls the language model with the messages list (after applying the prompt). - If the resulting AIMessage contains `tool_calls`, the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode]. - The "tools" node executes the tools (1 tool per `tool_call`) and adds the responses to the messages list - as `ToolMessage` objects. The agent node then calls the language model again. + If the resulting AIMessage contains `tool_calls`, + the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode]. + The "tools" node executes the tools (1 tool per `tool_call`) + and adds the responses to the messages list as `ToolMessage` objects. + The agent node then calls the language model again. The process repeats until no more `tool_calls` are present in the response. The agent then returns the full list of messages as a dictionary containing the key "messages". @@ -1135,7 +1167,8 @@ def create_agent( # noqa: D417 # Handle deprecated config_schema parameter if (config_schema := deprecated_kwargs.pop("config_schema", MISSING)) is not MISSING: warn( - "`config_schema` is deprecated and will be removed. Please use `context_schema` instead.", + "`config_schema` is deprecated and will be removed. " + "Please use `context_schema` instead.", category=DeprecationWarning, stacklevel=2, ) diff --git a/libs/langchain_v1/langchain/agents/structured_output.py b/libs/langchain_v1/langchain/agents/structured_output.py index 2e7b559878a..2eb585fe16e 100644 --- a/libs/langchain_v1/langchain/agents/structured_output.py +++ b/libs/langchain_v1/langchain/agents/structured_output.py @@ -47,7 +47,8 @@ class MultipleStructuredOutputsError(StructuredOutputError): self.tool_names = tool_names super().__init__( - f"Model incorrectly returned multiple structured responses ({', '.join(tool_names)}) when only one is expected." + "Model incorrectly returned multiple structured responses " + f"({', '.join(tool_names)}) when only one is expected." ) @@ -98,7 +99,8 @@ class _SchemaSpec(Generic[SchemaT]): """Describes a structured output schema.""" schema: type[SchemaT] - """The schema for the response, can be a Pydantic model, dataclass, TypedDict, or JSON schema dict.""" + """The schema for the response, can be a Pydantic model, dataclass, TypedDict, + or JSON schema dict.""" name: str """Name of the schema, used for tool calling. @@ -178,7 +180,8 @@ class ToolStrategy(Generic[SchemaT]): """Schema specs for the tool calls.""" tool_message_content: str | None - """The content of the tool message to be returned when the model calls an artificial structured output tool.""" + """The content of the tool message to be returned when the model calls + an artificial structured output tool.""" handle_errors: ( bool | str | type[Exception] | tuple[type[Exception], ...] | Callable[[Exception], str] @@ -204,7 +207,10 @@ class ToolStrategy(Generic[SchemaT]): | tuple[type[Exception], ...] | Callable[[Exception], str] = True, ) -> None: - """Initialize ToolStrategy with schemas, tool message content, and error handling strategy.""" + """Initialize ToolStrategy. + + Initialize ToolStrategy with schemas, tool message content, and error handling strategy. + """ self.schema = schema self.tool_message_content = tool_message_content self.handle_errors = handle_errors @@ -268,7 +274,8 @@ class OutputToolBinding(Generic[SchemaT]): """ schema: type[SchemaT] - """The original schema provided for structured output (Pydantic model, dataclass, TypedDict, or JSON schema dict).""" + """The original schema provided for structured output + (Pydantic model, dataclass, TypedDict, or JSON schema dict).""" schema_kind: SchemaKind """Classification of the schema type for proper response construction.""" @@ -321,7 +328,8 @@ class ProviderStrategyBinding(Generic[SchemaT]): """ schema: type[SchemaT] - """The original schema provided for structured output (Pydantic model, dataclass, TypedDict, or JSON schema dict).""" + """The original schema provided for structured output + (Pydantic model, dataclass, TypedDict, or JSON schema dict).""" schema_kind: SchemaKind """Classification of the schema type for proper response construction.""" @@ -362,7 +370,10 @@ class ProviderStrategyBinding(Generic[SchemaT]): data = json.loads(raw_text) except Exception as e: schema_name = getattr(self.schema, "__name__", "response_format") - msg = f"Native structured output expected valid JSON for {schema_name}, but parsing failed: {e}." + msg = ( + f"Native structured output expected valid JSON for {schema_name}, " + f"but parsing failed: {e}." + ) raise ValueError(msg) from e # Parse according to schema diff --git a/libs/langchain_v1/langchain/agents/tool_node.py b/libs/langchain_v1/langchain/agents/tool_node.py index a522d070f47..aea11721681 100644 --- a/libs/langchain_v1/langchain/agents/tool_node.py +++ b/libs/langchain_v1/langchain/agents/tool_node.py @@ -87,8 +87,16 @@ INVALID_TOOL_NAME_ERROR_TEMPLATE = ( "Error: {requested_tool} is not a valid tool, try one of [{available_tools}]." ) TOOL_CALL_ERROR_TEMPLATE = "Error: {error}\n Please fix your mistakes." -TOOL_EXECUTION_ERROR_TEMPLATE = "Error executing tool '{tool_name}' with kwargs {tool_kwargs} with error:\n {error}\n Please fix the error and try again." -TOOL_INVOCATION_ERROR_TEMPLATE = "Error invoking tool '{tool_name}' with kwargs {tool_kwargs} with error:\n {error}\n Please fix the error and try again." +TOOL_EXECUTION_ERROR_TEMPLATE = ( + "Error executing tool '{tool_name}' with kwargs {tool_kwargs} with error:\n" + " {error}\n" + " Please fix the error and try again." +) +TOOL_INVOCATION_ERROR_TEMPLATE = ( + "Error invoking tool '{tool_name}' with kwargs {tool_kwargs} with error:\n" + " {error}\n" + " Please fix the error and try again." +) def msg_content_output(output: Any) -> str | list[dict]: @@ -313,7 +321,8 @@ class ToolNode(RunnableCallable): error template containing the exception details. - **str**: Catch all errors and return a ToolMessage with this custom error message string. - - **type[Exception]**: Only catch exceptions with the specified type and return the default error message for it. + - **type[Exception]**: Only catch exceptions with the specified type and + return the default error message for it. - **tuple[type[Exception], ...]**: Only catch exceptions with the specified types and return default error messages for them. - **Callable[..., str]**: Catch exceptions matching the callable's signature @@ -368,7 +377,7 @@ class ToolNode(RunnableCallable): tool_node = ToolNode([my_tool], handle_tool_errors=handle_errors) ``` - """ + """ # noqa: E501 name: str = "tools" @@ -506,10 +515,12 @@ class ToolNode(RunnableCallable): # GraphInterrupt is a special exception that will always be raised. # It can be triggered in the following scenarios, - # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation most commonly: + # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation + # most commonly: # (1) a GraphInterrupt is raised inside a tool # (2) a GraphInterrupt is raised inside a graph node for a graph called as a tool - # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph called as a tool + # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph + # called as a tool # (2 and 3 can happen in a "supervisor w/ tools" multi-agent architecture) except GraphBubbleUp: raise @@ -570,10 +581,12 @@ class ToolNode(RunnableCallable): # GraphInterrupt is a special exception that will always be raised. # It can be triggered in the following scenarios, - # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation most commonly: + # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation + # most commonly: # (1) a GraphInterrupt is raised inside a tool # (2) a GraphInterrupt is raised inside a graph node for a graph called as a tool - # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph called as a tool + # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph + # called as a tool # (2 and 3 can happen in a "supervisor w/ tools" multi-agent architecture) except GraphBubbleUp: raise @@ -770,10 +783,12 @@ class ToolNode(RunnableCallable): input_type: Literal["list", "dict", "tool_calls"], ) -> Command: if isinstance(command.update, dict): - # input type is dict when ToolNode is invoked with a dict input (e.g. {"messages": [AIMessage(..., tool_calls=[...])]}) + # input type is dict when ToolNode is invoked with a dict input + # (e.g. {"messages": [AIMessage(..., tool_calls=[...])]}) if input_type not in ("dict", "tool_calls"): msg = ( - f"Tools can provide a dict in Command.update only when using dict with '{self._messages_key}' key as ToolNode input, " + "Tools can provide a dict in Command.update only when using dict " + f"with '{self._messages_key}' key as ToolNode input, " f"got: {command.update} for tool '{call['name']}'" ) raise ValueError(msg) @@ -782,10 +797,12 @@ class ToolNode(RunnableCallable): state_update = cast("dict[str, Any]", updated_command.update) or {} messages_update = state_update.get(self._messages_key, []) elif isinstance(command.update, list): - # Input type is list when ToolNode is invoked with a list input (e.g. [AIMessage(..., tool_calls=[...])]) + # Input type is list when ToolNode is invoked with a list input + # (e.g. [AIMessage(..., tool_calls=[...])]) if input_type != "list": msg = ( - f"Tools can provide a list of messages in Command.update only when using list of messages as ToolNode input, " + "Tools can provide a list of messages in Command.update " + "only when using list of messages as ToolNode input, " f"got: {command.update} for tool '{call['name']}'" ) raise ValueError(msg) @@ -815,13 +832,17 @@ class ToolNode(RunnableCallable): # Command.update if command is sent to the CURRENT graph if updated_command.graph is None and not has_matching_tool_message: example_update = ( - '`Command(update={"messages": [ToolMessage("Success", tool_call_id=tool_call_id), ...]}, ...)`' + '`Command(update={"messages": ' + '[ToolMessage("Success", tool_call_id=tool_call_id), ...]}, ...)`' if input_type == "dict" - else '`Command(update=[ToolMessage("Success", tool_call_id=tool_call_id), ...], ...)`' + else "`Command(update=" + '[ToolMessage("Success", tool_call_id=tool_call_id), ...], ...)`' ) msg = ( - f"Expected to have a matching ToolMessage in Command.update for tool '{call['name']}', got: {messages_update}. " - "Every tool call (LLM requesting to call a tool) in the message history MUST have a corresponding ToolMessage. " + "Expected to have a matching ToolMessage in Command.update " + f"for tool '{call['name']}', got: {messages_update}. " + "Every tool call (LLM requesting to call a tool) " + "in the message history MUST have a corresponding ToolMessage. " f"You can fix it by modifying the tool to return {example_update}." ) raise ValueError(msg) diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index dd911e4fd3e..0f5e9405125 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -131,7 +131,6 @@ flake8-annotations.allow-star-arg-any = true ] "langchain/agents/*" = [ "ANN401", # we use Any right now, need to narrow - "E501", # line too long, needs to fix "A002", # input is shadowing builtin "A001", # input is shadowing builtin "B904", # use from for exceptions