From b92b394804a11c650ee7f4e944dea0ba8ca05fbf Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Wed, 24 Sep 2025 15:25:55 -0400 Subject: [PATCH] style: repo linting pass (#33089) enable docstring-code-format --- libs/langchain_v1/pyproject.toml | 20 +- .../langchain_anthropic/chat_models.py | 322 ++++++++++++++---- libs/partners/anthropic/pyproject.toml | 4 + .../chroma/langchain_chroma/vectorstores.py | 22 +- libs/partners/chroma/pyproject.toml | 3 + .../langchain_deepseek/chat_models.py | 7 +- libs/partners/deepseek/pyproject.toml | 4 + libs/partners/exa/langchain_exa/tools.py | 35 +- libs/partners/exa/pyproject.toml | 3 + .../langchain_fireworks/chat_models.py | 45 ++- .../langchain_fireworks/embeddings.py | 6 +- libs/partners/fireworks/pyproject.toml | 3 + .../groq/langchain_groq/chat_models.py | 73 ++-- libs/partners/groq/pyproject.toml | 4 + .../chat_models/huggingface.py | 24 +- .../embeddings/huggingface.py | 6 +- .../embeddings/huggingface_endpoint.py | 1 + .../llms/huggingface_endpoint.py | 6 +- .../llms/huggingface_pipeline.py | 5 +- libs/partners/huggingface/pyproject.toml | 4 + libs/partners/mistralai/pyproject.toml | 3 + libs/partners/nomic/pyproject.toml | 3 + .../ollama/langchain_ollama/chat_models.py | 147 +++++--- .../ollama/langchain_ollama/embeddings.py | 4 +- libs/partners/ollama/pyproject.toml | 4 + libs/partners/openai/pyproject.toml | 10 +- libs/partners/perplexity/pyproject.toml | 10 +- libs/partners/prompty/pyproject.toml | 3 + .../qdrant/langchain_qdrant/qdrant.py | 51 ++- .../qdrant/langchain_qdrant/vectorstores.py | 2 + libs/partners/qdrant/pyproject.toml | 3 + .../partners/xai/langchain_xai/chat_models.py | 129 ++++--- libs/partners/xai/pyproject.toml | 4 + 33 files changed, 687 insertions(+), 283 deletions(-) diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index b5760a8c17f..705d4c05651 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -100,16 +100,16 @@ docstring-code-format = true [tool.ruff.lint] select = [ - "ALL" + "ALL" ] ignore = [ - "COM812", # Messes with the formatter - "ISC001", # Messes with the formatter - "PERF203", # Rarely useful - "SLF001", # Private member access - "PLC0415", # Imports should be at the top. Not always desirable - "PLR0913", # Too many arguments in function definition - "PLC0414", # Inconsistent with how type checkers expect to be notified of intentional re-exports + "COM812", # Messes with the formatter + "ISC001", # Messes with the formatter + "PERF203", # Rarely useful + "SLF001", # Private member access + "PLC0415", # Imports should be at the top. Not always desirable + "PLR0913", # Too many arguments in function definition + "PLC0414", # Inconsistent with how type checkers expect to be notified of intentional re-exports ] unfixable = ["B028"] # People should intentionally tune the stacklevel @@ -119,8 +119,8 @@ flake8-annotations.allow-star-arg-any = true [tool.ruff.lint.per-file-ignores] "tests/*" = [ - "D1", # Documentation rules - "PLC0415", # Imports should be at the top. Not always desirable for tests + "D1", # Documentation rules + "PLC0415", # Imports should be at the top. Not always desirable for tests ] "langchain/agents/*" = [ "ANN401", # we use Any right now, need to narrow diff --git a/libs/partners/anthropic/langchain_anthropic/chat_models.py b/libs/partners/anthropic/langchain_anthropic/chat_models.py index daf0d38fcd2..1dd9face9dd 100644 --- a/libs/partners/anthropic/langchain_anthropic/chat_models.py +++ b/libs/partners/anthropic/langchain_anthropic/chat_models.py @@ -577,14 +577,32 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python messages = [ - ("system", "You are a helpful translator. Translate the user sentence to French."), + ( + "system", + "You are a helpful translator. Translate the user sentence to French.", + ), ("human", "I love programming."), ] llm.invoke(messages) .. code-block:: python - AIMessage(content="J'aime la programmation.", response_metadata={'id': 'msg_01Trik66aiQ9Z1higrD5XFx3', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 25, 'output_tokens': 11}}, id='run-5886ac5f-3c2e-49f5-8a44-b1e92808c929-0', usage_metadata={'input_tokens': 25, 'output_tokens': 11, 'total_tokens': 36}) + AIMessage( + content="J'aime la programmation.", + response_metadata={ + "id": "msg_01Trik66aiQ9Z1higrD5XFx3", + "model": "claude-3-7-sonnet-20250219", + "stop_reason": "end_turn", + "stop_sequence": None, + "usage": {"input_tokens": 25, "output_tokens": 11}, + }, + id="run-5886ac5f-3c2e-49f5-8a44-b1e92808c929-0", + usage_metadata={ + "input_tokens": 25, + "output_tokens": 11, + "total_tokens": 36, + }, + ) Stream: .. code-block:: python @@ -594,14 +612,14 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - AIMessageChunk(content='J', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content="'", id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content='a', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content='ime', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content=' la', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content=' programm', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content='ation', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') - AIMessageChunk(content='.', id='run-272ff5f9-8485-402c-b90d-eac8babc5b25') + AIMessageChunk(content="J", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content="'", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content="a", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content="ime", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content=" la", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content=" programm", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content="ation", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") + AIMessageChunk(content=".", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25") .. code-block:: python @@ -613,7 +631,7 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - AIMessageChunk(content="J'aime la programmation.", id='run-b34faef0-882f-4869-a19c-ed2b856e6361') + AIMessageChunk(content="J'aime la programmation.", id="run-b34faef0-882f-4869-a19c-ed2b856e6361") Async: .. code-block:: python @@ -628,41 +646,69 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - AIMessage(content="J'aime la programmation.", response_metadata={'id': 'msg_01Trik66aiQ9Z1higrD5XFx3', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 25, 'output_tokens': 11}}, id='run-5886ac5f-3c2e-49f5-8a44-b1e92808c929-0', usage_metadata={'input_tokens': 25, 'output_tokens': 11, 'total_tokens': 36}) + AIMessage( + content="J'aime la programmation.", + response_metadata={ + "id": "msg_01Trik66aiQ9Z1higrD5XFx3", + "model": "claude-3-7-sonnet-20250219", + "stop_reason": "end_turn", + "stop_sequence": None, + "usage": {"input_tokens": 25, "output_tokens": 11}, + }, + id="run-5886ac5f-3c2e-49f5-8a44-b1e92808c929-0", + usage_metadata={ + "input_tokens": 25, + "output_tokens": 11, + "total_tokens": 36, + }, + ) Tool calling: .. code-block:: python 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") + llm_with_tools = llm.bind_tools([GetWeather, GetPopulation]) ai_msg = llm_with_tools.invoke("Which city is hotter today and which is bigger: LA or NY?") ai_msg.tool_calls .. code-block:: python - [{'name': 'GetWeather', - 'args': {'location': 'Los Angeles, CA'}, - 'id': 'toolu_01KzpPEAgzura7hpBqwHbWdo'}, - {'name': 'GetWeather', - 'args': {'location': 'New York, NY'}, - 'id': 'toolu_01JtgbVGVJbiSwtZk3Uycezx'}, - {'name': 'GetPopulation', - 'args': {'location': 'Los Angeles, CA'}, - 'id': 'toolu_01429aygngesudV9nTbCKGuw'}, - {'name': 'GetPopulation', - 'args': {'location': 'New York, NY'}, - 'id': 'toolu_01JPktyd44tVMeBcPPnFSEJG'}] + [ + { + "name": "GetWeather", + "args": {"location": "Los Angeles, CA"}, + "id": "toolu_01KzpPEAgzura7hpBqwHbWdo", + }, + { + "name": "GetWeather", + "args": {"location": "New York, NY"}, + "id": "toolu_01JtgbVGVJbiSwtZk3Uycezx", + }, + { + "name": "GetPopulation", + "args": {"location": "Los Angeles, CA"}, + "id": "toolu_01429aygngesudV9nTbCKGuw", + }, + { + "name": "GetPopulation", + "args": {"location": "New York, NY"}, + "id": "toolu_01JPktyd44tVMeBcPPnFSEJG", + }, + ] See ``ChatAnthropic.bind_tools()`` method for more. @@ -673,6 +719,7 @@ class ChatAnthropic(BaseChatModel): from pydantic import BaseModel, Field + class Joke(BaseModel): '''Joke to tell user.''' @@ -680,12 +727,17 @@ class ChatAnthropic(BaseChatModel): punchline: str = Field(description="The punchline to the joke") rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10") + structured_llm = llm.with_structured_output(Joke) structured_llm.invoke("Tell me a joke about cats") .. code-block:: python - Joke(setup='Why was the cat sitting on the computer?', punchline='To keep an eye on the mouse!', rating=None) + Joke( + setup="Why was the cat sitting on the computer?", + punchline="To keep an eye on the mouse!", + rating=None, + ) See ``ChatAnthropic.with_structured_output()`` for more. @@ -851,7 +903,14 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - [{'signature': '...', 'thinking': "To find the cube root of 50.653...", 'type': 'thinking'}, {'text': 'The cube root of 50.653 is ...', 'type': 'text'}] + [ + { + "signature": "...", + "thinking": "To find the cube root of 50.653...", + "type": "thinking", + }, + {"text": "The cube root of 50.653 is ...", "type": "text"}, + ] Citations: Anthropic supports a @@ -892,25 +951,39 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - [{'text': 'Based on the document, ', 'type': 'text'}, - {'text': 'the grass is green', - 'type': 'text', - 'citations': [{'type': 'char_location', - 'cited_text': 'The grass is green. ', - 'document_index': 0, - 'document_title': 'My Document', - 'start_char_index': 0, - 'end_char_index': 20}]}, - {'text': ', and ', 'type': 'text'}, - {'text': 'the sky is blue', - 'type': 'text', - 'citations': [{'type': 'char_location', - 'cited_text': 'The sky is blue.', - 'document_index': 0, - 'document_title': 'My Document', - 'start_char_index': 20, - 'end_char_index': 36}]}, - {'text': '.', 'type': 'text'}] + [ + {"text": "Based on the document, ", "type": "text"}, + { + "text": "the grass is green", + "type": "text", + "citations": [ + { + "type": "char_location", + "cited_text": "The grass is green. ", + "document_index": 0, + "document_title": "My Document", + "start_char_index": 0, + "end_char_index": 20, + } + ], + }, + {"text": ", and ", "type": "text"}, + { + "text": "the sky is blue", + "type": "text", + "citations": [ + { + "type": "char_location", + "cited_text": "The sky is blue.", + "document_index": 0, + "document_title": "My Document", + "start_char_index": 20, + "end_char_index": 36, + } + ], + }, + {"text": ".", "type": "text"}, + ] Token usage: .. code-block:: python @@ -920,7 +993,7 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - {'input_tokens': 25, 'output_tokens': 11, 'total_tokens': 36} + {"input_tokens": 25, "output_tokens": 11, "total_tokens": 36} Message chunks containing token usage will be included during streaming by default: @@ -935,7 +1008,7 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - {'input_tokens': 25, 'output_tokens': 11, 'total_tokens': 36} + {"input_tokens": 25, "output_tokens": 11, "total_tokens": 36} These can be disabled by setting ``stream_usage=False`` in the stream method, or by setting ``stream_usage=False`` when initializing ChatAnthropic. @@ -981,7 +1054,7 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - {'cache_read': 0, 'cache_creation': 1458} + {"cache_read": 0, "cache_creation": 1458} Alternatively, you may enable prompt caching at invocation time. You may want to conditionally cache based on runtime conditions, such as the length of the @@ -1006,7 +1079,8 @@ class ChatAnthropic(BaseChatModel): model="claude-3-7-sonnet-20250219", ) - messages = [{ + messages = [ + { "role": "user", "content": [ { @@ -1015,7 +1089,8 @@ class ChatAnthropic(BaseChatModel): "cache_control": {"type": "ephemeral", "ttl": "1h"}, }, ], - }] + } + ] response = llm.invoke(messages) @@ -1038,7 +1113,7 @@ class ChatAnthropic(BaseChatModel): "cache_creation": 1000, "ephemeral_1h_input_tokens": 750, "ephemeral_5m_input_tokens": 250, - } + }, } See `Claude documentation `__ @@ -1128,12 +1203,14 @@ class ChatAnthropic(BaseChatModel): llm = ChatAnthropic(model="claude-3-5-haiku-latest") - tool = {"type": "web_search_20250305", "name": "web_search", "max_uses": 3} + tool = { + "type": "web_search_20250305", + "name": "web_search", + "max_uses": 3, + } llm_with_tools = llm.bind_tools([tool]) - response = llm_with_tools.invoke( - "How do I update a web app to TypeScript 5.5?" - ) + response = llm_with_tools.invoke("How do I update a web app to TypeScript 5.5?") .. dropdown:: Web fetch (beta) @@ -1146,12 +1223,14 @@ class ChatAnthropic(BaseChatModel): betas=["web-fetch-2025-09-10"], # Enable web fetch beta ) - tool = {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 3} + tool = { + "type": "web_fetch_20250910", + "name": "web_fetch", + "max_uses": 3, + } llm_with_tools = llm.bind_tools([tool]) - response = llm_with_tools.invoke( - "Please analyze the content at https://example.com/article" - ) + response = llm_with_tools.invoke("Please analyze the content at https://example.com/article") .. dropdown:: Code execution @@ -1233,11 +1312,13 @@ class ChatAnthropic(BaseChatModel): .. code-block:: python - {'id': 'msg_013xU6FHEGEq76aP4RgFerVT', - 'model': 'claude-3-7-sonnet-20250219', - 'stop_reason': 'end_turn', - 'stop_sequence': None, - 'usage': {'input_tokens': 25, 'output_tokens': 11}} + { + "id": "msg_013xU6FHEGEq76aP4RgFerVT", + "model": "claude-3-7-sonnet-20250219", + "stop_reason": "end_turn", + "stop_sequence": None, + "usage": {"input_tokens": 25, "output_tokens": 11}, + } """ # noqa: E501 @@ -1722,11 +1803,13 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic 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 GetPrice(BaseModel): '''Get the price of a specific product.''' @@ -1735,7 +1818,9 @@ class ChatAnthropic(BaseChatModel): llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) llm_with_tools = llm.bind_tools([GetWeather, GetPrice]) - llm_with_tools.invoke("what is the weather like in San Francisco",) + llm_with_tools.invoke( + "What is the weather like in San Francisco", + ) # -> AIMessage( # content=[ # {'text': '\nBased on the user\'s question, the relevant function to call is GetWeather, which requires the "location" parameter.\n\nThe user has directly specified the location as "San Francisco". Since San Francisco is a well known city, I can reasonably infer they mean San Francisco, CA without needing the state specified.\n\nAll the required parameters are provided, so I can proceed with the API call.\n', 'type': 'text'}, @@ -1752,11 +1837,13 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic 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 GetPrice(BaseModel): '''Get the price of a specific product.''' @@ -1765,7 +1852,9 @@ class ChatAnthropic(BaseChatModel): llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) llm_with_tools = llm.bind_tools([GetWeather, GetPrice], tool_choice="any") - llm_with_tools.invoke("what is the weather like in San Francisco",) + llm_with_tools.invoke( + "what is the weather like in San Francisco", + ) Example — force specific tool call with tool_choice ``''``: @@ -1775,11 +1864,13 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic 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 GetPrice(BaseModel): '''Get the price of a specific product.''' @@ -1788,7 +1879,7 @@ class ChatAnthropic(BaseChatModel): llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) llm_with_tools = llm.bind_tools([GetWeather, GetPrice], tool_choice="GetWeather") - llm_with_tools.invoke("what is the weather like in San Francisco",) + llm_with_tools.invoke("What is the weather like in San Francisco") Example — cache specific tools: @@ -1797,16 +1888,19 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic, convert_to_anthropic_tool 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 GetPrice(BaseModel): '''Get the price of a specific product.''' product: str = Field(..., description="The product to look up.") + # We'll convert our pydantic class to the anthropic tool format # before passing to bind_tools so that we can set the 'cache_control' # field on our tool. @@ -1822,19 +1916,97 @@ class ChatAnthropic(BaseChatModel): temperature=0, ) llm_with_tools = llm.bind_tools([GetWeather, cached_price_tool]) - llm_with_tools.invoke("what is the weather like in San Francisco",) + llm_with_tools.invoke("What is the weather like in San Francisco") This outputs: .. code-block:: python - AIMessage(content=[{'text': "Certainly! I can help you find out the current weather in San Francisco. To get this information, I'll use the GetWeather function. Let me fetch that data for you right away.", 'type': 'text'}, {'id': 'toolu_01TS5h8LNo7p5imcG7yRiaUM', 'input': {'location': 'San Francisco, CA'}, 'name': 'GetWeather', 'type': 'tool_use'}], response_metadata={'id': 'msg_01Xg7Wr5inFWgBxE5jH9rpRo', 'model': 'claude-3-5-sonnet-latest', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 171, 'output_tokens': 96, 'cache_creation_input_tokens': 1470, 'cache_read_input_tokens': 0}}, id='run-b36a5b54-5d69-470e-a1b0-b932d00b089e-0', tool_calls=[{'name': 'GetWeather', 'args': {'location': 'San Francisco, CA'}, 'id': 'toolu_01TS5h8LNo7p5imcG7yRiaUM', 'type': 'tool_call'}], usage_metadata={'input_tokens': 171, 'output_tokens': 96, 'total_tokens': 267}) + AIMessage( + content=[ + { + "text": "Certainly! I can help you find out the current weather in San Francisco. To get this information, I'll use the GetWeather function. Let me fetch that data for you right away.", + "type": "text", + }, + { + "id": "toolu_01TS5h8LNo7p5imcG7yRiaUM", + "input": {"location": "San Francisco, CA"}, + "name": "GetWeather", + "type": "tool_use", + }, + ], + response_metadata={ + "id": "msg_01Xg7Wr5inFWgBxE5jH9rpRo", + "model": "claude-3-5-sonnet-latest", + "stop_reason": "tool_use", + "stop_sequence": None, + "usage": { + "input_tokens": 171, + "output_tokens": 96, + "cache_creation_input_tokens": 1470, + "cache_read_input_tokens": 0, + }, + }, + id="run-b36a5b54-5d69-470e-a1b0-b932d00b089e-0", + tool_calls=[ + { + "name": "GetWeather", + "args": {"location": "San Francisco, CA"}, + "id": "toolu_01TS5h8LNo7p5imcG7yRiaUM", + "type": "tool_call", + } + ], + usage_metadata={ + "input_tokens": 171, + "output_tokens": 96, + "total_tokens": 267, + }, + ) If we invoke the tool again, we can see that the "usage" information in the AIMessage.response_metadata shows that we had a cache hit: .. code-block:: python - AIMessage(content=[{'text': 'To get the current weather in San Francisco, I can use the GetWeather function. Let me check that for you.', 'type': 'text'}, {'id': 'toolu_01HtVtY1qhMFdPprx42qU2eA', 'input': {'location': 'San Francisco, CA'}, 'name': 'GetWeather', 'type': 'tool_use'}], response_metadata={'id': 'msg_016RfWHrRvW6DAGCdwB6Ac64', 'model': 'claude-3-5-sonnet-latest', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 171, 'output_tokens': 82, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 1470}}, id='run-88b1f825-dcb7-4277-ac27-53df55d22001-0', tool_calls=[{'name': 'GetWeather', 'args': {'location': 'San Francisco, CA'}, 'id': 'toolu_01HtVtY1qhMFdPprx42qU2eA', 'type': 'tool_call'}], usage_metadata={'input_tokens': 171, 'output_tokens': 82, 'total_tokens': 253}) + AIMessage( + content=[ + { + "text": "To get the current weather in San Francisco, I can use the GetWeather function. Let me check that for you.", + "type": "text", + }, + { + "id": "toolu_01HtVtY1qhMFdPprx42qU2eA", + "input": {"location": "San Francisco, CA"}, + "name": "GetWeather", + "type": "tool_use", + }, + ], + response_metadata={ + "id": "msg_016RfWHrRvW6DAGCdwB6Ac64", + "model": "claude-3-5-sonnet-latest", + "stop_reason": "tool_use", + "stop_sequence": None, + "usage": { + "input_tokens": 171, + "output_tokens": 82, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 1470, + }, + }, + id="run-88b1f825-dcb7-4277-ac27-53df55d22001-0", + tool_calls=[ + { + "name": "GetWeather", + "args": {"location": "San Francisco, CA"}, + "id": "toolu_01HtVtY1qhMFdPprx42qU2eA", + "type": "tool_call", + } + ], + usage_metadata={ + "input_tokens": 171, + "output_tokens": 82, + "total_tokens": 253, + }, + ) """ # noqa: E501 formatted_tools = [ @@ -1926,11 +2098,14 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic from pydantic import BaseModel + class AnswerWithJustification(BaseModel): '''An answer to the user question along with justification for the answer.''' + answer: str justification: str + llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification) @@ -1948,11 +2123,14 @@ class ChatAnthropic(BaseChatModel): from langchain_anthropic import ChatAnthropic from pydantic import BaseModel + class AnswerWithJustification(BaseModel): '''An answer to the user question along with justification for the answer.''' + answer: str justification: str + llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification, include_raw=True) @@ -1978,8 +2156,8 @@ class ChatAnthropic(BaseChatModel): "answer": {"type": "string"}, "justification": {"type": "string"}, }, - "required": ["answer", "justification"] - } + "required": ["answer", "justification"], + }, } llm = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0) structured_llm = llm.with_structured_output(schema) diff --git a/libs/partners/anthropic/pyproject.toml b/libs/partners/anthropic/pyproject.toml index 44ef78733e2..d0c2124a1ed 100644 --- a/libs/partners/anthropic/pyproject.toml +++ b/libs/partners/anthropic/pyproject.toml @@ -58,6 +58,10 @@ plugins = ['pydantic.mypy'] [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/chroma/langchain_chroma/vectorstores.py b/libs/partners/chroma/langchain_chroma/vectorstores.py index 78445ec407c..98e19c2158d 100644 --- a/libs/partners/chroma/langchain_chroma/vectorstores.py +++ b/libs/partners/chroma/langchain_chroma/vectorstores.py @@ -214,10 +214,10 @@ class Chroma(VectorStore): updated_document = Document( page_content="qux", - metadata={"bar": "baz"} + metadata={"bar": "baz"}, ) - vector_store.update_documents(ids=["1"],documents=[updated_document]) + vector_store.update_documents(ids=["1"], documents=[updated_document]) Delete Documents: .. code-block:: python @@ -227,29 +227,31 @@ class Chroma(VectorStore): Search: .. code-block:: python - results = vector_store.similarity_search(query="thud",k=1) + results = vector_store.similarity_search(query="thud", k=1) for doc in results: print(f"* {doc.page_content} [{doc.metadata}]") .. code-block:: python - * thud [{'baz': 'bar'}] + *thud[{"baz": "bar"}] Search with filter: .. code-block:: python - results = vector_store.similarity_search(query="thud",k=1,filter={"baz": "bar"}) + results = vector_store.similarity_search( + query="thud", k=1, filter={"baz": "bar"} + ) for doc in results: print(f"* {doc.page_content} [{doc.metadata}]") .. code-block:: python - * foo [{'baz': 'bar'}] + *foo[{"baz": "bar"}] Search with score: .. code-block:: python - results = vector_store.similarity_search_with_score(query="qux",k=1) + results = vector_store.similarity_search_with_score(query="qux", k=1) for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") @@ -270,8 +272,8 @@ class Chroma(VectorStore): # results = vector_store.asimilarity_search(query="thud",k=1) # search with score - results = await vector_store.asimilarity_search_with_score(query="qux",k=1) - for doc,score in results: + results = await vector_store.asimilarity_search_with_score(query="qux", k=1) + for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") .. code-block:: python @@ -289,7 +291,7 @@ class Chroma(VectorStore): .. code-block:: python - [Document(metadata={'baz': 'bar'}, page_content='thud')] + [Document(metadata={"baz": "bar"}, page_content="thud")] """ # noqa: E501 diff --git a/libs/partners/chroma/pyproject.toml b/libs/partners/chroma/pyproject.toml index e7a13626bf1..aef8ed19a60 100644 --- a/libs/partners/chroma/pyproject.toml +++ b/libs/partners/chroma/pyproject.toml @@ -61,6 +61,9 @@ disallow_untyped_defs = true [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/deepseek/langchain_deepseek/chat_models.py b/libs/partners/deepseek/langchain_deepseek/chat_models.py index 68c5b8c6b44..ed607b90795 100644 --- a/libs/partners/deepseek/langchain_deepseek/chat_models.py +++ b/libs/partners/deepseek/langchain_deepseek/chat_models.py @@ -110,16 +110,19 @@ class ChatDeepSeek(BaseChatOpenAI): 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") + llm_with_tools = llm.bind_tools([GetWeather, GetPopulation]) ai_msg = llm_with_tools.invoke("Which city is hotter today and which is bigger: LA or NY?") ai_msg.tool_calls @@ -133,6 +136,7 @@ class ChatDeepSeek(BaseChatOpenAI): from pydantic import BaseModel, Field + class Joke(BaseModel): '''Joke to tell user.''' @@ -140,6 +144,7 @@ class ChatDeepSeek(BaseChatOpenAI): punchline: str = Field(description="The punchline to the joke") rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10") + structured_llm = llm.with_structured_output(Joke) structured_llm.invoke("Tell me a joke about cats") @@ -153,7 +158,7 @@ class ChatDeepSeek(BaseChatOpenAI): .. code-block:: python - {'input_tokens': 28, 'output_tokens': 5, 'total_tokens': 33} + {"input_tokens": 28, "output_tokens": 5, "total_tokens": 33} Response metadata .. code-block:: python diff --git a/libs/partners/deepseek/pyproject.toml b/libs/partners/deepseek/pyproject.toml index 97c8e793ad0..bc4dc5f78df 100644 --- a/libs/partners/deepseek/pyproject.toml +++ b/libs/partners/deepseek/pyproject.toml @@ -47,6 +47,10 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/exa/langchain_exa/tools.py b/libs/partners/exa/langchain_exa/tools.py index 9b62155fa7f..9fa0b306451 100644 --- a/libs/partners/exa/langchain_exa/tools.py +++ b/libs/partners/exa/langchain_exa/tools.py @@ -39,21 +39,48 @@ class ExaSearchResults(BaseTool): # type: ignore[override] Invocation with args: .. code-block:: python - tool.invoke({"query":"what is the weather in SF","num_results":1}) + tool.invoke({"query": "what is the weather in SF", "num_results": 1}) .. code-block:: python - SearchResponse(results=[Result(url='https://www.wunderground.com/weather/37.8,-122.4', id='https://www.wunderground.com/weather/37.8,-122.4', title='San Francisco, CA Weather Conditionsstar_ratehome', score=0.1843988299369812, published_date='2023-02-23T01:17:06.594Z', author=None, text='The time period when the sun is no more than 6 degrees below the horizon at either sunrise or sunset. The horizon should be clearly defined and the brightest stars should be visible under good atmospheric conditions (i.e. no moonlight, or other lights). One still should be able to carry on ordinary outdoor activities. The time period when the sun is between 6 and 12 degrees below the horizon at either sunrise or sunset. The horizon is well defined and the outline of objects might be visible without artificial light. Ordinary outdoor activities are not possible at this time without extra illumination. The time period when the sun is between 12 and 18 degrees below the horizon at either sunrise or sunset. The sun does not contribute to the illumination of the sky before this time in the morning, or after this time in the evening. In the beginning of morning astronomical twilight and at the end of astronomical twilight in the evening, sky illumination is very faint, and might be undetectable. The time of Civil Sunset minus the time of Civil Sunrise. The time of Actual Sunset minus the time of Actual Sunrise. The change in length of daylight between today and tomorrow is also listed when available.', highlights=None, highlight_scores=None, summary=None)], autoprompt_string=None) + SearchResponse( + results=[ + Result( + url="https://www.wunderground.com/weather/37.8,-122.4", + id="https://www.wunderground.com/weather/37.8,-122.4", + title="San Francisco, CA Weather Conditionsstar_ratehome", + score=0.1843988299369812, + published_date="2023-02-23T01:17:06.594Z", + author=None, + text="The time period when the sun is no more than 6 degrees below the horizon at either sunrise or sunset. The horizon should be clearly defined and the brightest stars should be visible under good atmospheric conditions (i.e. no moonlight, or other lights). One still should be able to carry on ordinary outdoor activities. The time period when the sun is between 6 and 12 degrees below the horizon at either sunrise or sunset. The horizon is well defined and the outline of objects might be visible without artificial light. Ordinary outdoor activities are not possible at this time without extra illumination. The time period when the sun is between 12 and 18 degrees below the horizon at either sunrise or sunset. The sun does not contribute to the illumination of the sky before this time in the morning, or after this time in the evening. In the beginning of morning astronomical twilight and at the end of astronomical twilight in the evening, sky illumination is very faint, and might be undetectable. The time of Civil Sunset minus the time of Civil Sunrise. The time of Actual Sunset minus the time of Actual Sunrise. The change in length of daylight between today and tomorrow is also listed when available.", + highlights=None, + highlight_scores=None, + summary=None, + ) + ], + autoprompt_string=None, + ) Invocation with ToolCall: .. code-block:: python - tool.invoke({"args": {"query":"what is the weather in SF","num_results":1}, "id": "1", "name": tool.name, "type": "tool_call"}) + tool.invoke( + { + "args": {"query": "what is the weather in SF", "num_results": 1}, + "id": "1", + "name": tool.name, + "type": "tool_call", + } + ) .. code-block:: python - ToolMessage(content='Title: San Francisco, CA Weather Conditionsstar_ratehome\nURL: https://www.wunderground.com/weather/37.8,-122.4\nID: https://www.wunderground.com/weather/37.8,-122.4\nScore: 0.1843988299369812\nPublished Date: 2023-02-23T01:17:06.594Z\nAuthor: None\nText: The time period when the sun is no more than 6 degrees below the horizon at either sunrise or sunset. The horizon should be clearly defined and the brightest stars should be visible under good atmospheric conditions (i.e. no moonlight, or other lights). One still should be able to carry on ordinary outdoor activities. The time period when the sun is between 6 and 12 degrees below the horizon at either sunrise or sunset. The horizon is well defined and the outline of objects might be visible without artificial light. Ordinary outdoor activities are not possible at this time without extra illumination. The time period when the sun is between 12 and 18 degrees below the horizon at either sunrise or sunset. The sun does not contribute to the illumination of the sky before this time in the morning, or after this time in the evening. In the beginning of morning astronomical twilight and at the end of astronomical twilight in the evening, sky illumination is very faint, and might be undetectable. The time of Civil Sunset minus the time of Civil Sunrise. The time of Actual Sunset minus the time of Actual Sunrise. The change in length of daylight between today and tomorrow is also listed when available.\nHighlights: None\nHighlight Scores: None\nSummary: None\n', name='exa_search_results_json', tool_call_id='1') + ToolMessage( + content="Title: San Francisco, CA Weather Conditionsstar_ratehome\nURL: https://www.wunderground.com/weather/37.8,-122.4\nID: https://www.wunderground.com/weather/37.8,-122.4\nScore: 0.1843988299369812\nPublished Date: 2023-02-23T01:17:06.594Z\nAuthor: None\nText: The time period when the sun is no more than 6 degrees below the horizon at either sunrise or sunset. The horizon should be clearly defined and the brightest stars should be visible under good atmospheric conditions (i.e. no moonlight, or other lights). One still should be able to carry on ordinary outdoor activities. The time period when the sun is between 6 and 12 degrees below the horizon at either sunrise or sunset. The horizon is well defined and the outline of objects might be visible without artificial light. Ordinary outdoor activities are not possible at this time without extra illumination. The time period when the sun is between 12 and 18 degrees below the horizon at either sunrise or sunset. The sun does not contribute to the illumination of the sky before this time in the morning, or after this time in the evening. In the beginning of morning astronomical twilight and at the end of astronomical twilight in the evening, sky illumination is very faint, and might be undetectable. The time of Civil Sunset minus the time of Civil Sunrise. The time of Actual Sunset minus the time of Actual Sunrise. The change in length of daylight between today and tomorrow is also listed when available.\nHighlights: None\nHighlight Scores: None\nSummary: None\n", + name="exa_search_results_json", + tool_call_id="1", + ) """ # noqa: E501 diff --git a/libs/partners/exa/pyproject.toml b/libs/partners/exa/pyproject.toml index aff97a17850..e23406cac98 100644 --- a/libs/partners/exa/pyproject.toml +++ b/libs/partners/exa/pyproject.toml @@ -49,6 +49,9 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/fireworks/langchain_fireworks/chat_models.py b/libs/partners/fireworks/langchain_fireworks/chat_models.py index 949c88ec778..7b869dc0ff6 100644 --- a/libs/partners/fireworks/langchain_fireworks/chat_models.py +++ b/libs/partners/fireworks/langchain_fireworks/chat_models.py @@ -278,8 +278,10 @@ class ChatFireworks(BaseChatModel): .. code-block:: python from langchain_fireworks.chat_models import ChatFireworks + fireworks = ChatFireworks( - model_name="accounts/fireworks/models/llama-v3p1-8b-instruct") + model_name="accounts/fireworks/models/llama-v3p1-8b-instruct" + ) """ @@ -825,7 +827,10 @@ class ChatFireworks(BaseChatModel): ) - llm = ChatFireworks(model="accounts/fireworks/models/firefunction-v1", temperature=0) + llm = ChatFireworks( + model="accounts/fireworks/models/firefunction-v1", + temperature=0, + ) structured_llm = llm.with_structured_output(AnswerWithJustification) structured_llm.invoke( @@ -852,7 +857,10 @@ class ChatFireworks(BaseChatModel): justification: str - llm = ChatFireworks(model="accounts/fireworks/models/firefunction-v1", temperature=0) + llm = ChatFireworks( + model="accounts/fireworks/models/firefunction-v1", + temperature=0, + ) structured_llm = llm.with_structured_output( AnswerWithJustification, include_raw=True ) @@ -886,7 +894,10 @@ class ChatFireworks(BaseChatModel): ] - llm = ChatFireworks(model="accounts/fireworks/models/firefunction-v1", temperature=0) + llm = ChatFireworks( + model="accounts/fireworks/models/firefunction-v1", + temperature=0, + ) structured_llm = llm.with_structured_output(AnswerWithJustification) structured_llm.invoke( @@ -904,19 +915,25 @@ class ChatFireworks(BaseChatModel): from langchain_fireworks import ChatFireworks oai_schema = { - 'name': 'AnswerWithJustification', - 'description': 'An answer to the user question along with justification for the answer.', - 'parameters': { - 'type': 'object', - 'properties': { - 'answer': {'type': 'string'}, - 'justification': {'description': 'A justification for the answer.', 'type': 'string'} + "name": "AnswerWithJustification", + "description": "An answer to the user question along with justification for the answer.", + "parameters": { + "type": "object", + "properties": { + "answer": {"type": "string"}, + "justification": { + "description": "A justification for the answer.", + "type": "string", + }, }, - 'required': ['answer'] - } + "required": ["answer"], + }, } - llm = ChatFireworks(model="accounts/fireworks/models/firefunction-v1", temperature=0) + llm = ChatFireworks( + model="accounts/fireworks/models/firefunction-v1", + temperature=0, + ) structured_llm = llm.with_structured_output(oai_schema) structured_llm.invoke( diff --git a/libs/partners/fireworks/langchain_fireworks/embeddings.py b/libs/partners/fireworks/langchain_fireworks/embeddings.py index 2291c859fe0..40617dd6eb5 100644 --- a/libs/partners/fireworks/langchain_fireworks/embeddings.py +++ b/libs/partners/fireworks/langchain_fireworks/embeddings.py @@ -35,7 +35,7 @@ class FireworksEmbeddings(BaseModel, Embeddings): from langchain_fireworks import FireworksEmbeddings model = FireworksEmbeddings( - model='nomic-ai/nomic-embed-text-v1.5' + model="nomic-ai/nomic-embed-text-v1.5" # Use FIREWORKS_API_KEY env var or pass it in directly # fireworks_api_key="..." ) @@ -44,7 +44,7 @@ class FireworksEmbeddings(BaseModel, Embeddings): .. code-block:: python - vectors = embeddings.embed_documents(['hello', 'goodbye']) + vectors = embeddings.embed_documents(["hello", "goodbye"]) # Showing only the first 3 coordinates print(len(vectors)) print(vectors[0][:3]) @@ -59,7 +59,7 @@ class FireworksEmbeddings(BaseModel, Embeddings): .. code-block:: python input_text = "The meaning of life is 42" - vector = embeddings.embed_query('hello') + vector = embeddings.embed_query("hello") print(vector[:3]) .. code-block:: python diff --git a/libs/partners/fireworks/pyproject.toml b/libs/partners/fireworks/pyproject.toml index 2214836207f..696f43d6d9b 100644 --- a/libs/partners/fireworks/pyproject.toml +++ b/libs/partners/fireworks/pyproject.toml @@ -50,6 +50,9 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/groq/langchain_groq/chat_models.py b/libs/partners/groq/langchain_groq/chat_models.py index c254a6ffbc7..ac97ec790a3 100644 --- a/libs/partners/groq/langchain_groq/chat_models.py +++ b/libs/partners/groq/langchain_groq/chat_models.py @@ -220,25 +220,32 @@ class ChatGroq(BaseChatModel): 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") + model_with_tools = llm.bind_tools([GetWeather, GetPopulation]) ai_msg = model_with_tools.invoke("What is the population of NY?") ai_msg.tool_calls .. code-block:: python - [{'name': 'GetPopulation', - 'args': {'location': 'NY'}, - 'id': 'call_bb8d'}] + [ + { + "name": "GetPopulation", + "args": {"location": "NY"}, + "id": "call_bb8d", + } + ] See ``ChatGroq.bind_tools()`` method for more. @@ -249,6 +256,7 @@ class ChatGroq(BaseChatModel): from pydantic import BaseModel, Field + class Joke(BaseModel): '''Joke to tell user.''' @@ -256,12 +264,17 @@ class ChatGroq(BaseChatModel): punchline: str = Field(description="The punchline to the joke") rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10") + structured_model = llm.with_structured_output(Joke) structured_model.invoke("Tell me a joke about cats") .. code-block:: python - Joke(setup="Why don't cats play poker in the jungle?", punchline='Too many cheetahs!', rating=None) + Joke( + setup="Why don't cats play poker in the jungle?", + punchline="Too many cheetahs!", + rating=None, + ) See ``ChatGroq.with_structured_output()`` for more. @@ -273,17 +286,21 @@ class ChatGroq(BaseChatModel): .. code-block:: python - {'token_usage': {'completion_tokens': 70, - 'prompt_tokens': 28, - 'total_tokens': 98, - 'completion_time': 0.111956391, - 'prompt_time': 0.007518279, - 'queue_time': None, - 'total_time': 0.11947467}, - 'model_name': 'llama-3.1-8b-instant', - 'system_fingerprint': 'fp_c5f20b5bb1', - 'finish_reason': 'stop', - 'logprobs': None} + { + "token_usage": { + "completion_tokens": 70, + "prompt_tokens": 28, + "total_tokens": 98, + "completion_time": 0.111956391, + "prompt_time": 0.007518279, + "queue_time": None, + "total_time": 0.11947467, + }, + "model_name": "llama-3.1-8b-instant", + "system_fingerprint": "fp_c5f20b5bb1", + "finish_reason": "stop", + "logprobs": None, + } """ # noqa: E501 @@ -971,9 +988,7 @@ class ChatGroq(BaseChatModel): llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> AnswerWithJustification( # answer='They weigh the same', @@ -996,12 +1011,11 @@ class ChatGroq(BaseChatModel): llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0) structured_llm = llm.with_structured_output( - AnswerWithJustification, include_raw=True + AnswerWithJustification, + include_raw=True, ) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> { # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}), # 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'), @@ -1022,17 +1036,13 @@ class ChatGroq(BaseChatModel): '''An answer to the user question along with justification for the answer.''' answer: str - justification: Annotated[ - Optional[str], None, "A justification for the answer." - ] + justification: Annotated[Optional[str], None, "A justification for the answer."] llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> { # 'answer': 'They weigh the same', # 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.' @@ -1090,12 +1100,11 @@ class ChatGroq(BaseChatModel): llm = ChatGroq(model="openai/gpt-oss-120b", temperature=0) structured_llm = llm.with_structured_output( - AnswerWithJustification, method="json_schema" + AnswerWithJustification, + method="json_schema", ) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> AnswerWithJustification( # answer='They weigh the same', diff --git a/libs/partners/groq/pyproject.toml b/libs/partners/groq/pyproject.toml index 6680d46b167..03cfb01546a 100644 --- a/libs/partners/groq/pyproject.toml +++ b/libs/partners/groq/pyproject.toml @@ -42,6 +42,10 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/huggingface/langchain_huggingface/chat_models/huggingface.py b/libs/partners/huggingface/langchain_huggingface/chat_models/huggingface.py index cccb852749e..73de6452034 100644 --- a/libs/partners/huggingface/langchain_huggingface/chat_models/huggingface.py +++ b/libs/partners/huggingface/langchain_huggingface/chat_models/huggingface.py @@ -326,7 +326,8 @@ class ChatHuggingFace(BaseChatModel): .. code-block:: python from huggingface_hub import login - login() # You will be prompted for your HF key, which will then be saved locally + + login() # You will be prompted for your HF key, which will then be saved locally Key init args — completion params: llm: `HuggingFaceTextGenInference`, `HuggingFaceEndpoint`, `HuggingFaceHub`, or @@ -447,9 +448,13 @@ class ChatHuggingFace(BaseChatModel): .. code-block:: python - [{'name': 'GetPopulation', - 'args': {'location': 'Los Angeles, CA'}, - 'id': '0'}] + [ + { + "name": "GetPopulation", + "args": {"location": "Los Angeles, CA"}, + "id": "0", + } + ] Response metadata .. code-block:: python @@ -458,10 +463,13 @@ class ChatHuggingFace(BaseChatModel): ai_msg.response_metadata .. code-block:: python - {'token_usage': ChatCompletionOutputUsage(completion_tokens=100, - prompt_tokens=8, total_tokens=108), - 'model': '', - 'finish_reason': 'length'} + { + "token_usage": ChatCompletionOutputUsage( + completion_tokens=100, prompt_tokens=8, total_tokens=108 + ), + "model": "", + "finish_reason": "length", + } """ # noqa: E501 diff --git a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py index d5b3da08d6c..627431f2115 100644 --- a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py +++ b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface.py @@ -28,12 +28,12 @@ class HuggingFaceEmbeddings(BaseModel, Embeddings): from langchain_huggingface import HuggingFaceEmbeddings model_name = "sentence-transformers/all-mpnet-base-v2" - model_kwargs = {'device': 'cpu'} - encode_kwargs = {'normalize_embeddings': False} + model_kwargs = {"device": "cpu"} + encode_kwargs = {"normalize_embeddings": False} hf = HuggingFaceEmbeddings( model_name=model_name, model_kwargs=model_kwargs, - encode_kwargs=encode_kwargs + encode_kwargs=encode_kwargs, ) """ diff --git a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface_endpoint.py b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface_endpoint.py index 7cf12b8c65e..2d3bfe88b79 100644 --- a/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface_endpoint.py +++ b/libs/partners/huggingface/langchain_huggingface/embeddings/huggingface_endpoint.py @@ -23,6 +23,7 @@ class HuggingFaceEndpointEmbeddings(BaseModel, Embeddings): .. code-block:: python from langchain_huggingface import HuggingFaceEndpointEmbeddings + model = "sentence-transformers/all-mpnet-base-v2" hf = HuggingFaceEndpointEmbeddings( model=model, diff --git a/libs/partners/huggingface/langchain_huggingface/llms/huggingface_endpoint.py b/libs/partners/huggingface/langchain_huggingface/llms/huggingface_endpoint.py index bbba42ea729..afe8e93b956 100644 --- a/libs/partners/huggingface/langchain_huggingface/llms/huggingface_endpoint.py +++ b/libs/partners/huggingface/langchain_huggingface/llms/huggingface_endpoint.py @@ -45,7 +45,7 @@ class HuggingFaceEndpoint(LLM): typical_p=0.95, temperature=0.01, repetition_penalty=1.03, - huggingfacehub_api_token="my-api-key" + huggingfacehub_api_token="my-api-key", ) print(llm.invoke("What is Deep Learning?")) @@ -63,7 +63,7 @@ class HuggingFaceEndpoint(LLM): repetition_penalty=1.03, callbacks=callbacks, streaming=True, - huggingfacehub_api_token="my-api-key" + huggingfacehub_api_token="my-api-key", ) print(llm.invoke("What is Deep Learning?")) @@ -73,7 +73,7 @@ class HuggingFaceEndpoint(LLM): provider="novita", max_new_tokens=100, do_sample=False, - huggingfacehub_api_token="my-api-key" + huggingfacehub_api_token="my-api-key", ) print(llm.invoke("What is Deep Learning?")) diff --git a/libs/partners/huggingface/langchain_huggingface/llms/huggingface_pipeline.py b/libs/partners/huggingface/langchain_huggingface/llms/huggingface_pipeline.py index 740132b7a19..43bae871e5f 100644 --- a/libs/partners/huggingface/langchain_huggingface/llms/huggingface_pipeline.py +++ b/libs/partners/huggingface/langchain_huggingface/llms/huggingface_pipeline.py @@ -61,7 +61,10 @@ class HuggingFacePipeline(BaseLLM): tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained(model_id) pipe = pipeline( - "text-generation", model=model, tokenizer=tokenizer, max_new_tokens=10 + "text-generation", + model=model, + tokenizer=tokenizer, + max_new_tokens=10, ) hf = HuggingFacePipeline(pipeline=pipe) diff --git a/libs/partners/huggingface/pyproject.toml b/libs/partners/huggingface/pyproject.toml index a79fa9221af..d0cc9888e24 100644 --- a/libs/partners/huggingface/pyproject.toml +++ b/libs/partners/huggingface/pyproject.toml @@ -57,6 +57,10 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/mistralai/pyproject.toml b/libs/partners/mistralai/pyproject.toml index ff922d4a698..f7342935bdc 100644 --- a/libs/partners/mistralai/pyproject.toml +++ b/libs/partners/mistralai/pyproject.toml @@ -46,6 +46,9 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/nomic/pyproject.toml b/libs/partners/nomic/pyproject.toml index 7689abf3086..5ba6739f4ea 100644 --- a/libs/partners/nomic/pyproject.toml +++ b/libs/partners/nomic/pyproject.toml @@ -45,6 +45,9 @@ langchain-tests = { path = "../../standard-tests", editable = true } [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/ollama/langchain_ollama/chat_models.py b/libs/partners/ollama/langchain_ollama/chat_models.py index 2a40c147377..6c0504bd761 100644 --- a/libs/partners/ollama/langchain_ollama/chat_models.py +++ b/libs/partners/ollama/langchain_ollama/chat_models.py @@ -262,10 +262,10 @@ class ChatOllama(BaseChatModel): from langchain_ollama import ChatOllama llm = ChatOllama( - model = "gpt-oss:20b", - validate_model_on_init = True, - temperature = 0.8, - num_predict = 256, + model="gpt-oss:20b", + validate_model_on_init=True, + temperature=0.8, + num_predict=256, # other params ... ) @@ -307,7 +307,22 @@ class ChatOllama(BaseChatModel): .. code-block:: python - AIMessageChunk(content='Je adore le programmation.(Note: "programmation" is the formal way to say "programming" in French, but informally, people might use the phrase "le développement logiciel" or simply "le code")', response_metadata={'model': 'llama3', 'created_at': '2024-07-04T03:38:54.933154Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 1977300042, 'load_duration': 1345709, 'prompt_eval_duration': 159343000, 'eval_count': 47, 'eval_duration': 1815123000}, id='run-3c81a3ed-3e79-4dd3-a796-04064d804890') + AIMessageChunk( + content='Je adore le programmation.(Note: "programmation" is the formal way to say "programming" in French, but informally, people might use the phrase "le développement logiciel" or simply "le code")', + response_metadata={ + "model": "llama3", + "created_at": "2024-07-04T03:38:54.933154Z", + "message": {"role": "assistant", "content": ""}, + "done_reason": "stop", + "done": True, + "total_duration": 1977300042, + "load_duration": 1345709, + "prompt_eval_duration": 159343000, + "eval_count": 47, + "eval_duration": 1815123000, + }, + id="run-3c81a3ed-3e79-4dd3-a796-04064d804890", + ) Async: .. code-block:: python @@ -316,7 +331,23 @@ class ChatOllama(BaseChatModel): .. code-block:: python - AIMessage(content="Hi there! I'm just an AI, so I don't have feelings or emotions like humans do. But I'm functioning properly and ready to help with any questions or tasks you may have! How can I assist you today?", response_metadata={'model': 'llama3', 'created_at': '2024-07-04T03:52:08.165478Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 2138492875, 'load_duration': 1364000, 'prompt_eval_count': 10, 'prompt_eval_duration': 297081000, 'eval_count': 47, 'eval_duration': 1838524000}, id='run-29c510ae-49a4-4cdd-8f23-b972bfab1c49-0') + AIMessage( + content="Hi there! I'm just an AI, so I don't have feelings or emotions like humans do. But I'm functioning properly and ready to help with any questions or tasks you may have! How can I assist you today?", + response_metadata={ + "model": "llama3", + "created_at": "2024-07-04T03:52:08.165478Z", + "message": {"role": "assistant", "content": ""}, + "done_reason": "stop", + "done": True, + "total_duration": 2138492875, + "load_duration": 1364000, + "prompt_eval_count": 10, + "prompt_eval_duration": 297081000, + "eval_count": 47, + "eval_duration": 1838524000, + }, + id="run-29c510ae-49a4-4cdd-8f23-b972bfab1c49-0", + ) .. code-block:: python @@ -332,23 +363,57 @@ class ChatOllama(BaseChatModel): .. code-block:: python - messages = [ - ("human", "Say hello world!"), - ("human","Say goodbye world!") - ] + messages = [("human", "Say hello world!"), ("human", "Say goodbye world!")] await llm.abatch(messages) .. code-block:: python - [AIMessage(content='HELLO, WORLD!', response_metadata={'model': 'llama3', 'created_at': '2024-07-04T03:55:07.315396Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 1696745458, 'load_duration': 1505000, 'prompt_eval_count': 8, 'prompt_eval_duration': 111627000, 'eval_count': 6, 'eval_duration': 185181000}, id='run-da6c7562-e25a-4a44-987a-2c83cd8c2686-0'), - AIMessage(content="It's been a blast chatting with you! Say goodbye to the world for me, and don't forget to come back and visit us again soon!", response_metadata={'model': 'llama3', 'created_at': '2024-07-04T03:55:07.018076Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 1399391083, 'load_duration': 1187417, 'prompt_eval_count': 20, 'prompt_eval_duration': 230349000, 'eval_count': 31, 'eval_duration': 1166047000}, id='run-96cad530-6f3e-4cf9-86b4-e0f8abba4cdb-0')] + [ + AIMessage( + content="HELLO, WORLD!", + response_metadata={ + "model": "llama3", + "created_at": "2024-07-04T03:55:07.315396Z", + "message": {"role": "assistant", "content": ""}, + "done_reason": "stop", + "done": True, + "total_duration": 1696745458, + "load_duration": 1505000, + "prompt_eval_count": 8, + "prompt_eval_duration": 111627000, + "eval_count": 6, + "eval_duration": 185181000, + }, + id="run-da6c7562-e25a-4a44-987a-2c83cd8c2686-0", + ), + AIMessage( + content="It's been a blast chatting with you! Say goodbye to the world for me, and don't forget to come back and visit us again soon!", + response_metadata={ + "model": "llama3", + "created_at": "2024-07-04T03:55:07.018076Z", + "message": {"role": "assistant", "content": ""}, + "done_reason": "stop", + "done": True, + "total_duration": 1399391083, + "load_duration": 1187417, + "prompt_eval_count": 20, + "prompt_eval_duration": 230349000, + "eval_count": 31, + "eval_duration": 1166047000, + }, + id="run-96cad530-6f3e-4cf9-86b4-e0f8abba4cdb-0", + ), + ] JSON mode: .. code-block:: python json_llm = ChatOllama(format="json") - llm.invoke("Return a query for the weather in a random location and time of day with two keys: location and time_of_day. Respond using JSON only.").content + llm.invoke( + "Return a query for the weather in a random location and time of day with two keys: location and time_of_day. " + "Respond using JSON only." + ).content .. code-block:: python @@ -360,19 +425,25 @@ class ChatOllama(BaseChatModel): from langchain_ollama import ChatOllama from pydantic import BaseModel, Field + class Multiply(BaseModel): a: int = Field(..., description="First integer") b: int = Field(..., description="Second integer") + ans = await chat.invoke("What is 45*67") ans.tool_calls .. code-block:: python - [{'name': 'Multiply', - 'args': {'a': 45, 'b': 67}, - 'id': '420c3f3b-df10-4188-945f-eb3abdb40622', - 'type': 'tool_call'}] + [ + { + "name": "Multiply", + "args": {"a": 45, "b": 67}, + "id": "420c3f3b-df10-4188-945f-eb3abdb40622", + "type": "tool_call", + } + ] Thinking / Reasoning: You can enable reasoning mode for models that support it by setting @@ -394,9 +465,9 @@ class ChatOllama(BaseChatModel): from langchain_ollama import ChatOllama llm = ChatOllama( - model = "deepseek-r1:8b", - validate_model_on_init = True, - reasoning= True, + model="deepseek-r1:8b", + validate_model_on_init=True, + reasoning=True, ) llm.invoke("how many r in the word strawberry?") @@ -1118,18 +1189,15 @@ class ChatOllama(BaseChatModel): answer: str justification: Optional[str] = Field( - default=..., description="A justification for the answer." + default=..., + description="A justification for the answer.", ) llm = ChatOllama(model="llama3.1", temperature=0) - structured_llm = llm.with_structured_output( - AnswerWithJustification - ) + structured_llm = llm.with_structured_output(AnswerWithJustification) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> AnswerWithJustification( # answer='They weigh the same', @@ -1153,12 +1221,11 @@ class ChatOllama(BaseChatModel): llm = ChatOllama(model="llama3.1", temperature=0) structured_llm = llm.with_structured_output( - AnswerWithJustification, include_raw=True + AnswerWithJustification, + include_raw=True, ) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> { # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}), # 'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'), @@ -1180,18 +1247,18 @@ class ChatOllama(BaseChatModel): answer: str justification: Optional[str] = Field( - default=..., description="A justification for the answer." + default=..., + description="A justification for the answer.", ) llm = ChatOllama(model="llama3.1", temperature=0) structured_llm = llm.with_structured_output( - AnswerWithJustification, method="function_calling" + AnswerWithJustification, + method="function_calling", ) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> AnswerWithJustification( # answer='They weigh the same', @@ -1213,17 +1280,13 @@ class ChatOllama(BaseChatModel): '''An answer to the user question along with justification for the answer.''' answer: str - justification: Annotated[ - Optional[str], None, "A justification for the answer." - ] + justification: Annotated[Optional[str], None, "A justification for the answer."] llm = ChatOllama(model="llama3.1", temperature=0) structured_llm = llm.with_structured_output(AnswerWithJustification) - structured_llm.invoke( - "What weighs more a pound of bricks or a pound of feathers" - ) + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") # -> { # 'answer': 'They weigh the same', # 'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.' diff --git a/libs/partners/ollama/langchain_ollama/embeddings.py b/libs/partners/ollama/langchain_ollama/embeddings.py index 5f6c96a2997..97f49818f00 100644 --- a/libs/partners/ollama/langchain_ollama/embeddings.py +++ b/libs/partners/ollama/langchain_ollama/embeddings.py @@ -81,9 +81,7 @@ class OllamaEmbeddings(BaseModel, Embeddings): from langchain_ollama import OllamaEmbeddings - embed = OllamaEmbeddings( - model="llama3" - ) + embed = OllamaEmbeddings(model="llama3") Embed single text: .. code-block:: python diff --git a/libs/partners/ollama/pyproject.toml b/libs/partners/ollama/pyproject.toml index 4c61748f992..ea88797a42d 100644 --- a/libs/partners/ollama/pyproject.toml +++ b/libs/partners/ollama/pyproject.toml @@ -45,6 +45,10 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/openai/pyproject.toml b/libs/partners/openai/pyproject.toml index 63060afc644..ba93ecb59dd 100644 --- a/libs/partners/openai/pyproject.toml +++ b/libs/partners/openai/pyproject.toml @@ -62,17 +62,13 @@ ignore_missing_imports = true [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = ["E", "F", "I", "T201", "UP", "S"] ignore = [ "UP007", "UP045" ] -[tool.ruff.format] -docstring-code-format = true -skip-magic-trailing-comma = true - -[tool.ruff.lint.isort] -split-on-trailing-comma = false - [tool.coverage.run] omit = ["tests/*"] diff --git a/libs/partners/perplexity/pyproject.toml b/libs/partners/perplexity/pyproject.toml index 0b613463311..b43ed099ed6 100644 --- a/libs/partners/perplexity/pyproject.toml +++ b/libs/partners/perplexity/pyproject.toml @@ -57,17 +57,13 @@ ignore_missing_imports = true [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = ["E", "F", "I", "T201", "UP", "S"] ignore = [ "UP007", "UP045"] -[tool.ruff.format] -docstring-code-format = true -skip-magic-trailing-comma = true - -[tool.ruff.lint.isort] -split-on-trailing-comma = false - [tool.coverage.run] omit = ["tests/*"] diff --git a/libs/partners/prompty/pyproject.toml b/libs/partners/prompty/pyproject.toml index 57e3d9b005a..476d9c3a102 100644 --- a/libs/partners/prompty/pyproject.toml +++ b/libs/partners/prompty/pyproject.toml @@ -53,6 +53,9 @@ langchain-tests = { path = "../../standard-tests", editable = true } [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = ["E", "F", "I", "T201", "UP", "S"] ignore = [ "UP007", "UP045" ] diff --git a/libs/partners/qdrant/langchain_qdrant/qdrant.py b/libs/partners/qdrant/langchain_qdrant/qdrant.py index d6be80dcc5e..4a41cbee1d6 100644 --- a/libs/partners/qdrant/langchain_qdrant/qdrant.py +++ b/libs/partners/qdrant/langchain_qdrant/qdrant.py @@ -99,32 +99,58 @@ class QdrantVectorStore(VectorStore): Search: .. code-block:: python - results = vector_store.similarity_search(query="thud",k=1) + results = vector_store.similarity_search( + query="thud", + k=1, + ) for doc in results: print(f"* {doc.page_content} [{doc.metadata}]") .. code-block:: python - * thud [{'bar': 'baz', '_id': '0d706099-6dd9-412a-9df6-a71043e020de', '_collection_name': 'demo_collection'}] + *thud[ + { + "bar": "baz", + "_id": "0d706099-6dd9-412a-9df6-a71043e020de", + "_collection_name": "demo_collection", + } + ] Search with filter: .. code-block:: python from qdrant_client.http import models - results = vector_store.similarity_search(query="thud",k=1,filter=models.Filter(must=[models.FieldCondition(key="metadata.bar", match=models.MatchValue(value="baz"),)])) + results = vector_store.similarity_search( + query="thud", + k=1, + filter=models.Filter( + must=[ + models.FieldCondition( + key="metadata.bar", + match=models.MatchValue(value="baz"), + ) + ] + ), + ) for doc in results: print(f"* {doc.page_content} [{doc.metadata}]") .. code-block:: python - * thud [{'bar': 'baz', '_id': '0d706099-6dd9-412a-9df6-a71043e020de', '_collection_name': 'demo_collection'}] + *thud[ + { + "bar": "baz", + "_id": "0d706099-6dd9-412a-9df6-a71043e020de", + "_collection_name": "demo_collection", + } + ] Search with score: .. code-block:: python - results = vector_store.similarity_search_with_score(query="qux",k=1) + results = vector_store.similarity_search_with_score(query="qux", k=1) for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") @@ -145,8 +171,8 @@ class QdrantVectorStore(VectorStore): # results = vector_store.asimilarity_search(query="thud",k=1) # search with score - results = await vector_store.asimilarity_search_with_score(query="qux",k=1) - for doc,score in results: + results = await vector_store.asimilarity_search_with_score(query="qux", k=1) + for doc, score in results: print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]") .. code-block:: python @@ -164,7 +190,16 @@ class QdrantVectorStore(VectorStore): .. code-block:: python - [Document(metadata={'bar': 'baz', '_id': '0d706099-6dd9-412a-9df6-a71043e020de', '_collection_name': 'demo_collection'}, page_content='thud')] + [ + Document( + metadata={ + "bar": "baz", + "_id": "0d706099-6dd9-412a-9df6-a71043e020de", + "_collection_name": "demo_collection", + }, + page_content="thud", + ) + ] """ # noqa: E501 diff --git a/libs/partners/qdrant/langchain_qdrant/vectorstores.py b/libs/partners/qdrant/langchain_qdrant/vectorstores.py index d4df2459199..b642edd2f65 100644 --- a/libs/partners/qdrant/langchain_qdrant/vectorstores.py +++ b/libs/partners/qdrant/langchain_qdrant/vectorstores.py @@ -1342,6 +1342,7 @@ class Qdrant(VectorStore): from langchain_qdrant import Qdrant from langchain_openai import OpenAIEmbeddings + embeddings = OpenAIEmbeddings() qdrant = Qdrant.from_texts(texts, embeddings, "localhost") @@ -1583,6 +1584,7 @@ class Qdrant(VectorStore): from langchain_qdrant import Qdrant from langchain_openai import OpenAIEmbeddings + embeddings = OpenAIEmbeddings() qdrant = await Qdrant.afrom_texts(texts, embeddings, "localhost") diff --git a/libs/partners/qdrant/pyproject.toml b/libs/partners/qdrant/pyproject.toml index a293649f3eb..1a9df642706 100644 --- a/libs/partners/qdrant/pyproject.toml +++ b/libs/partners/qdrant/pyproject.toml @@ -52,6 +52,9 @@ langchain-tests = { path = "../../standard-tests", editable = true } [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] select = [ "A", # flake8-builtins diff --git a/libs/partners/xai/langchain_xai/chat_models.py b/libs/partners/xai/langchain_xai/chat_models.py index 9137294543b..1e67c2cf4bc 100644 --- a/libs/partners/xai/langchain_xai/chat_models.py +++ b/libs/partners/xai/langchain_xai/chat_models.py @@ -92,14 +92,23 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] AIMessage( content="J'adore la programmation.", response_metadata={ - 'token_usage': {'completion_tokens': 9, 'prompt_tokens': 32, 'total_tokens': 41}, - 'model_name': 'grok-4', - 'system_fingerprint': None, - 'finish_reason': 'stop', - 'logprobs': None + "token_usage": { + "completion_tokens": 9, + "prompt_tokens": 32, + "total_tokens": 41, + }, + "model_name": "grok-4", + "system_fingerprint": None, + "finish_reason": "stop", + "logprobs": None, }, - id='run-168dceca-3b8b-4283-94e3-4c739dbc1525-0', - usage_metadata={'input_tokens': 32, 'output_tokens': 9, 'total_tokens': 41}) + id="run-168dceca-3b8b-4283-94e3-4c739dbc1525-0", + usage_metadata={ + "input_tokens": 32, + "output_tokens": 9, + "total_tokens": 41, + }, + ) Stream: .. code-block:: python @@ -136,14 +145,23 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] AIMessage( content="J'adore la programmation.", response_metadata={ - 'token_usage': {'completion_tokens': 9, 'prompt_tokens': 32, 'total_tokens': 41}, - 'model_name': 'grok-4', - 'system_fingerprint': None, - 'finish_reason': 'stop', - 'logprobs': None + "token_usage": { + "completion_tokens": 9, + "prompt_tokens": 32, + "total_tokens": 41, + }, + "model_name": "grok-4", + "system_fingerprint": None, + "finish_reason": "stop", + "logprobs": None, }, - id='run-09371a11-7f72-4c53-8e7c-9de5c238b34c-0', - usage_metadata={'input_tokens': 32, 'output_tokens': 9, 'total_tokens': 41}) + id="run-09371a11-7f72-4c53-8e7c-9de5c238b34c-0", + usage_metadata={ + "input_tokens": 32, + "output_tokens": 9, + "total_tokens": 41, + }, + ) Reasoning: `Certain xAI models `__ support reasoning, @@ -179,41 +197,38 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] llm = ChatXAI(model="grok-4") + class GetWeather(BaseModel): '''Get the current weather in a given location''' - location: str = Field( - ..., description="The city and state, e.g. San Francisco, CA" - ) + 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" - ) + location: str = Field(..., description="The city and state, e.g. San Francisco, CA") + llm_with_tools = llm.bind_tools([GetWeather, GetPopulation]) - ai_msg = llm_with_tools.invoke( - "Which city is bigger: LA or NY?" - ) + ai_msg = llm_with_tools.invoke("Which city is bigger: LA or NY?") ai_msg.tool_calls .. code-block:: python [ { - 'name': 'GetPopulation', - 'args': {'location': 'NY'}, - 'id': 'call_m5tstyn2004pre9bfuxvom8x', - 'type': 'tool_call' + "name": "GetPopulation", + "args": {"location": "NY"}, + "id": "call_m5tstyn2004pre9bfuxvom8x", + "type": "tool_call", }, { - 'name': 'GetPopulation', - 'args': {'location': 'LA'}, - 'id': 'call_0vjgq455gq1av5sp9eb1pw6a', - 'type': 'tool_call' - } + "name": "GetPopulation", + "args": {"location": "LA"}, + "id": "call_0vjgq455gq1av5sp9eb1pw6a", + "type": "tool_call", + }, ] .. note:: @@ -267,10 +282,14 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] .. code-block:: python - [{'name': 'GetWeather', - 'args': {'location': 'Los Angeles, CA'}, - 'id': 'call_81668711', - 'type': 'tool_call'}] + [ + { + "name": "GetWeather", + "args": {"location": "Los Angeles, CA"}, + "id": "call_81668711", + "type": "tool_call", + } + ] Parallel tool calling / parallel function calling: By default, parallel tool / function calling is enabled, so you can process @@ -299,9 +318,9 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] .. code-block:: python Joke( - setup='Why was the cat sitting on the computer?', - punchline='To keep an eye on the mouse!', - rating=7 + setup="Why was the cat sitting on the computer?", + punchline="To keep an eye on the mouse!", + rating=7, ) Live Search: @@ -320,7 +339,7 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] "max_search_results": 3, "from_date": "2025-05-26", "to_date": "2025-05-27", - } + }, ) llm.invoke("Provide me a digest of world news in the last 24 hours.") @@ -337,23 +356,23 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] .. code-block:: python - {'input_tokens': 37, 'output_tokens': 6, 'total_tokens': 43} + {"input_tokens": 37, "output_tokens": 6, "total_tokens": 43} Logprobs: .. code-block:: python logprobs_llm = llm.bind(logprobs=True) - messages=[("human","Say Hello World! Do not return anything else.")] + messages = [("human", "Say Hello World! Do not return anything else.")] ai_msg = logprobs_llm.invoke(messages) ai_msg.response_metadata["logprobs"] .. code-block:: python { - 'content': None, - 'token_ids': [22557, 3304, 28808, 2], - 'tokens': [' Hello', ' World', '!', ''], - 'token_logprobs': [-4.7683716e-06, -5.9604645e-07, 0, -0.057373047] + "content": None, + "token_ids": [22557, 3304, 28808, 2], + "tokens": [" Hello", " World", "!", ""], + "token_logprobs": [-4.7683716e-06, -5.9604645e-07, 0, -0.057373047], } Response metadata @@ -365,15 +384,15 @@ class ChatXAI(BaseChatOpenAI): # type: ignore[override] .. code-block:: python { - 'token_usage': { - 'completion_tokens': 4, - 'prompt_tokens': 19, - 'total_tokens': 23 - }, - 'model_name': 'grok-4', - 'system_fingerprint': None, - 'finish_reason': 'stop', - 'logprobs': None + "token_usage": { + "completion_tokens": 4, + "prompt_tokens": 19, + "total_tokens": 23, + }, + "model_name": "grok-4", + "system_fingerprint": None, + "finish_reason": "stop", + "logprobs": None, } """ # noqa: E501 diff --git a/libs/partners/xai/pyproject.toml b/libs/partners/xai/pyproject.toml index f2cb35c909e..11c9b7591f6 100644 --- a/libs/partners/xai/pyproject.toml +++ b/libs/partners/xai/pyproject.toml @@ -52,6 +52,10 @@ disallow_untyped_defs = "True" [tool.ruff] target-version = "py39" +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 100 + [tool.ruff.lint] select = [ "A", # flake8-builtins