chore(langchain): enable ruff docstring-code-format in langchain_v1 (#32855)

This commit is contained in:
Christophe Bornet
2025-09-08 22:51:18 +02:00
committed by GitHub
parent 35e9d36b0e
commit 54c2419a4e
9 changed files with 49 additions and 38 deletions

View File

@@ -61,6 +61,7 @@ def resolve_prompt(
def custom_prompt(state, runtime):
return [{"role": "system", "content": "Custom"}]
messages = resolve_prompt(custom_prompt, state, runtime, "content", "default")
messages = resolve_prompt("Custom system", state, runtime, "content", "default")
messages = resolve_prompt(None, state, runtime, "content", "Default")
@@ -128,15 +129,13 @@ async def aresolve_prompt(
async def async_prompt(state, runtime):
return [{"role": "system", "content": "Async"}]
def sync_prompt(state, runtime):
return [{"role": "system", "content": "Sync"}]
messages = await aresolve_prompt(
async_prompt, state, runtime, "content", "default"
)
messages = await aresolve_prompt(
sync_prompt, state, runtime, "content", "default"
)
messages = await aresolve_prompt(async_prompt, state, runtime, "content", "default")
messages = await aresolve_prompt(sync_prompt, state, runtime, "content", "default")
messages = await aresolve_prompt("Custom", state, runtime, "content", "default")
```

View File

@@ -53,15 +53,15 @@ class HumanInterrupt(TypedDict):
request = HumanInterrupt(
action_request=ActionRequest(
action="run_command", # The action being requested
args={"command": "ls", "args": ["-l"]} # Arguments for the action
args={"command": "ls", "args": ["-l"]}, # Arguments for the action
),
config=HumanInterruptConfig(
allow_ignore=True, # Allow skipping this step
allow_respond=True, # Allow text feedback
allow_edit=False, # Don't allow editing
allow_accept=True # Allow direct acceptance
allow_ignore=True, # Allow skipping this step
allow_respond=True, # Allow text feedback
allow_edit=False, # Don't allow editing
allow_accept=True, # Allow direct acceptance
),
description="Please review the command before execution"
description="Please review the command before execution",
)
# Send the interrupt request and get the response
response = interrupt([request])[0]

View File

@@ -957,14 +957,17 @@ def create_agent( # noqa: D417
```python
from dataclasses import dataclass
@dataclass
class ModelContext:
model_name: str = "gpt-3.5-turbo"
# Instantiate models globally
gpt4_model = ChatOpenAI(model="gpt-4")
gpt35_model = ChatOpenAI(model="gpt-3.5-turbo")
def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenAI:
model_name = runtime.context.model_name
model = gpt4_model if model_name == "gpt-4" else gpt35_model

View File

@@ -23,10 +23,12 @@ Typical Usage:
from langchain_core.tools import tool
from langchain.agents import ToolNode
@tool
def my_tool(x: int) -> str:
return f"Result: {x}"
tool_node = ToolNode([my_tool])
```
"""
@@ -369,6 +371,7 @@ class ToolNode(RunnableCallable):
def handle_errors(e: ValueError) -> str:
return "Invalid input provided"
tool_node = ToolNode([my_tool], handle_tool_errors=handle_errors)
```
"""
@@ -887,16 +890,18 @@ def tools_condition(
from langgraph.agents.tool_node import ToolNode, tools_condition
from typing_extensions import TypedDict
class State(TypedDict):
messages: list
graph = StateGraph(State)
graph.add_node("llm", call_model)
graph.add_node("tools", ToolNode([my_tool]))
graph.add_conditional_edges(
"llm",
tools_condition, # Routes to "tools" or "__end__"
{"tools": "tools", "__end__": "__end__"}
{"tools": "tools", "__end__": "__end__"},
)
```
@@ -956,6 +961,7 @@ class InjectedState(InjectedToolArg):
messages: List[BaseMessage]
foo: str
@tool
def state_tool(x: int, state: Annotated[dict, InjectedState]) -> str:
'''Do something with state.'''
@@ -964,11 +970,13 @@ class InjectedState(InjectedToolArg):
else:
return "not enough messages"
@tool
def foo_tool(x: int, foo: Annotated[str, InjectedState("foo")]) -> str:
'''Do something else with state.'''
return foo + str(x + 1)
node = ToolNode([state_tool, foo_tool])
tool_call1 = {"name": "state_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
@@ -982,8 +990,8 @@ class InjectedState(InjectedToolArg):
```pycon
[
ToolMessage(content='not enough messages', name='state_tool', tool_call_id='1'),
ToolMessage(content='bar2', name='foo_tool', tool_call_id='2')
ToolMessage(content="not enough messages", name="state_tool", tool_call_id="1"),
ToolMessage(content="bar2", name="foo_tool", tool_call_id="2"),
]
```

View File

@@ -191,14 +191,12 @@ def init_chat_model(
configurable_model = init_chat_model(temperature=0)
configurable_model.invoke(
"what's your name",
config={"configurable": {"model": "gpt-4o"}}
"what's your name", config={"configurable": {"model": "gpt-4o"}}
)
# GPT-4o response
configurable_model.invoke(
"what's your name",
config={"configurable": {"model": "claude-3-5-sonnet-latest"}}
"what's your name", config={"configurable": {"model": "claude-3-5-sonnet-latest"}}
)
# claude-3.5 sonnet response
@@ -213,7 +211,7 @@ def init_chat_model(
"openai:gpt-4o",
configurable_fields="any", # this allows us to configure other params like temperature, max_tokens, etc at runtime.
config_prefix="foo",
temperature=0
temperature=0,
)
configurable_model_with_default.invoke("what's your name")
@@ -224,9 +222,9 @@ def init_chat_model(
config={
"configurable": {
"foo_model": "anthropic:claude-3-5-sonnet-latest",
"foo_temperature": 0.6
"foo_temperature": 0.6,
}
}
},
)
# Claude-3.5 sonnet response with temperature 0.6
@@ -241,23 +239,26 @@ def init_chat_model(
from langchain.chat_models import init_chat_model
from pydantic import BaseModel, Field
class GetWeather(BaseModel):
'''Get the current weather in a given location'''
location: str = Field(..., description="The city and state, e.g. San Francisco, CA")
class GetPopulation(BaseModel):
'''Get the current population in a given location'''
location: str = Field(..., description="The city and state, e.g. San Francisco, CA")
configurable_model = init_chat_model(
"gpt-4o",
configurable_fields=("model", "model_provider"),
temperature=0
"gpt-4o", configurable_fields=("model", "model_provider"), temperature=0
)
configurable_model_with_tools = configurable_model.bind_tools([GetWeather, GetPopulation])
configurable_model_with_tools = configurable_model.bind_tools(
[GetWeather, GetPopulation]
)
configurable_model_with_tools.invoke(
"Which city is hotter today and which is bigger: LA or NY?"
)
@@ -265,7 +266,7 @@ def init_chat_model(
configurable_model_with_tools.invoke(
"Which city is hotter today and which is bigger: LA or NY?",
config={"configurable": {"model": "claude-3-5-sonnet-latest"}}
config={"configurable": {"model": "claude-3-5-sonnet-latest"}},
)
# Claude-3.5 sonnet response with tools

View File

@@ -162,17 +162,11 @@ def init_embeddings(
model.embed_query("Hello, world!")
# Using explicit provider
model = init_embeddings(
model="text-embedding-3-small",
provider="openai"
)
model = init_embeddings(model="text-embedding-3-small", provider="openai")
model.embed_documents(["Hello, world!", "Goodbye, world!"])
# With additional parameters
model = init_embeddings(
"openai:text-embedding-3-small",
api_key="sk-..."
)
model = init_embeddings("openai:text-embedding-3-small", api_key="sk-...")
.. versionadded:: 0.3.9

View File

@@ -22,15 +22,19 @@ class EncoderBackedStore(BaseStore[K, V]):
import json
def key_encoder(key: int) -> str:
return json.dumps(key)
def value_serializer(value: float) -> str:
return json.dumps(value)
def value_deserializer(serialized_value: str) -> float:
return json.loads(serialized_value)
# Create an instance of the abstract store
abstract_store = MyCustomStore()
@@ -39,7 +43,7 @@ class EncoderBackedStore(BaseStore[K, V]):
store=abstract_store,
key_encoder=key_encoder,
value_serializer=value_serializer,
value_deserializer=value_deserializer
value_deserializer=value_deserializer,
)
# Use the encoder-backed store methods

View File

@@ -102,6 +102,9 @@ skip = ".git,*.pdf,*.svg,*.pdf,*.yaml,*.ipynb,poetry.lock,*.min.js,*.css,package
ignore-regex = ".*(Stati Uniti|Tense=Pres).*"
ignore-words-list = "momento,collison,ned,foor,reworkd,parth,whats,aapply,mysogyny,unsecure,damon,crate,aadd,symbl,precesses,accademia,nin"
[tool.ruff.format]
docstring-code-format = true
[tool.ruff.lint]
select = [
"ALL"

View File

@@ -33,8 +33,7 @@ def pytest_collection_modifyitems(config: pytest.Config, items: Sequence[pytest.
.. code-block:: python
@pytest.mark.requires("package1", "package2")
def test_something():
...
def test_something(): ...
"""
# Mapping from the name of a package to whether it is installed or not.