diff --git a/.github/workflows/uv_lock_ugprade.yml b/.github/workflows/uv_lock_ugprade.yml index 8acd39393..75d74890c 100644 --- a/.github/workflows/uv_lock_ugprade.yml +++ b/.github/workflows/uv_lock_ugprade.yml @@ -30,11 +30,11 @@ jobs: run: make lock-upgrade - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "chore: upgrade dependencies with `uv lock --upgrade`" - title: "chore: upgrade dependencies with `uv lock --upgrade`" + commit-message: "chore[deps]: upgrade dependencies with `uv lock --upgrade`" + title: "chore[deps]: upgrade dependencies with `uv lock --upgrade`" body: | This PR updates the dependencies in all Python packages using `uv lock --upgrade`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a4e9a3eca..48fd5593f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,7 @@ In LangGraph, these are often higher level guides that show off end-to-end use c Some examples include: - [Build a Customer Support Bot](https://langchain-ai.github.io/langgraph/tutorials/customer-support/customer-support/) -- [Build a SQL Agent](https://langchain-ai.github.io/langgraph/tutorials/sql-agent/) +- [Build a SQL Agent](https://langchain-ai.github.io/langgraph/tutorials/sql/sql-agent/) Here are some high-level tips on writing a good tutorial: diff --git a/docs/_scripts/generate_llms_text.py b/docs/_scripts/generate_llms_text.py index ff981834e..a262549c9 100644 --- a/docs/_scripts/generate_llms_text.py +++ b/docs/_scripts/generate_llms_text.py @@ -14,10 +14,7 @@ from mkdocs.structure.pages import Page from pydantic import BaseModel, Field from yaml import SafeLoader -from _scripts.notebook_hooks import ( - _on_page_markdown_with_config, - _apply_conditional_rendering, -) +from _scripts.notebook_hooks import _on_page_markdown_with_config HERE = os.path.dirname(os.path.abspath(__file__)) # Get source directory (parent of HERE / docs) diff --git a/docs/_scripts/notebook_hooks.py b/docs/_scripts/notebook_hooks.py index 7b7f049eb..db31e41ce 100644 --- a/docs/_scripts/notebook_hooks.py +++ b/docs/_scripts/notebook_hooks.py @@ -72,6 +72,7 @@ REDIRECT_MAP = { "how-tos/pass-config-to-tools.ipynb": "how-tos/tool-calling.ipynb#access-config", "how-tos/pass-run-time-values-to-tools.ipynb": "how-tos/tool-calling.ipynb#read-state", "how-tos/update-state-from-tools.ipynb": "how-tos/tool-calling.ipynb#update-state", + "agents/tools.md": "how-tos/tool-calling.md", # multi-agent how-tos "how-tos/agent-handoffs.ipynb": "how-tos/multi_agent.md#handoffs", "how-tos/multi-agent-network.ipynb": "how-tos/multi_agent.md#use-in-a-multi-agent-system", diff --git a/docs/docs/additional-resources/index.md b/docs/docs/additional-resources/index.md new file mode 100644 index 000000000..6e4e7a93b --- /dev/null +++ b/docs/docs/additional-resources/index.md @@ -0,0 +1,11 @@ +# Additional resources + +This section contains additional resources for LangGraph. + +- [Community agents](../agents/prebuilt.md): A collection of prebuilt libraries that you can use in your LangGraph applications. +- [LangGraph Academy](https://academy.langchain.com/courses/intro-to-langgraph): A collection of courses that teach you how to use LangGraph. +- [Case studies](../adopters.md): A collection of case studies that show how LangGraph is used in production. +- [FAQ](../concepts/faq.md): A collection of frequently asked questions about LangGraph. +- [llms.txt](../llms-txt-overview.md): A list of documentation files in the `llms.txt` format that allow LLMs and agents to access our documentation. +- [LangChain Forum](https://forum.langchain.com/): A place to ask questions and get help from other LangGraph users. +- [Troubleshooting](../troubleshooting/errors/index.md.md): A collection of troubleshooting guides for common issues. \ No newline at end of file diff --git a/docs/docs/adopters.md b/docs/docs/adopters.md index 91142d44f..d2b8a278b 100644 --- a/docs/docs/adopters.md +++ b/docs/docs/adopters.md @@ -8,24 +8,41 @@ This list of companies using LangGraph and their success stories is compiled fro | [AirTop](https://www.airtop.ai/) | Software & Technology (GenAI Native) | Browser automation for AI agents | [Case study, 2024](https://blog.langchain.dev/customers-airtop/) | | [AppFolio](https://www.appfolio.com/) | Real Estate | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-appfolio/) | | [Athena Intelligence](https://www.athenaintel.com/) | Software & Technology (GenAI Native) | Research & summarization | [Case study, 2024](https://blog.langchain.dev/customers-athena-intelligence/) | +| [BlackRock](https://www.blackrock.com/) | Financial Services | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/oyqeCHFM5U4?feature=shared) | | [Captide](https://www.captide.co/) | Software & Technology (GenAI Native) | Data extraction | [Case study, 2025](https://blog.langchain.dev/how-captide-is-redefining-equity-research-with-agentic-workflows-built-on-langgraph-and-langsmith/) | -| [Cisco Outshift](https://outshift.cisco.com/) | Software & Technology | DevOps | [Blog post, 2025](https://outshift.cisco.com/blog/build-react-agent-application-for-devops-tasks-using-rest-apis) | +| [Cisco CX](https://www.cisco.com/site/us/en/services/modern-data-center/index.html?CCID=cc005911&DTID=eivtotr001480&OID=srwsas032775) | Software & Technology | Customer support | [Interrupt Talk, 2025](https://youtu.be/gPhyPRtIMn0?feature=shared) | +| [Cisco Outshift](https://outshift.cisco.com/) | Software & Technology | DevOps | [Video story, 2025](https://www.youtube.com/watch?v=htcb-vGR_x0); [Case study, 2025](https://blog.langchain.com/cisco-outshift/); [Blog post, 2025](https://outshift.cisco.com/blog/build-react-agent-application-for-devops-tasks-using-rest-apis) | +| [Cisco TAC](https://www.cisco.com/c/en/us/support/index.html) | Software & Technology | Customer support | [Video story, 2025](https://youtu.be/EAj0HBDGqaE?feature=shared) | +| [City of Hope](https://www.cityofhope.org/) | Non-profit | Copilot for domain-specific task | [Video story, 2025](https://youtu.be/9ABwtK2gIZU?feature=shared) | | [C.H. Robinson](https://www.chrobinson.com/en-us/) | Logistics | Automation | [Case study, 2025](https://blog.langchain.dev/customers-chrobinson/) | +| [Definely](https://www.definely.com/) | Legal | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.com/customers-definely/) | +| [Docent Pro](https://docentpro.com/) | Travel | GenAI embedded product experiences | [Case study, 2025](https://blog.langchain.com/customers-docentpro/) | | [Elastic](https://www.elastic.co/) | Software & Technology | Copilot for domain-specific task | [Blog post, 2025](https://www.elastic.co/blog/elastic-security-generative-ai-features) | +| [Exa](https://exa.ai/) | Software & Technology (GenAI Native) | Search | [Case study, 2025](https://blog.langchain.com/exa/) | | [GitLab](https://about.gitlab.com/) | Software & Technology | Code generation | [Duo workflow docs](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/duo_workflow/) | +| [Harmonic](https://harmonic.ai/) | Software & Technology | Search | [Case study, 2025](https://blog.langchain.com/customers-harmonic/) | | [Inconvo](https://inconvo.ai/?ref=blog.langchain.dev) | Software & Technology | Code generation | [Case study, 2025](https://blog.langchain.dev/customers-inconvo/) | | [Infor](https://infor.com/) | Software & Technology | GenAI embedded product experiences; customer support; copilot | [Case study, 2025](https://blog.langchain.dev/customers-infor/) | +| [J.P. Morgan](https://www.jpmorganchase.com/) | Financial Services | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/yMalr0jiOAc?feature=shared) | | [Klarna](https://www.klarna.com/) | Fintech | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.dev/customers-klarna/) | | [Komodo Health](https://www.komodohealth.com/) | Healthcare | Copilot for domain-specific task | [Blog post](https://www.komodohealth.com/perspectives/new-gen-ai-assistant-empowers-the-enterprise/) | -| [LinkedIn](https://www.linkedin.com/) | Social Media | Code generation; Search & discovery | [Blog post, 2025](https://www.linkedin.com/blog/engineering/ai/practical-text-to-sql-for-data-analytics); [Blog post, 2024](https://www.linkedin.com/blog/engineering/generative-ai/behind-the-platform-the-journey-to-create-the-linkedin-genai-application-tech-stack) | +| [LinkedIn](https://www.linkedin.com/) | Social Media | Code generation; Search & discovery | [Interrupt talk, 2025](https://youtu.be/NmblVxyBhi8?feature=shared); [Blog post, 2025](https://www.linkedin.com/blog/engineering/ai/practical-text-to-sql-for-data-analytics); [Blog post, 2024](https://www.linkedin.com/blog/engineering/generative-ai/behind-the-platform-the-journey-to-create-the-linkedin-genai-application-tech-stack) | | [Minimal](https://gominimal.ai/) | E-commerce | Customer support | [Case study, 2025](https://blog.langchain.dev/how-minimal-built-a-multi-agent-customer-support-system-with-langgraph-langsmith/) | +| [Modern Treasury](https://www.moderntreasury.com/) | Fintech | GenAI embedded product experiences | [Video story, 2025](https://youtu.be/AwAiffXqaCU?feature=shared) | +| [Monday](https://monday.com/) | Software & Technology | GenAI embedded product experiences | [Interrupt talk, 2025](https://blog.langchain.dev/how-minimal-built-a-multi-agent-customer-support-system-with-langgraph-langsmith/) | +| [Morningstar](https://www.morningstar.com/) | Financial Services | Research & summarization | [Video story, 2025](https://youtu.be/6LidoFXCJPs?feature=shared) | | [OpenRecovery](https://www.openrecovery.com/) | Healthcare | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-openrecovery/) | +| [Pigment](https://www.pigment.com/) | Fintech | GenAI embedded product experiences | [Video story, 2025](https://youtu.be/5JVSO2KYOmE?feature=shared) | +| [Prosper](https://www.prosper.com/) | Fintech | Customer support | [Video story, 2025](https://youtu.be/9RFNOYtkwsc?feature=shared) | | [Qodo](https://www.qodo.ai/) | Software & Technology (GenAI Native) | Code generation | [Blog post, 2025](https://www.qodo.ai/blog/why-we-chose-langgraph-to-build-our-coding-agent/) | -| [Rakuten](https://www.rakuten.com/) | E-commerce / Fintech | Copilot for domain-specific task | [Blog post, 2025](https://rakuten.today/blog/from-ai-hype-to-real-world-tools-rakuten-teams-up-with-langchain.html) | +| [Rakuten](https://www.rakuten.com/) | E-commerce / Fintech | Copilot for domain-specific task | [Video story, 2025](https://youtu.be/gD1LIjCkuA8?feature=shared); [Blog post, 2025](https://rakuten.today/blog/from-ai-hype-to-real-world-tools-rakuten-teams-up-with-langchain.html) | | [Replit](https://replit.com/) | Software & Technology | Code generation | [Blog post, 2024](https://blog.langchain.dev/customers-replit/); [Breakout agent story, 2024](https://www.langchain.com/breakoutagents/replit); [Fireside chat video, 2024](https://www.youtube.com/watch?v=ViykMqljjxU) | | [Rexera](https://www.rexera.com/) | Real Estate (GenAI Native) | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-rexera/) | +| [Abu Dhabi Government](https://www.tamm.abudhabi/) | Government | Search | [Case study, 2025](https://blog.langchain.com/customers-abu-dhabi-government/) | | [Tradestack](https://www.tradestack.uk/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-tradestack/) | -| [Uber](https://www.uber.com/) | Transportation | Developer productivity; Code generation | [Presentation, 2024](https://dpe.org/sessions/ty-smith-adam-huda/this-year-in-ubers-ai-driven-developer-productivity-revolution/); [Video, 2024](https://www.youtube.com/watch?v=8rkA5vWUE4Y) | -| [Unify](https://www.unifygtm.com/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Blog post, 2024](https://blog.langchain.dev/unify-launches-agents-for-account-qualification-using-langgraph-and-langsmith/) | -| [Vizient](https://www.vizientinc.com/) | Healthcare | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.dev/p/3d2cd58c-13a5-4df9-bd84-7d54ed0ed82c/) | +| [Uber](https://www.uber.com/) | Transportation | Developer productivity; Code generation | [Interrupt talk, 2025](https://youtu.be/Bugs0dVcNI8?feature=shared); [Presentation, 2024](https://dpe.org/sessions/ty-smith-adam-huda/this-year-in-ubers-ai-driven-developer-productivity-revolution/); [Video, 2024](https://www.youtube.com/watch?v=8rkA5vWUE4Y) | +| [Unify](https://www.unifygtm.com/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/pKk-LfhujwI?feature=shared); [Blog post, 2024](https://blog.langchain.dev/unify-launches-agents-for-account-qualification-using-langgraph-and-langsmith/) | +| [Vizient](https://www.vizientinc.com/) | Healthcare | Copilot for domain-specific task | [Video story, 2025](https://www.youtube.com/watch?v=vrjJ6NuyTWA); [Case study, 2025](https://blog.langchain.dev/p/3d2cd58c-13a5-4df9-bd84-7d54ed0ed82c/) | | [Vodafone](https://www.vodafone.com/) | Telecommunications | Code generation; internal search | [Case study, 2025](https://blog.langchain.dev/customers-vodafone/) | +| [WebToon](https://www.webtoons.com/en/) | Media & Entertainment | Data extraction | [Case study, 2025](https://blog.langchain.com/customers-webtoon/) | +| [11x](https://www.11x.ai/) | Software & Technology (GenAI Native) | Research & outreach | [Interrupt talk, 2025](https://youtu.be/fegwPmaAPQk?feature=shared) | diff --git a/docs/docs/agents/agents.md b/docs/docs/agents/agents.md index b00184266..04ee419ce 100644 --- a/docs/docs/agents/agents.md +++ b/docs/docs/agents/agents.md @@ -52,7 +52,7 @@ agent.invoke( ) ``` -1. Define a tool for the agent to use. Tools can be defined as vanilla Python functions. For more advanced tool usage and customization, check the [tools](./tools.md) page. +1. Define a tool for the agent to use. Tools can be defined as vanilla Python functions. For more advanced tool usage and customization, check the [tools](../how-tos/tool-calling.md) page. 2. Provide a language model for the agent to use. To learn more about configuring language models for the agents, check the [models](./models.md) page. 3. Provide a list of tools for the model to use. 4. Provide a system prompt (instructions) to the language model used by the agent. diff --git a/docs/docs/agents/overview.md b/docs/docs/agents/overview.md index d61b9d6ed..96fef74b3 100644 --- a/docs/docs/agents/overview.md +++ b/docs/docs/agents/overview.md @@ -60,7 +60,7 @@ Use the following tool to visualize the graph generated by and to view an outline of the corresponding code. It allows you to explore the infrastructure of the agent as defined by the presence of: -* [`tools`](../agents/tools.md): A list of tools (functions, APIs, or other callable objects) that the agent can use to perform tasks. +* [`tools`](../how-tos/tool-calling.md): A list of tools (functions, APIs, or other callable objects) that the agent can use to perform tasks. * [`pre_model_hook`](../how-tos/create-react-agent-manage-message-history.ipynb): A function that is called before the model is invoked. It can be used to condense messages or perform other preprocessing tasks. * `post_model_hook`: A function that is called after the model is invoked. It can be used to implement guardrails, human-in-the-loop flows, or other postprocessing tasks. * [`response_format`](../agents/agents.md#6-configure-structured-output): A data structure used to constrain the type of the final output, e.g., a `pydantic` `BaseModel`. diff --git a/docs/docs/agents/tools.md b/docs/docs/agents/tools.md deleted file mode 100644 index e9f45effb..000000000 --- a/docs/docs/agents/tools.md +++ /dev/null @@ -1,310 +0,0 @@ ---- -search: - boost: 2 -tags: - - agent -hide: - - tags ---- - -# Tools - -[Tools](https://python.langchain.com/docs/concepts/tools/) are a way to encapsulate a function and its input schema in a way that can be passed to a chat model that supports tool calling. This allows the model to request the execution of this function with specific inputs. - -You can either [define your own tools](#define-simple-tools) or use [prebuilt integrations](#prebuilt-tools) that LangChain provides. - -## Define simple tools - -You can pass a vanilla function to `create_react_agent` to use as a tool: - -```python -from langgraph.prebuilt import create_react_agent - -def multiply(a: int, b: int) -> int: - """Multiply two numbers.""" - return a * b - -create_react_agent( - model="anthropic:claude-3-7-sonnet", - tools=[multiply] -) -``` - -`create_react_agent` automatically converts vanilla functions to [LangChain tools](https://python.langchain.com/docs/concepts/tools/#tool-interface). - -## Customize tools - -For more control over tool behavior, use the `@tool` decorator: - -```python -# highlight-next-line -from langchain_core.tools import tool - -# highlight-next-line -@tool("multiply_tool", parse_docstring=True) -def multiply(a: int, b: int) -> int: - """Multiply two numbers. - - Args: - a: First operand - b: Second operand - """ - return a * b -``` - -You can also define a custom input schema using Pydantic: - -```python -from pydantic import BaseModel, Field - -class MultiplyInputSchema(BaseModel): - """Multiply two numbers""" - a: int = Field(description="First operand") - b: int = Field(description="Second operand") - -# highlight-next-line -@tool("multiply_tool", args_schema=MultiplyInputSchema) -def multiply(a: int, b: int) -> int: - return a * b -``` - -For additional customization, refer to the [custom tools guide](https://python.langchain.com/docs/how_to/custom_tools/). - -## Hide arguments from the model - -Some tools require runtime-only arguments (e.g., user ID or session context) that should not be controllable by the model. - -You can put these arguments in the `state` or `config` of the agent, and access -this information inside the tool: - -```python -from langgraph.prebuilt import InjectedState -from langgraph.prebuilt.chat_agent_executor import AgentState -from langchain_core.runnables import RunnableConfig - -def my_tool( - # This will be populated by an LLM - tool_arg: str, - # access information that's dynamically updated inside the agent - # highlight-next-line - state: Annotated[AgentState, InjectedState], - # access static data that is passed at agent invocation - # highlight-next-line - config: RunnableConfig, -) -> str: - """My tool.""" - do_something_with_state(state["messages"]) - do_something_with_config(config) - ... -``` - -## Disable parallel tool calling - -Some model providers support executing multiple tools in parallel, but -allow users to disable this feature. - -For supported providers, you can disable parallel tool calling by setting `parallel_tool_calls=False` via the `model.bind_tools()` method: - -```python -from langchain.chat_models import init_chat_model - -def add(a: int, b: int) -> int: - """Add two numbers""" - return a + b - -def multiply(a: int, b: int) -> int: - """Multiply two numbers.""" - return a * b - -model = init_chat_model("anthropic:claude-3-5-sonnet-latest", temperature=0) -tools = [add, multiply] -agent = create_react_agent( - # disable parallel tool calls - # highlight-next-line - model=model.bind_tools(tools, parallel_tool_calls=False), - tools=tools -) - -agent.invoke( - {"messages": [{"role": "user", "content": "what's 3 + 5 and 4 * 7?"}]} -) -``` - -## Return tool results directly - -Use `return_direct=True` to return tool results immediately and stop the agent loop: - -```python -from langchain_core.tools import tool - -# highlight-next-line -@tool(return_direct=True) -def add(a: int, b: int) -> int: - """Add two numbers""" - return a + b - -agent = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=[add] -) - -agent.invoke( - {"messages": [{"role": "user", "content": "what's 3 + 5?"}]} -) -``` - -## Force tool use - -To force the agent to use specific tools, you can set the `tool_choice` option in `model.bind_tools()`: - -```python -from langchain_core.tools import tool - -# highlight-next-line -@tool(return_direct=True) -def greet(user_name: str) -> int: - """Greet user.""" - return f"Hello {user_name}!" - -tools = [greet] - -agent = create_react_agent( - # highlight-next-line - model=model.bind_tools(tools, tool_choice={"type": "tool", "name": "greet"}), - tools=tools -) - -agent.invoke( - {"messages": [{"role": "user", "content": "Hi, I am Bob"}]} -) -``` - -!!! Warning "Avoid infinite loops" - - Forcing tool usage without stopping conditions can create infinite loops. Use one of the following safeguards: - - - Mark the tool with [`return_direct=True`](#return-tool-results-directly) to end the loop after execution. - - Set [`recursion_limit`](../concepts/low_level.md#recursion-limit) to restrict the number of execution steps. - -## Handle tool errors - -By default, the agent will catch all exceptions raised during tool calls and will pass those as tool messages to the LLM. To control how the errors are handled, you can use the prebuilt [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] — the node that executes tools inside `create_react_agent` — via its `handle_tool_errors` parameter: - -=== "Enable error handling (default)" - - ```python - from langgraph.prebuilt import create_react_agent - - def multiply(a: int, b: int) -> int: - """Multiply two numbers.""" - if a == 42: - raise ValueError("The ultimate error") - return a * b - - # Run with error handling (default) - agent = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=[multiply] - ) - agent.invoke( - {"messages": [{"role": "user", "content": "what's 42 x 7?"}]} - ) - ``` - -=== "Disable error handling" - - ```python - from langgraph.prebuilt import create_react_agent, ToolNode - - def multiply(a: int, b: int) -> int: - """Multiply two numbers.""" - if a == 42: - raise ValueError("The ultimate error") - return a * b - - # highlight-next-line - tool_node = ToolNode( - [multiply], - # highlight-next-line - handle_tool_errors=False # (1)! - ) - agent_no_error_handling = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=tool_node - ) - agent_no_error_handling.invoke( - {"messages": [{"role": "user", "content": "what's 42 x 7?"}]} - ) - ``` - - 1. This disables error handling (enabled by default). See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode]. - -=== "Custom error handling" - - ```python - from langgraph.prebuilt import create_react_agent, ToolNode - - def multiply(a: int, b: int) -> int: - """Multiply two numbers.""" - if a == 42: - raise ValueError("The ultimate error") - return a * b - - # highlight-next-line - tool_node = ToolNode( - [multiply], - # highlight-next-line - handle_tool_errors=( - "Can't use 42 as a first operand, you must switch operands!" # (1)! - ) - ) - agent_custom_error_handling = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=tool_node - ) - agent_custom_error_handling.invoke( - {"messages": [{"role": "user", "content": "what's 42 x 7?"}]} - ) - ``` - - 1. This provides a custom message to send to the LLM in case of an exception. See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode]. - -See [API reference][langgraph.prebuilt.tool_node.ToolNode] for more information on different tool error handling options. - -## Working with memory - -LangGraph allows access to short-term and long-term memory from tools. See [Memory](../how-tos/memory/add-memory.md) guide for more information on: - -* how to [read](../how-tos/memory/add-memory.md#read-short-term) from and [write](../how-tos/memory/add-memory.md#write-short-term) to **short-term** memory -* how to [read](../how-tos/memory/add-memory.md#read-long-term) from and [write](../how-tos/memory/add-memory.md#write-long-term) to **long-term** memory - -## Prebuilt tools - -You can use prebuilt tools from model providers by passing a dictionary with tool specs to the `tools` parameter of `create_react_agent`. For example, to use the `web_search_preview` tool from OpenAI: - -```python -from langgraph.prebuilt import create_react_agent - -agent = create_react_agent( - model="openai:gpt-4o-mini", - tools=[{"type": "web_search_preview"}] -) -response = agent.invoke( - {"messages": ["What was a positive news story from today?"]} -) -``` - -Additionally, LangChain supports a wide range of prebuilt tool integrations for interacting with APIs, databases, file systems, web data, and more. These tools extend the functionality of agents and enable rapid development. - -You can browse the full list of available integrations in the [LangChain integrations directory](https://python.langchain.com/docs/integrations/tools/). - -Some commonly used tool categories include: - -- **Search**: Bing, SerpAPI, Tavily -- **Code interpreters**: Python REPL, Node.js REPL -- **Databases**: SQL, MongoDB, Redis -- **Web data**: Web scraping and browsing -- **APIs**: OpenWeatherMap, NewsAPI, and others - -These integrations can be configured and added to your agents using the same `tools` parameter shown in the examples above. - diff --git a/docs/docs/cloud/concepts/threads.md b/docs/docs/cloud/concepts/threads.md deleted file mode 100644 index ffd48faa8..000000000 --- a/docs/docs/cloud/concepts/threads.md +++ /dev/null @@ -1,12 +0,0 @@ -# Threads - -A thread contains the accumulated state of a sequence of [runs](../../concepts/assistants.md#execution). When a run is executed, the [state](../../concepts/low_level.md#state) of the underlying graph of the assistant will be persisted to the thread. - -A thread's current and historical state can be retrieved. To persist state, a thread must be created prior to executing a run. - -The state of a thread at a particular point in time is called a [checkpoint](../../concepts/persistence.md#checkpoints). Checkpoints are persisted and can be used to restore the state of a thread at a later time. - -## Learn more - -* For more on threads and checkpoints, see this section of the [LangGraph conceptual guide](../../concepts/persistence.md). -* The LangGraph Platform API provides several endpoints for creating and managing threads and thread state. See the [API reference](../../cloud/reference/api/api_ref.html#tag/threads) for more details. diff --git a/docs/docs/cloud/quick_start.md b/docs/docs/cloud/quick_start.md index 2823b891d..41ad577e1 100644 --- a/docs/docs/cloud/quick_start.md +++ b/docs/docs/cloud/quick_start.md @@ -154,8 +154,9 @@ You can now test the API: ```bash curl -s --request POST \ - --url \ + --url /runs/stream \ --header 'Content-Type: application/json' \ + --header "X-Api-Key: \ --data "{ \"assistant_id\": \"agent\", \"input\": { diff --git a/docs/docs/cloud/reference/cli.md b/docs/docs/cloud/reference/cli.md index b43be5485..2181f59e2 100644 --- a/docs/docs/cloud/reference/cli.md +++ b/docs/docs/cloud/reference/cli.md @@ -51,6 +51,7 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema]( | `node_version` | Specify `node_version: 20` to use LangGraph.js. | | `pip_config_file` | Path to `pip` config file. | | `pip_installer` | _(Added in v0.3)_ Optional. Python package installer selector. It can be set to `"auto"`, `"pip"`, or `"uv"`. From version 0.3 onward the default strategy is to run `uv pip`, which typically delivers faster builds while remaining a drop-in replacement. In the uncommon situation where `uv` cannot handle your dependency graph or the structure of your `pyproject.toml`, specify `"pip"` here to revert to the earlier behaviour. | + | `keep_pkg_tools` | _(Added in v0.3.4)_ Optional. Control whether to retain Python packaging tools (`pip`, `setuptools`, `wheel`) in the final image. Accepted values:
  • true : Keep all three tools (skip uninstall).
  • false / omitted : Uninstall all three tools (default behaviour).
  • list[str] : Names of tools to retain. Each value must be one of "pip", "setuptools", "wheel".
. By default, all three tools are uninstalled. | | `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. | | `checkpointer` | Configuration for the checkpointer. Contains a `ttl` field which is an object with the following keys:
  • `strategy`: How to handle expired checkpoints (e.g., `"delete"`).
  • `sweep_interval_minutes`: How often to check for expired checkpoints (integer).
  • `default_ttl`: Default time-to-live for checkpoints in **minutes** (integer). Defines how long checkpoints are kept before the specified strategy is applied.
| | `http` | HTTP server configuration with the following fields:
  • `app`: Path to custom Starlette/FastAPI app (e.g., `"./src/agent/webapp.py:app"`). See [custom routes guide](../../how-tos/http/custom_routes.md).
  • `cors`: CORS configuration with fields for `allow_origins`, `allow_methods`, `allow_headers`, etc.
  • `configurable_headers`: Define which request headers to exclude or include as a run's configurable values.
  • `disable_assistants`: Disable `/assistants` routes
  • `disable_mcp`: Disable `/mcp` routes
  • `disable_meta`: Disable `/ok`, `/info`, `/metrics`, and `/docs` routes
  • `disable_runs`: Disable `/runs` routes
  • `disable_store`: Disable `/store` routes
  • `disable_threads`: Disable `/threads` routes
  • `disable_ui`: Disable `/ui` routes
  • `disable_webhooks`: Disable webhooks calls on run completion in all routes
  • `mount_prefix`: Prefix for mounted routes (e.g., "/my-deployment/api")
| diff --git a/docs/docs/concepts/langgraph_control_plane.md b/docs/docs/concepts/langgraph_control_plane.md index f3562516c..006a57df9 100644 --- a/docs/docs/concepts/langgraph_control_plane.md +++ b/docs/docs/concepts/langgraph_control_plane.md @@ -46,21 +46,40 @@ For simplicity, the control plane offers two deployment types with different res | **Deployment Type** | **CPU/Memory** | **Scaling** | **Database** | |---------------------|-----------------|---------------------|----------------------------------------------------------------------------------| -| Development | 1 CPU, 1 GB RAM | Up to 1 container | 10 GB disk, no backups | -| Production | 2 CPU, 2 GB RAM | Up to 10 containers | Autoscaling disk, automatic backups, highly available (multi-zone configuration) | +| Development | 1 CPU, 1 GB RAM | Up to 1 replica | 10 GB disk, no backups | +| Production | 2 CPU, 2 GB RAM | Up to 10 replicas | Autoscaling disk, automatic backups, highly available (multi-zone configuration) | -CPU and memory resources are per container. +CPU and memory resources are per replica. !!! warning "Immutable Deployment Type" Once a deployment is created, the deployment type cannot be changed. -!!! info "Resource Customization" - For `Production` type deployments, resources can be manually increased on a case-by-case basis depending on use case and capacity constraints. Contact support@langchain.dev to request an increase in resources. +!!! info "Self-Hosted Deployment" + Resources for [Self-Hosted Data Plane](../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../concepts/langgraph_self_hosted_control_plane.md) deployments can be fully customized. Deployment types are only applicable for [Cloud SaaS](../concepts/langgraph_cloud.md) deployments. - For `Development` types deployments, database disk size can be manually increased on a case-by-case basis depending on use case and capacity constraints. For most use cases, [TTLs](../how-tos/ttl/configure_ttl.md) should be configured to manage disk usage. Contact support@langchain.dev to request an increase in resources. +#### Production - Resources for [Self-Hosted Data Plane](../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../concepts/langgraph_self_hosted_control_plane.md) deployments can be fully customized. +`Production` type deployments are suitable for "production" workloads. For example, select `Production` for customer-facing applications in the critical path. + +Resources for `Production` type deployments can be manually increased on a case-by-case basis depending on use case and capacity constraints. Contact support@langchain.dev to request an increase in resources. + +#### Development + +`Development` type deployments are suitable development and testing. For example, select `Development` for internal testing environments. `Development` type deployments are not suitable for "production" workloads. + +!!! danger "Preemptible Compute Infrastructure" + `Development` type deployments (API server, queue server, and database) are provisioned on preemptible compute infrastructure. This means the compute infrastructure **may be terminated at any time without notice**. This may result in intermittent... + + - Redis connection timeouts/errors + - Postgres connection timeouts/errors + - Failed or retrying background runs + + This behavior is expected. Preemptible compute infrastructure **significantly reduces the cost to provision a `Development` type deployment**. By design, LangGraph Server is fault-tolerant. The implementation will automatically attempt to recover from Redis/Postgres connection errors and retry failed background runs. + + `Production` type deployments are provisioned on durable compute infrastructure, not preemptible compute infrastructure. + +Database disk size for `Development` type deployments can be manually increased on a case-by-case basis depending on use case and capacity constraints. For most use cases, [TTLs](../how-tos/ttl/configure_ttl.md) should be configured to manage disk usage. Contact support@langchain.dev to request an increase in resources. ### Database Provisioning @@ -93,6 +112,8 @@ After a deployment is ready, the control plane monitors the deployment and recor - Number of container restarts. - Number of replicas (this will increase with [autoscaling](../concepts/langgraph_data_plane.md#autoscaling)). - [Postgres](../concepts/langgraph_data_plane.md#postgres) CPU, memory usage, and disk usage. +- [LangGraph Server queue](../concepts/langgraph_server.md#persistence-and-task-queue) pending/active run count. +- [LangGraph Server API](../concepts/langgraph_server.md) success response count, error response count, and latency. These metrics are displayed as charts in the Control Plane UI. diff --git a/docs/docs/concepts/langgraph_data_plane.md b/docs/docs/concepts/langgraph_data_plane.md index 0b52b8b6f..5d7473cb6 100644 --- a/docs/docs/concepts/langgraph_data_plane.md +++ b/docs/docs/concepts/langgraph_data_plane.md @@ -50,6 +50,15 @@ Runs in a LangGraph Server may be retried for specific failures (currently only This section describes various features of the data plane. +### Data Region + +!!! info "Only for Cloud SaaS" + Data regions are only applicable for [Cloud SaaS](../concepts/langgraph_cloud.md) deployments. + +Deployments can be created in 2 data regions: US and EU + +The data region for a deployment is implied by the data region of the LangSmith organization where the deployment is created. Deployments and the underlying database for the deployments cannot be migrated between data regions. + ### Autoscaling [`Production` type](../concepts/langgraph_control_plane.md#deployment-types) deployments automatically scale up to 10 containers. Scaling is based on 3 metrics: diff --git a/docs/docs/concepts/multi_agent.md b/docs/docs/concepts/multi_agent.md index 81967f610..5d3e30a29 100644 --- a/docs/docs/concepts/multi_agent.md +++ b/docs/docs/concepts/multi_agent.md @@ -26,7 +26,7 @@ The primary benefits of using multi-agent systems are: There are several ways to connect agents in a multi-agent system: - **Network**: each agent can communicate with [every other agent](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/multi-agent-collaboration/). Any agent can decide which other agent to call next. -- **Supervisor**: each agent communicates with a single [supervisor](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/agent_supervisor/) agent. Supervisor agent makes decisions on which agent should be called next. +- **Supervisor**: each agent communicates with a single [supervisor](../tutorials/multi_agent/agent_supervisor.md) agent. Supervisor agent makes decisions on which agent should be called next. - **Supervisor (tool-calling)**: this is a special case of supervisor architecture. Individual agents can be represented as tools. In this case, a supervisor agent uses a tool-calling LLM to decide which of the agent tools to call, as well as the arguments to pass to those agents. - **Hierarchical**: you can define a multi-agent system with [a supervisor of supervisors](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/hierarchical_agent_teams/). This is a generalization of the supervisor architecture and allows for more complex control flows. - **Custom multi-agent workflow**: each agent communicates with only a subset of agents. Parts of the flow are deterministic, and only some agents can decide which other agents to call next. @@ -211,7 +211,7 @@ builder.add_edge(START, "supervisor") supervisor = builder.compile() ``` -Check out this [tutorial](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/agent_supervisor/) for an example of supervisor multi-agent architecture. +Check out this [tutorial](../tutorials/multi_agent/agent_supervisor.md) for an example of supervisor multi-agent architecture. ### Supervisor (tool-calling) diff --git a/docs/docs/concepts/persistence.md b/docs/docs/concepts/persistence.md index 7c612cf60..f3d807946 100644 --- a/docs/docs/concepts/persistence.md +++ b/docs/docs/concepts/persistence.md @@ -5,7 +5,7 @@ search: # Persistence -LangGraph has a built-in persistence layer, implemented through checkpointers. When you compile graph with a checkpointer, the checkpointer saves a `checkpoint` of the graph state at every super-step. Those checkpoints are saved to a `thread`, which can be accessed after graph execution. Because `threads` allow access to graph's state after execution, several powerful capabilities including human-in-the-loop, memory, time travel, and fault-tolerance are all possible. Below, we'll discuss each of these concepts in more detail. +LangGraph has a built-in persistence layer, implemented through checkpointers. When you compile a graph with a checkpointer, the checkpointer saves a `checkpoint` of the graph state at every super-step. Those checkpoints are saved to a `thread`, which can be accessed after graph execution. Because `threads` allow access to graph's state after execution, several powerful capabilities including human-in-the-loop, memory, time travel, and fault-tolerance are all possible. Below, we'll discuss each of these concepts in more detail. ![Checkpoints](img/persistence/checkpoints.jpg) @@ -78,7 +78,7 @@ After we run the graph, we expect to see exactly 4 checkpoints: * checkpoint with the outputs of `node_a` `{'foo': 'a', 'bar': ['a']}` and `node_b` as the next node to be executed * checkpoint with the outputs of `node_b` `{'foo': 'b', 'bar': ['a', 'b']}` and no next nodes to be executed -Note that we `bar` channel values contain outputs from both nodes as we have a reducer for `bar` channel. +Note that the `bar` channel values contain outputs from both nodes as we have a reducer for `bar` channel. ### Get state diff --git a/docs/docs/concepts/server-mcp.md b/docs/docs/concepts/server-mcp.md index 0d40bfb2e..b66eaada3 100644 --- a/docs/docs/concepts/server-mcp.md +++ b/docs/docs/concepts/server-mcp.md @@ -209,7 +209,7 @@ To make user-scoped tools available to your LangGraph Platform deployment, start ```python from langchain_mcp_adapters.client import MultiServerMCPClient -def get_mcp_tools_node(state, config): +def mcp_tools_node(state, config): user = config["configurable"].get("langgraph_auth_user") # e.g., user["github_token"], user["email"], etc. @@ -223,14 +223,19 @@ def get_mcp_tools_node(state, config): } }) tools = await client.get_tools() # (3) - return {"tools": tools} - + + # Your tool-calling logic here + + tool_messages = ... + return {"messages": tool_messages} ``` 1. MCP only supports adding headers to requests made to `streamable_http` and `sse` `transport` servers. 2. Your MCP server URL. 3. Get available tools from your MCP server. +_This can also be done by [rebuilding your graph at runtime](https://langchain-ai.github.io/langgraph/cloud/deployment/graph_rebuild/) to have a different configuration for a new run_ + ## Session behavior The current LangGraph MCP implementation does not support sessions. Each `/mcp` request is stateless and independent. diff --git a/docs/docs/concepts/template_applications.md b/docs/docs/concepts/template_applications.md index 76ebff698..8da3229b9 100644 --- a/docs/docs/concepts/template_applications.md +++ b/docs/docs/concepts/template_applications.md @@ -64,7 +64,7 @@ To create a new app from a template, use the `langgraph new` command. === "JS" ```bash - npx @langchain/langgraph-cli new + npm create langgraph@latest ``` ## Next Steps diff --git a/docs/docs/examples/index.md b/docs/docs/examples/index.md new file mode 100644 index 000000000..84c721ac3 --- /dev/null +++ b/docs/docs/examples/index.md @@ -0,0 +1,23 @@ +# Examples + +The pages in this section provide end-to-end examples for the following topics: + +## General + +- [Template Applications](../concepts/template_applications.md): Create a LangGraph application from a template. +- [Agentic RAG](./rag/langgraph_agentic_rag.md): Build a retrieval agent that can decide when to use a retriever tool. +- [Agent Supervisor](./multi_agent/agent_supervisor.md): Build a supervisor agent that can manage a team of agents. +- [SQL agent](./sql/sql-agent.md): Build a SQL agent that can execute SQL queries and return the results. +- [Prebuilt chat UI](../agents/ui.md): Use a prebuilt chat UI to interact with any LangGraph agent. +- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md): Use LangSmith to track and analyze graph runs. + +## LangGraph Platform + +- [Set up custom authentication](./auth/getting_started.md): Set up custom authentication for your LangGraph application. +- [Make conversations private](./auth/resource_auth.md): Make conversations private by using resource-based authentication. +- [Connect an authentication provider](./auth/add_auth_server.md): Connect an authentication provider to your LangGraph application. +- [Rebuild graph at runtime](../cloud/deployment/graph_rebuild.md): Rebuild a graph at runtime. +- [Use RemoteGraph](../how-tos/use-remote-graph.md): Use RemoteGraph to deploy your LangGraph application to a remote server. +- [Deploy CrewAI, AutoGen, and other frameworks](../how-tos/autogen-integration.md): Deploy CrewAI, AutoGen, and other frameworks with LangGraph. +- [Integrate LangGraph into a React app](../cloud/how-tos/use_stream_react.md) +- [Implement Generative User Interfaces with LangGraph](../cloud/how-tos/generative_ui_react.md) \ No newline at end of file diff --git a/docs/docs/guides/index.md b/docs/docs/guides/index.md new file mode 100644 index 000000000..1d57f63ea --- /dev/null +++ b/docs/docs/guides/index.md @@ -0,0 +1,41 @@ +# Guides + +The pages in this section provide a conceptual overview and how-tos for the following topics: + +## LangGraph APIs + +- [Graph API](../concepts/low_level.md): Use the Graph API to define workflows using a graph paradigm. +- [Functional API](../concepts/functional_api.md): Use Functional API to build workflows using a functional paradigm without thinking about the graph structure. +- [Runtime](../concepts/pregel.md): Pregel implements LangGraph's runtime, managing the execution of LangGraph applications. + +## Core capabilities + +These capabilities are available in both LangGraph OSS and the LangGraph Platform. + +- [Streaming](../concepts/streaming.md): Stream outputs from a LangGraph graph. +- [Persistence](../concepts/persistence.md): Persist the state of a LangGraph graph. +- [Durable execution](../concepts/durable_execution.md): Save progress at key points in the graph execution. +- [Memory](../concepts/memory.md): Remember information about previous interactions. +- [Context](../agents/context.md): Pass outside data to a LangGraph graph to provide context for the graph execution. +- [Models](../agents/models.md): Integrate various LLMs into your LangGraph application. +- [Tools](../concepts/tools.md): Interface directly with external systems. +- [Human-in-the-loop](../concepts/human_in_the_loop.md): Enable human intervention at any point in a workflow. +- [Breakpoints](../concepts/breakpoints.md): Pause the execution of a LangGraph graph at a specific point. +- [Time travel](../concepts/time-travel.md): Travel back in time to a specific point in the execution of a LangGraph graph. +- [Subgraphs](../concepts/subgraphs.md): Build modular graphs. +- [Multi-agent](../concepts/multi_agent.md): Break down a complex workflow into multiple agents. +- [MCP](../concepts/mcp.md): Use MCP servers in a LangGraph graph. +- [Evaluation](../agents/evals.md): Use LangSmith to evaluate your graph's performance. + +## Platform-only capabilities + +These capabilities are only available in [LangGraph Platform](../concepts/langgraph_platform.md). + +- [Authentication and access control](../concepts/auth.md): Authenticate and authorize users to access a Langraph graph. +- [Assistants](../concepts/assistants.md): Build assistants that can be used to interact with a LangGraph graph. +- [Double-texting](../concepts/double_texting.md): Handle double-texting (consecutive messages before a first response is returned) in a LangGraph graph. +- [Webhooks](../cloud/concepts/webhooks.md): Send webhooks to a LangGraph graph. +- [Cron jobs](../cloud/concepts/cron_jobs.md): Schedule jobs to run at a specific time. +- [Server customization](../how-tos/http/custom_lifespan.md): Customize the server that runs a LangGraph graph. +- [Data management](../cloud/concepts/data_storage_and_privacy.md): Manage data in a LangGraph graph. +- [Deployment](../concepts/deployment_options.md): Deploy a LangGraph graph to a server. \ No newline at end of file diff --git a/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png b/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png new file mode 100644 index 000000000..9bd66e565 Binary files /dev/null and b/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png differ diff --git a/docs/docs/how-tos/assets/autogen-output.png b/docs/docs/how-tos/assets/autogen-output.png new file mode 100644 index 000000000..02106782e Binary files /dev/null and b/docs/docs/how-tos/assets/autogen-output.png differ diff --git a/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png b/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png new file mode 100644 index 000000000..ce95409d6 Binary files /dev/null and b/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png differ diff --git a/docs/docs/how-tos/autogen-integration.ipynb b/docs/docs/how-tos/autogen-integration.ipynb deleted file mode 100644 index 5e58a260c..000000000 --- a/docs/docs/how-tos/autogen-integration.ipynb +++ /dev/null @@ -1,406 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "100c0c81-6a9f-4ba1-b1a8-42aae82b7172", - "metadata": {}, - "source": [ - "# How to integrate LangGraph with AutoGen, CrewAI, and other frameworks\n", - "\n", - "LangGraph is a framework for building agentic and multi-agent applications. LangGraph can be easily integrated with other agent frameworks. \n", - "\n", - "The primary reasons you might want to integrate LangGraph with other agent frameworks:\n", - "\n", - "- create [multi-agent systems](../../concepts/multi_agent) where individual agents are built with different frameworks\n", - "- leverage LangGraph to add features like [persistence](../../concepts/persistence), [streaming](../../concepts/streaming), [short and long-term memory](../../concepts/memory) and more\n", - "\n", - "The simplest way to integrate agents from other frameworks is by calling those agents inside a LangGraph [node](../../concepts/low_level/#nodes):\n", - "\n", - "```python\n", - "from langgraph.graph import StateGraph, MessagesState, START\n", - "\n", - "autogen_agent = autogen.AssistantAgent(name=\"assistant\", ...)\n", - "user_proxy = autogen.UserProxyAgent(name=\"user_proxy\", ...)\n", - "\n", - "def call_autogen_agent(state: MessagesState):\n", - " response = user_proxy.initiate_chat(\n", - " autogen_agent,\n", - " message=state[\"messages\"][-1],\n", - " ...\n", - " )\n", - " ...\n", - "\n", - "graph = (\n", - " StateGraph(MessagesState)\n", - " .add_node(call_autogen_agent)\n", - " .add_edge(START, \"call_autogen_agent\")\n", - " .compile()\n", - ")\n", - "\n", - "graph.invoke({\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Find numbers between 10 and 30 in fibonacci sequence\",\n", - " }\n", - " ]\n", - "})\n", - "```\n", - "\n", - "In this guide we show how to build a LangGraph chatbot that integrates with AutoGen, but you can follow the same approach with other frameworks." - ] - }, - { - "cell_type": "markdown", - "id": "b189ceb2-132b-4c7b-81b4-c7b8b062f833", - "metadata": {}, - "source": [ - "## Setup" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "62417d3a-94f9-4a52-9962-12639d714966", - "metadata": {}, - "outputs": [], - "source": [ - "%pip install autogen langgraph" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "d46da41d-0a71-4654-aec8-9e6ad8765236", - "metadata": {}, - "outputs": [ - { - "name": "stdin", - "output_type": "stream", - "text": [ - "OPENAI_API_KEY: ········\n" - ] - } - ], - "source": [ - "import getpass\n", - "import os\n", - "\n", - "\n", - "def _set_env(var: str):\n", - " if not os.environ.get(var):\n", - " os.environ[var] = getpass.getpass(f\"{var}: \")\n", - "\n", - "\n", - "_set_env(\"OPENAI_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "id": "1926bbc3-6b06-41e0-9604-860a2bbf8fa3", - "metadata": {}, - "source": [ - "## Define AutoGen agent\n", - "\n", - "Here we define our AutoGen agent. Adapted from official tutorial [here](https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb)." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "524de117-ff09-4b26-bfe8-a9f85a46ffd5", - "metadata": {}, - "outputs": [], - "source": [ - "import autogen\n", - "import os\n", - "\n", - "config_list = [{\"model\": \"gpt-4o\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n", - "\n", - "llm_config = {\n", - " \"timeout\": 600,\n", - " \"cache_seed\": 42,\n", - " \"config_list\": config_list,\n", - " \"temperature\": 0,\n", - "}\n", - "\n", - "autogen_agent = autogen.AssistantAgent(\n", - " name=\"assistant\",\n", - " llm_config=llm_config,\n", - ")\n", - "\n", - "user_proxy = autogen.UserProxyAgent(\n", - " name=\"user_proxy\",\n", - " human_input_mode=\"NEVER\",\n", - " max_consecutive_auto_reply=10,\n", - " is_termination_msg=lambda x: x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n", - " code_execution_config={\n", - " \"work_dir\": \"web\",\n", - " \"use_docker\": False,\n", - " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n", - " llm_config=llm_config,\n", - " system_message=\"Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "8aa858e2-4acb-4f75-be20-b9ccbbcb5073", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "dcc478f5-4a35-43f8-bf59-9cb71289cd00", - "metadata": {}, - "source": [ - "## Create the graph\n", - "\n", - "We will now create a LangGraph chatbot graph that calls AutoGen agent." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "d129e4e1-3766-429a-b806-cde3d8bc0469", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_core.messages import convert_to_openai_messages\n", - "from langgraph.graph import StateGraph, MessagesState, START\n", - "from langgraph.checkpoint.memory import MemorySaver\n", - "\n", - "\n", - "def call_autogen_agent(state: MessagesState):\n", - " # convert to openai-style messages\n", - " messages = convert_to_openai_messages(state[\"messages\"])\n", - " response = user_proxy.initiate_chat(\n", - " autogen_agent,\n", - " message=messages[-1],\n", - " # pass previous message history as context\n", - " carryover=messages[:-1],\n", - " )\n", - " # get the final response from the agent\n", - " content = response.chat_history[-1][\"content\"]\n", - " return {\"messages\": {\"role\": \"assistant\", \"content\": content}}\n", - "\n", - "\n", - "# add short-term memory for storing conversation history\n", - "checkpointer = MemorySaver()\n", - "\n", - "builder = StateGraph(MessagesState)\n", - "builder.add_node(call_autogen_agent)\n", - "builder.add_edge(START, \"call_autogen_agent\")\n", - "graph = builder.compile(checkpointer=checkpointer)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "c761fc05-e8b6-4905-a793-eb7522d20060", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.display import display, Image\n", - "\n", - "display(Image(graph.get_graph().draw_mermaid_png()))" - ] - }, - { - "cell_type": "markdown", - "id": "23d629c3-1d6b-40af-adf6-915e15657566", - "metadata": {}, - "source": [ - "## Run the graph\n", - "\n", - "We can now run the graph." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "a279b667-0f5d-4008-8d43-c806a3f379c4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001B[33muser_proxy\u001B[0m (to assistant):\n", - "\n", - "Find numbers between 10 and 30 in fibonacci sequence\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001B[33massistant\u001B[0m (to user_proxy):\n", - "\n", - "To find numbers between 10 and 30 in the Fibonacci sequence, we can generate the Fibonacci sequence and check which numbers fall within this range. Here's a plan:\n", - "\n", - "1. Generate Fibonacci numbers starting from 0.\n", - "2. Continue generating until the numbers exceed 30.\n", - "3. Collect and print the numbers that are between 10 and 30.\n", - "\n", - "Let's implement this in Python:\n", - "\n", - "```python\n", - "# filename: fibonacci_range.py\n", - "\n", - "def fibonacci_sequence():\n", - " a, b = 0, 1\n", - " while a <= 30:\n", - " if 10 <= a <= 30:\n", - " print(a)\n", - " a, b = b, a + b\n", - "\n", - "fibonacci_sequence()\n", - "```\n", - "\n", - "This script will print the Fibonacci numbers between 10 and 30. Please execute the code to see the result.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001B[31m\n", - ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001B[0m\n", - "\u001B[33muser_proxy\u001B[0m (to assistant):\n", - "\n", - "exitcode: 0 (execution succeeded)\n", - "Code output: \n", - "13\n", - "21\n", - "\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001B[33massistant\u001B[0m (to user_proxy):\n", - "\n", - "The Fibonacci numbers between 10 and 30 are 13 and 21. \n", - "\n", - "These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \n", - "\n", - "The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\n", - "\n", - "As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\n", - "\n", - "TERMINATE\n", - "\n", - "--------------------------------------------------------------------------------\n", - "{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The Fibonacci numbers between 10 and 30 are 13 and 21. \\n\\nThese numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \\n\\nThe sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\\n\\nAs you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\\n\\nTERMINATE'}}}\n" - ] - } - ], - "source": [ - "# pass the thread ID to persist agent outputs for future interactions\n", - "# highlight-next-line\n", - "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", - "\n", - "for chunk in graph.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Find numbers between 10 and 30 in fibonacci sequence\",\n", - " }\n", - " ]\n", - " },\n", - " # highlight-next-line\n", - " config,\n", - "):\n", - " print(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "c6cd57b4-d4ee-49f6-be12-318613849669", - "metadata": {}, - "source": [ - "Since we're leveraging LangGraph's [persistence](https://langchain-ai.github.io/langgraph/concepts/persistence/) features we can now continue the conversation using the same thread ID -- LangGraph will automatically pass previous history to the AutoGen agent:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "e68811a7-962e-4fe3-9f45-9b99ebbe04e7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001B[33muser_proxy\u001B[0m (to assistant):\n", - "\n", - "Multiply the last number by 3\n", - "Context: \n", - "Find numbers between 10 and 30 in fibonacci sequence\n", - "The Fibonacci numbers between 10 and 30 are 13 and 21. \n", - "\n", - "These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \n", - "\n", - "The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\n", - "\n", - "As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\n", - "\n", - "TERMINATE\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001B[33massistant\u001B[0m (to user_proxy):\n", - "\n", - "The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\n", - "\n", - "21 * 3 = 63\n", - "\n", - "TERMINATE\n", - "\n", - "--------------------------------------------------------------------------------\n", - "{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\\n\\n21 * 3 = 63\\n\\nTERMINATE'}}}\n" - ] - } - ], - "source": [ - "for chunk in graph.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Multiply the last number by 3\",\n", - " }\n", - " ]\n", - " },\n", - " # highlight-next-line\n", - " config,\n", - "):\n", - " print(chunk)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/how-tos/autogen-integration.md b/docs/docs/how-tos/autogen-integration.md new file mode 100644 index 000000000..efbcf3d30 --- /dev/null +++ b/docs/docs/how-tos/autogen-integration.md @@ -0,0 +1,321 @@ +# How to integrate LangGraph with AutoGen, CrewAI, and other frameworks + +This guide shows how to integrate AutoGen agents with LangGraph to leverage features like persistence, streaming, and memory, and then deploy the integrated solution to LangGraph Platform for scalable production use. In this guide we show how to build a LangGraph chatbot that integrates with AutoGen, but you can follow the same approach with other frameworks. + +Integrating AutoGen with LangGraph provides several benefits: + +- Enhanced features: Add [persistence](../concepts/persistence.md), [streaming](../concepts/streaming.md), [short and long-term memory](../concepts/memory.md) and more to your AutoGen agents. +- Multi-agent systems: Build [multi-agent systems](../concepts/multi_agent.md) where individual agents are built with different frameworks. +- Production deployment: Deploy your integrated solution to [LangGraph Platform](../concepts/langgraph_platform.md) for scalable production use. + +## Prerequisites + +- Python 3.9+ +- Autogen: `pip install autogen` +- LangGraph: `pip install langgraph` +- OpenAI API key + +## Setup + +Set your your environment: + +```python +import getpass +import os + + +def _set_env(var: str): + if not os.environ.get(var): + os.environ[var] = getpass.getpass(f"{var}: ") + + +_set_env("OPENAI_API_KEY") +``` + +## 1. Define AutoGen agent + +Create an AutoGen agent that can execute code. This example is adapted from AutoGen's [official tutorials](https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb): + +```python +import autogen +import os + +config_list = [{"model": "gpt-4o", "api_key": os.environ["OPENAI_API_KEY"]}] + +llm_config = { + "timeout": 600, + "cache_seed": 42, + "config_list": config_list, + "temperature": 0, +} + +autogen_agent = autogen.AssistantAgent( + name="assistant", + llm_config=llm_config, +) + +user_proxy = autogen.UserProxyAgent( + name="user_proxy", + human_input_mode="NEVER", + max_consecutive_auto_reply=10, + is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"), + code_execution_config={ + "work_dir": "web", + "use_docker": False, + }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly. + llm_config=llm_config, + system_message="Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.", +) +``` + +## 2. Create the graph + +We will now create a LangGraph chatbot graph that calls AutoGen agent. + +```python +from langchain_core.messages import convert_to_openai_messages +from langgraph.graph import StateGraph, MessagesState, START +from langgraph.checkpoint.memory import MemorySaver + +def call_autogen_agent(state: MessagesState): + # Convert LangGraph messages to OpenAI format for AutoGen + messages = convert_to_openai_messages(state["messages"]) + + # Get the last user message + last_message = messages[-1] + + # Pass previous message history as context (excluding the last message) + carryover = messages[:-1] if len(messages) > 1 else [] + + # Initiate chat with AutoGen + response = user_proxy.initiate_chat( + autogen_agent, + message=last_message, + carryover=carryover + ) + + # Extract the final response from the agent + final_content = response.chat_history[-1]["content"] + + # Return the response in LangGraph format + return {"messages": {"role": "assistant", "content": final_content}} + +# Create the graph with memory for persistence +checkpointer = MemorySaver() + +# Build the graph +builder = StateGraph(MessagesState) +builder.add_node("autogen", call_autogen_agent) +builder.add_edge(START, "autogen") + +# Compile with checkpointer for persistence +graph = builder.compile(checkpointer=checkpointer) +``` + +```python +from IPython.display import display, Image + +display(Image(graph.get_graph().draw_mermaid_png())) +``` + +![Graph](./assets/autogen-output.png) + +## 3. Test the graph locally + +Before deploying to LangGraph Platform, you can test the graph locally: + +```python +# pass the thread ID to persist agent outputs for future interactions +# highlight-next-line +config = {"configurable": {"thread_id": "1"}} + +for chunk in graph.stream( + { + "messages": [ + { + "role": "user", + "content": "Find numbers between 10 and 30 in fibonacci sequence", + } + ] + }, + # highlight-next-line + config, +): + print(chunk) +``` + +**Output:** +``` +user_proxy (to assistant): + +Find numbers between 10 and 30 in fibonacci sequence + +-------------------------------------------------------------------------------- +assistant (to user_proxy): + +To find numbers between 10 and 30 in the Fibonacci sequence, we can generate the Fibonacci sequence and check which numbers fall within this range. Here's a plan: + +1. Generate Fibonacci numbers starting from 0. +2. Continue generating until the numbers exceed 30. +3. Collect and print the numbers that are between 10 and 30. + +... +``` + +Since we're leveraging LangGraph's [persistence](https://langchain-ai.github.io/langgraph/concepts/persistence/) features we can now continue the conversation using the same thread ID -- LangGraph will automatically pass previous history to the AutoGen agent: + +```python +for chunk in graph.stream( + { + "messages": [ + { + "role": "user", + "content": "Multiply the last number by 3", + } + ] + }, + # highlight-next-line + config, +): + print(chunk) +``` + +**Output:** +``` +user_proxy (to assistant): + +Multiply the last number by 3 +Context: +Find numbers between 10 and 30 in fibonacci sequence +The Fibonacci numbers between 10 and 30 are 13 and 21. + +These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. + +The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... + +As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30. + +TERMINATE + +-------------------------------------------------------------------------------- +assistant (to user_proxy): + +The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives: + +21 * 3 = 63 + +TERMINATE + +-------------------------------------------------------------------------------- +{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\n\n21 * 3 = 63\n\nTERMINATE'}}} +``` + +## 4. Prepare for deployment + +To deploy to LangGraph Platform, create a file structure like the following: + +``` +my-autogen-agent/ +├── agent.py # Your main agent code +├── requirements.txt # Python dependencies +└── langgraph.json # LangGraph configuration +``` + +=== "agent.py" + + ```python + import os + import autogen + from langchain_core.messages import convert_to_openai_messages + from langgraph.graph import StateGraph, MessagesState, START + from langgraph.checkpoint.memory import MemorySaver + + # AutoGen configuration + config_list = [{"model": "gpt-4o", "api_key": os.environ["OPENAI_API_KEY"]}] + + llm_config = { + "timeout": 600, + "cache_seed": 42, + "config_list": config_list, + "temperature": 0, + } + + # Create AutoGen agents + autogen_agent = autogen.AssistantAgent( + name="assistant", + llm_config=llm_config, + ) + + user_proxy = autogen.UserProxyAgent( + name="user_proxy", + human_input_mode="NEVER", + max_consecutive_auto_reply=10, + is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"), + code_execution_config={ + "work_dir": "/tmp/autogen_work", + "use_docker": False, + }, + llm_config=llm_config, + system_message="Reply TERMINATE if the task has been solved at full satisfaction.", + ) + + def call_autogen_agent(state: MessagesState): + """Node function that calls the AutoGen agent""" + messages = convert_to_openai_messages(state["messages"]) + last_message = messages[-1] + carryover = messages[:-1] if len(messages) > 1 else [] + + response = user_proxy.initiate_chat( + autogen_agent, + message=last_message, + carryover=carryover + ) + + final_content = response.chat_history[-1]["content"] + return {"messages": {"role": "assistant", "content": final_content}} + + # Create and compile the graph + def create_graph(): + checkpointer = MemorySaver() + builder = StateGraph(MessagesState) + builder.add_node("autogen", call_autogen_agent) + builder.add_edge(START, "autogen") + return builder.compile(checkpointer=checkpointer) + + # Export the graph for LangGraph Platform + graph = create_graph() + ``` + +=== "requirements.txt" + + ``` + langgraph>=0.1.0 + pyautogen>=0.2.0 + langchain-core>=0.1.0 + langchain-openai>=0.0.5 + ``` + +=== "langgraph.json" + + ```json + { + "dependencies": ["."], + "graphs": { + "autogen_agent": "./agent.py:graph" + }, + "env": ".env" + } + ``` + + +## 5. Deploy to LangGraph Platform + +Deploy the graph with the LangGraph Platform CLI: + +``` +pip install -U langgraph-cli +``` + +``` +langgraph deploy --config langgraph.json +``` diff --git a/docs/docs/how-tos/autogen-langgraph-platform.ipynb b/docs/docs/how-tos/autogen-langgraph-platform.ipynb deleted file mode 100644 index 29bd24ba5..000000000 --- a/docs/docs/how-tos/autogen-langgraph-platform.ipynb +++ /dev/null @@ -1,171 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8381b6e0-29a6-48c5-b451-5d2549351249", - "metadata": {}, - "source": [ - "# How to use LangGraph Platform to deploy CrewAI, AutoGen, and other frameworks\n", - "\n", - "[LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) provides infrastructure for deploying agents. This integrates seamlessly with LangGraph, but can also work with other frameworks. The way to make this work is to wrap the agent in a single LangGraph node, and have that be the entire graph.\n", - "\n", - "Doing so will allow you to deploy to LangGraph Platform, and allows you to get a lot of the [benefits](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/). You get horizontally scalable infrastructure, a task queue to handle bursty operations, a persistence layer to power short term memory, and long term memory support.\n", - "\n", - "In this guide we show how to do this with an AutoGen agent, but this method should work for agents defined in other frameworks like CrewAI, LlamaIndex, and others as well." - ] - }, - { - "cell_type": "markdown", - "id": "1113cb16-b538-448c-924c-85731ce96ebd", - "metadata": {}, - "source": [ - "## Setup" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "f05993fa-9d03-4f45-bc13-0a8d87260d86", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "%pip install autogen langgraph" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4e0ca12-1714-4776-a30a-9527e519799b", - "metadata": {}, - "outputs": [], - "source": [ - "import getpass\n", - "import os\n", - "\n", - "\n", - "def _set_env(var: str):\n", - " if not os.environ.get(var):\n", - " os.environ[var] = getpass.getpass(f\"{var}: \")\n", - "\n", - "\n", - "_set_env(\"OPENAI_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "id": "1926bbc3-6b06-41e0-9604-860a2bbf8fa3", - "metadata": {}, - "source": [ - "## Define autogen agent\n", - "\n", - "Here we define our AutoGen agent. From https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d4a14dc7-d565-4207-8788-525f85b9fb27", - "metadata": {}, - "outputs": [], - "source": [ - "import autogen\n", - "import os\n", - "\n", - "config_list = [{\"model\": \"gpt-4o\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n", - "\n", - "llm_config = {\n", - " \"timeout\": 600,\n", - " \"cache_seed\": 42,\n", - " \"config_list\": config_list,\n", - " \"temperature\": 0,\n", - "}\n", - "\n", - "autogen_agent = autogen.AssistantAgent(\n", - " name=\"assistant\",\n", - " llm_config=llm_config,\n", - ")\n", - "\n", - "user_proxy = autogen.UserProxyAgent(\n", - " name=\"user_proxy\",\n", - " human_input_mode=\"NEVER\",\n", - " max_consecutive_auto_reply=10,\n", - " is_termination_msg=lambda x: x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n", - " code_execution_config={\n", - " \"work_dir\": \"web\",\n", - " \"use_docker\": False,\n", - " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n", - " llm_config=llm_config,\n", - " system_message=\"Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "b1170836-f23e-4e4c-ab83-ce791cd7fbd2", - "metadata": {}, - "source": [ - "## Wrap in LangGraph\n", - "\n", - "We now wrap the AutoGen agent in a single LangGraph node, and make that the entire graph.\n", - "The main thing this involves is defining an Input and Output schema for the node, which you would need to do if deploying this manually, so it's no extra work" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "7b417c16-ff4e-4d5c-a9a9-0aaeeef6ede5", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.graph import StateGraph, MessagesState\n", - "\n", - "\n", - "def call_autogen_agent(state: MessagesState):\n", - " last_message = state[\"messages\"][-1]\n", - " response = user_proxy.initiate_chat(autogen_agent, message=last_message.content)\n", - " # get the final response from the agent\n", - " content = response.chat_history[-1][\"content\"]\n", - " return {\"messages\": {\"role\": \"assistant\", \"content\": content}}\n", - "\n", - "\n", - "graph = StateGraph(MessagesState)\n", - "graph.add_node(call_autogen_agent)\n", - "graph.set_entry_point(\"call_autogen_agent\")\n", - "graph = graph.compile()" - ] - }, - { - "cell_type": "markdown", - "id": "f6a18377-ac29-478f-a76a-b213f1a3c85d", - "metadata": {}, - "source": [ - "## Deploy with LangGraph Platform\n", - "\n", - "You can now deploy this as you normally would with LangGraph Platform. See [these instructions](https://langchain-ai.github.io/langgraph/concepts/deployment_options/) for more details." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/how-tos/graph-api.md b/docs/docs/how-tos/graph-api.md index 2e15cacb1..4a71cc77d 100644 --- a/docs/docs/how-tos/graph-api.md +++ b/docs/docs/how-tos/graph-api.md @@ -163,7 +163,7 @@ Hello! In practice, there are additional considerations for updating lists of messages: - We may wish to update an existing message in the state. -- We may want to accept short-hands for [message formats](../concepts/low_level.md#using-messages-in-your-graph), such as [OpenAI format](https://python.langchain.com/docs/concepts/messages.md#openai-format). +- We may want to accept short-hands for [message formats](../concepts/low_level.md#using-messages-in-your-graph), such as [OpenAI format](https://python.langchain.com/docs/concepts/messages/#openai-format). LangGraph includes a built-in reducer `add_messages` that handles these considerations: @@ -658,7 +658,7 @@ print(graph.invoke({}, {"configurable": {"my_runtime_value": "b"}})) There are many use cases where you may wish for your node to have a custom retry policy, for example if you are calling an API, querying a database, or calling an LLM, etc. LangGraph lets you add retry policies to nodes. -To configure a retry policy, pass the `retry_policy` parameter to the [add_node](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.state.StateGraph.add_node). The `retry_policy` parameter takes in a `RetryPolicy` named tuple object. Below we instantiate a `RetryPolicy` object with the default parameters and associate it with a node: +To configure a retry policy, pass the `retry_policy` parameter to the [add_node](../reference/graphs.md#langgraph.graph.state.StateGraph.add_node). The `retry_policy` parameter takes in a `RetryPolicy` named tuple object. Below we instantiate a `RetryPolicy` object with the default parameters and associate it with a node: ```python from langgraph.pregel import RetryPolicy @@ -1874,4 +1874,4 @@ except ImportError: print( "You likely need to install dependencies for pygraphviz, see more here https://github.com/pygraphviz/pygraphviz/blob/main/INSTALL.txt" ) -``` \ No newline at end of file +``` diff --git a/docs/docs/how-tos/memory/add-memory.md b/docs/docs/how-tos/memory/add-memory.md index 4aaf8ec69..408c260aa 100644 --- a/docs/docs/how-tos/memory/add-memory.md +++ b/docs/docs/how-tos/memory/add-memory.md @@ -1351,7 +1351,7 @@ The problem with trimming or removing messages, as shown above, is that you may ```python from langchain_anthropic import ChatAnthropic - from langmem.short_term import SummarizationNode + from langmem.short_term import SummarizationNode, RunningSummary from langchain_core.messages.utils import count_tokens_approximately from langgraph.prebuilt import create_react_agent from langgraph.prebuilt.chat_agent_executor import AgentState @@ -1372,7 +1372,7 @@ The problem with trimming or removing messages, as shown above, is that you may # NOTE: we're adding this key to keep track of previous summary information # to make sure we're not summarizing on every LLM call # highlight-next-line - context: dict[str, Any] # (2)! + context: dict[str, RunningSummary] # (2)! checkpointer = InMemorySaver() # (3)! @@ -1447,18 +1447,18 @@ The problem with trimming or removing messages, as shown above, is that you may from langgraph.graph import StateGraph, START, MessagesState from langgraph.checkpoint.memory import InMemorySaver # highlight-next-line - from langmem.short_term import SummarizationNode + from langmem.short_term import SummarizationNode, RunningSummary model = init_chat_model("anthropic:claude-3-7-sonnet-latest") summarization_model = model.bind(max_tokens=128) class State(MessagesState): # highlight-next-line - context: dict[str, Any] # (1)! + context: dict[str, RunningSummary] # (1)! class LLMInputState(TypedDict): # (2)! summarized_messages: list[AnyMessage] - context: dict[str, Any] + context: dict[str, RunningSummary] # highlight-next-line summarization_node = SummarizationNode( diff --git a/docs/docs/how-tos/multi_agent.ipynb b/docs/docs/how-tos/multi_agent.ipynb deleted file mode 100644 index 6ee5777de..000000000 --- a/docs/docs/how-tos/multi_agent.ipynb +++ /dev/null @@ -1,657 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "34d3d54e-9a2b-481e-bccd-74aca7a53f9a", - "metadata": {}, - "source": [ - "# Build multi-agent systems" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "3f0b4f70-f14e-4026-82c0-874786789ee8", - "metadata": {}, - "source": [ - "A single agent might struggle if it needs to specialize in multiple domains or manage many tools. To tackle this, you can break your agent into smaller, independent agents and composing them into a [multi-agent system](../../concepts/multi_agent).\n", - "\n", - "In multi-agent systems, agents need to communicate between each other. They do so via [handoffs](#handoffs) — a primitive that describes which agent to hand control to and the payload to send to that agent.\n", - "\n", - "This guide covers the following:\n", - "\n", - "* implementing [handoffs](#handoffs) between agents\n", - "* using handoffs and the prebuilt [agent](../../agents/agents) to [build a custom multi-agent system](#build-a-multi-agent-system)\n", - "\n", - "To get started with building multi-agent systems, check out LangGraph [prebuilt implementations](#prebuilt-implementations) of two of the most popular multi-agent architectures — [supervisor](../../agents/multi-agent#supervisor) and [swarm](../../agents/multi-agent#swarm)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "7d43e110-16fc-4899-97f1-015d5b804b87", - "metadata": {}, - "source": [ - "## Handoffs\n", - "\n", - "To set up communication between the agents in a multi-agent system you can use [**handoffs**](../../concepts/multi_agent#handoffs) — a pattern where one agent *hands off* control to another. Handoffs allow you to specify:\n", - "\n", - "- **destination**: target agent to navigate to (e.g., name of the LangGraph node to go to)\n", - "- **payload**: information to pass to that agent (e.g., state update)\n", - "\n", - "### Create handoffs\n", - "\n", - "To implement handoffs, you can return [`Command`](../command) objects from your agent nodes or tools:\n", - "\n", - "```python\n", - "from typing import Annotated\n", - "from langchain_core.tools import tool, InjectedToolCallId\n", - "from langgraph.prebuilt import create_react_agent, InjectedState\n", - "from langgraph.graph import StateGraph, START, MessagesState\n", - "from langgraph.types import Command\n", - "\n", - "def create_handoff_tool(*, agent_name: str, description: str | None = None):\n", - " name = f\"transfer_to_{agent_name}\"\n", - " description = description or f\"Transfer to {agent_name}\"\n", - "\n", - " @tool(name, description=description)\n", - " def handoff_tool(\n", - " # highlight-next-line\n", - " state: Annotated[MessagesState, InjectedState], # (1)!\n", - " # highlight-next-line\n", - " tool_call_id: Annotated[str, InjectedToolCallId],\n", - " ) -> Command:\n", - " tool_message = {\n", - " \"role\": \"tool\",\n", - " \"content\": f\"Successfully transferred to {agent_name}\",\n", - " \"name\": name,\n", - " \"tool_call_id\": tool_call_id,\n", - " }\n", - " return Command( # (2)!\n", - " # highlight-next-line\n", - " goto=agent_name, # (3)!\n", - " # highlight-next-line\n", - " update={\"messages\": state[\"messages\"] + [tool_message]}, # (4)!\n", - " # highlight-next-line\n", - " graph=Command.PARENT, # (5)!\n", - " )\n", - " return handoff_tool\n", - "```\n", - "\n", - "1. Access the [state](../../concepts/low_level#state) of the agent that is calling the handoff tool using the [InjectedState][langgraph.prebuilt.InjectedState] annotation. See [this guide](../tool-calling/#read-state) for more information.\n", - "2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.\n", - "3. Name of the agent or node to hand off to.\n", - "4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.\n", - "5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph.\n", - "\n", - "!!! tip\n", - "\n", - " If you want to use tools that return `Command`, you can either use prebuilt [`create_react_agent`][langgraph.prebuilt.chat_agent_executor.create_react_agent] / [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] components, or implement your own tool-executing node that collects `Command` objects returned by the tools and returns a list of them, e.g.:\n", - " \n", - " ```python\n", - " def call_tools(state):\n", - " ...\n", - " commands = [tools_by_name[tool_call[\"name\"]].invoke(tool_call) for tool_call in tool_calls]\n", - " return commands\n", - " ```\n", - "\n", - "!!! Important\n", - "\n", - " This handoff implementation assumes that:\n", - " \n", - " - each agent receives overall message history (across all agents) in the multi-agent system as its input. If you want more control over agent inputs, see [this section](#control-agent-inputs)\n", - " - each agent outputs its internal messages history to the overall message history of the multi-agent system. If you want more control over **how agent outputs are added**, wrap the agent in a separate node function:\n", - "\n", - " ```python\n", - " def call_hotel_assistant(state):\n", - " # return agent's final response,\n", - " # excluding inner monologue\n", - " response = hotel_assistant.invoke(state)\n", - " # highlight-next-line\n", - " return {\"messages\": response[\"messages\"][-1]}\n", - " ```" - ] - }, - { - "cell_type": "markdown", - "id": "3956f12d-285a-4799-a0a5-db13def58a15", - "metadata": {}, - "source": [ - "### Control agent inputs\n", - "\n", - "You can use the [`Send()`][langgraph.types.Send] primitive to directly send data to the worker agents during the handoff. For example, you can request that the calling agent populate a task description for the next agent:\n", - "\n", - "```python\n", - "\n", - "from typing import Annotated\n", - "from langchain_core.tools import tool, InjectedToolCallId\n", - "from langgraph.prebuilt import InjectedState\n", - "from langgraph.graph import StateGraph, START, MessagesState\n", - "# highlight-next-line\n", - "from langgraph.types import Command, Send\n", - "\n", - "def create_task_description_handoff_tool(\n", - " *, agent_name: str, description: str | None = None\n", - "):\n", - " name = f\"transfer_to_{agent_name}\"\n", - " description = description or f\"Ask {agent_name} for help.\"\n", - "\n", - " @tool(name, description=description)\n", - " def handoff_tool(\n", - " # this is populated by the calling agent\n", - " task_description: Annotated[\n", - " str,\n", - " \"Description of what the next agent should do, including all of the relevant context.\",\n", - " ],\n", - " # these parameters are ignored by the LLM\n", - " state: Annotated[MessagesState, InjectedState],\n", - " ) -> Command:\n", - " task_description_message = {\"role\": \"user\", \"content\": task_description}\n", - " agent_input = {**state, \"messages\": [task_description_message]}\n", - " return Command(\n", - " # highlight-next-line\n", - " goto=[Send(agent_name, agent_input)],\n", - " graph=Command.PARENT,\n", - " )\n", - "\n", - " return handoff_tool\n", - "```\n", - "\n", - "See the multi-agent [supervisor](../tutorials/agent_supervisor.ipynb#4-create-delegation-tasks) tutorial for a full example of using [`Send()`][langgraph.types.Send] in handoffs." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "21511f57-7bf3-4223-9a17-ce9fc84c40ab", - "metadata": {}, - "source": [ - "## Build a multi-agent system\n", - "\n", - "You can use handoffs in any agents built with LangGraph. We recommend using the prebuilt [agent](../../agents/overview) or [`ToolNode`](../tool-calling#use-prebuilt-toolnode), as they natively support handoffs tools returning `Command`. Below is an example of how you can implement a multi-agent system for booking travel using handoffs:\n", - "\n", - "```python\n", - "from langgraph.prebuilt import create_react_agent\n", - "from langgraph.graph import StateGraph, START, MessagesState\n", - "\n", - "def create_handoff_tool(*, agent_name: str, description: str | None = None):\n", - " # same implementation as above\n", - " ...\n", - " return Command(...)\n", - "\n", - "# Handoffs\n", - "transfer_to_hotel_assistant = create_handoff_tool(agent_name=\"hotel_assistant\")\n", - "transfer_to_flight_assistant = create_handoff_tool(agent_name=\"flight_assistant\")\n", - "\n", - "# Define agents\n", - "flight_assistant = create_react_agent(\n", - " model=\"anthropic:claude-3-5-sonnet-latest\",\n", - " # highlight-next-line\n", - " tools=[..., transfer_to_hotel_assistant],\n", - " # highlight-next-line\n", - " name=\"flight_assistant\"\n", - ")\n", - "hotel_assistant = create_react_agent(\n", - " model=\"anthropic:claude-3-5-sonnet-latest\",\n", - " # highlight-next-line\n", - " tools=[..., transfer_to_flight_assistant],\n", - " # highlight-next-line\n", - " name=\"hotel_assistant\"\n", - ")\n", - "\n", - "# Define multi-agent graph\n", - "multi_agent_graph = (\n", - " StateGraph(MessagesState)\n", - " # highlight-next-line\n", - " .add_node(flight_assistant)\n", - " # highlight-next-line\n", - " .add_node(hotel_assistant)\n", - " .add_edge(START, \"flight_assistant\")\n", - " .compile()\n", - ")\n", - "```\n", - "\n", - "??? example \"Full example: Multi-agent system for booking travel\"\n", - "\n", - " ```python\n", - " from typing import Annotated\n", - " from langchain_core.messages import convert_to_messages\n", - " from langchain_core.tools import tool, InjectedToolCallId\n", - " from langgraph.prebuilt import create_react_agent, InjectedState\n", - " from langgraph.graph import StateGraph, START, MessagesState\n", - " from langgraph.types import Command\n", - " \n", - " # We'll use `pretty_print_messages` helper to render the streamed agent outputs nicely\n", - " \n", - " def pretty_print_message(message, indent=False):\n", - " pretty_message = message.pretty_repr(html=True)\n", - " if not indent:\n", - " print(pretty_message)\n", - " return\n", - " \n", - " indented = \"\\n\".join(\"\\t\" + c for c in pretty_message.split(\"\\n\"))\n", - " print(indented)\n", - " \n", - " \n", - " def pretty_print_messages(update, last_message=False):\n", - " is_subgraph = False\n", - " if isinstance(update, tuple):\n", - " ns, update = update\n", - " # skip parent graph updates in the printouts\n", - " if len(ns) == 0:\n", - " return\n", - " \n", - " graph_id = ns[-1].split(\":\")[0]\n", - " print(f\"Update from subgraph {graph_id}:\")\n", - " print(\"\\n\")\n", - " is_subgraph = True\n", - " \n", - " for node_name, node_update in update.items():\n", - " update_label = f\"Update from node {node_name}:\"\n", - " if is_subgraph:\n", - " update_label = \"\\t\" + update_label\n", - " \n", - " print(update_label)\n", - " print(\"\\n\")\n", - " \n", - " messages = convert_to_messages(node_update[\"messages\"])\n", - " if last_message:\n", - " messages = messages[-1:]\n", - " \n", - " for m in messages:\n", - " pretty_print_message(m, indent=is_subgraph)\n", - " print(\"\\n\")\n", - "\n", - "\n", - " def create_handoff_tool(*, agent_name: str, description: str | None = None):\n", - " name = f\"transfer_to_{agent_name}\"\n", - " description = description or f\"Transfer to {agent_name}\"\n", - " \n", - " @tool(name, description=description)\n", - " def handoff_tool(\n", - " # highlight-next-line\n", - " state: Annotated[MessagesState, InjectedState], # (1)!\n", - " # highlight-next-line\n", - " tool_call_id: Annotated[str, InjectedToolCallId],\n", - " ) -> Command:\n", - " tool_message = {\n", - " \"role\": \"tool\",\n", - " \"content\": f\"Successfully transferred to {agent_name}\",\n", - " \"name\": name,\n", - " \"tool_call_id\": tool_call_id,\n", - " }\n", - " return Command( # (2)!\n", - " # highlight-next-line\n", - " goto=agent_name, # (3)!\n", - " # highlight-next-line\n", - " update={\"messages\": state[\"messages\"] + [tool_message]}, # (4)!\n", - " # highlight-next-line\n", - " graph=Command.PARENT, # (5)!\n", - " )\n", - " return handoff_tool\n", - " \n", - " # Handoffs\n", - " transfer_to_hotel_assistant = create_handoff_tool(\n", - " agent_name=\"hotel_assistant\",\n", - " description=\"Transfer user to the hotel-booking assistant.\",\n", - " )\n", - " transfer_to_flight_assistant = create_handoff_tool(\n", - " agent_name=\"flight_assistant\",\n", - " description=\"Transfer user to the flight-booking assistant.\",\n", - " )\n", - " \n", - " # Simple agent tools\n", - " def book_hotel(hotel_name: str):\n", - " \"\"\"Book a hotel\"\"\"\n", - " return f\"Successfully booked a stay at {hotel_name}.\"\n", - " \n", - " def book_flight(from_airport: str, to_airport: str):\n", - " \"\"\"Book a flight\"\"\"\n", - " return f\"Successfully booked a flight from {from_airport} to {to_airport}.\"\n", - " \n", - " # Define agents\n", - " flight_assistant = create_react_agent(\n", - " model=\"anthropic:claude-3-5-sonnet-latest\",\n", - " # highlight-next-line\n", - " tools=[book_flight, transfer_to_hotel_assistant],\n", - " prompt=\"You are a flight booking assistant\",\n", - " # highlight-next-line\n", - " name=\"flight_assistant\"\n", - " )\n", - " hotel_assistant = create_react_agent(\n", - " model=\"anthropic:claude-3-5-sonnet-latest\",\n", - " # highlight-next-line\n", - " tools=[book_hotel, transfer_to_flight_assistant],\n", - " prompt=\"You are a hotel booking assistant\",\n", - " # highlight-next-line\n", - " name=\"hotel_assistant\"\n", - " )\n", - " \n", - " # Define multi-agent graph\n", - " multi_agent_graph = (\n", - " StateGraph(MessagesState)\n", - " .add_node(flight_assistant)\n", - " .add_node(hotel_assistant)\n", - " .add_edge(START, \"flight_assistant\")\n", - " .compile()\n", - " )\n", - " \n", - " # Run the multi-agent graph\n", - " for chunk in multi_agent_graph.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"book a flight from BOS to JFK and a stay at McKittrick Hotel\"\n", - " }\n", - " ]\n", - " },\n", - " # highlight-next-line\n", - " subgraphs=True\n", - " ):\n", - " pretty_print_messages(chunk)\n", - " ```\n", - "\n", - " 1. Access agent's state\n", - " 2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.\n", - " 3. Name of the agent or node to hand off to.\n", - " 4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.\n", - " 5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph." - ] - }, - { - "cell_type": "markdown", - "id": "e8314da4-9971-429b-9e70-58b40795de74", - "metadata": {}, - "source": [ - "## Multi-turn conversation\n", - "\n", - "Users might want to engage in a *multi-turn conversation* with one or more agents. To build a system that can handle this, you can create a node that uses an [`interrupt`][langgraph.types.interrupt] to collect user input and routes back to the **active** agent.\n", - "\n", - "The agents can then be implemented as nodes in a graph that executes agent steps and determines the next action:\n", - "\n", - "1. **Wait for user input** to continue the conversation, or \n", - "2. **Route to another agent** (or back to itself, such as in a loop) via a [handoff](#handoffs)\n", - "\n", - "```python\n", - "def human(state) -> Command[Literal[\"agent\", \"another_agent\"]]:\n", - " \"\"\"A node for collecting user input.\"\"\"\n", - " user_input = interrupt(value=\"Ready for user input.\")\n", - "\n", - " # Determine the active agent.\n", - " active_agent = ...\n", - "\n", - " ...\n", - " return Command(\n", - " update={\n", - " \"messages\": [{\n", - " \"role\": \"human\",\n", - " \"content\": user_input,\n", - " }]\n", - " },\n", - " goto=active_agent\n", - " )\n", - "\n", - "def agent(state) -> Command[Literal[\"agent\", \"another_agent\", \"human\"]]:\n", - " # The condition for routing/halting can be anything, e.g. LLM tool call / structured output, etc.\n", - " goto = get_next_agent(...) # 'agent' / 'another_agent'\n", - " if goto:\n", - " return Command(goto=goto, update={\"my_state_key\": \"my_state_value\"})\n", - " else:\n", - " return Command(goto=\"human\") # Go to human node\n", - "```\n", - "\n", - "??? example \"Full example: multi-agent system for travel recommendations\"\n", - "\n", - " In this example, we will build a team of travel assistant agents that can communicate with each other via handoffs.\n", - " \n", - " We will create 2 agents:\n", - " \n", - " * travel_advisor: can help with travel destination recommendations. Can ask hotel_advisor for help.\n", - " * hotel_advisor: can help with hotel recommendations. Can ask travel_advisor for help.\n", - "\n", - " ```python\n", - " from langchain_anthropic import ChatAnthropic\n", - " from langgraph.graph import MessagesState, StateGraph, START\n", - " from langgraph.prebuilt import create_react_agent, InjectedState\n", - " from langgraph.types import Command, interrupt\n", - " from langgraph.checkpoint.memory import MemorySaver\n", - " \n", - " \n", - " model = ChatAnthropic(model=\"claude-3-5-sonnet-latest\")\n", - "\n", - " class MultiAgentState(MessagesState):\n", - " last_active_agent: str\n", - " \n", - " \n", - " # Define travel advisor tools and ReAct agent\n", - " travel_advisor_tools = [\n", - " get_travel_recommendations,\n", - " make_handoff_tool(agent_name=\"hotel_advisor\"),\n", - " ]\n", - " travel_advisor = create_react_agent(\n", - " model,\n", - " travel_advisor_tools,\n", - " prompt=(\n", - " \"You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). \"\n", - " \"If you need hotel recommendations, ask 'hotel_advisor' for help. \"\n", - " \"You MUST include human-readable response before transferring to another agent.\"\n", - " ),\n", - " )\n", - " \n", - " \n", - " def call_travel_advisor(\n", - " state: MultiAgentState,\n", - " ) -> Command[Literal[\"hotel_advisor\", \"human\"]]:\n", - " # You can also add additional logic like changing the input to the agent / output from the agent, etc.\n", - " # NOTE: we're invoking the ReAct agent with the full history of messages in the state\n", - " response = travel_advisor.invoke(state)\n", - " update = {**response, \"last_active_agent\": \"travel_advisor\"}\n", - " return Command(update=update, goto=\"human\")\n", - " \n", - " \n", - " # Define hotel advisor tools and ReAct agent\n", - " hotel_advisor_tools = [\n", - " get_hotel_recommendations,\n", - " make_handoff_tool(agent_name=\"travel_advisor\"),\n", - " ]\n", - " hotel_advisor = create_react_agent(\n", - " model,\n", - " hotel_advisor_tools,\n", - " prompt=(\n", - " \"You are a hotel expert that can provide hotel recommendations for a given destination. \"\n", - " \"If you need help picking travel destinations, ask 'travel_advisor' for help.\"\n", - " \"You MUST include human-readable response before transferring to another agent.\"\n", - " ),\n", - " )\n", - " \n", - " \n", - " def call_hotel_advisor(\n", - " state: MultiAgentState,\n", - " ) -> Command[Literal[\"travel_advisor\", \"human\"]]:\n", - " response = hotel_advisor.invoke(state)\n", - " update = {**response, \"last_active_agent\": \"hotel_advisor\"}\n", - " return Command(update=update, goto=\"human\")\n", - " \n", - " \n", - " def human_node(\n", - " state: MultiAgentState, config\n", - " ) -> Command[Literal[\"hotel_advisor\", \"travel_advisor\", \"human\"]]:\n", - " \"\"\"A node for collecting user input.\"\"\"\n", - " \n", - " user_input = interrupt(value=\"Ready for user input.\")\n", - " active_agent = state[\"last_active_agent\"]\n", - " \n", - " return Command(\n", - " update={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"human\",\n", - " \"content\": user_input,\n", - " }\n", - " ]\n", - " },\n", - " goto=active_agent,\n", - " )\n", - " \n", - " \n", - " builder = StateGraph(MultiAgentState)\n", - " builder.add_node(\"travel_advisor\", call_travel_advisor)\n", - " builder.add_node(\"hotel_advisor\", call_hotel_advisor)\n", - " \n", - " # This adds a node to collect human input, which will route\n", - " # back to the active agent.\n", - " builder.add_node(\"human\", human_node)\n", - " \n", - " # We'll always start with a general travel advisor.\n", - " builder.add_edge(START, \"travel_advisor\")\n", - " \n", - " \n", - " checkpointer = MemorySaver()\n", - " graph = builder.compile(checkpointer=checkpointer)\n", - " ```\n", - " \n", - " Let's test a multi turn conversation with this application.\n", - "\n", - " ```python\n", - " import uuid\n", - " \n", - " thread_config = {\"configurable\": {\"thread_id\": str(uuid.uuid4())}}\n", - " \n", - " inputs = [\n", - " # 1st round of conversation,\n", - " {\n", - " \"messages\": [\n", - " {\"role\": \"user\", \"content\": \"i wanna go somewhere warm in the caribbean\"}\n", - " ]\n", - " },\n", - " # Since we're using `interrupt`, we'll need to resume using the Command primitive.\n", - " # 2nd round of conversation,\n", - " Command(\n", - " resume=\"could you recommend a nice hotel in one of the areas and tell me which area it is.\"\n", - " ),\n", - " # 3rd round of conversation,\n", - " Command(\n", - " resume=\"i like the first one. could you recommend something to do near the hotel?\"\n", - " ),\n", - " ]\n", - " \n", - " for idx, user_input in enumerate(inputs):\n", - " print()\n", - " print(f\"--- Conversation Turn {idx + 1} ---\")\n", - " print()\n", - " print(f\"User: {user_input}\")\n", - " print()\n", - " for update in graph.stream(\n", - " user_input,\n", - " config=thread_config,\n", - " stream_mode=\"updates\",\n", - " ):\n", - " for node_id, value in update.items():\n", - " if isinstance(value, dict) and value.get(\"messages\", []):\n", - " last_message = value[\"messages\"][-1]\n", - " if isinstance(last_message, dict) or last_message.type != \"ai\":\n", - " continue\n", - " print(f\"{node_id}: {last_message.content}\")\n", - " ```\n", - " \n", - " ```\n", - " --- Conversation Turn 1 ---\n", - " \n", - " User: {'messages': [{'role': 'user', 'content': 'i wanna go somewhere warm in the caribbean'}]}\n", - " \n", - " travel_advisor: Based on the recommendations, Aruba would be an excellent choice for your Caribbean getaway! Aruba is known as \"One Happy Island\" and offers:\n", - " - Year-round warm weather with consistent temperatures around 82°F (28°C)\n", - " - Beautiful white sand beaches like Eagle Beach and Palm Beach\n", - " - Clear turquoise waters perfect for swimming and snorkeling\n", - " - Minimal rainfall and location outside the hurricane belt\n", - " - A blend of Caribbean and Dutch culture\n", - " - Great dining options and nightlife\n", - " - Various water sports and activities\n", - " \n", - " Would you like me to get some specific hotel recommendations in Aruba for your stay? I can transfer you to our hotel advisor who can help with accommodations.\n", - " \n", - " --- Conversation Turn 2 ---\n", - " \n", - " User: Command(resume='could you recommend a nice hotel in one of the areas and tell me which area it is.')\n", - " \n", - " hotel_advisor: Based on the recommendations, I can suggest two excellent options:\n", - " \n", - " 1. The Ritz-Carlton, Aruba - Located in Palm Beach\n", - " - This luxury resort is situated in the vibrant Palm Beach area\n", - " - Known for its exceptional service and amenities\n", - " - Perfect if you want to be close to dining, shopping, and entertainment\n", - " - Features multiple restaurants, a casino, and a world-class spa\n", - " - Located on a pristine stretch of Palm Beach\n", - " \n", - " 2. Bucuti & Tara Beach Resort - Located in Eagle Beach\n", - " - An adults-only boutique resort on Eagle Beach\n", - " - Known for being more intimate and peaceful\n", - " - Award-winning for its sustainability practices\n", - " - Perfect for a romantic getaway or peaceful vacation\n", - " - Located on one of the most beautiful beaches in the Caribbean\n", - " \n", - " Would you like more specific information about either of these properties or their locations?\n", - " \n", - " --- Conversation Turn 3 ---\n", - " \n", - " User: Command(resume='i like the first one. could you recommend something to do near the hotel?')\n", - " \n", - " travel_advisor: Near the Ritz-Carlton in Palm Beach, here are some highly recommended activities:\n", - " \n", - " 1. Visit the Palm Beach Plaza Mall - Just a short walk from the hotel, featuring shopping, dining, and entertainment\n", - " 2. Try your luck at the Stellaris Casino - It's right in the Ritz-Carlton\n", - " 3. Take a sunset sailing cruise - Many depart from the nearby pier\n", - " 4. Visit the California Lighthouse - A scenic landmark just north of Palm Beach\n", - " 5. Enjoy water sports at Palm Beach:\n", - " - Jet skiing\n", - " - Parasailing\n", - " - Snorkeling\n", - " - Stand-up paddleboarding\n", - " \n", - " Would you like more specific information about any of these activities or would you like to know about other options in the area?\n", - " ```" - ] - }, - { - "cell_type": "markdown", - "id": "04d18c63-a0eb-45ac-86dc-0cc5bd683973", - "metadata": {}, - "source": [ - "## Prebuilt implementations" - ] - }, - { - "cell_type": "markdown", - "id": "e0e4ce57-f8de-4f37-836e-c1e1a02dd7b7", - "metadata": {}, - "source": [ - "LangGraph comes with prebuilt implementations of two of the most popular multi-agent architectures:\n", - "\n", - "- [supervisor](../../agents/multi-agent#supervisor) — individual agents are coordinated by a central supervisor agent. The supervisor controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements. You can use [`langgraph-supervisor`](https://github.com/langchain-ai/langgraph-supervisor-py) library to create a supervisor multi-agent systems.\n", - "- [swarm](../../agents/multi-agent#supervisor) — agents dynamically hand off control to one another based on their specializations. The system remembers which agent was last active, ensuring that on subsequent interactions, the conversation resumes with that agent. You can use [`langgraph-swarm`](https://github.com/langchain-ai/langgraph-swarm-py) library to create a swarm multi-agent systems." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/how-tos/multi_agent.md b/docs/docs/how-tos/multi_agent.md index 5aead8b95..fdd781d4f 100644 --- a/docs/docs/how-tos/multi_agent.md +++ b/docs/docs/how-tos/multi_agent.md @@ -130,7 +130,7 @@ def create_task_description_handoff_tool( return handoff_tool ``` -See the multi-agent [supervisor](../tutorials/multi_agent/agent_supervisor.ipynb#4-create-delegation-tasks) example for a full example of using [`Send()`][langgraph.types.Send] in handoffs. +See the multi-agent [supervisor](../tutorials/multi_agent/agent_supervisor.md#4-create-delegation-tasks) example for a full example of using [`Send()`][langgraph.types.Send] in handoffs. ## Build a multi-agent system diff --git a/docs/docs/how-tos/run-id-langsmith.ipynb b/docs/docs/how-tos/run-id-langsmith.ipynb deleted file mode 100644 index 550c8ae64..000000000 --- a/docs/docs/how-tos/run-id-langsmith.ipynb +++ /dev/null @@ -1,274 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# How to pass custom run ID or set tags and metadata for graph runs in LangSmith\n", - "\n", - "
\n", - "

Prerequisites

\n", - "

\n", - " This guide assumes familiarity with the following:\n", - "

\n", - "

\n", - "
\n", - "\n", - "Debugging graph runs can sometimes be difficult to do in an IDE or terminal. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read the [LangSmith documentation](https://docs.smith.langchain.com) for more information on how to get started.\n", - "\n", - "To make it easier to identify and analyzed traces generated during graph invocation, you can set additional configuration at run time (see [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig)):\n", - "\n", - "| **Field** | **Type** | **Description** |\n", - "|-------------|---------------------|--------------------------------------------------------------------------------------------------------------------|\n", - "| run_name | `str` | Name for the tracer run for this call. Defaults to the name of the class. |\n", - "| run_id | `UUID` | Unique identifier for the tracer run for this call. If not provided, a new UUID will be generated. |\n", - "| tags | `List[str]` | Tags for this call and any sub-calls (e.g., a Chain calling an LLM). You can use these to filter calls. |\n", - "| metadata | `Dict[str, Any]` | Metadata for this call and any sub-calls (e.g., a Chain calling an LLM). Keys should be strings, values should be JSON-serializable. |\n", - "\n", - "LangGraph graphs implement the [LangChain Runnable Interface](https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.Runnable.html) and accept a second argument (`RunnableConfig`) in methods like `invoke`, `ainvoke`, `stream` etc.\n", - "\n", - "The LangSmith platform will allow you to search and filter traces based on `run_name`, `run_id`, `tags` and `metadata`.\n", - "\n", - "\n", - "## TLDR\n", - "\n", - "```python\n", - "import uuid\n", - "# Generate a random UUID -- it must be a UUID\n", - "config = {\"run_id\": uuid.uuid4()}, \"tags\": [\"my_tag1\"], \"metadata\": {\"a\": 5}}\n", - "# Works with all standard Runnable methods \n", - "# like invoke, batch, ainvoke, astream_events etc\n", - "graph.stream(inputs, config, stream_mode=\"values\")\n", - "```\n", - "\n", - "The rest of the how to guide will show a full agent.\n", - "\n", - "## Setup\n", - "\n", - "First, let's install the required packages and set our API keys" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "%%capture --no-stderr\n", - "%pip install --quiet -U langgraph langchain_openai" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "import getpass\n", - "import os\n", - "\n", - "\n", - "def _set_env(var: str):\n", - " if not os.environ.get(var):\n", - " os.environ[var] = getpass.getpass(f\"{var}: \")\n", - "\n", - "\n", - "_set_env(\"OPENAI_API_KEY\")\n", - "_set_env(\"LANGSMITH_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Set up LangSmith for LangGraph development

\n", - "

\n", - " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", - "

\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define the graph\n", - "\n", - "For this example we will use the [prebuilt ReAct agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/)." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_openai import ChatOpenAI\n", - "from typing import Literal\n", - "from langgraph.prebuilt import create_react_agent\n", - "from langchain_core.tools import tool\n", - "\n", - "# First we initialize the model we want to use.\n", - "model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n", - "\n", - "\n", - "# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF)\n", - "@tool\n", - "def get_weather(city: Literal[\"nyc\", \"sf\"]):\n", - " \"\"\"Use this to get weather information.\"\"\"\n", - " if city == \"nyc\":\n", - " return \"It might be cloudy in nyc\"\n", - " elif city == \"sf\":\n", - " return \"It's always sunny in sf\"\n", - " else:\n", - " raise AssertionError(\"Unknown city\")\n", - "\n", - "\n", - "tools = [get_weather]\n", - "\n", - "\n", - "# Define the graph\n", - "graph = create_react_agent(model, tools=tools)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Run your graph\n", - "\n", - "Now that we've defined our graph let's run it once and view the trace in LangSmith. In order for our trace to be easily accessible in LangSmith, we will pass in a custom `run_id` in the config.\n", - "\n", - "This assumes that you have set your `LANGSMITH_API_KEY` environment variable.\n", - "\n", - "Note that you can also configure what project to trace to by setting the `LANGCHAIN_PROJECT` environment variable, by default runs will be traced to the `default` project." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================\u001b[1m Human Message \u001b[0m=================================\n", - "\n", - "what is the weather in sf\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " get_weather (call_9ZudXyMAdlUjptq9oMGtQo8o)\n", - " Call ID: call_9ZudXyMAdlUjptq9oMGtQo8o\n", - " Args:\n", - " city: sf\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: get_weather\n", - "\n", - "It's always sunny in sf\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "The weather in San Francisco is currently sunny.\n" - ] - } - ], - "source": [ - "import uuid\n", - "\n", - "\n", - "def print_stream(stream):\n", - " for s in stream:\n", - " message = s[\"messages\"][-1]\n", - " if isinstance(message, tuple):\n", - " print(message)\n", - " else:\n", - " message.pretty_print()\n", - "\n", - "\n", - "inputs = {\"messages\": [(\"user\", \"what is the weather in sf\")]}\n", - "\n", - "config = {\"run_name\": \"agent_007\", \"tags\": [\"cats are awesome\"]}\n", - "\n", - "print_stream(graph.stream(inputs, config, stream_mode=\"values\"))" - ] - }, - { - "attachments": { - "d38d1f2b-0f4c-4707-b531-a3c749de987f.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABUAAAAHACAIAAADsm1WnAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4XuydB5RURdqGnUTOOUgSBcmgIgiiEiQpiAQRUBFB17y6uuuuYf81u66rrhkUsyhKjiKIBMlBSSIqURBEchjCpP/pqba4dqK7p3ume+btM4fT1K34VN3b96svVEL58pXO0EcEREAEREAEREAEREAEREAEREAERCC2CSTGdvfUOxEQAREQAREQAREQAREQAREQAREQARcBCfBaByIgAiIgAiIgAiIgAiIgAiIgAiIQBwQkwMfBJKmLIiACIiACIiACIiACIiACIiACIiABXmtABERABERABERABERABERABERABOKAgAT4OJgkdVEEREAEREAEREAEREAEREAEREAEJMBrDYiACIiACIiACIiACIiACIiACIhAHBCQAB8Hk6QuioAIiIAIiIAIiIAIiIAIiIAIiIAEeK0BERABERABERABERABERABERABEYgDAhLg42CS1EUREAEREAEREAEREAEREAEREAERkACvNSACIiACIiACIiACIiACIiACIiACcUBAAnwcTJK6KAIiIAIiIAIiIAIiIAIiIAIiIAIS4LUGREAEREAEREAEREAEREAEREAERCAOCEiAj4NJUhdFQAREQAREQAREQAREQAREQAREQAK81oAIiIAIiIAIiIAIiIAIiIAIiIAIxAEBCfBxMEnqogiIgAiIgAiIgAiIgAiIgAiIgAhIgNcaEAEREAEREAEREAEREAEREAEREIE4ICABPg4mSV0UAREQAREQAREQAREQAREQAREQAQnwWgMiIAIiIAIiIAIiIAIiIAIiIAIiEAcEJMDHwSSpiyIgAiIgAiIgAiIgAiIgAiIgAiIgAV5rQAREQAREQAREQAREQAREQAREQATigIAE+DiYJHVRBERABERABERABERABERABERABCTAaw2IgAiIgAiIgAiIgAiIgAiIgAiIQBwQkAAfB5OkLoqACIiACIiACIiACIiACIiACIiABHitAREQAREQAREQAREQAREQAREQARGIAwIS4ONgktRFERABERABERABERABERABERABEZAArzUgAiIgAiIgAiIgAiIgAiIgAiIgAnFAQAJ8HEySuigCIiACIiACIiACIiACIiACIiACEuC1BkRABERABERABERABERABERABEQgDghIgI+DSVIXRUAEREAEREAEREAEREAEREAERCCpWLHioiACIiAC+ZJAuXJle/XqVaFC+S1btubLAWpQIiACIiACIiACIiACBYpAcrRH+9hj/ype3PceQVZWVmrqsd9++239+vULFy5KTU2NdmcKYP2NGjW66aYbwxv4Aw/8Iz093ZTt3r1bx44d+D5v3vyJEyeFV2G8l+ratcvll3diFF9//fX48RPjfTim/xUrVvz73/9mx7Jo0eIxY8YGP7SmTZsOHny9zT9hwsT5878OvnhUcyK9z537VdWqVWnlf/976fHHn4xqc/mj8pIlS7LIu3XrWqdO7UqVKiUkJOzevXvz5i2ffz5jxowvDh8+nD+GqVGIgAiIgAiIgAiIQJwSiLoAf+211/IafVo6x44dGzXq4yeeeEoviKdlFVKGWrVqDh58Q0hFbOYHH3zYCvAXXHC+qef48RMFVoA/77zzDASw5BsBvkyZMs4V0qVL5/HjJ2RkZAS5Zm6//da+ffvYzD/++GPsCPBt2rQx0jvd69u3rwT4wHOalJQ0ZMiN//jHA6VLl3bmhGGzZs169brq4MGDTz/973feeTf45RG4RV0VAREQAREQAREQAREIlUCs+MAXLVp06NCb5s2bc955LUIdg/KLgAhEikCVKlU6deoYZG2lSpW68sorgsyc+9nWrFlz/Phx0+7SpUs9OvD888/NmDGdv4svbpv7fYu1FpOTk99++61nnnnKKb2fdH3SbFe5RIa33hqBqB/Z/lOhmQv+ZVFFtnLVJgIiIAIiIAIiIAL5iUDUNfAhwapR48xRoz5s377Tzp07QyqozP4ILF26rH//Ad5XGzdu/MgjD5l0nxm4lJZ26t3duwal5FcC1103CGPpYEbXp0/vIkWKBJMzT/Js3brtyiuvGjCg/86du0aMeNOjD/Xr1z///PNILFeuXJ50L6Ya/c9/nr3iiu6mS8uXr3jjjeHz5s3bt28/KZUrV77sskvvuOP2hg0b8N8ePa5EjP/rXx+IYP8x1DdzQZ0pKbH1qxTBYaoqERABERABERABEcg5gVx9VcJ9+tln/2M7jW981apVOnbsyItjYqLbFqBChQr/+98L11xzbc7HphogsGfPni+/nO2NwtrGc8lnBu8iSsnfBLZv34G3S7FixXCBxvkZz+fTjve66waaPOvWfdeoUcPT5s/9DN9mf3K/3fhqkUAG118/yPT5lVdeffTRxwlQYofw66+/jh796dix47BZGDjQtRt4442D3333PSY9voap3oqACIiACIiACIhAPiCQqyb0e/fuW7x4if1Dbvzww1FDhgzt2fNqa+kK0w4d2terd04+gKshiEAcEcCx2SjesaYeMOD0O2hI7LhGM8D167//+eef42ik6qoHgb59e5uUVatW/etfjzmld5uTLb+//OX+LVu2kILCvHfvq4VRBERABERABERABEQg9wnkqgbe3/AWL178/PMvPPjgP2wGAp7/8MOP5r+FCqU0bNjIXuIN8sCBA95VIfPbI/H279+/deupU6Nq1qxRrlx5U2Tv3j0//7zdfK9duzax2TCgRU39448/4THrXa13CgalzZs3q1ixQtGixWho+/btK1asLIDW5rzEt2jRHCmucOEi6OjQc1qw3tDOOecccxjBhg0bCFhIhjp16gC/WrVqx48fGz7c07yZDIUKFSIgwtln12Va4bxu3ToERZ+ihXdz9I310LBhw/Lly3O6AR4Za9eu47wD75w+U+rWrcsUU5aQij/99BMWxUG2a2o7++yzMTYmujsOxJBZsmQp0b98NhRTiZguE57w6qt70StU6y+99HLgUQ8a5Fa/T5w4sWXLlkGOpUSJEsx7rVq1ChcuzI3MtAZW5BJBjTuOyrnRuE/5Et7C27x5s5kFmi5b1hVWk9Vr+sxcb9vm3oDYuHGjvziarKgmTZqwKphWOsOq8PkgMnXSSbO7wbaIfbBgJW7WJKH+pk6dFiSxXMhGr0wrU6ZMDdAcMvwHH3xkdPUege68S/Fk4AgMQiQeOXJk06bNK1eucLrT2/zkSWHlJZ9yqm/evDlbvSYDGwpmEVqepMPTXxQ9bj0WGHk8fiYIrc9NTTprgJVgKucRxBrA5is19eiGDT+sXPmNv2q9R6cUERABERABERABEcgrAjEhwDP4yZOnOgV45D1LhKhas2bNsP+96aZhkyZN9ub1+uuvmjfm7NqmoNi3ef72t79ee21/89+PPhr15z/fi7M9Pp8ewbq++279ww8/gp2/d+UmhXhdf/nLPbzE8zbpzHP06NFPP/3sueeeR1rzVzafpXfq1Omppx4/66yz7Lh4z547d959992P47H3YF955SXj49qpU5dNmza98MJ/8aQ1fhMI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dBs/fqIzZKnHdLCKLrusI442zl8Bnhg8fnksOI+i9NdD0lnMPXv2Qp/v8ZOxdes2jnhkru3ZeAEq0SUREAEREAEREAERyCsCCeXLV8qrtsNrF/0MZwURPurAgYObN2/OTZWd6TCaH2z1y5Urh54WE1PcXwljHt5YVCowAdTpKNXLlCmdmnqMPRQc3YMxVMZUu02bizCsxdmVUgsXLmKaAjfkcZWyxF1HnX7o0OEffvjB21o4QG2sT8pSQ8mSJdhTQOzBFN+aAQcoWEAucVoEfGrWrFm4cCFuYUyauYvzduwYBWCYXbp0KUQ7TL79TRYqZdwxWBUIeOzZIY46w7Dn7RAi2zrm6MwRDzqsyk+cOI5SHQMWIomG9LAlOgC4KlWqiJzMDchdwM0YTD8x2q9b9yz+xUcGodpnEe4yDqKnewcPHmL92AB4PjOTiJ0FLjl8wbzi0kvdwTXQ5LNTzE8J88htTqSGkAbory2li4AIiIAIiIAIiEBUCcSfAB9VHKpcBERABEQgnxHwKcDnszFqOCIgAiIgAiIgAgWEQKyY0BcQ3BqmCIiACIiACIiACIiACIiACIiACIRHQAJ8eNxUSgREQAREQAREQAREQAREQAREQARylYAE+FzFrcZEQAREQAREQAREQAREQAREQAREIDwCEuDD46ZSIiACIiACIiACIiACIiACIiACIpCrBCTA5ypuNSYCIiACIiACIiACIiACIiACIiAC4RFQFPrwuKmUCIiACIhAfBAoUaJE7dq16StH0OvUz/iYM/VSBERABERABETADwEJ8H7AKFkEREAEREAEREAEREAEREAEREAEYomATOhjaTbUFxEQAREQAREQAREQAREQAREQARHwQ0ACvB8wShYBERABERABERABERABERABERCBWCIgAT6WZkN9EQEREAEREAEREAEREAEREAEREAE/BCTA+wGjZBEQAREQAREQAREQAREQAREQARGIJQIS4GNpNtQXERABERABERABERABERABERABEfBDQAK8HzBKFgEREAEREAEREAEREAEREAEREIFYIiABPpZmQ30RAREQAREQAREQAREQAREQAREQAT8EJMD7AaNkERABERABERABERABERABERABEYglAhLgY2k21BcREAEREAEREAEREAEREAEREAER8ENAArwfMEoWAREQAREQAREQAREQAREQAREQgVgiIAE+lmZDfREBERABERABERABERABERABERABPwQkwPsBo2QREAEREAEREAEREAEREAEREAERiCUCEuBjaTbUFxEQAREQAREQAREQAREQAREQARHwQ0ACvB8wShYBERABERABERABERABERABERCBWCIgAT6WZkN9EQEREAEREAEREAEREAEREAEREAE/BCTA+wGjZBEQAREQAREQAREQAREQAREQARGIJQIS4GNpNtQXERABERABERABERABERABERABEfBDQAK8HzBKFgEREAEREAEREAEREAEREAEREIFYIiABPpZmQ30RAREQAREQAREQAREQAREQAREQAT8EJMD7AaNkERABERABERABERABERABERABEYglAhLgY2k21BcREAEREAEREAEREAEREAEREAER8ENAArwfMEoWAREQAREQAREQAREQAREQAREQgVgiIAE+lmZDfREBERABERABERABERABERABERABPwQkwPsBo2QREAEREAEREAEREAEREAEREAERiCUCydHrzOq166JXeezX3LRxo9jvpHooAiIgAiIgAiIgAiIgAiIgAiIQLwSkgY+XmVI/RUAEREAEREAEREAEREAEREAECjQBCfAFevo1eBEQAREQAREQAREQAREQAREQgXghIAE+XmZK/RQBERABERABERABERABERABESjQBBLq1ZerdoFeARq8CIiACIiACIiACIiACIiACIhAXBCQBj4upkmdFAEREAEREAEREAEREAEREAERKOgEEsqXr1TQGWj8IiACIiACIiACIiACIiACIiACIhDzBKSBj/kpUgdFQAREQAREQAREQAREQAREQARE4IwzJMBrFYiACIiACIiACIiACIiACIiACIhAHBCQAB8Hk6QuioAIiIAIiIAIiIAIiIAIiIAIiIAEeK0BERABERABERABERABERABERABEYgDAhLg42CS1EUREAEREAEREAEREAEREAEREAERkACvNSACIiACIiACIiACIiACIiACIiACcUBAAnwcTJK6KAIiIAIiIAIiIAIiIAIiIAIiIAIS4LUGREAEREAEREAEREAEREAEREAERCAOCEiAj4NJUhdFQAREQAREQAREQAREQAREQAREQAK81oAIiIAIiIAIiIAIiIAIiIAIiIAIxAEBCfBxMEnqogiIgAiIgAiIgAiIgAiIgAiIgAhIgNcaEAEREAEREAEREAEREAEREAEREIE4ICABPg4mSV0UAREQAREQAREQAREQAREQAREQAQnwWgMiIAIiIAIiIAIiIAIiIAIiIAIiEAcEJMDHwSSpiyIgAiIgAiIgAiIgAiIgAiIgAiIgAV5rQAREQAREQAREQAREQAREQAREQATigIAE+DiYJHVRBERABERABERABERABERABERABCTAaw2IgAiIgAiIgAiIgAiIgAiIgAiIQBwQkAAfB5OkLoqACIiACIiACIiACIiACIiACIiABHitAREQAREQAREQAREQAREQAREQARGIAwIS4ONgktRFERABERABERABERABERABERABEZAArzUgAiIgAiIgAiIgAiIgAiIgAiIgAnFAQAJ8HEySuigCIiACIiACIiACIiACIiACIiACEuC1BkRABERABERABERABERABERABEQgDghIgI+DSVIXRUAEREAEREAEREAEREAEREAEREACvNaACIiACIiACIiACIiACIiACIiACMQBAQnwcTBJ6qIIiIAIiIAIiIAIiIAIiIAIiIAISIDXGhABERABERABERABERABERABERCBOCAgAT4OJkldFAEREAEREAEREAEREAEREAEREAEJ8FoDIiACIiACIiACIiACIiACIiACIhAHBCTAx8EkqYsiIAIiIAIiIAIiIAIiIAIiIAIiIAFea0AEREAEREAEREAEREAEREAEREAE4oCABPg4mCR1UQREQAREQAREQAREQAREQAREQAQkwGsNiIAIiIAIiIAIiIAIiIAIiIAIiEAcEEjO/T4mFEpJKl48qWhRviQmJ5+RkJD7fVCLYRLIyspMT886mZZx7FjG0aN8CbOeUIolJSUXKlQoOSWZT0L2J5TSyisCeUYgK/uTzict/eTJkxkZ6bnQFd0vuQBZTYiACIhAHhLIkx+XPByvmhYBEfAgkFC+fKVcg5JYpEhy2TLJJYrnWotqKKoE0o8cTd9/IPP48Si1gsRetFgxpPco1a9qRSA3CSDDH0tNRZyPUqO6X6IEVtWKgAiIQCwTiPaPSyyPXX0TgYJJIPcE+JTy5VLKlYVyVkZG5omTWSdPZqZnnJGZkZWZVTDRx+OoExITzkhMSkxJSkgplFikcEKiywUjbd/+tL37Ij6cYsWKFy1W1LVgsrIyXErMjMzs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H54feyOQPAKa2U4rOHg8xRs2rM/NJWJPnjNHSRFAAAEEEEAAAQQQ2CmQgQMCCKSIwLZtW/WTIpWlmggggAACCCCAAAIIVD6BiM0MX/loqBECCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQIKN6jeoB3+QNBBBAAAEEEEAAAQQQQAABBBBIDAFa4BPjPFAKBBBAAAEEEEAAAQQQQAABBIIKZGzdsjVoAt5EAAEEEEAAAQQQQAABBBBAAIH4C9AC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RfFP9+7dunb9z0EHHVi3bt3c3LzVq1drwPDzz7/w008/2XfxucbqlGnsjxIYGb+ZWxutLwi/Z1Dz2w0YcKa+HRo1aqjyqMxffvnlCy9MXbBgQfBszbvlLViNGjUGDx7YrVvXvfbaq7jY89tvv02f/vYLL7yQn1/6te5zXH1tDR48yPr+WrNmrQbzv/TSVJUzlBIqjU7o5MmT9CER2tVXX+PIv8njj4/Wxi1bNg8adJbPBynIvvpqEF2XLie1bNlSD5U2btyo0zF9+vSZM98N8j1+xBGdevfWt/+h+vbXQVevXvPjjz9qGvn33//AXrDywup2vUePbv3799cJ1dfxqlUrZ8/+QAPQ/v7770BK5Sq/7jH0QVJWvXr1rl+/3siRI/7zn//stlt9fVMfccRRgQ5htgf6BJq/7q+//vqmm27x+8F4/vnnrdbE4IewvxvKR/rGG69v166d9rLuW8aMecz8TWnj5ZdfoRkfQz8iKQMJEMAHkonidsXwF110ib7niOGjqFyZst41elfN0luVblLUHU5dvevGnVYylj59v3TXm7tkVrS0OKPdzn46Ga70pml+nhSoIBHuvF/x2tSuXfu+++459thj7Fnstdfe+tHGc845Z8SIkc4bWcWr9957lxWgal/loxvrE0447oorrs7JyTZfQtWqVXGWrH//vjfddKP5QzbvanI4ffXqpYGRl19+pc/stbqrNrnpy6xlyxaTJk3Ul7TZUffNh+58de/+n/POG7F9+3azfd9991GfdvuhrS/FKlWynUUKskV35+bd9957z+89kEr72Wefd+58tJLpOYg9gA9nX79FEvKQIQPNWy+88JLuVPwmYyMCySugOSXMX2ugcEh/BSZBjRresNZ6Kdh78MH7dBmxtugioxmh9HPGGX2uvPKa//3vfz4saja//vprFYxZ2zVYplWrlvoZNGjQvffeP2nScz676BKkR4ebN286+uijnnji8exsP9eT3r1P0e24ot9rrvmvlpn0ycH5T8U2J5/cRds7dGj34Ycf2xPss88+7dt7b+v10qQbPgG84paTTjpRcaBWmfIbvV955RXnn3+ulaGutJrdunv3rrfccuvLL7/qUxIda/Toh8388OYtrZWtf+pHS2M8+OBD9ieGga6xkvHJ1vlPdSPyewaV8rzzhl122aU+3w6aOE2vCRMm3H33fc7cfLaU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" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## View the trace in LangSmith\n", - "\n", - "Now that we've ran our graph, let's head over to LangSmith and view our trace. First click into the project that you traced to (in our case the default project). You should see a run with the custom run name \"agent_007\".\n", - "\n", - "![image.png](attachment:d38d1f2b-0f4c-4707-b531-a3c749de987f.png)" - ] - }, - { - "attachments": { - "410e0089-2ab8-46bb-a61a-827187fd46b3.png": { - "image/png": "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Vy63y6ty5ao33XSrOrR06aIFC76zm61MmbI33zyCQ8eOHV67drXKQ+WkHz9+TAREu9A8SZw8eYKWDj/66OM333zLqjae0EOH3jRnzixkL5abn376Hw899LAbLY4ZM7pZs2YUnDfvex8JiAMGDLjvvnud9G3Xrt2TJ389efJkUUo5oeQPh66++mqkQ3rCm0n37t0XLFjgD72SPggBISAE/JmAP9og7tz5l0JWt25DR+zq1WugDxl/W+WvVy+nhp07dziqStK9RQCJrX37Dqq2sWPtSIfqEBq4Rx99TP2+7rrrypYt460O5HM9uGa//PKLkyZNRG+az00bm6tevcbChT/wveuuuwqwG/7c9Nat25KTk+kh/27b9oc/dzUg+iZTLiBOk3TSHwjExZWPiIhwqSeseVaqVNmlIj7K7I8axCNH/k5IuFSiRPE6deoS9J9dMm0HbxQKq1atHhUVzZKxbba6deupRC102uaRFG8R2LZt26FDf1evXu299z54//33nVSL7u2nnxb169eXPF27dmUl2knmAj/0zDPPrFjxi+5GdHR0hQrlMaa87bYRKEHxtnnhhef/9a9nC6qfUVERjRo1onV6VVB98PN2Dx06iDFDp07t16xZz28/763/d0+mnP+fI+mhPxBgOfSxx55OSIj/+OP3Tpw4YaZLPF9Gj34cAXH69K/Xr19jpojv8vijBpEFu927dzLmyMioKlWq2Q4+NDQE2ZH0PXt28S/2iHXq5AiCVpnr1q1PSlpa6t69e2zrkRSvE+jatVuNGrWcS4eq0RUrctxTGjZ0qCf2evfcq/DcufM42ejP3r17f/11DbaV118/SFmz4Zddo0ZN9yqXUvlD4MCB/VOnTuff/GlOWhECQkAInDhx7MyZMyVKxDz00D8qVKiYJxCkw1GjHkM6TElJ9oeblT8KiEDctStnldnu8nGNGrXDwsLJtmHDWqVftJutXLkKpUqVJhvSYUZGep7nJt8yIODyybfm/LOhM2fOqo6VKROoS8zoQceNG6dGMWSIxWpWPkJACNglEB4eFhrqjwtWdnsriULAKwRSU1PRHZ49e7Z48eKjRz+BTOKkWlZNH3roicqVq6SkpHz66YcnTx53kjl/DvnpFWsUEPFBsWKhLQtRNOJ9UqVKdbsCYr16FvUhH12bLVPWpq+6qluLFm0IgYGseerUyd9+27Bq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FNFRXJb0UHGDCWMXSYAESIAEbCagRQERgwoPf/X27Vus6CVNlpR6RJtnmRVYTwCXHy5CXIq4IHFZWl8RS5IACZAACZCA+xDQrn7u5YsXwJggQYIkH3zw5jWO8OjoGPcBy566PQF4pcDuUKwsQzoUF6Tbj4oDIAESIAESIAELCGhXQETn8UqOjooODArESzpBwoQRb9++0x2RMTFRMZQVLZhdZokrAeyVgmjYiHeIiDbwWYbiEDVgZZm6w7iSZH4SIAESIAG3JqBpARFk8WKOiHgbGBSElT7IiPjPrXGz8+5FAD7LkA1pd+hes8bekgAJkAAJ2E5A6wIiRojX84vnz+EoABnRz98PB/Q6QrVj+/hZAwkYEsA2ejhwySEaNiPa8NogARIgARLwWgJuICCKuUHwudevI+PpnJt5kAAJkAAJkAAJkAAJOJCARr2YHThiVk0CJEACJEACJEACJKBKgAKiKh6eJAESIAESIAESIAHvI0AB0fvmnCMmARIgARIgARIgAVUCFBBV8fAkCZAACZAACZAACXgfAQqI3jfnHDEJkAAJkAAJkAAJqBKggKiKhydJgARIgARIgARIwPsIUED0vjnniEmABEiABEiABEhAlQAFRFU8PEkCJEACJEACJEAC3keAAqL3zTlHTAIkQAIkQAIkQAKqBCggquLhSRIgARIgARIgARLwPgIUEL1vzjliEiABEiABEiABElAlQAFRFQ9PkgAJkAAJkAAJkID3EaCA6H1zzhGTAAmQAAmQAAmQgCoBCoiqeHiSBEiABEiABEiABLyPAAVE75tzjpgESIAESIAESIAEVAlQQFTFw5MkQAIkQAIkQAIk4H0EKCB635xzxCRAAiRAAiRAAiSgSoACoioeniQBEiABEiABEiAB7yNAAdH75pwjJgESIAESIAESIAFVAhQQVfHwJAmQAAmQAAmQAAl4HwEKiN435xwxCZAACZAACZAACagSoICoiocnSYAESIAESIAESMD7CFBA9L4554hJgARIgARIgARIQJUABURVPDxJAiRAAiRAAiRAAt5HgAKi9805R0wCJEACJEACJEACqgQoIKri4UkSIAESIAESIAES8D4CFBC9b845YhIgARIgARIgARJQJUABURUPT5IACZAACZAACZCA9xGggOh9c84RkwAJkAAJkAAJkIAqAQqIqnh4kgRIgARI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CZAACSgRKFy48Lp1a5TOMC1elizZjCggnp1Yql6/fpMkHd648X6h+dix440bN3EaOwqIVqI2Mk+0shanFIP/FCw/KlWq2KdPbzSIwI2bN29xSstshARIgARIgARIQI0AAuU8efIE/i7YnQX54LmMaHpqBZx1jgKis0i7qB24hP/663apcdjGYuvxOBlEuqjjbJYESIAESIAEPJwAdl5BbDv4NkjjnD595rVrf2ph2BQQtTALDuwDdgSSaoc/zaBBg/fu1UWZ4kECJEACJEACDiVw6tQp+UKqQ1t0u8qxrCxJh9DdTJs2Y8KECYajcCFACohudznFrcObN2++ffs2grbfuXMHuwDBMz9u5ZmbBEiABEiABEjAMQT+/POvjh07JUuWDJ7OR48etTGYnX37SC9m+/JkbSRAAiRAAiRAAiTgBgTUvZi1GCjbDaCyiyRAAiRAAiRAAiTguQQoIHru3HJkJEACJEACJEACJGAVAQqIVmFjIRIgARIgARIgARLwXAIUED13bjkyEiABEiABEiABErCKAAVEq7CxEAmQAAmQAAmQAAl4LgEKiJ47txwZCZAACZAACZAACVhFgAKiVdhYiARIgARIgARIgAQ8lwAFRM+dW46MBEiABEiABEiABKwiQAHRKmwsRAIkQAIkQAIkQAKeS4ACoufOLUdGAiRAAiRAAiRAAlYRoIBoFTYWIgESIAESIAESIAHPJUAB0XPnliMjARIgARIgARIgAasIUEC0ChsLkQAJkAAJkAAJkIDnEqCA6Llzy5GRAAmQAAmQAAmQgFUEKCBahY2FSIAESIAESIAESMBzCVBA9Ny55chIgARIgARIgARIwCoCFBCtwsZCJEACJEACJEACJOC5BCggeu7ccmQkQAIkQAIkQAIkYBUBCohWYWMhEiABEiABEiABEvBcAhQQPXduOTISIAESIAESIAESsIoABUSrsLEQCZAACZAACZAACXguAT93GZqvr19AQICfvx8OH/3hLj1nP0mABEiABEiABEhAhUCM/ojE8S4yIiIiKipSJbNzTrmBgAiJMDAoCNKhc4iwFRIgARIgARIgARJwJgGh+YKogyMoURBkxNfh4RAXndkHo7a0LiAGBSUKDApEpyFZR7x9+053RMbERMXEuBAamyYBEiABEiABEiABuxHAsqiPj6+/v5+/v39AggRCUnwdDinx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vNxYE1H8uF1jDyYYmZOaDx/cVzk526sWMc1WBERABOrU8QTwmdfGjRsXLFhIpptgj9qrxhgjTiByL00yGksjGnW4cGFkbsCdJ9cg72r8iEfO0pCJFZOpJ3IQaqUiIAIRRAA5OG/evD17solKrgZHJ5f7nYtEgQhENKLJiUjuj/vvfyBS1WG5P07qUAREQAREQASqDIF//vPFKjPXSp9ohApEOH9W9Kp04BpQBERABERABERABMKdQMnhWuE+U81PBERABERABERABESgUghIIFYKZg0iAiIgAiIgAiIgAlWHgARi1blXmqkIiIAIiIAIiIAIVAoBCcRKwaxBREAEREAEREAERKDqEJBArDr3SjMVAREQAREQAREQgUohIIFYKZg1iAiIgAiIgAiIgAhUHQISiFXnXmmmIiACIiACIiACIlApBCQQKwWzBhEBERABERABERCBqkMg7ATi+fPnoRcVVXUQaqYiIAIiIAIiIAIiUGEEjCgyAqnCBvHuOGwFYrT3TPW3CIiACIiACIiACEQegagojyiKdIFYWFgIhdjYyD0DMPKefK1YBERABERABETAJwEjioxA8lmpvC+EnQWx8IwRiLHlvVL1JwIiIAIiIAIiIAJVj0BsrEcUGYFUabMPO4FYUFDA4uPi42vWlB9ipT0GGkgEREAEREAERCAcCSCHEEXMzAikSpti2AnEs2cLQRAVFZWYmFRpFDSQCIiACIiACIiACIQhAeQQoghphECqzOmFnUBk8Xm5ufw3ITExLi6uMlloLBEQAREQAREQAREIHwIIIeQQ8zHSqDInFo4CETfMvNw8KNRKSYmOVrRKZT4PGksEREAEREAERCAsCCCBEEJMBVFUyREqDBqOApFp5eaeys/Px6Zap24d2RHD4jnVJERABERABERABCqLAOIHCYQQQg4hiipr2JJxwtc+dzInh2nGx8en1K59Oo9X7rlznhzaeomACIiACIiACIhAdSVAVAp+h2ZnGXVo5FDlLzZ8BSIsgHLu7LnEpEQwxSckFOTnn/G8Cs+fP1t03opeIiACIiACIiACIlDlCXBWCtmwyXdIRhtiljEcsiR2li+J7dDQDGuByBRBU1CQn5iUhK0Vjci7yj8FWoAIiIAIiIAIiIAI+CZAzDLasPL9Du0zCneByFwBXtW3OQAAIABJREFUlHPiBK6aaMSY2Bhe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iIAIiIAIiIAIhCEBI96MkHOdXpkEYkFBPp3GxcfXrCk/RFe8KhQBERABERABERCB8CKAbEO8MScj5FwnVyaBePbsWbqOiopKTExy7V2FIiACIiACIiACIiACYUUA2YZ4Q8Ih5HxNrEwCkU5zT+Xy34TExLi4OF9jqFwEREAEREAEREAERCAcCCDYkG3MxEg4X1MKQSBetJtcWFhoBqiVkhIdrWgVX5xVLgIiIAIiIAIiIAKXmABSDcHGJBBvSLiLZ3ORwItOSkoOdrJeiQ/PnCmIjvG84hPisVX6MVcGO5Dqi4AIiIAIiIAIiIAIlAsBbIe169Rmczk/P//UyRwSFVrdFkm7MgtExyyjCvJPF2tEAlaios6eLSxKoa2XCIiACIiACIiACIjAJSZAVAoGweRatYw6zDlx3EsOVpBA9Cw7/3R+VI2o2LjYmNjYhITE6OhoJlEkEyUVL/FjoeFFQAREQAREQAQijQCar2bNaKyGiYmJybVSTF4bdpZP5uQ45aBLSf36jYJH5no0i6cwJiY2KTkpvih2Wi8REAEREAEREAEREIFwIMC2cpHf4RmnFmR6zsKokAQiXfnUiFzDBTI+Pi42Li4mBjsie87KkhgOz4bmIAIiIAIiIAIiECkEEGqcpMdZKWfIZ5NfgPsfK3cKQV+F5Rx3zMDYEZlEbm5hjVxPBpyil3aZL5DQ/xcBERABERABERCByiDgbZ4Lyl4XskAs8jD0Fn5FMTA+yt1QeLd3q6MyERABERABERABERABXwS8haBrPVfbITV9lYcsED19+jANerQjlx3y0TnhgJbkbKYSERABERABERABERCBQAhcMBz6El3u5SEkyi6ZjG/nQmNKNLI0kMmrjgiIgAiIgAiIgAiIQHkSQBr6V4e+hVyNslgQPWswToduqykWpEUzK2UrOQBbo9sIKhMBERABERABERCBiCQQgEOhu2nQouW/h7IKRI9EdHE69LpXXlP01ov+pxiR912LFgEREAEREAEREIGgCJSiCO19FUkvf/XLLhA9AwTsdGjm5m9CQZFQZREQAREQAREQAREQgcAJ+N90tvopkw+ibTZFQlTCL/D7o5oiIAIiIAIiIAIiULkEAlSHTKpcLIhmcUYjBhi/XLk8NJoIiIAIiIAIiIAIRDCBwKWhgVSOAtF0KJkYwU+fli4CIiACIiACIhBmBIKVhmb65S4QTbclMtH8rTjlMHtaNB0REAEREAEREIFqS+Bir79QXAArSCAa4iUTMlEs1fY+aGEiIAIiIAIiIAIiEEYEQhGF9ulXqEC0D1TWiYYRc01FBERABERABERABKo1gfKKYq7WkLQ4ERABERABERABEYgkAhKIkXS3tVYREAEREAEREAERCICABGIAkFRFBERABERABERABCKJgARiJN1trVUEREAEREAEREAEAiAggRgAJFURAREQAREQAREQgUgi8P8DjezhV1S5aa0AAAAASUVORK5CYII=" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition, you will be able to filter traces after the fact using the tags or metadata provided. For example,\n", - "\n", - "![image.png](attachment:410e0089-2ab8-46bb-a61a-827187fd46b3.png)\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/docs/how-tos/run-id-langsmith.md b/docs/docs/how-tos/run-id-langsmith.md new file mode 100644 index 000000000..0cd87e864 --- /dev/null +++ b/docs/docs/how-tos/run-id-langsmith.md @@ -0,0 +1,155 @@ +# How to pass custom run ID or set tags and metadata for graph runs in LangSmith + +!!! tip "Prerequisites" + This guide assumes familiarity with the following: + + - [LangSmith Documentation](https://docs.smith.langchain.com) + - [LangSmith Platform](https://smith.langchain.com) + - [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig) + - [Add metadata and tags to traces](https://docs.smith.langchain.com/how_to_guides/tracing/trace_with_langchain#add-metadata-and-tags-to-traces) + - [Customize run name](https://docs.smith.langchain.com/how_to_guides/tracing/trace_with_langchain#customize-run-name) + +Debugging graph runs can sometimes be difficult to do in an IDE or terminal. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read the [LangSmith documentation](https://docs.smith.langchain.com) for more information on how to get started. + +To make it easier to identify and analyzed traces generated during graph invocation, you can set additional configuration at run time (see [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig)): + +| **Field** | **Type** | **Description** | +|-------------|---------------------|--------------------------------------------------------------------------------------------------------------------| +| run_name | `str` | Name for the tracer run for this call. Defaults to the name of the class. | +| run_id | `UUID` | Unique identifier for the tracer run for this call. If not provided, a new UUID will be generated. | +| tags | `List[str]` | Tags for this call and any sub-calls (e.g., a Chain calling an LLM). You can use these to filter calls. | +| metadata | `Dict[str, Any]` | Metadata for this call and any sub-calls (e.g., a Chain calling an LLM). Keys should be strings, values should be JSON-serializable. | + +LangGraph graphs implement the [LangChain Runnable Interface](https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.Runnable.html) and accept a second argument (`RunnableConfig`) in methods like `invoke`, `ainvoke`, `stream` etc. + +The LangSmith platform will allow you to search and filter traces based on `run_name`, `run_id`, `tags` and `metadata`. + +## TLDR + +```python +import uuid +# Generate a random UUID -- it must be a UUID +config = {"run_id": uuid.uuid4()}, "tags": ["my_tag1"], "metadata": {"a": 5}} +# Works with all standard Runnable methods +# like invoke, batch, ainvoke, astream_events etc +graph.stream(inputs, config, stream_mode="values") +``` + +The rest of the how to guide will show a full agent. + +## Setup + +First, let's install the required packages and set our API keys + +```python +%%capture --no-stderr +%pip install --quiet -U langgraph langchain_openai +``` + +```python +import getpass +import os + + +def _set_env(var: str): + if not os.environ.get(var): + os.environ[var] = getpass.getpass(f"{var}: ") + + +_set_env("OPENAI_API_KEY") +_set_env("LANGSMITH_API_KEY") +``` + +!!! tip + Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started [here](https://docs.smith.langchain.com). + +## Define the graph + +For this example we will use the [prebuilt ReAct agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/). + +```python +from langchain_openai import ChatOpenAI +from typing import Literal +from langgraph.prebuilt import create_react_agent +from langchain_core.tools import tool + +# First we initialize the model we want to use. +model = ChatOpenAI(model="gpt-4o", temperature=0) + + +# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF) +@tool +def get_weather(city: Literal["nyc", "sf"]): + """Use this to get weather information.""" + if city == "nyc": + return "It might be cloudy in nyc" + elif city == "sf": + return "It's always sunny in sf" + else: + raise AssertionError("Unknown city") + + +tools = [get_weather] + + +# Define the graph +graph = create_react_agent(model, tools=tools) +``` + +## Run your graph + +Now that we've defined our graph let's run it once and view the trace in LangSmith. In order for our trace to be easily accessible in LangSmith, we will pass in a custom `run_id` in the config. + +This assumes that you have set your `LANGSMITH_API_KEY` environment variable. + +Note that you can also configure what project to trace to by setting the `LANGCHAIN_PROJECT` environment variable, by default runs will be traced to the `default` project. + +```python +import uuid + + +def print_stream(stream): + for s in stream: + message = s["messages"][-1] + if isinstance(message, tuple): + print(message) + else: + message.pretty_print() + + +inputs = {"messages": [("user", "what is the weather in sf")]} + +config = {"run_name": "agent_007", "tags": ["cats are awesome"]} + +print_stream(graph.stream(inputs, config, stream_mode="values")) +``` + +**Output:** +``` +================================ Human Message ================================== + +what is the weather in sf +================================== Ai Message =================================== +Tool Calls: + get_weather (call_9ZudXyMAdlUjptq9oMGtQo8o) + Call ID: call_9ZudXyMAdlUjptq9oMGtQo8o + Args: + city: sf +================================= Tool Message ================================== +Name: get_weather + +It's always sunny in sf +================================== Ai Message =================================== + +The weather in San Francisco is currently sunny. +``` + +## View the trace in LangSmith + +Now that we've ran our graph, let's head over to LangSmith and view our trace. First click into the project that you traced to (in our case the default project). You should see a run with the custom run name "agent_007". + +![LangSmith Trace View](assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png) + +In addition, you will be able to filter traces after the fact using the tags or metadata provided. For example, + +![LangSmith Filter View](assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png) \ No newline at end of file diff --git a/docs/docs/how-tos/tool-calling.md b/docs/docs/how-tos/tool-calling.md index a2e711ba3..9968b0036 100644 --- a/docs/docs/how-tos/tool-calling.md +++ b/docs/docs/how-tos/tool-calling.md @@ -344,6 +344,8 @@ tool_node.invoke({"messages": [...]}) ## Tool customization +For more control over tool behavior, use the `@tool` decorator. + ### Parameter descriptions Auto-generate descriptions from docstrings: diff --git a/docs/docs/troubleshooting/studio.md b/docs/docs/troubleshooting/studio.md index b06f325de..3fcbdea7f 100644 --- a/docs/docs/troubleshooting/studio.md +++ b/docs/docs/troubleshooting/studio.md @@ -17,7 +17,7 @@ Safari blocks plain-HTTP traffic on localhost. When running Studio with `langgra ```shell # Requires @langchain/langgraph-cli>=0.0.26 - npx @langchain/langgraph-cli dev + npx @langchain/langgraph-cli dev --tunnel ``` The command outputs a URL in this format: @@ -55,7 +55,7 @@ Disable Brave Shields for LangSmith using the Brave icon in the URL bar. ```shell # Requires @langchain/langgraph-cli>=0.0.26 - npx @langchain/langgraph-cli dev + npx @langchain/langgraph-cli dev --tunnel ``` The command outputs a URL in this format: diff --git a/docs/docs/tutorials/get-started/1-build-basic-chatbot.md b/docs/docs/tutorials/get-started/1-build-basic-chatbot.md index 9235fa65f..3304822c6 100644 --- a/docs/docs/tutorials/get-started/1-build-basic-chatbot.md +++ b/docs/docs/tutorials/get-started/1-build-basic-chatbot.md @@ -112,7 +112,7 @@ This tells the graph to terminate after running the chatbot node. ## 6. Compile the graph Before running the graph, we'll need to compile it. We can do so by calling `compile()` -on the graph builder. This creates a `CompiledGraph` we can invoke on our state. +on the graph builder. This creates a `CompiledStateGraph` we can invoke on our state. ```python graph = graph_builder.compile() diff --git a/docs/docs/tutorials/get-started/2-add-tools.md b/docs/docs/tutorials/get-started/2-add-tools.md index 33accd9a8..4d30ae522 100644 --- a/docs/docs/tutorials/get-started/2-add-tools.md +++ b/docs/docs/tutorials/get-started/2-add-tools.md @@ -23,12 +23,16 @@ pip install -U langchain-tavily Configure your environment with your search engine API key: -```bash +```python +def _set_env(var: str): + if not os.environ.get(var): + os.environ[var] = getpass.getpass(f"{var}: ") + _set_env("TAVILY_API_KEY") ``` ``` -TAVILY_API_KEY: ········ +os.environ["TAVILY_API_KEY"]: "········" ``` ## 3. Define the tool diff --git a/docs/docs/tutorials/multi_agent/agent_supervisor.ipynb b/docs/docs/tutorials/multi_agent/agent_supervisor.ipynb deleted file mode 100644 index 2303872ef..000000000 --- a/docs/docs/tutorials/multi_agent/agent_supervisor.ipynb +++ /dev/null @@ -1,1403 +0,0 @@ -{ - "cells": [ - { - "attachments": { - "8ee0a8ce-f0a8-4019-b5bf-b20933e40956.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "id": "a3e3ebc4-57af-4fe4-bdd3-36aff67bf276", - "metadata": {}, - "source": [ - "# Multi-agent supervisor\n", - "\n", - "[**Supervisor**](../../../concepts/multi_agent#supervisor) is a multi-agent architecture where **specialized** agents are coordinated by a central **supervisor agent**. The supervisor agent controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements.\n", - "\n", - "In this tutorial, you will build a supervisor system with two agents — a research and a math expert. By the end of the tutorial you will:\n", - "\n", - "1. Build specialized research and math agents\n", - "2. Build a supervisor for orchestrating them with the prebuilt [`langgraph-supervisor`](https://langchain-ai.github.io/langgraph/agents/multi-agent/#supervisor)\n", - "3. Build a supervisor from scratch\n", - "4. Implement advanced task delegation\n", - "\n", - "![diagram](attachment:8ee0a8ce-f0a8-4019-b5bf-b20933e40956.png)\n", - "\n", - "## Setup\n", - "\n", - "First, let's install required packages and set our API keys" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "0d30b6f7-3bec-4d9f-af50-43dfdc81ae6c", - "metadata": {}, - "outputs": [], - "source": [ - "%%capture --no-stderr\n", - "%pip install -U langgraph langgraph-supervisor langchain-tavily \"langchain[openai]\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c84adef6-51b3-46c5-8490-c2a1ad967769", - "metadata": {}, - "outputs": [], - "source": [ - "import getpass\n", - "import os\n", - "\n", - "\n", - "def _set_if_undefined(var: str):\n", - " if not os.environ.get(var):\n", - " os.environ[var] = getpass.getpass(f\"Please provide your {var}\")\n", - "\n", - "\n", - "_set_if_undefined(\"OPENAI_API_KEY\")\n", - "_set_if_undefined(\"TAVILY_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "id": "be85e3ad", - "metadata": {}, - "source": [ - "
\n", - "

Set up LangSmith for LangGraph development

\n", - "

\n", - " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", - "

\n", - "
" - ] - }, - { - "cell_type": "markdown", - "id": "349a5673-962e-4de9-ac19-70ee426ef433", - "metadata": {}, - "source": [ - "## 1. Create worker agents" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "ad822cf5-56d4-47f7-ad64-d9fd3f57551e", - "metadata": {}, - "source": [ - "First, let's create our specialized worker agents — research agent and math agent:\n", - "\n", - "* Research agent will have access to a web search tool using [Tavily API](https://tavily.com/)\n", - "* Math agent will have access to simple math tools (`add`, `multiply`, `divide`)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "5e34989a-8989-432e-b6aa-8de91ab83372", - "metadata": {}, - "source": [ - "### Research agent\n", - "\n", - "For web search, we will use `TavilySearch` tool from `langchain-tavily`:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "0fdc7345-2967-484b-881a-114dfac3f534", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Find events, attractions, deals, and more at nyctourism.com Skip Main Navigation Menu The Official Website of the City of New York Text Size Powered by Translate SearchSearch Primary Navigation The official website of NYC Home NYC Resources NYC311 Office of the Mayor Events Connect Jobs Search Office of the Mayor | Mayor's Bio | City of New York Secondary Navigation MayorBiographyNewsOfficials Eric L. Adams 110th Mayor of New York City Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. He gave voice to a diverse coalition of working families in all five boroughs and is leading the fight to bring back New York City’s economy, reduce inequality, improve public safety, and build a stronger, healthier city that delivers for all New Yorkers. As the representative of one of the nation’s largest counties, Eric fought tirelessly to grow the local economy, invest in schools, reduce inequality, improve public safety, and advocate for smart policies and better government that delivers for all New Yorkers.\n" - ] - } - ], - "source": [ - "from langchain_tavily import TavilySearch\n", - "\n", - "web_search = TavilySearch(max_results=3)\n", - "web_search_results = web_search.invoke(\"who is the mayor of NYC?\")\n", - "\n", - "print(web_search_results[\"results\"][0][\"content\"])" - ] - }, - { - "cell_type": "markdown", - "id": "cc899eb6-b08e-41b8-b92b-75908c44e8b0", - "metadata": {}, - "source": [ - "To create individual worker agents, we will use LangGraph's prebuilt [agent](../../../agents/agents#basic-configuration)." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "15e179e4-1a49-4c76-9235-0ca989eb0d2d", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.prebuilt import create_react_agent\n", - "\n", - "research_agent = create_react_agent(\n", - " model=\"openai:gpt-4.1\",\n", - " tools=[web_search],\n", - " prompt=(\n", - " \"You are a research agent.\\n\\n\"\n", - " \"INSTRUCTIONS:\\n\"\n", - " \"- Assist ONLY with research-related tasks, DO NOT do any math\\n\"\n", - " \"- After you're done with your tasks, respond to the supervisor directly\\n\"\n", - " \"- Respond ONLY with the results of your work, do NOT include ANY other text.\"\n", - " ),\n", - " name=\"research_agent\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "023ae2f2-517b-4611-a0ca-506b8c0b734e", - "metadata": {}, - "source": [ - "Let's [run the agent](../../../agents/run_agents) to verify that it behaves as expected. \n", - "\n", - "\n", - "??? note \"We'll use `pretty_print_messages` helper to render the streamed agent outputs nicely\"\n", - "\n", - " ```python\n", - " from langchain_core.messages import convert_to_messages\n", - " \n", - " \n", - " def pretty_print_message(message, indent=False):\n", - " pretty_message = message.pretty_repr(html=True)\n", - " if not indent:\n", - " print(pretty_message)\n", - " return\n", - " \n", - " indented = \"\\n\".join(\"\\t\" + c for c in pretty_message.split(\"\\n\"))\n", - " print(indented)\n", - " \n", - " \n", - " def pretty_print_messages(update, last_message=False):\n", - " is_subgraph = False\n", - " if isinstance(update, tuple):\n", - " ns, update = update\n", - " # skip parent graph updates in the printouts\n", - " if len(ns) == 0:\n", - " return\n", - " \n", - " graph_id = ns[-1].split(\":\")[0]\n", - " print(f\"Update from subgraph {graph_id}:\")\n", - " print(\"\\n\")\n", - " is_subgraph = True\n", - " \n", - " for node_name, node_update in update.items():\n", - " update_label = f\"Update from node {node_name}:\"\n", - " if is_subgraph:\n", - " update_label = \"\\t\" + update_label\n", - " \n", - " print(update_label)\n", - " print(\"\\n\")\n", - " \n", - " messages = convert_to_messages(node_update[\"messages\"])\n", - " if last_message:\n", - " messages = messages[-1:]\n", - " \n", - " for m in messages:\n", - " pretty_print_message(m, indent=is_subgraph)\n", - " print(\"\\n\")\n", - " ```" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "bfaa81e6", - "metadata": {}, - "outputs": [], - "source": [ - "# hide-cell\n", - "from langchain_core.messages import convert_to_messages\n", - "\n", - "\n", - "def pretty_print_message(message, indent=False):\n", - " pretty_message = message.pretty_repr(html=True)\n", - " if not indent:\n", - " print(pretty_message)\n", - " return\n", - "\n", - " indented = \"\\n\".join(\"\\t\" + c for c in pretty_message.split(\"\\n\"))\n", - " print(indented)\n", - "\n", - "\n", - "def pretty_print_messages(update, last_message=False):\n", - " is_subgraph = False\n", - " if isinstance(update, tuple):\n", - " ns, update = update\n", - " # skip parent graph updates in the printouts\n", - " if len(ns) == 0:\n", - " return\n", - "\n", - " graph_id = ns[-1].split(\":\")[0]\n", - " print(f\"Update from subgraph {graph_id}:\")\n", - " print(\"\\n\")\n", - " is_subgraph = True\n", - "\n", - " for node_name, node_update in update.items():\n", - " update_label = f\"Update from node {node_name}:\"\n", - " if is_subgraph:\n", - " update_label = \"\\t\" + update_label\n", - "\n", - " print(update_label)\n", - " print(\"\\n\")\n", - "\n", - " messages = convert_to_messages(node_update[\"messages\"])\n", - " if last_message:\n", - " messages = messages[-1:]\n", - "\n", - " for m in messages:\n", - " pretty_print_message(m, indent=is_subgraph)\n", - " print(\"\\n\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "71474c5b-6a9b-460e-bf30-77831976aaf9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from node agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "Tool Calls:\n", - " tavily_search (call_U748rQhQXT36sjhbkYLSXQtJ)\n", - " Call ID: call_U748rQhQXT36sjhbkYLSXQtJ\n", - " Args:\n", - " query: current mayor of New York City\n", - " search_depth: basic\n", - "\n", - "\n", - "Update from node tools:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search\n", - "\n", - "{\"query\": \"current mayor of New York City\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"title\": \"List of mayors of New York City - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/List_of_mayors_of_New_York_City\", \"content\": \"The mayor of New York City is the chief executive of the Government of New York City, as stipulated by New York City's charter.The current officeholder, the 110th in the sequence of regular mayors, is Eric Adams, a member of the Democratic Party.. During the Dutch colonial period from 1624 to 1664, New Amsterdam was governed by the Director of New Netherland.\", \"score\": 0.9039154, \"raw_content\": null}, {\"title\": \"Office of the Mayor | Mayor's Bio | City of New York - NYC.gov\", \"url\": \"https://www.nyc.gov/office-of-the-mayor/bio.page\", \"content\": \"Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. He gave voice to a diverse coalition of working families in all five boroughs and is leading the fight to bring back New York City's economy, reduce inequality, improve\", \"score\": 0.8405867, \"raw_content\": null}, {\"title\": \"Eric Adams - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Eric_Adams\", \"content\": \"Eric Leroy Adams (born September 1, 1960) is an American politician and former police officer who has served as the 110th mayor of New York City since 2022. Adams was an officer in the New York City Transit Police and then the New York City Police Department (NYPD) for more than 20 years, retiring at the rank of captain.He served in the New York State Senate from 2006 to 2013, representing the\", \"score\": 0.77731717, \"raw_content\": null}], \"response_time\": 1.81}\n", - "\n", - "\n", - "Update from node agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "\n", - "The current mayor of New York City is Eric Adams.\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in research_agent.stream(\n", - " {\"messages\": [{\"role\": \"user\", \"content\": \"who is the mayor of NYC?\"}]}\n", - "):\n", - " pretty_print_messages(chunk)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "95e76c28-e9c9-42b7-8381-5e2a07f900cb", - "metadata": {}, - "source": [ - "### Math agent\n", - "\n", - "For math agent tools we will use [vanilla Python functions](../../../agents/tools#define-simple-tools):" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "95910bb8-7144-4015-9ea4-d97d0c22db12", - "metadata": {}, - "outputs": [], - "source": [ - "def add(a: float, b: float):\n", - " \"\"\"Add two numbers.\"\"\"\n", - " return a + b\n", - "\n", - "\n", - "def multiply(a: float, b: float):\n", - " \"\"\"Multiply two numbers.\"\"\"\n", - " return a * b\n", - "\n", - "\n", - "def divide(a: float, b: float):\n", - " \"\"\"Divide two numbers.\"\"\"\n", - " return a / b\n", - "\n", - "\n", - "math_agent = create_react_agent(\n", - " model=\"openai:gpt-4.1\",\n", - " tools=[add, multiply, divide],\n", - " prompt=(\n", - " \"You are a math agent.\\n\\n\"\n", - " \"INSTRUCTIONS:\\n\"\n", - " \"- Assist ONLY with math-related tasks\\n\"\n", - " \"- After you're done with your tasks, respond to the supervisor directly\\n\"\n", - " \"- Respond ONLY with the results of your work, do NOT include ANY other text.\"\n", - " ),\n", - " name=\"math_agent\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "0df97bc0-f38b-4893-a135-c16cecbfa759", - "metadata": {}, - "source": [ - "Let's run the math agent:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "f803943c-6dd2-4b42-93ba-0210ec276132", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from node agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "Tool Calls:\n", - " add (call_p6OVLDHB4LyCNCxPOZzWR15v)\n", - " Call ID: call_p6OVLDHB4LyCNCxPOZzWR15v\n", - " Args:\n", - " a: 3\n", - " b: 5\n", - "\n", - "\n", - "Update from node tools:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: add\n", - "\n", - "8.0\n", - "\n", - "\n", - "Update from node agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "Tool Calls:\n", - " multiply (call_EoaWHMLFZAX4AkajQCtZvbli)\n", - " Call ID: call_EoaWHMLFZAX4AkajQCtZvbli\n", - " Args:\n", - " a: 8\n", - " b: 7\n", - "\n", - "\n", - "Update from node tools:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: multiply\n", - "\n", - "56.0\n", - "\n", - "\n", - "Update from node agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "\n", - "56\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in math_agent.stream(\n", - " {\"messages\": [{\"role\": \"user\", \"content\": \"what's (3 + 5) x 7\"}]}\n", - "):\n", - " pretty_print_messages(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "dceefc4c-95e1-4565-8946-4c113a11416a", - "metadata": {}, - "source": [ - "## 2. Create supervisor with `langgraph-supervisor`" - ] - }, - { - "cell_type": "markdown", - "id": "eb5637a4-8ecb-4c2c-82f5-3674205e37b5", - "metadata": {}, - "source": [ - "To implement out multi-agent system, we will use [`create_supervisor`][langgraph_supervisor.supervisor.create_supervisor] from the prebuilt `langgraph-supervisor` library:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "6f32a820-1f3d-4698-831b-46252e2316bc", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph_supervisor import create_supervisor\n", - "from langchain.chat_models import init_chat_model\n", - "\n", - "supervisor = create_supervisor(\n", - " model=init_chat_model(\"openai:gpt-4.1\"),\n", - " agents=[research_agent, math_agent],\n", - " prompt=(\n", - " \"You are a supervisor managing two agents:\\n\"\n", - " \"- a research agent. Assign research-related tasks to this agent\\n\"\n", - " \"- a math agent. Assign math-related tasks to this agent\\n\"\n", - " \"Assign work to one agent at a time, do not call agents in parallel.\\n\"\n", - " \"Do not do any work yourself.\"\n", - " ),\n", - " add_handoff_back_messages=True,\n", - " output_mode=\"full_history\",\n", - ").compile()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "4c45a3c2-4d9e-4760-87bc-3cc2c007a167", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.display import display, Image\n", - "\n", - "display(Image(supervisor.get_graph().draw_mermaid_png()))" - ] - }, - { - "cell_type": "markdown", - "id": "3a94c3d1-3617-4d68-ac9a-b9bb2c05a604", - "metadata": {}, - "source": [ - "Let's now run it with a query that requires both agents:\n", - "\n", - "* research agent will look up the necessary GDP information\n", - "* math agent will perform division to find the percentage of NY state GDP, as requested" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "89b77171-58d0-4b36-8cb3-b69d69e4bdf9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from node supervisor:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_research_agent\n", - "\n", - "Successfully transferred to research_agent\n", - "\n", - "\n", - "Update from node research_agent:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_back_to_supervisor\n", - "\n", - "Successfully transferred back to supervisor\n", - "\n", - "\n", - "Update from node supervisor:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_math_agent\n", - "\n", - "Successfully transferred to math_agent\n", - "\n", - "\n", - "Update from node math_agent:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_back_to_supervisor\n", - "\n", - "Successfully transferred back to supervisor\n", - "\n", - "\n", - "Update from node supervisor:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: supervisor\n", - "\n", - "In 2024, the US GDP was $29.18 trillion and New York State's GDP was $2.297 trillion. New York State accounted for approximately 7.87% of the total US GDP in 2024.\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in supervisor.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"find US and New York state GDP in 2024. what % of US GDP was New York state?\",\n", - " }\n", - " ]\n", - " },\n", - "):\n", - " pretty_print_messages(chunk, last_message=True)\n", - "\n", - "final_message_history = chunk[\"supervisor\"][\"messages\"]" - ] - }, - { - "cell_type": "markdown", - "id": "599b8d13-70a9-40f3-99b9-5e3d35cc6f56", - "metadata": {}, - "source": [ - "## 3. Create supervisor from scratch" - ] - }, - { - "cell_type": "markdown", - "id": "e23764f8-f818-45f3-a5ee-4cb7b7002336", - "metadata": {}, - "source": [ - "Let's now implement this same multi-agent system from scratch. We will need to:\n", - "\n", - "1. Set up how the supervisor [communicates](#set-up-agent-communication) with individual agents\n", - "2. Create the [supervisor agent](#create-supervisor-agent)\n", - "3. [Combine]() supervisor and worker agents into a single multi-agent graph." - ] - }, - { - "cell_type": "markdown", - "id": "78d32089-0259-4aa3-a473-077ecce342dd", - "metadata": {}, - "source": [ - "### Set up agent communication" - ] - }, - { - "cell_type": "markdown", - "id": "a6c6b436-e95b-476b-b427-7b02d8384cc5", - "metadata": {}, - "source": [ - "We will need to define a way for the supervisor agent to communicate with the worker agents. A common way to implement this in multi-agent architectures is using **handoffs**, where one agent *hands off* control to another. Handoffs allow you to specify:\n", - "\n", - "- **destination**: target agent to transfer to\n", - "- **payload**: information to pass to that agent\n", - "\n", - "We will implement handoffs via **handoff tools** and give these tools to the supervisor agent: when the supervisor calls these tools, it will hand off control to a worker agent, passing the full message history to that agent." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7873a6c3-7de0-46d1-96ce-2dca7c62245a", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import Annotated\n", - "from langchain_core.tools import tool, InjectedToolCallId\n", - "from langgraph.prebuilt import InjectedState\n", - "from langgraph.graph import StateGraph, START, MessagesState\n", - "from langgraph.types import Command\n", - "\n", - "\n", - "def create_handoff_tool(*, agent_name: str, description: str | None = None):\n", - " name = f\"transfer_to_{agent_name}\"\n", - " description = description or f\"Ask {agent_name} for help.\"\n", - "\n", - " @tool(name, description=description)\n", - " def handoff_tool(\n", - " state: Annotated[MessagesState, InjectedState],\n", - " tool_call_id: Annotated[str, InjectedToolCallId],\n", - " ) -> Command:\n", - " tool_message = {\n", - " \"role\": \"tool\",\n", - " \"content\": f\"Successfully transferred to {agent_name}\",\n", - " \"name\": name,\n", - " \"tool_call_id\": tool_call_id,\n", - " }\n", - " # highlight-next-line\n", - " return Command(\n", - " # highlight-next-line\n", - " goto=agent_name, # (1)!\n", - " # highlight-next-line\n", - " update={**state, \"messages\": state[\"messages\"] + [tool_message]}, # (2)!\n", - " # highlight-next-line\n", - " graph=Command.PARENT, # (3)!\n", - " )\n", - "\n", - " return handoff_tool\n", - "\n", - "\n", - "# Handoffs\n", - "assign_to_research_agent = create_handoff_tool(\n", - " agent_name=\"research_agent\",\n", - " description=\"Assign task to a researcher agent.\",\n", - ")\n", - "\n", - "assign_to_math_agent = create_handoff_tool(\n", - " agent_name=\"math_agent\",\n", - " description=\"Assign task to a math agent.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "3bc810a4-1866-4915-abd9-12655954e673", - "metadata": {}, - "source": [ - "1. Name of the agent or node to hand off to.\n", - "2. Take the agent's messages and add them to the parent's state as part of the handoff. The next agent will see the parent state.\n", - "3. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph." - ] - }, - { - "cell_type": "markdown", - "id": "6a7bd301-c954-4189-87e2-b3bf42d187c1", - "metadata": {}, - "source": [ - "### Create supervisor agent" - ] - }, - { - "cell_type": "markdown", - "id": "ca787ce6-46f9-49c3-8f9f-ddb7ff52cdeb", - "metadata": {}, - "source": [ - "Then, let's create the supervisor agent with the handoff tools we just defined. We will use the prebuilt [`create_react_agent`][langgraph.prebuilt.chat_agent_executor.create_react_agent]:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "de5d1ff8-e7a0-4efe-93fe-d304eaef29b6", - "metadata": {}, - "outputs": [], - "source": [ - "supervisor_agent = create_react_agent(\n", - " model=\"openai:gpt-4.1\",\n", - " tools=[assign_to_research_agent, assign_to_math_agent],\n", - " prompt=(\n", - " \"You are a supervisor managing two agents:\\n\"\n", - " \"- a research agent. Assign research-related tasks to this agent\\n\"\n", - " \"- a math agent. Assign math-related tasks to this agent\\n\"\n", - " \"Assign work to one agent at a time, do not call agents in parallel.\\n\"\n", - " \"Do not do any work yourself.\"\n", - " ),\n", - " name=\"supervisor\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "dd4bc4e2-e133-42fd-a47f-6fb63fa51697", - "metadata": {}, - "source": [ - "### Create multi-agent graph" - ] - }, - { - "cell_type": "markdown", - "id": "8e6dcae1-eb91-4a07-aef8-53cbed14a002", - "metadata": {}, - "source": [ - "Putting this all together, let's create a graph for our overall multi-agent system. We will add the supervisor and the individual agents as [subgraph](../../../concepts/low_level#subgraphs) nodes." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "584443af-587a-44f3-a320-f942868191e4", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.graph import END\n", - "\n", - "# Define the multi-agent supervisor graph\n", - "supervisor = (\n", - " StateGraph(MessagesState)\n", - " # NOTE: `destinations` is only needed for visualization and doesn't affect runtime behavior\n", - " .add_node(supervisor_agent, destinations=(\"research_agent\", \"math_agent\", END))\n", - " .add_node(research_agent)\n", - " .add_node(math_agent)\n", - " .add_edge(START, \"supervisor\")\n", - " # always return back to the supervisor\n", - " .add_edge(\"research_agent\", \"supervisor\")\n", - " .add_edge(\"math_agent\", \"supervisor\")\n", - " .compile()\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "12576211-a946-46ec-bf81-24215597a1fe", - "metadata": {}, - "source": [ - "Notice that we've added explicit [edges](../../../concepts/low_level#edges) from worker agents back to the supervisor — this means that they are guaranteed to return control back to the supervisor. If you want the agents to respond directly to the user (i.e., turn the system into a router, you can remove these edges)." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "0175fe14-5854-4197-b7e8-559335d0f81b", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.display import display, Image\n", - "\n", - "display(Image(supervisor.get_graph().draw_mermaid_png()))" - ] - }, - { - "cell_type": "markdown", - "id": "d36496de-7121-4c49-8cb6-58c943c66628", - "metadata": {}, - "source": [ - "With the multi-agent graph created, let's now run it!" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "56ba78e9-d9c1-457c-a073-d606d5d3e013", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from node supervisor:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_research_agent\n", - "\n", - "Successfully transferred to research_agent\n", - "\n", - "\n", - "Update from node research_agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "\n", - "- US GDP in 2024 is projected to be about $28.18 trillion USD (Statista; CBO projection).\n", - "- New York State's nominal GDP for 2024 is estimated at approximately $2.16 trillion USD (various economic reports).\n", - "- New York State's share of US GDP in 2024 is roughly 7.7%.\n", - "\n", - "Sources:\n", - "- https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/\n", - "- https://nyassembly.gov/Reports/WAM/2025economic_revenue/2025_report.pdf?v=1740533306\n", - "\n", - "\n", - "Update from node supervisor:\n", - "\n", - "\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_math_agent\n", - "\n", - "Successfully transferred to math_agent\n", - "\n", - "\n", - "Update from node math_agent:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "\n", - "US GDP in 2024: $28.18 trillion\n", - "New York State GDP in 2024: $2.16 trillion\n", - "Percentage of US GDP from New York State: 7.67%\n", - "\n", - "\n", - "Update from node supervisor:\n", - "\n", - "\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: supervisor\n", - "\n", - "Here are your results:\n", - "\n", - "- 2024 US GDP (projected): $28.18 trillion USD\n", - "- 2024 New York State GDP (estimated): $2.16 trillion USD\n", - "- New York State's share of US GDP: approximately 7.7%\n", - "\n", - "If you need the calculation steps or sources, let me know!\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in supervisor.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"find US and New York state GDP in 2024. what % of US GDP was New York state?\",\n", - " }\n", - " ]\n", - " },\n", - "):\n", - " pretty_print_messages(chunk, last_message=True)\n", - "\n", - "final_message_history = chunk[\"supervisor\"][\"messages\"]" - ] - }, - { - "cell_type": "markdown", - "id": "dac583a8-af2c-402f-801e-15a6bc318e44", - "metadata": {}, - "source": [ - "Let's examine the full resulting message history:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "1eff504c-7437-477e-ab28-936c1238eaca", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================\u001b[1m Human Message \u001b[0m=================================\n", - "\n", - "find US and New York state GDP in 2024. what % of US GDP was New York state?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: supervisor\n", - "Tool Calls:\n", - " transfer_to_research_agent (call_KlGgvF5ahlAbjX8d2kHFjsC3)\n", - " Call ID: call_KlGgvF5ahlAbjX8d2kHFjsC3\n", - " Args:\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_research_agent\n", - "\n", - "Successfully transferred to research_agent\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "Tool Calls:\n", - " tavily_search (call_ZOaTVUA6DKrOjWQldLhtrsO2)\n", - " Call ID: call_ZOaTVUA6DKrOjWQldLhtrsO2\n", - " Args:\n", - " query: US GDP 2024 estimate or actual\n", - " search_depth: advanced\n", - " tavily_search (call_QsRAasxW9K03lTlqjuhNLFbZ)\n", - " Call ID: call_QsRAasxW9K03lTlqjuhNLFbZ\n", - " Args:\n", - " query: New York state GDP 2024 estimate or actual\n", - " search_depth: advanced\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search\n", - "\n", - "{\"query\": \"US GDP 2024 estimate or actual\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://www.advisorperspectives.com/dshort/updates/2025/05/29/gdp-gross-domestic-product-q1-2025-second-estimate\", \"title\": \"Q1 GDP Second Estimate: Real GDP at -0.2%, Higher Than Expected\", \"content\": \"> Real gross domestic product (GDP) decreased at an annual rate of 0.2 percent in the first quarter of 2025 (January, February, and March), according to the second estimate released by the U.S. Bureau of Economic Analysis. In the fourth quarter of 2024, real GDP increased 2.4 percent. The decrease in real GDP in the first quarter primarily reflected an increase in imports, which are a subtraction in the calculation of GDP, and a decrease in government spending. These movements were partly [...] by [Harry Mamaysky](https://www.advisorperspectives.com/search?author=Harry%20Mamaysky) of [QuantStreet Capital](https://www.advisorperspectives.com/firm/quantstreet-capital), 10/14/2024\\n\\n#### [The Worst of Allan Roth](https://www.advisorperspectives.com/articles/2024/10/21/worst-of-allan-roth/)\\n\\n by [Allan Roth](https://www.advisorperspectives.com/search?author=Allan%20Roth), 10/21/2024 [...] by [Juan Pablo Spinetto](https://www.advisorperspectives.com/search?author=Juan%20Pablo%20Spinetto) of [Bloomberg News](https://www.advisorperspectives.com/firm/bloomberg-news), 04/05/2025\\n\\n#### [Your Clients Are Clueless About Their Risk Tolerance](https://www.advisorperspectives.com/articles/2024/10/23/clients-clueless-about-risk-tolerance/)\\n\\n by [Dan Solin](https://www.advisorperspectives.com/search?author=Dan%20Solin), 10/23/2024\", \"score\": 0.78650844, \"raw_content\": null}, {\"url\": \"https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/\", \"title\": \"GDP forecast U.S. 2034 - Statista\", \"content\": \"[](https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/#statisticContainer) This graph shows a forecast of the gross domestic product of the United States of America for fiscal years 2024 to 2034. GDP refers to the market value of all final goods and services produced within a country in a given period. According to the CBO, the United States GDP will increase steadily over the next decade from 28.18 trillion U.S. dollars in 2023 to 41.65 trillion U.S. dollars in [...] US Congressional Budget Office. (February 7, 2024). Forecast of the gross domestic product of the United States from fiscal year 2024 to fiscal year 2034 (in billion U.S. dollars) [Graph]. In Statista. Retrieved May 20, 2025, from https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/ [...] US Congressional Budget Office. (2024). Forecast of the gross domestic product of the United States from fiscal year 2024 to fiscal year 2034 (in billion U.S. dollars). Statista. Statista Inc.. Accessed: May 20, 2025. https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/\", \"score\": 0.7576693, \"raw_content\": null}, {\"url\": \"https://www.bea.gov/data/gdp/gross-domestic-product\", \"title\": \"Gross Domestic Product | U.S. Bureau of Economic Analysis (BEA)\", \"content\": \"Real gross domestic product (GDP) decreased at an annual rate of 0.2 percent in the first quarter of 2025 (January, February, and March), according to the second estimate released by the U.S. Bureau of Economic Analysis. In the fourth quarter of 2024, real GDP increased 2.4 percent. The decrease in real GDP in the first quarter primarily reflected an increase in imports, which are a subtraction in the calculation of GDP, and a decrease in government spending. These movements were partly offset\", \"score\": 0.75723875, \"raw_content\": null}], \"response_time\": 2.48}\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search\n", - "\n", - "{\"query\": \"New York state GDP 2024 estimate or actual\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/\", \"title\": \"Annual State of the City's Economy and Finances 2024\", \"content\": \"[[1]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref1) At that time, the Comptroller’s Office expected five-year cumulative real GDP growth, 2020 to 2024, of 8.7 percent while the mayor expected 9.5 percent.\\n\\n[[2]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref2) U.S. Bureau of Labor Statistics Local Area Unemployment Statistics (LAUS). [...] [[19]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref19) FY 2024 actuals include $742 million in transfers to the capital fund through Interfund Agreements, as detailed in Schedule G6 of the FY 2024 Annual Comprehensive Financial Report. [...] (constant 2019 dollars)**22,550 15,322 13,596 19,451 21,211 21,096\\n**_% change_**(32.1%)(11.3%)43.1%9.0%(0.5%)\\n\\nSource: NY State Department of Taxation and Finance and Office of the New York City Comptroller\", \"score\": 0.82795376, \"raw_content\": null}], \"response_time\": 2.76}\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "Tool Calls:\n", - " tavily_search (call_DxuGWv9Ii19fPys582KcSLOg)\n", - " Call ID: call_DxuGWv9Ii19fPys582KcSLOg\n", - " Args:\n", - " query: New York state GDP 2024 (in dollars, not percentage growth or projections)\n", - " search_depth: advanced\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search\n", - "\n", - "{\"query\": \"New York state GDP 2024 (in dollars, not percentage growth or projections)\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/\", \"title\": \"Annual State of the City's Economy and Finances 2024\", \"content\": \"(constant 2019 dollars)**22,550 15,322 13,596 19,451 21,211 21,096\\n**_% change_**(32.1%)(11.3%)43.1%9.0%(0.5%)\\n\\nSource: NY State Department of Taxation and Finance and Office of the New York City Comptroller [...] | Retail Trade | 301,565 | $56,208 | 14.4 | (0.6) | (5.2) | 2.7 | 2.9 | 2.2 | 2.1 |\\n| Leisure & Hospitality | 431,227 | $56,086 | 96.2 | 32.4 | 15.4 | 8.9 | 3.8 | 4.5 | 7.3 |\\n| **Total: Low Wage Sectors** | **1,997,491** | **$62,185** | **184.6** | **102.2** | **91.6** | **62.7** | **32.0** | **26.8** | **29.3** |\\n| **Total NYC Employment** | **4,485,695** | **$114,294** | **307.7** | **119.9** | **78.1** | **88.0** | **65.1** | **53.2** | **51.4** | [...] [[1]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref1) At that time, the Comptroller’s Office expected five-year cumulative real GDP growth, 2020 to 2024, of 8.7 percent while the mayor expected 9.5 percent.\\n\\n[[2]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref2) U.S. Bureau of Labor Statistics Local Area Unemployment Statistics (LAUS).\", \"score\": 0.8098936, \"raw_content\": null}, {\"url\": \"https://nyassembly.gov/Reports/WAM/2025economic_revenue/2025_report.pdf?v=1740533306\", \"title\": \"[PDF] New York State Economic and Revenue Report\", \"content\": \"Sources: Federal Reserve; NYS Assembly Ways and Means Committee staff. NYS ASSEMBLY| U.S. ECONOMIC FORECAST AT A GLANCE| 15 Actual Actual Actual Forecast Forecast 2022 2023 2024 2025 2026 Real GDP 2.5 2.9 2.8 2.4 2.1 Consumption 3.0 2.5 2.8 2.7 2.1 Investment 6.0 0.1 4.0 3.1 3.8 Exports 7.5 2.8 3.2 2.4 1.1 Imports 8.6 (1.2) 5.4 3.5 1.3 Government (1.1) 3.9 3.4 1.5 0.1 Federal (3.2) 2.9 2.5 1.7 0.2 State and Local 0.2 4.4 3.9 1.4 0.1 Personal Income 3.1 5.9 5.5 5.0 4.9 Wages & Salaries 7.8 5.4 [...] in 2024 on an annualized basis. National output, measured with inflation-adjusted Gross Domestic Product (or real GDP), continues to grow at solid rates, surpassing its pre-pandemic peak by 12.1 percent, as of the fourth quarter of 2024 (see Figure 2). However, the pace of average quarterly growth has decelerated from 3.2 percent in 2023 to 2.5 percent in 2024 on an annualized basis. 121.7 114.5 115.3 112.1 109.2 106.3 70 75 80 85 90 95 100 105 110 115 120 125 130 2019Q4 2020Q2 2020Q4 2021Q2 [...] three-month moving average of 2.5 million in December 2023 to 872,000 in December 2024. The ratio of job openings to unemployed persons, another key metric for assessing the balance between labor demand and supply, has also steadily declined in recent months. By December 2024, this ratio had dropped to 1.10, down from its peak of 2.03 in March 2022. 24 | U.S. ECONOMIC FORECAST ANALYSIS | NYS ASSEMBLY With diminishing supply shortages in the labor market, growth of labor and other incomes will\", \"score\": 0.8051581, \"raw_content\": null}], \"response_time\": 2.86}\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "Tool Calls:\n", - " tavily_search (call_wjYTJR9EnmCqzKrkrONpxYO0)\n", - " Call ID: call_wjYTJR9EnmCqzKrkrONpxYO0\n", - " Args:\n", - " query: New York State GDP (nominal) in US dollars for 2024 (actual or forecast)\n", - " search_depth: advanced\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: tavily_search\n", - "\n", - "{\"query\": \"New York State GDP (nominal) in US dollars for 2024 (actual or forecast)\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://nyassembly.gov/Reports/WAM/2025economic_revenue/2025_report.pdf?v=1740533306\", \"title\": \"[PDF] New York State Economic and Revenue Report\", \"content\": \"Sources: Federal Reserve; NYS Assembly Ways and Means Committee staff. NYS ASSEMBLY| U.S. ECONOMIC FORECAST AT A GLANCE| 15 Actual Actual Actual Forecast Forecast 2022 2023 2024 2025 2026 Real GDP 2.5 2.9 2.8 2.4 2.1 Consumption 3.0 2.5 2.8 2.7 2.1 Investment 6.0 0.1 4.0 3.1 3.8 Exports 7.5 2.8 3.2 2.4 1.1 Imports 8.6 (1.2) 5.4 3.5 1.3 Government (1.1) 3.9 3.4 1.5 0.1 Federal (3.2) 2.9 2.5 1.7 0.2 State and Local 0.2 4.4 3.9 1.4 0.1 Personal Income 3.1 5.9 5.5 5.0 4.9 Wages & Salaries 7.8 5.4 [...] New York State Economic Outlook (Percent Change) Actual Estimate Forecast Forecast 2023-24 2024-25 2025-26 2026-27 Employment Percent Change 1.8 1.5 1.0 0.8 Level (Thousands) 9,441.6 9,589.7 9,694.3 9,773.6 Personal Income Percent Change 5.2 5.8 4.6 4.4 Level (Billions) 1,581.5 1,671.1 1,754.9 1,835.0 Total Wages Percent Change 4.2 6.7 4.4 4.0 Level (Billions) 864.0 915.9 964.3 1,005.1 Base Wages Percent Change 5.1 5.4 4.4 4.3 Level (Billions) 764.0 803.1 840.7 876.6 Variable Compensation [...] is 0.3 percentage point above the forecast of the Division of the Budget. The Committee’s forecast is 0.1 percentage point above S&P Global forecast and Moody’s Analytics’ projection. The forecast is 0.2 percentage point above the Blue Chip Consensus forecast. Actual Estimate Forecast Forecast 2023 2024 2025 2026 Ways and Means 2.9 2.8 2.4 2.1 Division of the Budget 2.9 2.8 2.1 2.0 Blue Chip Consensus 2.9 2.8 2.2 2.0 Moody's Analytics 2.9 2.8 2.3 1.6 S&P Global 2.9 2.8 2.3 2.0 Sources: NYS\", \"score\": 0.846159, \"raw_content\": null}, {\"url\": \"https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/\", \"title\": \"Annual State of the City's Economy and Finances 2024\", \"content\": \"(constant 2019 dollars)**22,550 15,322 13,596 19,451 21,211 21,096\\n**_% change_**(32.1%)(11.3%)43.1%9.0%(0.5%)\\n\\nSource: NY State Department of Taxation and Finance and Office of the New York City Comptroller [...] [[1]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref1) At that time, the Comptroller’s Office expected five-year cumulative real GDP growth, 2020 to 2024, of 8.7 percent while the mayor expected 9.5 percent.\\n\\n[[2]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref2) U.S. Bureau of Labor Statistics Local Area Unemployment Statistics (LAUS). [...] | Retail Trade | 301,565 | $56,208 | 14.4 | (0.6) | (5.2) | 2.7 | 2.9 | 2.2 | 2.1 |\\n| Leisure & Hospitality | 431,227 | $56,086 | 96.2 | 32.4 | 15.4 | 8.9 | 3.8 | 4.5 | 7.3 |\\n| **Total: Low Wage Sectors** | **1,997,491** | **$62,185** | **184.6** | **102.2** | **91.6** | **62.7** | **32.0** | **26.8** | **29.3** |\\n| **Total NYC Employment** | **4,485,695** | **$114,294** | **307.7** | **119.9** | **78.1** | **88.0** | **65.1** | **53.2** | **51.4** |\", \"score\": 0.7992077, \"raw_content\": null}], \"response_time\": 2.65}\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: research_agent\n", - "\n", - "- US GDP in 2024 is projected to be about $28.18 trillion USD (Statista; CBO projection).\n", - "- New York State's nominal GDP for 2024 is estimated at approximately $2.16 trillion USD (various economic reports).\n", - "- New York State's share of US GDP in 2024 is roughly 7.7%.\n", - "\n", - "Sources:\n", - "- https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/\n", - "- https://nyassembly.gov/Reports/WAM/2025economic_revenue/2025_report.pdf?v=1740533306\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: supervisor\n", - "Tool Calls:\n", - " transfer_to_math_agent (call_WEBMqUupSKqT5slb6ilX2VEO)\n", - " Call ID: call_WEBMqUupSKqT5slb6ilX2VEO\n", - " Args:\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: transfer_to_math_agent\n", - "\n", - "Successfully transferred to math_agent\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "Tool Calls:\n", - " divide (call_fsn6la6HTqfNl3sLp9v1WVoz)\n", - " Call ID: call_fsn6la6HTqfNl3sLp9v1WVoz\n", - " Args:\n", - " a: 2.16\n", - " b: 28.18\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: divide\n", - "\n", - "0.0766501064584812\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: math_agent\n", - "\n", - "US GDP in 2024: $28.18 trillion\n", - "New York State GDP in 2024: $2.16 trillion\n", - "Percentage of US GDP from New York State: 7.67%\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Name: supervisor\n", - "\n", - "Here are your results:\n", - "\n", - "- 2024 US GDP (projected): $28.18 trillion USD\n", - "- 2024 New York State GDP (estimated): $2.16 trillion USD\n", - "- New York State's share of US GDP: approximately 7.7%\n", - "\n", - "If you need the calculation steps or sources, let me know!\n" - ] - } - ], - "source": [ - "for message in final_message_history:\n", - " message.pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "239700cd-d2d3-44be-8cf5-021d15615de2", - "metadata": {}, - "source": [ - "!!! Important\n", - "\n", - " You can see that the supervisor system appends **all** of the individual agent messages (i.e., their internal tool-calling loop) to the full message history. This means that on every supervisor turn, supervisor agent sees this full history. If you want more control over:\n", - "\n", - " * **how inputs are passed to agents**: you can use LangGraph [`Send()`][langgraph.types.Send] primitive to directly send data to the worker agents during the handoff. See the [task delegation](#create-delegation-tasks) example below\n", - " * **how agent outputs are added**: you can control how much of the agent's internal message history is added to the overall supervisor message history by wrapping the agent in a separate node function:\n", - "\n", - " ```python\n", - " def call_research_agent(state):\n", - " # return agent's final response,\n", - " # excluding inner monologue\n", - " response = research_agent.invoke(state)\n", - " # highlight-next-line\n", - " return {\"messages\": response[\"messages\"][-1]}\n", - " ```" - ] - }, - { - "cell_type": "markdown", - "id": "1c2a0aff-935a-46b8-bdcf-7125b80f1f41", - "metadata": {}, - "source": [ - "## 4. Create delegation tasks" - ] - }, - { - "cell_type": "markdown", - "id": "1a13d919-49bf-4cc3-838f-714cd3fb8b26", - "metadata": {}, - "source": [ - "So far the individual agents relied on **interpreting full message history** to determine their tasks. An alternative approach is to ask the supervisor to **formulate a task explicitly**. We can do so by adding a `task_description` parameter to the `handoff_tool` function." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "dc1e4d24-8738-4548-a5e7-8556e476b805", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.types import Send\n", - "\n", - "\n", - "def create_task_description_handoff_tool(\n", - " *, agent_name: str, description: str | None = None\n", - "):\n", - " name = f\"transfer_to_{agent_name}\"\n", - " description = description or f\"Ask {agent_name} for help.\"\n", - "\n", - " @tool(name, description=description)\n", - " def handoff_tool(\n", - " # this is populated by the supervisor LLM\n", - " task_description: Annotated[\n", - " str,\n", - " \"Description of what the next agent should do, including all of the relevant context.\",\n", - " ],\n", - " # these parameters are ignored by the LLM\n", - " state: Annotated[MessagesState, InjectedState],\n", - " ) -> Command:\n", - " task_description_message = {\"role\": \"user\", \"content\": task_description}\n", - " agent_input = {**state, \"messages\": [task_description_message]}\n", - " return Command(\n", - " # highlight-next-line\n", - " goto=[Send(agent_name, agent_input)],\n", - " graph=Command.PARENT,\n", - " )\n", - "\n", - " return handoff_tool\n", - "\n", - "\n", - "assign_to_research_agent_with_description = create_task_description_handoff_tool(\n", - " agent_name=\"research_agent\",\n", - " description=\"Assign task to a researcher agent.\",\n", - ")\n", - "\n", - "assign_to_math_agent_with_description = create_task_description_handoff_tool(\n", - " agent_name=\"math_agent\",\n", - " description=\"Assign task to a math agent.\",\n", - ")\n", - "\n", - "supervisor_agent_with_description = create_react_agent(\n", - " model=\"openai:gpt-4.1\",\n", - " tools=[\n", - " assign_to_research_agent_with_description,\n", - " assign_to_math_agent_with_description,\n", - " ],\n", - " prompt=(\n", - " \"You are a supervisor managing two agents:\\n\"\n", - " \"- a research agent. Assign research-related tasks to this assistant\\n\"\n", - " \"- a math agent. Assign math-related tasks to this assistant\\n\"\n", - " \"Assign work to one agent at a time, do not call agents in parallel.\\n\"\n", - " \"Do not do any work yourself.\"\n", - " ),\n", - " name=\"supervisor\",\n", - ")\n", - "\n", - "supervisor_with_description = (\n", - " StateGraph(MessagesState)\n", - " .add_node(\n", - " supervisor_agent_with_description, destinations=(\"research_agent\", \"math_agent\")\n", - " )\n", - " .add_node(research_agent)\n", - " .add_node(math_agent)\n", - " .add_edge(START, \"supervisor\")\n", - " .add_edge(\"research_agent\", \"supervisor\")\n", - " .add_edge(\"math_agent\", \"supervisor\")\n", - " .compile()\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "622bc89a-0787-41ea-bf18-c591be85509b", - "metadata": {}, - "source": [ - "!!! note\n", - "\n", - " We're using [`Send()`][langgraph.types.Send] primitive in the `handoff_tool`. This means that instead of receiving the full `supervisor` graph state as input, each worker agent only sees the contents of the `Send` payload. In this example, we're sending the task description as a single \"human\" message." - ] - }, - { - "cell_type": "markdown", - "id": "4d1dba40-c948-4117-9df6-5bdb1ab162c7", - "metadata": {}, - "source": [ - "Let's now running it with the same input query:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "882f9e00-5fdf-4278-ab26-a59fc949fa91", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from subgraph supervisor:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: supervisor\n", - "\tTool Calls:\n", - "\t transfer_to_research_agent (call_tk8q8py8qK6MQz6Kj6mijKua)\n", - "\t Call ID: call_tk8q8py8qK6MQz6Kj6mijKua\n", - "\t Args:\n", - "\t task_description: Find the 2024 GDP (Gross Domestic Product) for both the United States and New York state, using the most up-to-date and reputable sources available. Provide both GDP values and cite the data sources.\n", - "\n", - "\n", - "Update from subgraph research_agent:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: research_agent\n", - "\tTool Calls:\n", - "\t tavily_search (call_KqvhSvOIhAvXNsT6BOwbPlRB)\n", - "\t Call ID: call_KqvhSvOIhAvXNsT6BOwbPlRB\n", - "\t Args:\n", - "\t query: 2024 United States GDP value from a reputable source\n", - "\t search_depth: advanced\n", - "\t tavily_search (call_kbbAWBc9KwCWKHmM5v04H88t)\n", - "\t Call ID: call_kbbAWBc9KwCWKHmM5v04H88t\n", - "\t Args:\n", - "\t query: 2024 New York state GDP value from a reputable source\n", - "\t search_depth: advanced\n", - "\n", - "\n", - "Update from subgraph research_agent:\n", - "\n", - "\n", - "\tUpdate from node tools:\n", - "\n", - "\n", - "\t=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "\tName: tavily_search\n", - "\t\n", - "\t{\"query\": \"2024 United States GDP value from a reputable source\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://www.focus-economics.com/countries/united-states/\", \"title\": \"United States Economy Overview - Focus Economics\", \"content\": \"The United States' Macroeconomic Analysis:\\n------------------------------------------\\n\\n**Nominal GDP of USD 29,185 billion in 2024.**\\n\\n**Nominal GDP of USD 29,179 billion in 2024.**\\n\\n**GDP per capita of USD 86,635 compared to the global average of USD 10,589.**\\n\\n**GDP per capita of USD 86,652 compared to the global average of USD 10,589.**\\n\\n**Average real GDP growth of 2.5% over the last decade.**\\n\\n**Average real GDP growth of 2.5% over the last decade.**\\n\\nShare of the region's population [...] | | 2020 | 2021 | 2022 | 2023 | 2024 |\\n| --- | --- | --- | --- | --- | --- |\\n| [Population (million)](https://www.focus-economics.com/country-indicator/united-states/population/) | 331 | 332 | 334 | 337 | 340 |\\n| [GDP (USD bn)](https://www.focus-economics.com/country-indicator/united-states/gdp/) | 21,354 | 23,681 | 26,007 | 27,721 | 29,185 |\", \"score\": 0.73981786, \"raw_content\": null}, {\"url\": \"https://tradingeconomics.com/united-states/gdp\", \"title\": \"United States GDP - Trading Economics\", \"content\": \"| Related | Last | Previous | Unit | Reference |\\n| --- | --- | --- | --- | --- |\\n| [Full Year GDP Growth](/united-states/full-year-gdp-growth) | 2.80 | 2.90 | percent | Dec 2024 |\\n| [GDP](/united-states/gdp) | 27720.71 | 26006.89 | USD Billion | Dec 2023 |\\n| [GDP Annual Growth Rate](/united-states/gdp-growth-annual) | 2.10 | 2.50 | percent | Mar 2025 |\\n| [GDP Constant Prices](/united-states/gdp-constant-prices) | 23528.00 | 23542.30 | USD Billion | Mar 2025 |\", \"score\": 0.65359193, \"raw_content\": null}, {\"url\": \"https://fred.stlouisfed.org/series/GDP\", \"title\": \"Gross Domestic Product (GDP) | FRED | St. Louis Fed\", \"content\": \"Q1 2025: 29,976.638 |\\nBillions of Dollars, Seasonally Adjusted Annual Rate |\\nQuarterly\\n\\nUpdated:\\nMay 29, 2025\\n7:56 AM CDT\\n\\n[Next Release Date:\\nJun 26, 2025](/releases/calendar?rid=53&y=2025)\\n\\nObservations\\n\\n| | | |\\n| --- | --- | --- |\\n| Q1 2025: | 29,976.638 | |\\n| Q4 2024: | 29,723.864 | |\\n| Q3 2024: | 29,374.914 | |\\n| Q2 2024: | 29,016.714 | |\\n| Q1 2024: | 28,624.069 | |\\n| [View All](/data/GDP.txt) | |\\n\\nUnits:\\n\\nFrequency:\", \"score\": 0.6152965, \"raw_content\": null}], \"response_time\": 2.53}\n", - "\n", - "\n", - "Update from subgraph research_agent:\n", - "\n", - "\n", - "\tUpdate from node tools:\n", - "\n", - "\n", - "\t=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "\tName: tavily_search\n", - "\t\n", - "\t{\"query\": \"2024 New York state GDP value from a reputable source\", \"follow_up_questions\": null, \"answer\": null, \"images\": [], \"results\": [{\"url\": \"https://www.ibisworld.com/united-states/economic-profiles/new-york/\", \"title\": \"New York Economic Trends, Stats & Rankings | IBISWorld\", \"content\": \"#### What is New York's Gross Domestic Product (GDP)?\\n\\nIn 2024, New York's GDP reached $1.8tn, representing an increase of 1.3% from 2023. New York's GDP has grown at an annualized rate of 2.9% over the five years to 2024. Moreover, New York's trailing five-year GDP growth ranks it 37th out of all 50 US states. [...] In 2024, the state of New York has a population of 19,482,372, having grown an annualized 0.0% over the five years to 2024, which ranks it 44th out of all 50 US states by growth rate. New York's gross state product (GSP) in 2024 reached $1.8tn, with growth of 1.3% over the 5 years to 2024. Businesses in New York employed a total of 11,671,845 people in 2024, with average annual employment growth over the past five years of 0.0%. The top three sectors by total employment are Finance and [...] The Finance and Insurance, Real Estate and Rental and Leasing and Information sectors contributed the most to New York's GDP in 2024, representing a combined 46.3% of state GDP.\\n\\nGDP trends by sector are an important indicator of which sectors are contributing the most value-add to the state's economy, in addition to how the state economy is evolving over time.\\n\\nSector\\n\\nGDP\\n\\nGrowth 2024 (%)\\n\\nAnnualized Growth 2019-24\", \"score\": 0.8051581, \"raw_content\": null}, {\"url\": \"https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/\", \"title\": \"Annual State of the City's Economy and Finances 2024\", \"content\": \"(constant 2019 dollars)**22,550 15,322 13,596 19,451 21,211 21,096\\n**_% change_**(32.1%)(11.3%)43.1%9.0%(0.5%)\\n\\nSource: NY State Department of Taxation and Finance and Office of the New York City Comptroller [...] [[1]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref1) At that time, the Comptroller’s Office expected five-year cumulative real GDP growth, 2020 to 2024, of 8.7 percent while the mayor expected 9.5 percent.\\n\\n[[2]](https://comptroller.nyc.gov/reports/annual-state-of-the-citys-economy-and-finances-2024/#_ftnref2) U.S. Bureau of Labor Statistics Local Area Unemployment Statistics (LAUS). [...] **($ in millions)****FY 2025****FY 2026****FY 2027****FY 2028****Total****Change from June 2024 (FY2025-FY2028)****Source as Share of Total**\\n**General Obligation Bonds**$6,900$6,230$6,920$7,110$27,160$1,960 42.8%\\n**TFA FTS Bonds**6,900 6,230 6,920 7,110 27,160 2,460 42.8%\\n**NYC Water Finance Authority**1,726 2,474 2,452 2,505 9,157 435 14.4%\\n**Total****$15,526****$14,934****$16,292****$16,725****$63,477****$4,855****100.0%**\", \"score\": 0.74541736, \"raw_content\": null}], \"response_time\": 3.45}\n", - "\n", - "\n", - "Update from subgraph research_agent:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: research_agent\n", - "\t\n", - "\t- United States 2024 GDP: $29.2 trillion (USD) \n", - "\t Source: [Focus Economics](https://www.focus-economics.com/countries/united-states/)\n", - "\t\n", - "\t- New York State 2024 GDP: $1.8 trillion (USD) \n", - "\t Source: [IBISWorld](https://www.ibisworld.com/united-states/economic-profiles/new-york/)\n", - "\n", - "\n", - "Update from subgraph supervisor:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: supervisor\n", - "\tTool Calls:\n", - "\t transfer_to_math_agent (call_EqT01HDOQDd5Timk89cccdXP)\n", - "\t Call ID: call_EqT01HDOQDd5Timk89cccdXP\n", - "\t Args:\n", - "\t task_description: Calculate what percentage of the US GDP ($29.2 trillion) was New York State's GDP ($1.8 trillion) in 2024. Show your working and round the final answer to two decimal points.\n", - "\n", - "\n", - "Update from subgraph math_agent:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: math_agent\n", - "\tTool Calls:\n", - "\t divide (call_OpdUlYEFqk4RZ2rF46M9eTrS)\n", - "\t Call ID: call_OpdUlYEFqk4RZ2rF46M9eTrS\n", - "\t Args:\n", - "\t a: 1.8\n", - "\t b: 29.2\n", - "\n", - "\n", - "Update from subgraph math_agent:\n", - "\n", - "\n", - "\tUpdate from node tools:\n", - "\n", - "\n", - "\t=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "\tName: divide\n", - "\t\n", - "\t0.06164383561643836\n", - "\n", - "\n", - "Update from subgraph math_agent:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: math_agent\n", - "\tTool Calls:\n", - "\t multiply (call_vdKJTLtIzmG6JbPcGQn93MR6)\n", - "\t Call ID: call_vdKJTLtIzmG6JbPcGQn93MR6\n", - "\t Args:\n", - "\t a: 0.06164383561643836\n", - "\t b: 100\n", - "\n", - "\n", - "Update from subgraph math_agent:\n", - "\n", - "\n", - "\tUpdate from node tools:\n", - "\n", - "\n", - "\t=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "\tName: multiply\n", - "\t\n", - "\t6.164383561643836\n", - "\n", - "\n", - "Update from subgraph math_agent:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: math_agent\n", - "\t\n", - "\tNew York State's GDP was approximately 6.16% of the US GDP in 2024.\n", - "\n", - "\n", - "Update from subgraph supervisor:\n", - "\n", - "\n", - "\tUpdate from node agent:\n", - "\n", - "\n", - "\t==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\tName: supervisor\n", - "\t\n", - "\tNew York State’s GDP was approximately 6.16% of the US GDP in 2024.\n", - "\t\n", - "\t**Working:**\n", - "\t- Percentage = (NY GDP / US GDP) × 100\n", - "\t- = ($1.8 trillion / $29.2 trillion) × 100\n", - "\t- = 0.06164 × 100\n", - "\t- = 6.16% (rounded to two decimal points)\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in supervisor_with_description.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"find US and New York state GDP in 2024. what % of US GDP was New York state?\",\n", - " }\n", - " ]\n", - " },\n", - " subgraphs=True,\n", - "):\n", - " pretty_print_messages(chunk, last_message=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d3916d1-7de9-47c1-ae6f-80865b804e77", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/tutorials/multi_agent/agent_supervisor.md b/docs/docs/tutorials/multi_agent/agent_supervisor.md new file mode 100644 index 000000000..71335c8db --- /dev/null +++ b/docs/docs/tutorials/multi_agent/agent_supervisor.md @@ -0,0 +1,812 @@ +# Multi-agent supervisor + +[**Supervisor**](../../concepts/multi_agent.md#supervisor) is a multi-agent architecture where **specialized** agents are coordinated by a central **supervisor agent**. The supervisor agent controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements. + +In this tutorial, you will build a supervisor system with two agents — a research and a math expert. By the end of the tutorial you will: + +1. Build specialized research and math agents +2. Build a supervisor for orchestrating them with the prebuilt [`langgraph-supervisor`](https://langchain-ai.github.io/langgraph/agents/multi-agent/#supervisor) +3. Build a supervisor from scratch +4. Implement advanced task delegation + +![diagram](assets/diagram.png) + +## Setup + +First, let's install required packages and set our API keys + +```python +%%capture --no-stderr +%pip install -U langgraph langgraph-supervisor langchain-tavily "langchain[openai]" +``` + +```python +import getpass +import os + + +def _set_if_undefined(var: str): + if not os.environ.get(var): + os.environ[var] = getpass.getpass(f"Please provide your {var}") + + +_set_if_undefined("OPENAI_API_KEY") +_set_if_undefined("TAVILY_API_KEY") +``` + +!!! tip + Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph. + +## 1. Create worker agents + +First, let's create our specialized worker agents — research agent and math agent: + +* Research agent will have access to a web search tool using [Tavily API](https://tavily.com/) +* Math agent will have access to simple math tools (`add`, `multiply`, `divide`) + +### Research agent + +For web search, we will use `TavilySearch` tool from `langchain-tavily`: + +```python +from langchain_tavily import TavilySearch + +web_search = TavilySearch(max_results=3) +web_search_results = web_search.invoke("who is the mayor of NYC?") + +print(web_search_results["results"][0]["content"]) +``` + +**Output:** +``` +Find events, attractions, deals, and more at nyctourism.com Skip Main Navigation Menu The Official Website of the City of New York Text Size Powered by Translate SearchSearch Primary Navigation The official website of NYC Home NYC Resources NYC311 Office of the Mayor Events Connect Jobs Search Office of the Mayor | Mayor's Bio | City of New York Secondary Navigation MayorBiographyNewsOfficials Eric L. Adams 110th Mayor of New York City Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. He gave voice to a diverse coalition of working families in all five boroughs and is leading the fight to bring back New York City's economy, reduce inequality, improve public safety, and build a stronger, healthier city that delivers for all New Yorkers. As the representative of one of the nation's largest counties, Eric fought tirelessly to grow the local economy, invest in schools, reduce inequality, improve public safety, and advocate for smart policies and better government that delivers for all New Yorkers. +``` + +To create individual worker agents, we will use LangGraph's prebuilt [agent](../../agents/agents.md). + +```python +from langgraph.prebuilt import create_react_agent + +research_agent = create_react_agent( + model="openai:gpt-4.1", + tools=[web_search], + prompt=( + "You are a research agent.\n\n" + "INSTRUCTIONS:\n" + "- Assist ONLY with research-related tasks, DO NOT do any math\n" + "- After you're done with your tasks, respond to the supervisor directly\n" + "- Respond ONLY with the results of your work, do NOT include ANY other text." + ), + name="research_agent", +) +``` + +Let's [run the agent](../../agents/run_agents.md) to verify that it behaves as expected. + +!!! note "We'll use `pretty_print_messages` helper to render the streamed agent outputs nicely" + + ```python + from langchain_core.messages import convert_to_messages + + + def pretty_print_message(message, indent=False): + pretty_message = message.pretty_repr(html=True) + if not indent: + print(pretty_message) + return + + indented = "\n".join("\t" + c for c in pretty_message.split("\n")) + print(indented) + + + def pretty_print_messages(update, last_message=False): + is_subgraph = False + if isinstance(update, tuple): + ns, update = update + # skip parent graph updates in the printouts + if len(ns) == 0: + return + + graph_id = ns[-1].split(":")[0] + print(f"Update from subgraph {graph_id}:") + print("\n") + is_subgraph = True + + for node_name, node_update in update.items(): + update_label = f"Update from node {node_name}:" + if is_subgraph: + update_label = "\t" + update_label + + print(update_label) + print("\n") + + messages = convert_to_messages(node_update["messages"]) + if last_message: + messages = messages[-1:] + + for m in messages: + pretty_print_message(m, indent=is_subgraph) + print("\n") + ``` + +```python +from langchain_core.messages import convert_to_messages + + +def pretty_print_message(message, indent=False): + pretty_message = message.pretty_repr(html=True) + if not indent: + print(pretty_message) + return + + indented = "\n".join("\t" + c for c in pretty_message.split("\n")) + print(indented) + + +def pretty_print_messages(update, last_message=False): + is_subgraph = False + if isinstance(update, tuple): + ns, update = update + # skip parent graph updates in the printouts + if len(ns) == 0: + return + + graph_id = ns[-1].split(":")[0] + print(f"Update from subgraph {graph_id}:") + print("\n") + is_subgraph = True + + for node_name, node_update in update.items(): + update_label = f"Update from node {node_name}:" + if is_subgraph: + update_label = "\t" + update_label + + print(update_label) + print("\n") + + messages = convert_to_messages(node_update["messages"]) + if last_message: + messages = messages[-1:] + + for m in messages: + pretty_print_message(m, indent=is_subgraph) + print("\n") +``` + +```python +for chunk in research_agent.stream( + {"messages": [{"role": "user", "content": "who is the mayor of NYC?"}]} +): + pretty_print_messages(chunk) +``` + +**Output:** +``` +Update from node agent: + + +================================== Ai Message ================================== +Name: research_agent +Tool Calls: + tavily_search (call_U748rQhQXT36sjhbkYLSXQtJ) + Call ID: call_U748rQhQXT36sjhbkYLSXQtJ + Args: + query: current mayor of New York City + search_depth: basic + + +Update from node tools: + + +================================= Tool Message ================================== +Name: tavily_search + +{"query": "current mayor of New York City", "follow_up_questions": null, "answer": null, "images": [], "results": [{"title": "List of mayors of New York City - Wikipedia", "url": "https://en.wikipedia.org/wiki/List_of_mayors_of_New_York_City", "content": "The mayor of New York City is the chief executive of the Government of New York City, as stipulated by New York City's charter.The current officeholder, the 110th in the sequence of regular mayors, is Eric Adams, a member of the Democratic Party.. During the Dutch colonial period from 1624 to 1664, New Amsterdam was governed by the Director of Netherland.", "score": 0.9039154, "raw_content": null}, {"title": "Office of the Mayor | Mayor's Bio | City of New York - NYC.gov", "url": "https://www.nyc.gov/office-of-the-mayor/bio.page", "content": "Mayor Eric Adams has served the people of New York City as an NYPD officer, State Senator, Brooklyn Borough President, and now as the 110th Mayor of the City of New York. He gave voice to a diverse coalition of working families in all five boroughs and is leading the fight to bring back New York City's economy, reduce inequality, improve", "score": 0.8405867, "raw_content": null}, {"title": "Eric Adams - Wikipedia", "url": "https://en.wikipedia.org/wiki/Eric_Adams", "content": "Eric Leroy Adams (born September 1, 1960) is an American politician and former police officer who has served as the 110th mayor of New York City since 2022. Adams was an officer in the New York City Transit Police and then the New York City Police Department (``` +``` + +### Math agent + +For math agent tools we will use [vanilla Python functions](../../how-tos/tool-calling.md#define-a-tool): + +```python +def add(a: float, b: float): + """Add two numbers.""" + return a + b + + +def multiply(a: float, b: float): + """Multiply two numbers.""" + return a * b + + +def divide(a: float, b: float): + """Divide two numbers.""" + return a / b + + +math_agent = create_react_agent( + model="openai:gpt-4.1", + tools=[add, multiply, divide], + prompt=( + "You are a math agent.\n\n" + "INSTRUCTIONS:\n" + "- Assist ONLY with math-related tasks\n" + "- After you're done with your tasks, respond to the supervisor directly\n" + "- Respond ONLY with the results of your work, do NOT include ANY other text." + ), + name="math_agent", +) +``` + +Let's run the math agent: + +```python +for chunk in math_agent.stream( + {"messages": [{"role": "user", "content": "what's (3 + 5) x 7"}]} +): + pretty_print_messages(chunk) +``` + +**Output:** +``` +Update from node agent: + + +================================== Ai Message ================================== +Name: math_agent +Tool Calls: + add (call_p6OVLDHB4LyCNCxPOZzWR15v) + Call ID: call_p6OVLDHB4LyCNCxPOZzWR15v + Args: + a: 3 + b: 5 + + +Update from node tools: + + +================================= Tool Message ================================== +Name: add + +8.0 + + +Update from node agent: + + +================================== Ai Message ================================== +Name: math_agent +Tool Calls: + multiply (call_EoaWHMLFZAX4AkajQCtZvbli) + Call ID: call_EoaWHMLFZAX4AkajQCtZvbli + Args: + a: 8 + b: 7 + + +Update from node tools: + + +================================= Tool Message ================================== +Name: multiply + +56.0 + + +Update from node agent: + + +================================== Ai Message ================================== +Name: math_agent + +56 + + +``` + +## 2. Create supervisor with `langgraph-supervisor` + +To implement out multi-agent system, we will use [`create_supervisor`][langgraph_supervisor.supervisor.create_supervisor] from the prebuilt `langgraph-supervisor` library: + +```python +from langgraph_supervisor import create_supervisor +from langchain.chat_models import init_chat_model + +supervisor = create_supervisor( + model=init_chat_model("openai:gpt-4.1"), + agents=[research_agent, math_agent], + prompt=( + "You are a supervisor managing two agents:\n" + "- a research agent. Assign research-related tasks to this agent\n" + "- a math agent. Assign math-related tasks to this agent\n" + "Assign work to one agent at a time, do not call agents in parallel.\n" + "Do not do any work yourself." + ), + add_handoff_back_messages=True, + output_mode="full_history", +).compile() +``` + +```python +from IPython.display import display, Image + +display(Image(supervisor.get_graph().draw_mermaid_png())) +``` + +![Graph](assets/output.png) + +**Note:** When you run this code, it will generate and display a visual representation of the supervisor graph showing the flow between the supervisor and worker agents. + +Let's now run it with a query that requires both agents: + +* research agent will look up the necessary GDP information +* math agent will perform division to find the percentage of NY state GDP, as requested + +```python +for chunk in supervisor.stream( + { + "messages": [ + { + "role": "user", + "content": "find US and New York state GDP in 2024. what % of US GDP was New York state?", + } + ] + }, +): + pretty_print_messages(chunk, last_message=True) + +final_message_history = chunk["supervisor"]["messages"] +``` + +**Output:** +``` +Update from node supervisor: + + +================================= Tool Message ================================== +Name: transfer_to_research_agent + +Successfully transferred to research_agent + + +Update from node research_agent: + + +================================= Tool Message ================================== +Name: transfer_back_to_supervisor + +Successfully transferred back to supervisor + + +Update from node supervisor: + + +================================= Tool Message ================================== +Name: transfer_to_math_agent + +Successfully transferred to math_agent + + +Update from node math_agent: + + +================================= Tool Message ================================== +Name: transfer_back_to_supervisor + +Successfully transferred back to supervisor + + +Update from node supervisor: + + +================================== Ai Message ================================== +Name: supervisor + +In 2024, the US GDP was $29.18 trillion and New York State's GDP was $2.297 trillion. New York State accounted for approximately 7.87% of the total US GDP in 2024. + + +``` + +## 3. Create supervisor from scratch + +Let's now implement this same multi-agent system from scratch. We will need to: + +1. [Set up how the supervisor communicates](#set-up-agent-communication) with individual agents +2. [Create the supervisor agent](#create-supervisor-agent) +3. Combine supervisor and worker agents into a [single multi-agent graph](#create-multi-agent-graph). + +### Set up agent communication + +We will need to define a way for the supervisor agent to communicate with the worker agents. A common way to implement this in multi-agent architectures is using **handoffs**, where one agent *hands off* control to another. Handoffs allow you to specify: + +- **destination**: target agent to transfer to +- **payload**: information to pass to that agent + +We will implement handoffs via **handoff tools** and give these tools to the supervisor agent: when the supervisor calls these tools, it will hand off control to a worker agent, passing the full message history to that agent. + +```python +from typing import Annotated +from langchain_core.tools import tool, InjectedToolCallId +from langgraph.prebuilt import InjectedState +from langgraph.graph import StateGraph, START, MessagesState +from langgraph.types import Command + + +def create_handoff_tool(*, agent_name: str, description: str | None = None): + name = f"transfer_to_{agent_name}" + description = description or f"Ask {agent_name} for help." + + @tool(name, description=description) + def handoff_tool( + state: Annotated[MessagesState, InjectedState], + tool_call_id: Annotated[str, InjectedToolCallId], + ) -> Command: + tool_message = { + "role": "tool", + "content": f"Successfully transferred to {agent_name}", + "name": name, + "tool_call_id": tool_call_id, + } + # highlight-next-line + return Command( + # highlight-next-line + goto=agent_name, # (1)! + # highlight-next-line + update={**state, "messages": state["messages"] + [tool_message]}, # (2)! + # highlight-next-line + graph=Command.PARENT, # (3)! + ) + + return handoff_tool + + +# Handoffs +assign_to_research_agent = create_handoff_tool( + agent_name="research_agent", + description="Assign task to a researcher agent.", +) + +assign_to_math_agent = create_handoff_tool( + agent_name="math_agent", + description="Assign task to a math agent.", +) +``` + +1. Name of the agent or node to hand off to. +2. Take the agent's messages and add them to the parent's state as part of the handoff. The next agent will see the parent state. +3. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph. + +### Create supervisor agent + +Then, let's create the supervisor agent with the handoff tools we just defined. We will use the prebuilt [`create_react_agent`][langgraph.prebuilt.chat_agent_executor.create_react_agent]: + +```python +supervisor_agent = create_react_agent( + model="openai:gpt-4.1", + tools=[assign_to_research_agent, assign_to_math_agent], + prompt=( + "You are a supervisor managing two agents:\n" + "- a research agent. Assign research-related tasks to this agent\n" + "- a math agent. Assign math-related tasks to this agent\n" + "Assign work to one agent at a time, do not call agents in parallel.\n" + "Do not do any work yourself." + ), + name="supervisor", +) +``` + +### Create multi-agent graph + +Putting this all together, let's create a graph for our overall multi-agent system. We will add the supervisor and the individual agents as subgraph [nodes](../../concepts/low_level.md#nodes). + +```python +from langgraph.graph import END + +# Define the multi-agent supervisor graph +supervisor = ( + StateGraph(MessagesState) + # NOTE: `destinations` is only needed for visualization and doesn't affect runtime behavior + .add_node(supervisor_agent, destinations=("research_agent", "math_agent", END)) + .add_node(research_agent) + .add_node(math_agent) + .add_edge(START, "supervisor") + # always return back to the supervisor + .add_edge("research_agent", "supervisor") + .add_edge("math_agent", "supervisor") + .compile() +) +``` + +Notice that we've added explicit [edges](../../concepts/low_level.md#edges) from worker agents back to the supervisor — this means that they are guaranteed to return control back to the supervisor. If you want the agents to respond directly to the user (i.e., turn the system into a router, you can remove these edges). + +```python +from IPython.display import display, Image + +display(Image(supervisor.get_graph().draw_mermaid_png())) +``` + +![Graph](assets/multi-output.png) + +**Note:** When you run this code, it will generate and display a visual representation of the multi-agent supervisor graph showing the flow between the supervisor and worker agents. + +With the multi-agent graph created, let's now run it! + +```python +for chunk in supervisor.stream( + { + "messages": [ + { + "role": "user", + "content": "find US and New York state GDP in 2024. what % of US GDP was New York state?", + } + ] + }, +): + pretty_print_messages(chunk, last_message=True) + +final_message_history = chunk["supervisor"]["messages"] +``` + +**Output:** +``` +Update from node supervisor: + + +================================= Tool Message ================================== +Name: transfer_to_research_agent + +Successfully transferred to research_agent + + +Update from node research_agent: + + +================================== Ai Message ================================== +Name: research_agent + +- US GDP in 2024 is projected to be about $28.18 trillion USD (Statista; CBO projection). +- New York State's nominal GDP for 2024 is estimated at approximately $2.16 trillion USD (various economic reports). +- New York State's share of US GDP in 2024 is roughly 7.7%. + +Sources: +- https://www.statista.com/statistics/216985/forecast-of-us-gross-domestic-product/ +- https://nyassembly.gov/Reports/WAM/2025economic_revenue/2025_report.pdf?v=1740533306 + + +Update from node supervisor: + + +================================= Tool Message ================================== +Name: transfer_to_math_agent + +Successfully transferred to math_agent + + +Update from node math_agent: + + +================================== Ai Message ================================== +Name: math_agent + +US GDP in 2024: $28.18 trillion +New York State GDP in 2024: $2.16 trillion +Percentage of US GDP from New York State: 7.67% + + +Update from node supervisor: + + +================================== Ai Message ================================== +Name: supervisor + +Here are your results: + +- 2024 US GDP (projected): $28.18 trillion USD +- 2024 New York State GDP (estimated): $2.16 trillion USD +- New York State's share of US GDP: approximately 7.7% + +If you need the calculation steps or sources, let me know! + + +``` + +Let's examine the full resulting message history: + +```python +for message in final_message_history: + message.pretty_print() +``` + +**Output:** +``` +================================ Human Message ================================== + +find US and New York state GDP in 2024. what % of US GDP was New York state? +================================== Ai Message =================================== +Name: supervisor +Tool Calls: + transfer_to_research_agent (call_KlGgvF5ahlAbjX8d2kHFjsC3) + Call ID: call_KlGgvF5ahlAbjX8d2kHFjsC3 + Args: +================================= Tool Message ================================== +Name: transfer_to_research_agent + +Successfully transferred to research_agent +================================== Ai Message =================================== +Name: research_agent +Tool Calls: + tavily_search (call_ZOaTVUA6DKrOjWQldLhtrsO2) + Call ID: call_ZOaTVUA6DKrOjWQldLhtrsO2 + Args: + query: US GDP 2024 estimate or actual + search_depth: advanced + tavily_search (call_QsRAasxW9K03lTlqjuhNLFbZ) + Call ID: call_QsRAasxW9K03lTlqjuhNLFbZ + Args: + query: New York state GDP 2024 estimate or actual + search_depth: advanced +================================= Tool Message ================================== +Name: tavily_search + +{"query": "US GDP 2024 estimate or actual", "follow_up_questions": null, "answer": null, "images": [], "results": [{"url": "https://www.advisorperspectives.com/dshort/updates/2025/05/29/gdp-gross-domestic-product-q1-2025-second-estimate", "title": "Q1 GDP Second Estimate: Real GDP at -0.2%, Higher Than Expected", "content": "> Real gross domestic product (GDP) decreased at an annual rate of 0.2 percent in the first quarter of 2025 (January, February, and March), according to the second estimate released by the U.S. Bureau of Economic Analysis. In the fourth quarter of 2024, real GDP increased 2.4 percent. The decrease in real GDP in the first quarter primarily reflected an increase in imports, which are a subtraction in the calculation of GDP, and a decrease in government spending. These movements were partly [...] by [Harry Mamaysky](https://www.advisor``` +``` + +!!! important + You can see that the supervisor system appends **all** of the individual agent messages (i.e., their internal tool-calling loop) to the full message history. This means that on every supervisor turn, supervisor agent sees this full history. If you want more control over: + + * **how inputs are passed to agents**: you can use LangGraph [`Send()`][langgraph.types.Send] primitive to directly send data to the worker agents during the handoff. See the [task delegation](#4-create-delegation-tasks) example below + * **how agent outputs are added**: you can control how much of the agent's internal message history is added to the overall supervisor message history by wrapping the agent in a separate node function: + + ```python + def call_research_agent(state): + # return agent's final response, + # excluding inner monologue + response = research_agent.invoke(state) + # highlight-next-line + return {"messages": response["messages"][-1]} + ``` + +## 4. Create delegation tasks + +So far the individual agents relied on **interpreting full message history** to determine their tasks. An alternative approach is to ask the supervisor to **formulate a task explicitly**. We can do so by adding a `task_description` parameter to the `handoff_tool` function. + +```python +from langgraph.types import Send + + +def create_task_description_handoff_tool( + *, agent_name: str, description: str | None = None +): + name = f"transfer_to_{agent_name}" + description = description or f"Ask {agent_name} for help." + + @tool(name, description=description) + def handoff_tool( + # this is populated by the supervisor LLM + task_description: Annotated[ + str, + "Description of what the next agent should do, including all of the relevant context.", + ], + # these parameters are ignored by the LLM + state: Annotated[MessagesState, InjectedState], + ) -> Command: + task_description_message = {"role": "user", "content": task_description} + agent_input = {**state, "messages": [task_description_message]} + return Command( + # highlight-next-line + goto=[Send(agent_name, agent_input)], + graph=Command.PARENT, + ) + + return handoff_tool + + +assign_to_research_agent_with_description = create_task_description_handoff_tool( + agent_name="research_agent", + description="Assign task to a researcher agent.", +) + +assign_to_math_agent_with_description = create_task_description_handoff_tool( + agent_name="math_agent", + description="Assign task to a math agent.", +) + +supervisor_agent_with_description = create_react_agent( + model="openai:gpt-4.1", + tools=[ + assign_to_research_agent_with_description, + assign_to_math_agent_with_description, + ], + prompt=( + "You are a supervisor managing two agents:\n" + "- a research agent. Assign research-related tasks to this assistant\n" + "- a math agent. Assign math-related tasks to this assistant\n" + "Assign work to one agent at a time, do not call agents in parallel.\n" + "Do not do any work yourself." + ), + name="supervisor", +) + +supervisor_with_description = ( + StateGraph(MessagesState) + .add_node( + supervisor_agent_with_description, destinations=("research_agent", "math_agent") + ) + .add_node(research_agent) + .add_node(math_agent) + .add_edge(START, "supervisor") + .add_edge("research_agent", "supervisor") + .add_edge("math_agent", "supervisor") + .compile() +) +``` + +!!! note + We're using [`Send()`][langgraph.types.Send] primitive in the `handoff_tool`. This means that instead of receiving the full `supervisor` graph state as input, each worker agent only sees the contents of the `Send` payload. In this example, we're sending the task description as a single "human" message. + +Let's now running it with the same input query: + +```python +for chunk in supervisor_with_description.stream( + { + "messages": [ + { + "role": "user", + "content": "find US and New York state GDP in 2024. what % of US GDP was New York state?", + } + ] + }, + subgraphs=True, +): + pretty_print_messages(chunk, last_message=True) +``` + +**Output:** +``` +Update from subgraph supervisor: + + + Update from node agent: + + + ================================== Ai Message ================================== + Name: supervisor + Tool Calls: + transfer_to_research_agent (call_tk8q8py8qK6MQz6Kj6mijKua) + Call ID: call_tk8q8py8qK6MQz6Kj6mijKua + Args: + task_description: Find the 2024 GDP (Gross Domestic Product) for both the United States and New York state, using the most up-to-date and reputable sources available. Provide both GDP values and cite the data sources. + + +Update from subgraph research_agent: + + + Update from node agent: + + + ================================== Ai Message ================================== + Name: research_agent + Tool Calls: + tavily_search (call_KqvhSvOIhAvXNsT6BOwbPlRB) + Call ID: call_KqvhSvOIhAvXNsT6BOwbPlRB + Args: + query: 2024 United States GDP value from a reputable source + search_depth: advanced + tavily_search (call_kbbAWBc9KwCWKHmM5v04H88t) + Call ID: call_kbbAWBc9KwCWKHmM5v04H88t + Args: + query: 2024 New York state GDP value from a reputable source + search_depth: advanced + + +Update from subgraph research_agent: + + + Update from node tools: + + + ================================= Tool Message ================================== + Name: tavily_search + + {"query": "2024 United States GDP value from a reputable source", "follow_up_questions": null, "answer": null, "images": [], "results": [{"url": "https://www.focus-economics.com/countries/united-states/", "title": "United States Economy Overview - Focus Economics", "content": "The United States' Macroeconomic Analysis:\n------------------------------------------\n\n**Nominal GDP of USD 29,185 billion in 2024.**\n\n**Nominal GDP of USD 29,179 billion in 2024.**\n\n**GDP per capita of USD 86,635 compared to the global average of USD 10,589.**\n\n**GDP per capita of USD 86,652 compared to the global average of USD 10,589.**\n\n**Average real GDP growth of 2.5% over the last decade.**\n\n**Average real GDP growth of ``` +``` \ No newline at end of file diff --git a/docs/docs/tutorials/multi_agent/assets/diagram.png b/docs/docs/tutorials/multi_agent/assets/diagram.png new file mode 100644 index 000000000..8aaad4759 Binary files /dev/null and b/docs/docs/tutorials/multi_agent/assets/diagram.png differ diff --git a/docs/docs/tutorials/multi_agent/assets/multi-output.png b/docs/docs/tutorials/multi_agent/assets/multi-output.png new file mode 100644 index 000000000..99afd27f9 Binary files /dev/null and b/docs/docs/tutorials/multi_agent/assets/multi-output.png differ diff --git a/docs/docs/tutorials/multi_agent/assets/output.png b/docs/docs/tutorials/multi_agent/assets/output.png new file mode 100644 index 000000000..99afd27f9 Binary files /dev/null and b/docs/docs/tutorials/multi_agent/assets/output.png differ diff --git a/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb b/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb index 3031fa74a..4222d111e 100644 --- a/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb +++ b/docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb @@ -49,7 +49,7 @@ "outputs": [], "source": [ "%%capture --no-stderr\n", - "%pip install -U langgraph langchain_community langchain_anthropic langchain_experimental" + "%pip install -U langgraph langchain_community langchain_anthropic langchain-tavily langchain_experimental" ] }, { @@ -121,10 +121,10 @@ "from typing import Annotated, List\n", "\n", "from langchain_community.document_loaders import WebBaseLoader\n", - "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "from langchain_tavily import TavilySearch\n", "from langchain_core.tools import tool\n", "\n", - "tavily_tool = TavilySearchResults(max_results=5)\n", + "tavily_tool = TavilySearch(max_results=5)\n", "\n", "\n", "@tool\n", diff --git a/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb b/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb index 6bdaf978e..223cb4fb6 100644 --- a/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb +++ b/docs/docs/tutorials/multi_agent/multi-agent-collaboration.ipynb @@ -37,7 +37,7 @@ "outputs": [], "source": [ "%%capture --no-stderr\n", - "%pip install -U langchain_community langchain_anthropic langchain_experimental matplotlib langgraph" + "%pip install -U langchain_community langchain_anthropic langchain-tavily langchain_experimental matplotlib langgraph" ] }, { @@ -92,11 +92,11 @@ "source": [ "from typing import Annotated\n", "\n", - "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "from langchain_tavily import TavilySearch\n", "from langchain_core.tools import tool\n", "from langchain_experimental.utilities import PythonREPL\n", "\n", - "tavily_tool = TavilySearchResults(max_results=5)\n", + "tavily_tool = TavilySearch(max_results=5)\n", "\n", "# Warning: This executes code locally, which can be unsafe when not sandboxed\n", "\n", diff --git a/docs/docs/tutorials/overview.md b/docs/docs/tutorials/overview.md deleted file mode 100644 index 5ecd968c0..000000000 --- a/docs/docs/tutorials/overview.md +++ /dev/null @@ -1,21 +0,0 @@ -# Examples - -The pages in this section provide end-to-end examples for the following topics: - -## General - -- [Agentic RAG](./rag/langgraph_adaptive_rag.ipynb) -- [Agent Supervisor](./multi_agent/agent_supervisor.ipynb) -- [SQL agent](./sql-agent.ipynb) -- [Graph runs in LangSmith](../how-tos/run-id-langsmith.ipynb) - -## LangGraph Platform - -- [Set up custom authentication](./auth/getting_started.md) -- [Make conversations private](./auth/resource_auth.md) -- [Connect an authentication provider](./auth/add_auth_server.md) -- [Rebuild graph at runtime](../cloud/deployment/graph_rebuild.md) -- [Use RemoteGraph](../how-tos/use-remote-graph.md) -- [Deploy CrewAI, AutoGen, and other frameworks](../how-tos/autogen-langgraph-platform.ipynb) -- [Integrate LangGraph into a React app](../cloud/how-tos/use_stream_react.md) -- [Implement Generative User Interfaces with LangGraph](../cloud/how-tos/generative_ui_react.md) \ No newline at end of file diff --git a/docs/docs/tutorials/rag/assets/agentic-rag-output.png b/docs/docs/tutorials/rag/assets/agentic-rag-output.png new file mode 100644 index 000000000..2efa13534 Binary files /dev/null and b/docs/docs/tutorials/rag/assets/agentic-rag-output.png differ diff --git a/docs/docs/tutorials/rag/assets/screenshot_2024_02_14_3_43_58_pm.png b/docs/docs/tutorials/rag/assets/screenshot_2024_02_14_3_43_58_pm.png new file mode 100644 index 000000000..65402f1e0 Binary files /dev/null and b/docs/docs/tutorials/rag/assets/screenshot_2024_02_14_3_43_58_pm.png differ diff --git a/docs/docs/tutorials/rag/langgraph_agentic_rag.ipynb b/docs/docs/tutorials/rag/langgraph_agentic_rag.ipynb deleted file mode 100644 index e9fe98d47..000000000 --- a/docs/docs/tutorials/rag/langgraph_agentic_rag.ipynb +++ /dev/null @@ -1,928 +0,0 @@ -{ - "cells": [ - { - "attachments": { - "7ad1a116-28d7-473f-8cff-5f2efd0bf118.png": { - "image/png": "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AQQQQAABBBBAgOAJ9wACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEBIgeBLCoIsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIEDzhHkAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEQgIET0IYdBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABgifcAwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBASIDgSQiDLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBA8IR7AAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAICRA8CWHQRQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQInnAPIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIhAYInIQy6CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggADBE+4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCAkQPAkhEEXAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECB4wj2AAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCIQECJ6EMOgigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgRPuAcQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgZAAwZMQBl0EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAgOAJ9wACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEBIgeBLCoIsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIEDzhHkAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEQgIET0IYdBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABgifcAwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBASIDgSQiDLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBA8IR7AAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAICRA8CWHQRQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQInnAPIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIhAYInIQy6CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggADBE+4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCAkQPAkhEEXAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECB4wj2AAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCIQECJ6EMOgigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgRPuAcQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgZAAwZMQBl0EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAgOAJ9wACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEBIgeBLCoIsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIEDzhHkAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEQgIET0IYdBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABgifcAwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBASIDgSQiDLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBA8IR7AAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAICRA8CWHQRQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQInnAPIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIhAYInIQy6CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggADBE+4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCAkQPAkhEEXAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECB4wj2AAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCIQECJ6EMOgigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgRPuAcQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgZAAwZMQBl0EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAgOAJ9wACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEBIgeBLCoIsAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIEDzhHkAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEQgIET0IYdBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABgifcAwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBASIDgSQiDLgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCBA8IR7AAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAICRA8CWHQRQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQInnAPIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIhAYInIQy6CCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggADBE+4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCAkkD/Up4sAAggggAACCCCAAAIIIIAAArkk8N5779n48ePt0EMPtWeffdby5897f6Lv2LHD7r77btu1a5c1a9bMunbtmks6uXOYjRs32gMPPBD3YHfddZfVrFkz7jJmIoAAAggggMCBL3DI31478C+TK0QAAQQQQAABBBBAAAEEEEBg7wssXbrUPvvsM5sxY4ZNnTrV1qxZY0ceeaT/OvHEE61t27bBSdx00002cOBAf3rmzJlWuHDhYFle6Wzbts3q1avnn85pp51mr7/++l49tVmzZlnPnj3jHuOQQw6xKlWqWO3ate3MM8/0+3FXzMLMFStWWKtWreJu8eWXX1rz5s3jLmMmAggggAACCBz4Annvay0HvjlXiAACCCCAAAIIIIAAAgggcAAKDBo0yLp162abNm2KurqxY8eaXn379rV7773XbrjhBlMggJZeYP369TZy5Mj0C2LmPP744/bwww/nOBOmaNGidsUVVwR7nzRpkk2ePDmYpoMAApkLzF2+yT7+ZbHNWLjRFixLse3bd1mVCkWsfrXidupRFa19w3KZ74ClvsD2nX/bzzNW+/0qZQpb/SrFkEEAgTwgQPAkD3wInAICCCCAAAIIIIAAAggggMD+LfDuu+/aQw89FFyEsjWOPfZYK1u2rI0ZM8Z++eUXf1mfPn2sc+fO/vxgZTpxBRo0aGBVq1YNlimLZ+LEicH0o48+ag0bNrQ2bdoE87LaKVasmPXo0SPYTJk1BE8CDjoIZCrQb/Qie+GzWenWWeQFVPQaOn65de5Uw+44q54XME63GjNCAms3brV7+0zx5xzbpJz16to0tJQuAgjsKwGCJ/tKnuMigAACCCCAAAIIIIAAAggcEALJycn21FNPBddy55132s03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IECgh8MffvihValSJdOzGzRokHXr1s02bdoUtZ6CB3r17dvX7r33Xrvhhhu8bw3vv18brlChQmBTunTpqGuNnVi3bp116dLFn33ppZfa448/HrvKbqezcrzd7mwfr6AH+gpOuTZp0iSbPHmym9wr7wsWLLCRI0cmtO+KFSsmtF5eWil//vx2/vnn+6/777/frrvuOhs9erT/c/jwww/7wcy8dL6cy+4Flq1LtUufHWspm7b7K+c79BBr4gUMWniv1vXLRO3g2ld+t+R/1rvyxJp22lHRgZUXB/1lP/2xxqqVL2zPXdkkats9PbF5606bPHudv9uSRQt4wZOcH+GkphUsJXW7TZidbNPmJJuycXSMi5781d67q5WVLZaU84OwBwQQyJYAwZNssbERAggggAACCCCAAAIIIIDA/iywatUqv26CrkFDEqnmSZky0Q/sYq9PdRYeeuihYHa9evXs2GOPNQ0pNGbMGPvll1/8ZX369LHOnTv784OV97POE0884QeClH1z1VVX7fWzz+3j7c0LKlasWFRWz+uvv77Xgyfh6+nQoYMVKFAgPCuqv79naSg49fbbb5syovRzN378eP+ljDHa/iPw3Fezg8BJMS8I0ffOllajbOG4FzB93nrb/k9NkNe/nZsuePLn4o22YGmKrduwNe72eX1mhZIF7bqTvYy9k81mLUmxa14cb6lekGb1uq32xuB5dv8Fh+f1S+D8EDhgBQieHLAfLReGAAIIIIAAAggggAACCCCQkYACIa5pCKPdBU6Sk5PtqaeecpvYnXfeaTfffLPly5c2pIrqpgwYMMAUBPj000/368CJLlKZOI899lhwvXu7k9vH29vXsy/3/+qrr5oCOAdyS0pKsptuuskPnug6X3vtNb/+yYF8zQfSta1ITrVRk1b6l1TIG5bq4/taW7niBRO6xOWrt9g0b5ivRjVKJLT+/rZS/arFrN+9re2inr/6GSgDf15iN59e10oU5hHu/vZZcr4HhgA/eQfG58hVIIAAAggggAACCCCAAAIIZEHg+++/D9a+8MILg35GHWUPuKG6lImhYElsUwH28847zzTEUGxT8EU1KaZPn24aYkkF2JUBcMEFF5i+SR/bvvrqK39dFa6/8sor/ToPymzR9nXr1rWTTz7ZOnXqFLuZP71r1y6/PoS+ka+6LPXr17czzjgj01okf/31lx/8ibfDs88+26/nEl6mOi9vvvmmPyslJSVYpHNUACm2de3a1cLDRWX1eLH707T28d133/nXqKHDGjZsaM2aNfOv9dBDD43aJHy++owKFixow4YNs59++sm0buPGje0///mPlSpVKmo7TUybNs2/VgXK9NkqG0c1bo4++mirUSPn9Q7SHXAfzFAGx4gRI/wMmeLFi/uGJ510UqZnktF9pmysl19+2f95kZHu1dimnyX9PMycOdNmzZrlZ38dfvjh/s+D6uYk0lRbSP6qyfLjjz+a6qLE+9lLZF+sk7sCb/wwPzjghR2qJxw4cRu9N3yBPX1FYzd5wL1XLVPYTmlT2b79ZakfQHnXu95bvAAKDQEEcl8g/W90uX8OHBEBBBBAAAEEEEAAAQQQQACBXBWYPXu2fzwNcRTvgXnsyajWiWvXX3+966Z7j/fwduLEif7QV3qA75rqo3z88cfWu3dv/8F8gwYN3CL//YcffrCBAwf6GSwlSpSwe+65J1iubT/66CO79dZb7a677grmq7N582a7++67LXy+CqL069cvasixqI28ifnz55sCRPHaEUcckS54snr16rjrz507N+78s846Kyp4ktXjxZ5X//79/doy4flu2DQ9lH/uuecsXKtF9u769MD9pZdeCoqOax96+P7ee+/ZN998Y1WrVg3v1g/OKJgVr6nGy4MPPmiFChWKt3i/mKdMlXBWlU568ODBmQ7Xltl9Juf/+7//869dtV9igycKRqkmkIIesU11iJ5//vl028Sup2kFvU4//fTgc125cuVuaxbF2w/zcl9g9JS0rBMd+ZL21bN8AiMnrrSUzjutWKG0zL/d7WBNyjbrP3qRTfcyVpZ4mSvVKxSxRjVL2CXtaljxDDI6vLIj9vHPi23c7LU2xxtKq3blonZWy8pWr2rx3R3O5q3YZF+MXWozF220lV5tlxoVi1pj73gqLl84KbFzvuL4mn7wRAcbOWUVwZPdqrMCAntHgODJ3nFlrwgggAACCCCAAAIIIIAAAnlUYP369cGZJfItd32j3T3obdeunam4eaJN37D/97//HWStKMukadOm/jf8tUz7vfbaa/0siHh1KvTQv1evXn52Sng7Hf/FF1+0c889189Ecefz1ltvRQVOlDWiwvUKDrgH2m7d8LvqtnTs2DGYtWTJEnMBpmBmqKPsBPdQfMuWLX7x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yodqiVQtGwmkL1gVGc7LnePO6H9W3WyrUykyVJ6Kw//yXKcMXy9d0yzYLqPOmpRttnpd2rBjZUtxb2fkxHwE9rYAmSd7W5j9I4AAAggggAACCCCAAAII5DmBq666yj744AP/vPr06WNnnXVWpt+Cb9KkiZ199tn29ddf+9vceOONdsopp1iHDh1MBdw3b97sP8j//fff7aSTTrJLL73UX++6666zL774wu/36NHDL5CtQMmECRNMx3XtP//5j+tm+/2II47ws030jX5lSdx999128cUXm7IH9G3/1157Le6+FWRRBk44MyWc1aEH/uH6Ii1atLDwkE/a6VFHHWXKAlAwqnPnzta1a1e/4LiOrQLrumYNeaWWneNpO3fM22+/3VxGiI7VvXt3UwBHzrp2NWUWqQh6Tppq0ihQoACKPAcMGGDHHHOMaQg2BU6ef/75YPdarswH3Se1atUK5qsTDjb07NnTX3b44Yfb6tWrbdq0af69ovPdU02ZUZllUimo1L59e79A/LXXXmu9evXyD6179p577jFlEukz/+ijj+KeUnbvM+1MPzfar+6T3r172+DBg+344483BTPlpyLy8+bNs3/9619BYCfuSXgz33777WDRTTfdFPTp5H2BJnVL2i9TVvvBiy/HLrVL2mU9S6yhV3ukcvnCtmzVlmB4rtgrr12lmE2elVak/d0RC+zm0+oGq/QeMj/o16sayVypXSEynNxnPy32z02BGNe+HLPEdaPelQ2jYI2GAJvsFYbXdZ3bqkrUOlmZ+Gj0omD1o+qXDvp0EEAgdwUO8X5pySBmmrsnwtEQQAABBBBAAAEEEEAAAQQQyE2B66+/3lRcW+20006zF154IdNvrycnJ9sjjzwSBEMyOtd27doFgRmt89hjj0UFSmK3u+uuu+zWW2+Nmq2HwQMHDvTnzZw5M+phuOq0tG7d2l92xRVXmIIyro0bN84uvPBCNxn1ruCFy3wIb7dt2zZ/eLGolTOZGD58uB+cCK+iIMAZZ5wRnhXVv/POO81l72TneNqZCzBoe12jyzqIOtA/E8rqUYDANdUnUVBLTeeh8wm3//73v+YygWToskUUcMooQ0JBJNVV0XBurt1www123333ucngXYG3jM739ddf9++/YOVsdHTvPvfccwltqYDaM88846+rYIWCTBkNt+aGt9O7PnfXMrvPwnVN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irglARIgARIggWgToHgSbXS8kARIgARIgARIgARIgARIgARIgARIgATijoARUFatWiV16tSJu4F4qOemTZtqy+PGjQvVQ4YMGfT4zJkzcvPmTds5E9IsU6ZMtjLukAAJkAAJkEB0CVA8iS45XkcCJEACJEACJEACJEACJEACJEACJEACcUwAAkpAQIAmV69UqVIcj8a93SOHSdWqVW3J4E3ryP2SMmVKPVy4cKFuEcYLieJh+fLl0y3fSIAESIAESCAmBCiexIQeryUBEiABEiABEiABEiABEiABEiABEiCBOCZw+PBhSZUqlZw6dUpM6Ko4HpLbum/ZsmWYthIkSCC9evXS8h49esirr74qpUuX1mTxEFxq1aoV5hoWkAAJkAAJkEBUCVA8iSox1icBEiABEiABEiABEiABEiABEiABEiABLyOAvCAIZ3Xnzh3JkSOHXL9+3ctGGPlwIIrAEib8Z7mqcuXKAk8Tx3KIKr1791YPlJ07d+r5ChUqyJQpUyRx4sR6zDcSIAESIAESiAmBf34bxaQVXksCJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACfkIgwRPL/GQunAYJkAAJkAAJkAAJkAAJkAAJkAAJkAAJxGsCL774ophE8mvWrJFs2bL5NQ8sa50/f15Sp04tyZMn9+u5cnIkQAIkQAKxS4CeJ7HLm72RAAmQAAmQAAmQAAmQAAmQAAmQAAmQgMcI/P7771KoUCFt//nnnxeE83LVOnXqJCNHjnS1ulfUQ6ivTJkyUTjxirvBQZAACZCAfxGgeOJf95OzIQESIAESIAESIAESIAESIAESIAESiOcEFi9erAnUgaF27dqydu1al4js2LFDvvjiC1mxYoVL9VmJBEiABEiABPyZAMUTf767nBsJkAAJkAAJWATwBCGShtJIgARIgARIgARIgATiD4E5c+bIc889pxNu0aKFQFCJzHr16qVVhg4dqonnI6vP8yRAAiRAAiTgzwQonvjz3eXcSIAESIAE4jWBZcuWSYECBeSXX37RJw7jNQxOngRIgARIgARIgATiIYHJkydLtWrVdObvvPOOTJs2LUIKr776qhQrVkxDff3vf/+LsC5PkgAJkAAJkIC/E2DCeH+/w5wfCZAACZBAvCJw7949wVOGeK1fv17nHhAQIIcPH45XHDhZEiABEiAB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EaIrPJEQizoQT9AvBEXjSYDrkZPiypUruvCDfjAubGPTwARzhUCA8YVn8JhAPHnk08A4w5tveNdHt9zV8UXWPoQe5IHBE8q4J2CPe4EX7o2joT5CvSGRu73njmM9V48hKEEsAmd8xhz7hOM9PicQsOxDpzm272o9c50rn1FTl1sSIAES8GYCeDAHeczgjWJv+J2NhyLsDWIKwjTSSIAESIAESMAfCVA88ce7yjmRAAmQAAn4PAF74WTmzJlStmzZMHP6+eef9elvnEDcaTyxTyMBEiABEiABEiABEiABdxCApyT+3lywYIF69TlrE96YyHdGIwESIAESIAF/JEDxxB/vKudEAiRAAiTg0wTshZOJEydq7H5nE0LYHPxDW716dc2J4KwOy0iABEiABEiABEiABEggpgTgiYJcVwgja2/wKjQhIu3LuU8CJEACJEAC/kAgrN+8P8yKcyABEiABEiABHyVgL5wgnwmSdDozhOpasmSJnqpbt66zKiwjARIgARIgARIgARIgAbcQaNCggYwbN05z7XXq1MkW+hJhEvv06eOWPtgICZAACZAACXgbAYon3nZHOB4SIAESIIF4S2D06NEycuRInT/24VESniGBNvI/IFFx/fr1w6vGchIgARIgARIgARIgARJwGwEkle/Zs6ccOHBASpcure1CQKGRAAmQAAmQgD8SSOSPk+KcSIAESIAESMDXCMDLZMiQITrs4cOHS506dSKcggmZ0Lhx4wjr8SQJkAAJkAAJkAAJkAAJeIIAQnnBazpBggSeaJ5tkgAJkAAJkECcE2DOkzi/BRwACZAACZBAfCcwYcIE+c9//qMYBg0aJC1btowQyeXLl6VUqVISEhIiixYtktSpU0dYnydJgARIgARIgARIgARIgARIgARIgARIgASiRoCeJ1HjxdokQAIkQAIk4FYCM2bMsAkniBcdmXCCzpMnTy5FihTRsF4UTtx6O9gYCZAACZAACZAACZAACZAACZAACZAACSgBep7wg0ACJEACJEACcURg/vz58u6772rvH3zwgXTu3DmORsJuSYAESIAESIAESIAESIAESIAESIAESIAE7AkwYbw9De6TAAmQAAmQQCwRWLp0qU046dq1K4WTWOLObkiABEiABEiABEiABEiABEiABEiABEjAFQIUT1yhxDokQAIkQAIk4EYCq1atkrff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O27cuFA0MmTIoMdnzpyRmzdv2s7t27dP9zNlymQr4w4JkAAJkAAJkAAJkAAJuJMAPU/cSZNtkQAJkAAJOBKgeOJIhMckQAIkQAIk4GECAQEBAgElV65c2pMvCCjIYVK1alXZs2dPKDrBwcEa0guFCxcu1HMI47VixQrdN142esA3EiABEiABEiABEiABEnADAeN54oam2AQJkAAJkAAJhEuA4km4aHiCBEiABEiABDxHIHHixJpcPSYCyvr16z03QCctt2zZMkwpnvbr1auXlvfo0UNeffVVKV26tCaLh+BSq1atMNewgARIgARIgARIgARIgARiQsCIJ/Q8iQlFXksCJEACJBAZAYonkRHieRIgARIgARLwEIFkyZLJggULbMnj4YHy+PFjl3qbPXu2NGvWTCZPnuxS/ahWMv+IJkz4z58KlStXFniawOzLIar07t1bPVB27typ5ytUqCBTpkwRiEQ0EiABEiABEiABEiABEiABEiABEiABEvA1Agkstf6Jrw2a4yUBEiABEiABfyJw/fp19dg4fvy4Tmv37t22UFjhzfPy5ctSqlQpKVasmAow4dWLzXL8SXH+/HlJnTq1JE+ePDa7Zl8kQAIkQAIkQAIkQALxiECHDh00DG7hwoVl0aJF8WjmnCoJkAAJkEBsEvjncdLY7JV9kQAJkAAJkAAJ2AhAbJg/f76EhIRoGf4JRN6QiCwoKEjatm0rO3bs8Jj3SUT9OzsHbxUkiKdw4owOy0iABEiABEiABEiABNxFgM8Bu4sk2yEBEiABEoiIAMWTiOj8fe727dvStWtXjen+8OFDF64Q+fbbb+Wjjz4SPBlMIwESIAESIIHICKRLl04FlKxZs2pV5A05ffp0hJfVq1dPz8+dOzfCejxJAiRAAiRAAiRAAiRAAv5EwIgnJtSsP82NcyEBEiABEvAeAl4vnkCsQAx480IM9Xbt2skPP/wgrgoZMcW9efNmmTdvnsZu37dvn0vNLV68WCZOnCg3b950qb4nK125ckVj0X/99dee7MZv2541a5by279/v9/OkRMjARLwDgLIJwIhJEuWLDqgihUryuHDh8MdHMJ24bVhwwZZs2ZNuPV4ggRIgARIgARIgARIgAT8iQDFE3+6m5wLCZAACXgvAa8XT+zRlShRQhAX/tdff5V+/fpJw4YN5erVq/ZVPLJftmxZady4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q9/RaOsFFKlAMiOAAALlVEDTYfqk/6eTEEg0gUfenR8JnKQHQYiXbuhlLeulRW3m3OVbbcnKre6atpef3Npq18gJKCgQ46/v2rvPMqz4fweM2pBSOtmwVqr9f/3bmvU3m7ci6N/jU2xnEKRZv3GXPTNmkd16DiPFSomeYhFAAAEEChBg2q4CcLiEAAIIIFBsgYRf8fGTTz6xVq1auY+mAVm5cqVddNFFdthhh7kpPl5//fUIgl78a5op5evRo4fbDhw40M2p7jOdcsopriyNOlHSNFy+fG2/+uorn9XVE76mfb28DyetgeLzXHXVVTZp0iQ76aST7PDDD7cLLrjAHfv8O3bscHO+t2nTxo488khr166dXXnllaZAj0+aFz5vO3Tt008/dec1J7xPK1assIsvvtjat2/vymvdurU98sgjpmDKgSQt6KspyY466ijn+8EHH0QtRvPVaxFfTadyxBFHOGe55/3GhwIIt912m7uufMp/xhln2Pjx4yPl+v4uX748ck7tkMGLL77ozqk+HWuKNT13fZ5//nk75phjrFu3bpF59H0BGinSr18/15fu3bu734V///vf/rLb6lmpTP1+9enTx/VDjg8++GAkX1F+VxRIuvvuu11fNc9/7969rWfPnm5U08yZMyNlsoMAAgggkCPQuHHjyEH4zwF/koCKl2BbFgJrsnbaF9PXuqqrBdNSvTnsqHwDJ9HaN/LrFdFOl4tzHZul2/CbjzKNxFF6/6sVpunNSAgggAACCMRLwL9/IHgSL3HqQQABBCqmQMIHT/RiRS/q69Wr50YcPPPMM6ZRHb/+9a9Nc6ffeuuttmTJEvf0RowY4V7Wa/FZvbjWXO2zZs1y92uEgtKJJ57ojps0aeKO9QJe5ftPeB53BRHOOuss93GZgx/+D2h/rGCD7lVasGCBPf7449aiRQv38vybb74xvaT36eabb7ZXXnnFHfbt29eNilGA4rrrrvNZTMEeJU2VEk4ff/yxO9Q0Y0q7du1yC/BOmDDBlaPylB577DF77rnn3H5Rfig4c/vttztj9Ud2f/3rX/crQgGgs88+2yZPnuyudejQwd2jIMk777wTya8g04UXXuiCWf55KO+MGTPcosDaKvlAT9jVvyzbt2+fy+OPx40b5567TipQcf7557vrMtUIE6V58+a58wsXLrS2bdu64IqCU1dffbVN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gAACCCCAAAIIIIAAAggggAACCCCAQL4CBE/ypeECAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIVEQBgicV8anTZwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEMhXgOBJvjRcQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgYooQPCkIj51+owAAggggAACCCCAAAIIIIAAAggggAACCCCAAAL5ChA8yZeGCwgggAACCCCAAAIIlH+B7du327XXXmvDhg2zvXv3lv8O00MEEEAAAQQQQAABBBBAIAaBKjHkIQsCCCCAAAIIIIAAAggEAgsWLLATTjghl0W9evWsW7dudtVVV1nPnj1zXUuGgylTpti7777rmjpkyBA75JBD9mv23//+d8vKyrI777zTUlJS9rvOCQQQQAABBBBAAAEEEECgvAkc9N8glbdO0R8EEEAAAQQQQAABBEpDYN68eXbyySdbjRo1rH379q6KGTNmRKoaPXq0de/ePXKcDDs7duywv/zlL1atWjW76667rHLlyvs1u3fv3rZq1SqbPXu26/t+GTiBAAIIIIAAAggggAACCJQzAabtKmcPlO4ggAACCCCAAAIIlL7AgAED7L333nOfWbNm2Xnnnecqfe6556JWvmHDBtu2bVvUa/E4uXHjxnyrSUtLs4cfftjuvffeqIGTfG/M58KePXtszZo1xne08gHiNAIIIIAAAggggAACCCSFAMGTpHhMNBIBBBBAAAEEEEAgUQUyMjLskksucc3TyBSfFDx47bXXrEuXLtajRw+3HThwoP3www8+S8xbldGvXz+X//7777dWrVrZxx9/7NYo0b5Ghijdc8897prOaRqxSZMm2UknnWSHH364XXDBBe7YZQx+XHTRRZG8yq9PeM0TBXz8eY06UVI7/DltNWrFpxUrVtjFF1/sRuQceeSR1rp1a3vkkUdMwRQSAggggAACCCCAAAIIIJBsAqx5kmxPjPYigAACCCCAAAIIJJyARlootW3bNtK2ESNG2G233eaOtRbK2rVrzY9S+eabb6xmzZqRvIXtaF2VhQsXumxad0Vp8eLFtn79erffokULt9V6JRoFM3LkSLc+y+OPP266pvtVpwIq3333nct71FFHWf369d3+O++847bh0SKaxsuPqFF5SoMGDcq15kmVKtn/nNi1a5edc845bmovTWmm/k6YMMEee+wxNx3YlVde6e7nBwIIIIAAAggggAACCCCQLAIET5LlSdFOBBBAAAEEEEAAgYQR0KiMadOm2c8//2zff/+9vfDCC65tfgSIghAPPvigO/fmm2+6kSH79u2zW265xXSsKb808mP48OH24osv5tuv6tWru7wa5bF06VI39ddPP/3k8it4sm7dOrffrl07tz3rrLNMHwU75syZY5dddpndcccdproV2FG7N23aZLVq1bJrrrkmUu8nn3yy37RiCoI89NBDLs+XX37pAiP33Xdf1DVPtOC8Rqf07dvXnn/+eRdgUft0/M9//tMInkSo2UEAAQQQQAABBBBAAIEkESB4kiQPimYigAACCCCAAAIIJI6ARlXoE06nnnqqmxpL5zIzM12gokmTJqbPkiVLXFZNn6XgyaJFi9yxpsnaunWr24/2Q0EPpaZNm7qtgiUagXLuuee6MnzwRFNkRUuDBw92p7UI/BtvvGFbtmyx1NTUaFmLde7HH3909ytY4qf4Ouigg1zARu2VR926dYtVBzcjgAACCCCAAAIIIIAAAvEUIHgST23qQgABBBBAAAEEECgXAh06dLAzzjjD9eXpp592ozY0qkSjNZR8UEOBhOOOO86dC//Q6A8lrRGiT2GpWbNmLotfL+WEE06w22+/PVKPRqZESy1btoycPuaYYyL7Jb2zevVqV+Rdd91l+uRNCtoQPMmrwjECCCCAAAIIIIAAAggksgDBk0R+OrQNAQQQQAABBBBAICEFunbtatdee61rm0aHPProo/bEE0/YAw884M5ptIlPmr4rJSXFH7ptfsGOXJlCB748rVeiAM1hhx3mRrb4dVDCQZLQbSU+ykSjZHyAKFxP8+bN3eGAAQPstNNOC19y+w0bNtzvHCcQQAABBBBAAAEEEEAAgUQWIHiSyE+HtiGAAAIIIIAAAggkvIBGjih4oum4tLaHptDSmiIKaGidEo3KuPrqq61SpUoH3JfGjRu7e7XouxaF98GUSZMmufM+eHHAFRRyoxad1yiasWPH2oUXXrhfbgWTlLQ2yj333GMES/Yj4gQCCCCAAAIIIIAAAggkmQDBkyR7YDQXAQQQQAABBBBAILEE6tWrZ5dffrk999xzbnF0v8j6vffea0OGDLGHH37YNLVX//79LT093QVUnnrqqagjOPLrWaNGjdylWbNmuYXm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" - } - }, - "cell_type": "markdown", - "id": "46397e48-aba2-4bd3-bb31-d840f2fcbda4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "# Agentic RAG\n", - "\n", - "In this tutorial we will build a [retrieval agent](https://python.langchain.com/docs/tutorials/qa_chat_history). Retrieval agents are useful when you want an LLM to make a decision about whether to retrieve context from a vectorstore or respond to the user directly.\n", - "\n", - "By the end of the tutorial we will have done the following:\n", - "\n", - "1. Fetch and preprocess documents that will be used for retrieval.\n", - "2. Index those documents for semantic search and create a retriever tool for the agent.\n", - "3. Build an agentic RAG system that can decide when to use the retriever tool.\n", - "\n", - "![Screenshot 2024-02-14 at 3.43.58 PM.png](attachment:7ad1a116-28d7-473f-8cff-5f2efd0bf118.png)\n", - "\n", - "## Setup\n", - "\n", - "Let's download the required packages and set our API keys:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "969fb438", - "metadata": {}, - "outputs": [], - "source": [ - "%%capture --no-stderr\n", - "%pip install -U --quiet langgraph \"langchain[openai]\" langchain-community langchain-text-splitters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e4958a8c", - "metadata": {}, - "outputs": [], - "source": [ - "import getpass\n", - "import os\n", - "\n", - "\n", - "def _set_env(key: str):\n", - " if key not in os.environ:\n", - " os.environ[key] = getpass.getpass(f\"{key}:\")\n", - "\n", - "\n", - "_set_env(\"OPENAI_API_KEY\")" - ] - }, - { - "cell_type": "markdown", - "id": "3d07e8d4", - "metadata": {}, - "source": [ - "
\n", - "

Set up LangSmith for LangGraph development

\n", - "

\n", - " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", - "

\n", - "
" - ] - }, - { - "cell_type": "markdown", - "id": "c74e4532", - "metadata": {}, - "source": [ - "## 1. Preprocess documents\n", - "\n", - "1\\. Fetch documents to use in our RAG system. We will use three of the most recent pages from [Lilian Weng's excellent blog](https://lilianweng.github.io/). We'll start by fetching the content of the pages using `WebBaseLoader` utility:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "53ff068e-053f-41da-a8b5-b23efc2442fd", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "from langchain_community.document_loaders import WebBaseLoader\n", - "\n", - "urls = [\n", - " \"https://lilianweng.github.io/posts/2024-11-28-reward-hacking/\",\n", - " \"https://lilianweng.github.io/posts/2024-07-07-hallucination/\",\n", - " \"https://lilianweng.github.io/posts/2024-04-12-diffusion-video/\",\n", - "]\n", - "\n", - "docs = [WebBaseLoader(url).load() for url in urls]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "0e027561-c144-469c-913d-c3d8295500ed", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\"Reward Hacking in Reinforcement Learning | Lil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nLil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n|\\n\\n\\n\\n\\n\\n\\nPosts\\n\\n\\n\\n\\nArchive\\n\\n\\n\\n\\nSearch\\n\\n\\n\\n\\nTags\\n\\n\\n\\n\\nFAQ\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n Reward Hacking in Reinforcement Learning\\n \\nDate: November 28, 2024 | Estimated Reading Time: 37 min | Author: Lilian Weng\\n\\n\\n \\n\\n\\nTable of Contents\\n\\n\\n\\nBackground\\n\\nReward Function in RL\\n\\nSpurious Correlation\\n\\n\\nLet’s Define Reward Hacking\\n\\nList of Examples\\n\\nReward hacking examples in RL tasks\\n\\nReward hacking examples in LLM tasks\\n\\nReward hacking examples in real life\\n\\n\\nWhy does Reward Hacking Exist?\\n\\n\\nHacking RL Environment\\n\\nHacking RLHF of LLMs\\n\\nHacking the Training Process\\n\\nHacking the Evaluator\\n\\nIn-Context Reward Hacking\\n\\n\\nGeneralization of Hacking Skills\\n\\nPeek into Mitigations\\n\\nRL Algorithm Improvement\\n\\nDetecting Reward Hacking\\n\\nData Analysis of RLHF\\n\\n\\nCitation\\n\\nReferences\\n\\n\\n\\n\\n\\nReward hacking occurs when a reinforcement learning (RL) agent exploits flaws or ambiguities in the reward function to ac\"" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "docs[0][0].page_content.strip()[:1000]" - ] - }, - { - "cell_type": "markdown", - "id": "ca258767-ce4f-4eaa-8ae5-25e9361675e1", - "metadata": {}, - "source": [ - "2\\. Split the fetched documents into smaller chunks for indexing into our vectorstore:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "24d2cefd-d0f0-44ae-aa4b-0436a675dc56", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", - "\n", - "docs_list = [item for sublist in docs for item in sublist]\n", - "\n", - "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", - " chunk_size=100, chunk_overlap=50\n", - ")\n", - "doc_splits = text_splitter.split_documents(docs_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "a82479d9-e7d3-481f-893d-0a95c404f0bf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\"Reward Hacking in Reinforcement Learning | Lil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nLil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n|\\n\\n\\n\\n\\n\\n\\nPosts\\n\\n\\n\\n\\nArchive\\n\\n\\n\\n\\nSearch\\n\\n\\n\\n\\nTags\\n\\n\\n\\n\\nFAQ\"" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "doc_splits[0].page_content.strip()" - ] - }, - { - "cell_type": "markdown", - "id": "c5e7b434-c4c3-4a42-aa4e-2a0bb1e7a2a0", - "metadata": {}, - "source": [ - "## 2. Create a retriever tool" - ] - }, - { - "cell_type": "markdown", - "id": "732d6512-51af-426d-995f-98ae72eff4af", - "metadata": {}, - "source": [ - "Now that we have our split documents, we can index them into a vector store that we'll use for semantic search. \n", - "\n", - "1\\. Use an in-memory vector store and OpenAI embeddings:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "e50c9efe-4abe-42fa-b35a-05eeeede9ec6", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_core.vectorstores import InMemoryVectorStore\n", - "from langchain_openai import OpenAIEmbeddings\n", - "\n", - "vectorstore = InMemoryVectorStore.from_documents(\n", - " documents=doc_splits, embedding=OpenAIEmbeddings()\n", - ")\n", - "retriever = vectorstore.as_retriever()" - ] - }, - { - "cell_type": "markdown", - "id": "225d2277-45b2-4ae8-a7d6-62b07fb4a002", - "metadata": {}, - "source": [ - "2\\. Create a retriever tool using LangChain's prebuilt `create_retriever_tool`:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "0b97bdd8-d7e3-444d-ac96-5ef4725f9048", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.tools.retriever import create_retriever_tool\n", - "\n", - "retriever_tool = create_retriever_tool(\n", - " retriever,\n", - " \"retrieve_blog_posts\",\n", - " \"Search and return information about Lilian Weng blog posts.\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "9cfdc027-5ea8-42ba-b0f4-0590505d76ff", - "metadata": {}, - "source": [ - "3\\. Test the tool:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "58c17a90-9a85-46c9-96a9-1e7b224330c4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(Note: Some work defines reward tampering as a distinct category of misalignment behavior from reward hacking. But I consider reward hacking as a broader concept here.)\\nAt a high level, reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering.\\n\\nWhy does Reward Hacking Exist?#\\n\\nPan et al. (2022) investigated reward hacking as a function of agent capabilities, including (1) model size, (2) action space resolution, (3) observation space noise, and (4) training time. They also proposed a taxonomy of three types of misspecified proxy rewards:\\n\\nLet’s Define Reward Hacking#\\nReward shaping in RL is challenging. Reward hacking occurs when an RL agent exploits flaws or ambiguities in the reward function to obtain high rewards without genuinely learning the intended behaviors or completing the task as designed. In recent years, several related concepts have been proposed, all referring to some form of reward hacking:'" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "retriever_tool.invoke({\"query\": \"types of reward hacking\"})" - ] - }, - { - "cell_type": "markdown", - "id": "7c4e9e70-3de1-4ab4-ab42-c298cef00eb6", - "metadata": {}, - "source": [ - "## 3. Generate query" - ] - }, - { - "cell_type": "markdown", - "id": "2ba89a91-3dc5-4663-a6a5-43ccb2575849", - "metadata": {}, - "source": [ - "Now we will start building components ([nodes](../../../concepts/low_level#nodes) and [edges](../../../concepts/low_level#edges)) for our agentic RAG graph. Note that the components will operate on the [`MessagesState`](../../../concepts/low_level#messagesstate) — graph state that contains a `messages` key with a list of [chat messages](https://python.langchain.com/docs/concepts/messages/).\n", - "\n", - "1\\. Build a `generate_query_or_respond` node. It will call an LLM to generate a response based on the current graph state (list of messages). Given the input messages, it will decide to retrieve using the retriever tool, or respond directly to the user. Note that we're giving the chat model access to the `retriever_tool` we created earlier via `.bind_tools`:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "32f21d6f-9d0e-44e1-8edd-1fd903164d6d", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.graph import MessagesState\n", - "from langchain.chat_models import init_chat_model\n", - "\n", - "response_model = init_chat_model(\"openai:gpt-4.1\", temperature=0)\n", - "\n", - "\n", - "def generate_query_or_respond(state: MessagesState):\n", - " \"\"\"Call the model to generate a response based on the current state. Given\n", - " the question, it will decide to retrieve using the retriever tool, or simply respond to the user.\n", - " \"\"\"\n", - " response = (\n", - " response_model\n", - " # highlight-next-line\n", - " .bind_tools([retriever_tool]).invoke(state[\"messages\"])\n", - " )\n", - " return {\"messages\": [response]}" - ] - }, - { - "cell_type": "markdown", - "id": "552e0f6c-5af5-4c13-91a6-437f320a4ed6", - "metadata": {}, - "source": [ - "2\\. Try it on a random input:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "5cdc7e76-8680-42e6-9cdb-44aa4104f0f7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Hello! How can I help you today?\n" - ] - } - ], - "source": [ - "input = {\"messages\": [{\"role\": \"user\", \"content\": \"hello!\"}]}\n", - "generate_query_or_respond(input)[\"messages\"][-1].pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "df45f7c8-df6c-4687-9f25-0357e29532cb", - "metadata": {}, - "source": [ - "3\\. Ask a question that requires semantic search:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "845e1bca-3097-423f-a9c8-967fe1216375", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " retrieve_blog_posts (call_tYQxgfIlnQUDMdtAhdbXNwIM)\n", - " Call ID: call_tYQxgfIlnQUDMdtAhdbXNwIM\n", - " Args:\n", - " query: types of reward hacking\n" - ] - } - ], - "source": [ - "input = {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " }\n", - " ]\n", - "}\n", - "generate_query_or_respond(input)[\"messages\"][-1].pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "3e4756cb-b952-47a7-be4a-4f8a0866b67f", - "metadata": {}, - "source": [ - "## 4. Grade documents" - ] - }, - { - "cell_type": "markdown", - "id": "0b278967-18ab-409e-9ca4-6ee44a23e708", - "metadata": {}, - "source": [ - "1\\. Add a [conditional edge](../../../concepts/low_level#conditional-edges) — `grade_documents` — to determine whether the retrieved documents are relevant to the question. We will use a model with a structured output schema `GradeDocuments` for document grading. The `grade_documents` function will return the name of the node to go to based on the grading decision (`generate_answer` or `rewrite_question`):" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "98f0e1a5-5ca8-4d8c-a94c-fc0976ae1937", - "metadata": {}, - "outputs": [], - "source": [ - "from pydantic import BaseModel, Field\n", - "from typing import Literal\n", - "\n", - "GRADE_PROMPT = (\n", - " \"You are a grader assessing relevance of a retrieved document to a user question. \\n \"\n", - " \"Here is the retrieved document: \\n\\n {context} \\n\\n\"\n", - " \"Here is the user question: {question} \\n\"\n", - " \"If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\"\n", - " \"Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\n", - ")\n", - "\n", - "\n", - "# highlight-next-line\n", - "class GradeDocuments(BaseModel):\n", - " \"\"\"Grade documents using a binary score for relevance check.\"\"\"\n", - "\n", - " binary_score: str = Field(\n", - " description=\"Relevance score: 'yes' if relevant, or 'no' if not relevant\"\n", - " )\n", - "\n", - "\n", - "grader_model = init_chat_model(\"openai:gpt-4.1\", temperature=0)\n", - "\n", - "\n", - "def grade_documents(\n", - " state: MessagesState,\n", - ") -> Literal[\"generate_answer\", \"rewrite_question\"]:\n", - " \"\"\"Determine whether the retrieved documents are relevant to the question.\"\"\"\n", - " question = state[\"messages\"][0].content\n", - " context = state[\"messages\"][-1].content\n", - "\n", - " prompt = GRADE_PROMPT.format(question=question, context=context)\n", - " response = (\n", - " grader_model\n", - " # highlight-next-line\n", - " .with_structured_output(GradeDocuments).invoke(\n", - " [{\"role\": \"user\", \"content\": prompt}]\n", - " )\n", - " )\n", - " score = response.binary_score\n", - "\n", - " if score == \"yes\":\n", - " return \"generate_answer\"\n", - " else:\n", - " return \"rewrite_question\"" - ] - }, - { - "cell_type": "markdown", - "id": "ddbdc0c2-6f0c-41ec-b4d1-ad20d4498006", - "metadata": {}, - "source": [ - "2\\. Run this with irrelevant documents in the tool response:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "0a62e5f7-4c4e-44cd-b4bd-77b6879ce970", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'rewrite_question'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from langchain_core.messages import convert_to_messages\n", - "\n", - "input = {\n", - " \"messages\": convert_to_messages(\n", - " [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"\",\n", - " \"tool_calls\": [\n", - " {\n", - " \"id\": \"1\",\n", - " \"name\": \"retrieve_blog_posts\",\n", - " \"args\": {\"query\": \"types of reward hacking\"},\n", - " }\n", - " ],\n", - " },\n", - " {\"role\": \"tool\", \"content\": \"meow\", \"tool_call_id\": \"1\"},\n", - " ]\n", - " )\n", - "}\n", - "grade_documents(input)" - ] - }, - { - "cell_type": "markdown", - "id": "ba25a787-004e-4e6c-8f22-62087af7da1d", - "metadata": {}, - "source": [ - "3\\. Confirm that the relevant documents are classified as such:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "8bd5d24b-f05e-47c4-b954-267ab514a090", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'generate_answer'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "input = {\n", - " \"messages\": convert_to_messages(\n", - " [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"\",\n", - " \"tool_calls\": [\n", - " {\n", - " \"id\": \"1\",\n", - " \"name\": \"retrieve_blog_posts\",\n", - " \"args\": {\"query\": \"types of reward hacking\"},\n", - " }\n", - " ],\n", - " },\n", - " {\n", - " \"role\": \"tool\",\n", - " \"content\": \"reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering\",\n", - " \"tool_call_id\": \"1\",\n", - " },\n", - " ]\n", - " )\n", - "}\n", - "grade_documents(input)" - ] - }, - { - "cell_type": "markdown", - "id": "4c337d45-bc35-4e88-8b27-ebc6631f9fed", - "metadata": {}, - "source": [ - "## 5. Rewrite question" - ] - }, - { - "cell_type": "markdown", - "id": "e8d67fdf-0b77-4b90-97f2-63a571c3e496", - "metadata": {}, - "source": [ - "1\\. Build the `rewrite_question` node. The retriever tool can return potentially irrelevant documents, which indicates a need to improve the original user question. To do so, we will call the `rewrite_question` node:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "278d1d83-dda6-4de4-bf8b-be9965c227fa", - "metadata": {}, - "outputs": [], - "source": [ - "REWRITE_PROMPT = (\n", - " \"Look at the input and try to reason about the underlying semantic intent / meaning.\\n\"\n", - " \"Here is the initial question:\"\n", - " \"\\n ------- \\n\"\n", - " \"{question}\"\n", - " \"\\n ------- \\n\"\n", - " \"Formulate an improved question:\"\n", - ")\n", - "\n", - "\n", - "def rewrite_question(state: MessagesState):\n", - " \"\"\"Rewrite the original user question.\"\"\"\n", - " messages = state[\"messages\"]\n", - " question = messages[0].content\n", - " prompt = REWRITE_PROMPT.format(question=question)\n", - " response = response_model.invoke([{\"role\": \"user\", \"content\": prompt}])\n", - " return {\"messages\": [{\"role\": \"user\", \"content\": response.content}]}" - ] - }, - { - "cell_type": "markdown", - "id": "1ec05f29-48a2-4325-8c56-da60490f2a60", - "metadata": {}, - "source": [ - "2\\. Try it out:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "15404075-b7c8-4248-84d3-ca2b361aa3d2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "What are the different types of reward hacking described by Lilian Weng, and how does she explain them?\n" - ] - } - ], - "source": [ - "input = {\n", - " \"messages\": convert_to_messages(\n", - " [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"\",\n", - " \"tool_calls\": [\n", - " {\n", - " \"id\": \"1\",\n", - " \"name\": \"retrieve_blog_posts\",\n", - " \"args\": {\"query\": \"types of reward hacking\"},\n", - " }\n", - " ],\n", - " },\n", - " {\"role\": \"tool\", \"content\": \"meow\", \"tool_call_id\": \"1\"},\n", - " ]\n", - " )\n", - "}\n", - "\n", - "response = rewrite_question(input)\n", - "print(response[\"messages\"][-1][\"content\"])" - ] - }, - { - "cell_type": "markdown", - "id": "55eab9fe-f1d6-4ad3-93d6-4638a92c9395", - "metadata": {}, - "source": [ - "## 6. Generate an answer" - ] - }, - { - "cell_type": "markdown", - "id": "d9362002-e66e-4e58-90af-d225c184b5d1", - "metadata": {}, - "source": [ - "1\\. Build `generate_answer` node: if we pass the grader checks, we can generate the final answer based on the original question and the retrieved context:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "20b0e60a-a5aa-4e95-a15a-2c91382e508f", - "metadata": {}, - "outputs": [], - "source": [ - "GENERATE_PROMPT = (\n", - " \"You are an assistant for question-answering tasks. \"\n", - " \"Use the following pieces of retrieved context to answer the question. \"\n", - " \"If you don't know the answer, just say that you don't know. \"\n", - " \"Use three sentences maximum and keep the answer concise.\\n\"\n", - " \"Question: {question} \\n\"\n", - " \"Context: {context}\"\n", - ")\n", - "\n", - "\n", - "def generate_answer(state: MessagesState):\n", - " \"\"\"Generate an answer.\"\"\"\n", - " question = state[\"messages\"][0].content\n", - " context = state[\"messages\"][-1].content\n", - " prompt = GENERATE_PROMPT.format(question=question, context=context)\n", - " response = response_model.invoke([{\"role\": \"user\", \"content\": prompt}])\n", - " return {\"messages\": [response]}" - ] - }, - { - "cell_type": "markdown", - "id": "8f59a1fc-fe75-4907-ae86-0dd33c4d9a7f", - "metadata": {}, - "source": [ - "2\\. Try it:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "15d84cb0-b529-49d0-b18e-1d03ff3f7c0d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Lilian Weng says that reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering. These categories describe different ways in which an agent might exploit flaws in the reward system. Environment or goal misspecification involves unintended behaviors due to poorly specified objectives, while reward tampering involves directly manipulating the reward signal.\n" - ] - } - ], - "source": [ - "input = {\n", - " \"messages\": convert_to_messages(\n", - " [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"\",\n", - " \"tool_calls\": [\n", - " {\n", - " \"id\": \"1\",\n", - " \"name\": \"retrieve_blog_posts\",\n", - " \"args\": {\"query\": \"types of reward hacking\"},\n", - " }\n", - " ],\n", - " },\n", - " {\n", - " \"role\": \"tool\",\n", - " \"content\": \"reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering\",\n", - " \"tool_call_id\": \"1\",\n", - " },\n", - " ]\n", - " )\n", - "}\n", - "\n", - "response = generate_answer(input)\n", - "response[\"messages\"][-1].pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "955882ef-7467-48db-ae51-de441f2fc3a7", - "metadata": {}, - "source": [ - "## 7. Assemble the graph\n", - "\n", - "* Start with a `generate_query_or_respond` and determine if we need to call `retriever_tool`\n", - "* Route to next step using `tools_condition`:\n", - " * If `generate_query_or_respond` returned `tool_calls`, call `retriever_tool` to retrieve context \n", - " * Otherwise, respond directly to the user\n", - "* Grade retrieved document content for relevance to the question (`grade_documents`) and route to next step:\n", - " * If not relevant, rewrite the question using `rewrite_question` and then call `generate_query_or_respond` again\n", - " * If relevant, proceed to `generate_answer` and generate final response using the `ToolMessage` with the retrieved document context" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "8718a37f-83c2-4f16-9850-e61e0f49c3d4", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.graph import StateGraph, START, END\n", - "from langgraph.prebuilt import ToolNode\n", - "from langgraph.prebuilt import tools_condition\n", - "\n", - "workflow = StateGraph(MessagesState)\n", - "\n", - "# Define the nodes we will cycle between\n", - "workflow.add_node(generate_query_or_respond)\n", - "workflow.add_node(\"retrieve\", ToolNode([retriever_tool]))\n", - "workflow.add_node(rewrite_question)\n", - "workflow.add_node(generate_answer)\n", - "\n", - "workflow.add_edge(START, \"generate_query_or_respond\")\n", - "\n", - "# Decide whether to retrieve\n", - "workflow.add_conditional_edges(\n", - " \"generate_query_or_respond\",\n", - " # Assess LLM decision (call `retriever_tool` tool or respond to the user)\n", - " tools_condition,\n", - " {\n", - " # Translate the condition outputs to nodes in our graph\n", - " \"tools\": \"retrieve\",\n", - " END: END,\n", - " },\n", - ")\n", - "\n", - "# Edges taken after the `action` node is called.\n", - "workflow.add_conditional_edges(\n", - " \"retrieve\",\n", - " # Assess agent decision\n", - " grade_documents,\n", - ")\n", - "workflow.add_edge(\"generate_answer\", END)\n", - "workflow.add_edge(\"rewrite_question\", \"generate_query_or_respond\")\n", - "\n", - "# Compile\n", - "graph = workflow.compile()" - ] - }, - { - "cell_type": "markdown", - "id": "fb7c8138-8b01-4858-b9d1-b4bc5f7ebb33", - "metadata": {}, - "source": [ - "Visualize the graph:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "7b5a1d35", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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ERGTJk3KcFW9w74HFcXj966MVCpi5ZLqqNnYGPn9szNdFgAAdCs93YDtsvSdLb2kRu3WL/oVyvB7srvuuqtF4NYbVFdXxx133JEO3Og+eQV9YvTu/dLLyxb5NwAAoPcRugHbZfm7Wz5EF0/ot5Utgd6oeGJB+nHJuxu3siUAAOyahG7AdilZuCV0GzOhfwYrAXqi4mavC8vfrc5gJQAAkBlCN6DTmpoiVizZ8iF67HihG9DS2PEFEVmbHq9aVh2N9anMFgQAAN3MIExAp5WtrI3Ue2PwFw7qG/kF8vuuUl5eHq+++mqUlJTE8uXLo6KiIkaOHBljx46N3XbbLaZMmRL5+flt7ltaWhplZWUREVFRUdFq/WuvvRaDBrWeAGPAgAExduzYbda2fv36WLhwYSxcuDDefffdWLt2beTl5cXgwYNj8uTJse+++8bo0aM79XwrKipixYoVLdrGjx+ffo6bZ2B94403YsWKFVFVVRUDBgyIMWPGxJ577hnTpk2LRYsWRXV1daxdu7bV8cvKyuL1119v89wjR46MIUOGdKpe2peT1ycGDcmJdWX1kWqKKFtVGyPGtn2tAgDArkjoBnTaurK69OPBw3MzWMmuq7y8PG699db43e9+t81tTz755JgxY0YceuihkZOTk26/5pprYs6cOe3u96UvfanN9nHjxsXdd9/d5rqGhoZ4/PHH46abborXXnttm7UNHjw4vvjFL8bMmTOjT59th7M333xz3HjjjS3afvSjH8VHP/rReOKJJ+Kaa66J5cuXt7nv9OnTY9q0aXHOOee0O3lCeXl5nH322W2umzVrVnz961/fZo103ODhubGurD4iIirW1gndAADoVXRPATpt/drmoVteBivZNZWWlsaZZ57ZocAtImL27Nnxla98Je67774W7U1NTYnW9cILL8TMmTPjW9/6VocCt4hNIdfVV18dn/vc56KkpGS7z33TTTfFv/7rv7YbuEVEnHHGGRERZivtQZq/PqxvFtYDAEBvIHQDOq1CT7cuU1NTE1//+tejvLy80/seeOCBXVDRFvPmzYvS0tLt2nfu3Llx+eWXRyrV+XG9Hn300bj22mu3us2IESPi8MMP367a6DrNXx8293gDAIDewu2lQKc1v720SOiWqMcee6zdXmQFBQVxyCGHRE1NTcyfP79Fj67i4uKYOHFii+333Xff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8i+xaNGidFtDQ0O88MILcc0117QIxvbaa69W+//whz+Mp556qkVbKpWKRYsWxZVXXhm//vWv232eJSUl7a5LUlt1z5kzJ66++upYv359uq26ujoefvjh+P3vf98tdfUGyxdVReq9PL54fL9o425fAADYpfXNdAHAzql4QkEsfnNjREQsf2djjN+nMMMV7RoeffTRFstvv/12fOtb30ovDx48OMrLy9vcd8SIEW32SIuIOProo6O4uDiWL1/eon3evHlxxhlnpGdDraraEqD+0z/9U+yxxx4REXHiiSfGdddd12J9RMRXv/rVGD9+fOy7775RWloa77zzTrv1NXfjjTfGd77znTbHXUvSpz71qTZnXr333nvj3nvvjYKCgsjLy0vXPHjw4PjMZz7TpTX1Fkvfrkw/Lp7YerZdAADY1enpBmyXsRP6px8ve0dPt6Tcc889W12/tUDrBz/4QfTp0/bLen5+fnzzm99sd9+qqqpWgdrixYvTj4cNGxaXXnppm/suXLgwHnjggXjxxRc7FLhFRNx3331x4403dmjbHTFx4sQ499xz211fVVXVouby8vJOzepK+5a9veV6Kh7ffytbAgDArknoBmyX0XsURNZ7ryArl1RHbZVx3ZKw9957d3qfgoKC+OlPfxr777//Vrf78Ic/HF/84hc7fNyFCxe2WD7++OPjwgsv7FRt3/nOd2LOnDnpnnTNzZs3r1PH2l4XXHBBHHvssR3evnnYyPaprWqKFYurIyIiq0/EmN31dAMAoPcRugHbpU+fiN332tR7JZWKeOMVvYOScPXVV8e9994b5557bptBVXMFBQVx8cUXx0MPPRRHHXVUh45/3nnnxfXXXx8jRozY6nbtTchw0UUXxe9+97sYN27cVvedNWtWPPjgg/Hxj388ioqK4tZbb42pU6dus778/PxWbXl5edvcb1vH/OEPfxiXXHLJNrctLi5udwZYOu7NeRWRSm16vNuk/pGdY0A3AAB6n6xUavPbYoDOef2linjo1k0D4o/Zo1988uLxGa5o15JKpWLt2rWxatWqWLFiRXpig1GjRsXo0aNj6NChkZ2dvd3HX7lyZbz55ptRU1MT2dnZMXLkyBg+fHgMGzYs+vbd9pCfpaWlsWDBgqisrIz6+vooKiqKUaNGxcSJE9sdq23NmjXx5ptvxrp162LcuHExZcqU7a5/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H7cSERERERERERGZGEM3IiIiIiIiIiIiE2PoRkREREREREREZGIM3YiIiIiIiIiIiEyMoRsREREREREREZGJMXQjIiIiIiIiIiIyMYZuREREREREREREJsbQjYiIiIiIiIiIyMQYuhEREREREREREZkYQzciIiIiIiIiIiITY+hGRERERERERERkYgzdiIiIiIiIiIiITIyhGxERERERERERkYkxdCMiIiIiIiIiIjIxhm5EREREREREREQmxtCNiIiIiIiIiIjIxBi6ERERERERERERmRhDNyIiIiIiIiIiIhNj6EZERERERERERGRiDN2IiIiIiIiIiIhMjKEbERERERERERGRiTF0IyIiIiIiIiIiMjGGbkRERERERERERCbG0I2IiIiIiIiIiMjEGLoRERERERERERGZGEM3IiIiIiIiIiIiE2PoRkREREREREREZGIM3YiIiIiIiIiIiEyMoRsREREREREREZGJMXQjIiIiIiIiIiIyMYZuREREREREREREJmbXoZujk0z/78oKnYSVEBERERHdoav8+3Wpk5Ndv1wnIiKyanb9V9y1saP+3yW3tRJWQkRERER0R/Gtv1+X3v16lYiIiKyLXYdujdyd9P8uul0hYSVERERERHfcLvw7dGvU2KmGnkRERFSf2XXo1rS5q/7f2enFElZCRERERHRH1pW/X5f6NneRsBIiIiJ6EHYdujm7OsA34M4LmaLbFbhxrUTiioiIiIjInmVnlqD4fyswfPwawtWdM92IiIislV2HbgDQskMj/b/PJOZIWAkRERER2bu7X4+2fMhdwkqIiIjoQdl96NYl1Av43yGm5//KR0FOmbQFEREREZFdul1QjrNJ+fqvu/RpImE1RERE9KDsPnST+zTEQ90aAwB0lcBRzQ2JKyIiIiIie3Qk9gZ0ujv/bt+1MZo0ayhtQURERPRA7D50A4CwIc30s91S/ipAysn8mi8gIiIiIjKhlJP5OHf879egYYObSVgNERERmQJDN9yZ7aYc/vcLm9hfr+Hs0VwJKyIiIiIie3HuWC5if70G/G+WW/iwppzlRkREZAMYuv1Pj0hvhIR56b+O25aJQ7uzJKyIiIiIiGzd4b1Z0GzJ1H/dqacHevdvKmFFREREZCoyna5q5wgCgO3fXsG5Y7f0XwcENULYUD94evPTRiIiIiIyjYKcMuz/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KJGdsYvQ7Z///CdmzJiBJ598Es8++yzX2xNRvePj44MPPvgAgPiyyGHDhmHq1Kl1us9vv/1WtF2hUODVV18V7KWWnJyMd955RxCgbd26FcOHDxedARYbG4uUlBRBe8uWLfHOO++gWbNm1dpzc3Px7rvv4uzZs9XaL1++jJiYGAwcONCo760mFRUV2Llzp6C9devWmDt3Llq2bKlvKysrw44dO7By5UoAQO/evR/48YmI6P/Zu/OwKuv8/+OvAyiL6EEQc0FcMheS1IamKdO0NJdwyWUyzK1cpnKaNpv4fptmamyYyr7WlFZj5mRGjS1upGZRtpmFaYWhueJ+XFAQBQ4e5feHP4/gOQdBb7jPDc/HdXV1n8/9ue/7fTyXCC8+C1Cz1a1bV927d1f37t1VUlKiX375xT0Kbtu2bWX65ufna8WKFVqxYoWCgoLUtWtX3XjjjerZs6eaNGli0jsAUF1qzFZtWVlZev31172e69Kli5YtW6YHH3yQwA1ArbB161atXLnSo/22227To48+6nXzgg4dOujFF19U8+bNPc7Nnz/fo62wsNDr192rrrpKzz33nEfgJkkNGzZUSve0uMYAACAASURBVEqKunfv7nHujTfeKDNV42IdP37ca/v9999fJnCTznzTPGTIEM2fP18jRozQVVdddcnPBwAAtYfNZlOnTp1033336b///a/S0tL08MMPKyEhwWP0vMvlUkZGhqZPn67ExETdfvvtmjlzpjIzM32uFwfA2iwfum3atEkPPPCAxowZo1dffdXjNwtnRUREVHNlAGCe1157zaOtefPmuuuuu8qdPtm4cWONGTPGo/2rr77yGJ22cOFCr9NKx40bV+7mCyEhIZo4caJHe15enpYtW+bzuoryteNqbm6uz2siIyM1fvz4C+6kCgAAUJ4mTZrojjvu0Kuvvqr09HRNmzZNffr08TqtdNu2bZo7d67Gjx+vvn376qmnntKqVasM+SUkAP9g2dDtbNh255136uuvv3a3X2g3OwCo6Y4ePapffvnFo33EiBEVWq/suuuu8zoqeOPGjWVef/nllx59unXrpkaNGl3wGY0aNdKNN97o0f7zzz9f8NoLqV+/vtf6P//8c36LDAAAqk14eLj69eunlJQUrVq1SjNnztTvf/97r9NKjxw5oiVLluiRRx7RDTfcoPvvv19LliwxoWoA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duFp94fgQV6wrcKMGxERWSZbWyu8NLAe8P+XuoQr2bh5PVveoMhiXL34ACk3n/TssLYGXnq9HqxtZA6KiIhIYlZWQNfXPGHz/7mDjLTHiDx1v5S1TBuTbmQQZ47cU/3s16wGarvbyxgNERGR4TnVropnWjqpXkcc5thuJI1zR5/Wq5q2roXqNTiGGxERWSa7ajZo2dFF9frcMSbdiDQUFQLxV54+3W/WhtPXExFR5aB+zUu8moMCJSeJp4p5lFeI5Lhc1evm7VmvIiIiy9asdS3V0FT37z7Cw4zH8gZUAUy6keRuxWXjUd6TjtfVqtugjmc1mSMiIiIyDuc6dqju9KQVUmFBERKusYspVUxs9APVz6517eDgyFZuRERk2arYWcPT9+nYbtejsnQsbdrM9qo9dOhQZGU92fF2dnYyR0Pq7iY9nU3W99kaMkZCRERkfP7NnHDhxJPugHeTcuDXxLGUNYi0U69X+TSpKWMkRERExlO/aQ0kxT55eHk3KbeUpU2XWSfdyDRlZylVP7vUZSs3IiKqXGrXfTqOaU5WgYyRkCXIUatXqR9bRERElqy2+9NcgnqOwdyweylJLufh0z8IO3tOrUVERJWLXbWn1z5zriSSachWS9zaV2O9ioiIKge7ak/TVeb8EJNJN5Jcft7TP4gqdjzEiIiocqmqdu3LzzHfSiKZhke5avWqqqxXERFR5aDegCcvx3wfYvLKTdJTm6itiJO2ERFRpWOl+onXQZJSUaHcERARERlHkYXkFZh0IyIiIiIiIiIikpjZTqQQFhaGe/eezAy2cOFCVK9evZQ1iIiIiIiIiIiIjMNsk26RkZFISUkBACiV5tu/l4iIiIiIiIiILA+7lxIREREREREREUmMSTciIiIiIiIiIiKJMelGREREREREREQkMSbdiIiIiIiIiIiIJGa2EynMmzcP+fn5AAAnJyeZoyEiIiIiIiIiInrKbJNuAQEBcodAREREREREREQkit1LiYiIiIiIiIiIJMakGxERERERERERkcSYdCMiIiIiIiIiIpIYk25EREREREREREQSM9uJFHr37o2UlBQAwMGDBzmDKRERERERERERmQy2dCMiIiIiIiIiIpIYk25EREREREREREQSY9KNiIiIiIiIiIhIYky6ERERERERERERSYxJNyIiIiIiIiIiIomZ7eylu3fvljsEIiIiIiIiIiIiUWzpRkREREREREREJDEm3YiIiIiIiIiIiCTGpBsREREREREREZHEmHQjIiIiIiIiIiKSGJNuREREREREREREEjPb2Ut79+6NlJQUAMDBgwfh5OQkc0RERERERERERERPsKUbERERERERERGRxJh0IyIiIiIiIiIikhiTbkRERERERERERBJj0o2IiIiIiIiIiEhiZjuRQkBAADw8PAAAtrZm+zWIiIiIiIiIiMgCmW22at68eXKHQEREREREREREJIrdS4mIiIiIiIiIiCTGpBsREREREREREZHEmHQjIiIiIiIiIiKSGJNuREREREREREREEjPbiRQiIyORn58PAAgKCpI5GiIiIiIiIiIioqfMNukWFhaGlJQUAMDBgwfh5OQkc0RERERERESmLTc3F8ePH4KyQInng9rBxcVV7pCIZFdQUICIM6eRnJyE5gHPoUGDhnKHRBbCbJNuREREREREpL/ExHi8PXEkcnJyVGUfh32ObsE9ZYyKSF5KpRJjxw1FQkKcqqxvn9cwfdpHMkZFloJjuhERGUFhYaHcIRAREVEl99ffOzUSbgDw0+Z1KCoq0nsbrNOQKarIcfnff//TSLgBwM5dvyItLbWiYREx6UZEZEhxcTewavUS9On3Is6e+0/ucIiIiKgSOydSF0lIiENmZkap67JOQ6ZIiuMyMuqCaPn99HsVCY0IALuXEhEZRMSZ01i7djlirlxWleXn5ckYEREREVV2nTsH4+q1GI2ygICWUCicta7DOg2ZIimPy/btOmHLzxsE5R51vcodH1Exs026DR06FFlZWQAAOzs7maMhItJ0+vRJjUoAERERkdx6dH8FB//Zg9jY6wAAhcIZI4aP1bkO6zRkiqQ8Lps1a4EunYNx+MgBVdm4kMlwdHSUZPtUuZl10o2IiIiIiIj0U7u2C9aGb0FU1AU8eJCJ559vhypVqsgdFpHsPps5D2NuTcCVK5cRFNQWTjWd5A6JLITZJt2IiIiIiIio7Jo1ayF3CEQmx8uzHrw868kdBlkYTqRAJLFdu3dg8ZL5UCqVcodCRERERERERDJhSzciPTzIeoDEhDjEJ8QiNu4Gsh5kQqGoBQ8PT9St64mWLVrB3t4e/0WcwoKF8wAAqal38cmMuXqPOVhYWIhr16/gwoWzSEtLRUZmOhyqOcDbuz7q1fOBp2c9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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.display import Image, display\n", - "\n", - "display(Image(graph.get_graph().draw_mermaid_png()))" - ] - }, - { - "cell_type": "markdown", - "id": "eb655cfb-d4e4-4f6a-8a0d-01e8611b18ab", - "metadata": {}, - "source": [ - "## 8. Run the agentic RAG" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "7649f05a-cb67-490d-b24a-74d41895139a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update from node generate_query_or_respond\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " retrieve_blog_posts (call_NYu2vq4km9nNNEFqJwefWKu1)\n", - " Call ID: call_NYu2vq4km9nNNEFqJwefWKu1\n", - " Args:\n", - " query: types of reward hacking\n", - "\n", - "\n", - "\n", - "Update from node retrieve\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: retrieve_blog_posts\n", - "\n", - "(Note: Some work defines reward tampering as a distinct category of misalignment behavior from reward hacking. But I consider reward hacking as a broader concept here.)\n", - "At a high level, reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering.\n", - "\n", - "Why does Reward Hacking Exist?#\n", - "\n", - "Pan et al. (2022) investigated reward hacking as a function of agent capabilities, including (1) model size, (2) action space resolution, (3) observation space noise, and (4) training time. They also proposed a taxonomy of three types of misspecified proxy rewards:\n", - "\n", - "Let’s Define Reward Hacking#\n", - "Reward shaping in RL is challenging. Reward hacking occurs when an RL agent exploits flaws or ambiguities in the reward function to obtain high rewards without genuinely learning the intended behaviors or completing the task as designed. In recent years, several related concepts have been proposed, all referring to some form of reward hacking:\n", - "\n", - "\n", - "\n", - "Update from node generate_answer\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Lilian Weng categorizes reward hacking into two types: environment or goal misspecification, and reward tampering. She considers reward hacking as a broad concept that includes both of these categories. Reward hacking occurs when an agent exploits flaws or ambiguities in the reward function to achieve high rewards without performing the intended behaviors.\n", - "\n", - "\n", - "\n" - ] - } - ], - "source": [ - "for chunk in graph.stream(\n", - " {\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n", - " }\n", - " ]\n", - " }\n", - "):\n", - " for node, update in chunk.items():\n", - " print(\"Update from node\", node)\n", - " update[\"messages\"][-1].pretty_print()\n", - " print(\"\\n\\n\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/tutorials/rag/langgraph_agentic_rag.md b/docs/docs/tutorials/rag/langgraph_agentic_rag.md new file mode 100644 index 000000000..2aae24820 --- /dev/null +++ b/docs/docs/tutorials/rag/langgraph_agentic_rag.md @@ -0,0 +1,522 @@ +# Agentic RAG + +In this tutorial we will build a [retrieval agent](https://python.langchain.com/docs/tutorials/qa_chat_history). Retrieval agents are useful when you want an LLM to make a decision about whether to retrieve context from a vectorstore or respond to the user directly. + +By the end of the tutorial we will have done the following: + +1. Fetch and preprocess documents that will be used for retrieval. +2. Index those documents for semantic search and create a retriever tool for the agent. +3. Build an agentic RAG system that can decide when to use the retriever tool. + +![Screenshot 2024-02-14 at 3.43.58 PM.png](assets/screenshot_2024_02_14_3_43_58_pm.png) + +## Setup + +Let's download the required packages and set our API keys: + +```python +%%capture --no-stderr +%pip install -U --quiet langgraph "langchain[openai]" langchain-community langchain-text-splitters +``` + +```python +import getpass +import os + + +def _set_env(key: str): + if key not in os.environ: + os.environ[key] = getpass.getpass(f"{key}:") + + +_set_env("OPENAI_API_KEY") +``` + +!!! tip + Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph. + + +## 1. Preprocess documents + +1. Fetch documents to use in our RAG system. We will use three of the most recent pages from [Lilian Weng's excellent blog](https://lilianweng.github.io/). We'll start by fetching the content of the pages using `WebBaseLoader` utility: + + ```python + from langchain_community.document_loaders import WebBaseLoader + + urls = [ + "https://lilianweng.github.io/posts/2024-11-28-reward-hacking/", + "https://lilianweng.github.io/posts/2024-07-07-hallucination/", + "https://lilianweng.github.io/posts/2024-04-12-diffusion-video/", + ] + + docs = [WebBaseLoader(url).load() for url in urls] + ``` + + ```python + docs[0][0].page_content.strip()[:1000] + ``` + +2. Split the fetched documents into smaller chunks for indexing into our vectorstore: + + ```python + from langchain_text_splitters import RecursiveCharacterTextSplitter + + docs_list = [item for sublist in docs for item in sublist] + + text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder( + chunk_size=100, chunk_overlap=50 + ) + doc_splits = text_splitter.split_documents(docs_list) + ``` + + ```python + doc_splits[0].page_content.strip() + ``` + +## 2. Create a retriever tool + +Now that we have our split documents, we can index them into a vector store that we'll use for semantic search. + +1. Use an in-memory vector store and OpenAI embeddings: + + ```python + from langchain_core.vectorstores import InMemoryVectorStore + from langchain_openai import OpenAIEmbeddings + + vectorstore = InMemoryVectorStore.from_documents( + documents=doc_splits, embedding=OpenAIEmbeddings() + ) + retriever = vectorstore.as_retriever() + ``` + +2. Create a retriever tool using LangChain's prebuilt `create_retriever_tool`: + + ```python + from langchain.tools.retriever import create_retriever_tool + + retriever_tool = create_retriever_tool( + retriever, + "retrieve_blog_posts", + "Search and return information about Lilian Weng blog posts.", + ) + ``` + +3. Test the tool: + + ```python + retriever_tool.invoke({"query": "types of reward hacking"}) + ``` + +## 3. Generate query + +Now we will start building components ([nodes](../../concepts/low_level.md#nodes) and [edges](../../concepts/low_level.md#edges)) for our agentic RAG graph. Note that the components will operate on the [`MessagesState`](../../concepts/low_level.md#messagesstate) — graph state that contains a `messages` key with a list of [chat messages](https://python.langchain.com/docs/concepts/messages/). + +1. Build a `generate_query_or_respond` node. It will call an LLM to generate a response based on the current graph state (list of messages). Given the input messages, it will decide to retrieve using the retriever tool, or respond directly to the user. Note that we're giving the chat model access to the `retriever_tool` we created earlier via `.bind_tools`: + + ```python + from langgraph.graph import MessagesState + from langchain.chat_models import init_chat_model + + response_model = init_chat_model("openai:gpt-4.1", temperature=0) + + + def generate_query_or_respond(state: MessagesState): + """Call the model to generate a response based on the current state. Given + the question, it will decide to retrieve using the retriever tool, or simply respond to the user. + """ + response = ( + response_model + # highlight-next-line + .bind_tools([retriever_tool]).invoke(state["messages"]) + ) + return {"messages": [response]} + ``` + +2. Try it on a random input: + + ```python + input = {"messages": [{"role": "user", "content": "hello!"}]} + generate_query_or_respond(input)["messages"][-1].pretty_print() + ``` + + **Output:** + ``` + ================================== Ai Message ================================== + + Hello! How can I help you today? + ``` + +3. Ask a question that requires semantic search: + + ```python + input = { + "messages": [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + } + ] + } + generate_query_or_respond(input)["messages"][-1].pretty_print() + ``` + + **Output:** + ``` + ================================== Ai Message ================================== + Tool Calls: + retrieve_blog_posts (call_tYQxgfIlnQUDMdtAhdbXNwIM) + Call ID: call_tYQxgfIlnQUDMdtAhdbXNwIM + Args: + query: types of reward hacking + ``` + +## 4. Grade documents + +1. Add a [conditional edge](../../concepts/low_level.md#conditional-edges) — `grade_documents` — to determine whether the retrieved documents are relevant to the question. We will use a model with a structured output schema `GradeDocuments` for document grading. The `grade_documents` function will return the name of the node to go to based on the grading decision (`generate_answer` or `rewrite_question`): + + ```python + from pydantic import BaseModel, Field + from typing import Literal + + GRADE_PROMPT = ( + "You are a grader assessing relevance of a retrieved document to a user question. \n " + "Here is the retrieved document: \n\n {context} \n\n" + "Here is the user question: {question} \n" + "If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \n" + "Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question." + ) + + + # highlight-next-line + class GradeDocuments(BaseModel): + """Grade documents using a binary score for relevance check.""" + + binary_score: str = Field( + description="Relevance score: 'yes' if relevant, or 'no' if not relevant" + ) + + + grader_model = init_chat_model("openai:gpt-4.1", temperature=0) + + + def grade_documents( + state: MessagesState, + ) -> Literal["generate_answer", "rewrite_question"]: + """Determine whether the retrieved documents are relevant to the question.""" + question = state["messages"][0].content + context = state["messages"][-1].content + + prompt = GRADE_PROMPT.format(question=question, context=context) + response = ( + grader_model + # highlight-next-line + .with_structured_output(GradeDocuments).invoke( + [{"role": "user", "content": prompt}] + ) + ) + score = response.binary_score + + if score == "yes": + return "generate_answer" + else: + return "rewrite_question" + ``` + +2. Run this with irrelevant documents in the tool response: + + ```python + from langchain_core.messages import convert_to_messages + + input = { + "messages": convert_to_messages( + [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "1", + "name": "retrieve_blog_posts", + "args": {"query": "types of reward hacking"}, + } + ], + }, + {"role": "tool", "content": "meow", "tool_call_id": "1"}, + ] + ) + } + grade_documents(input) + ``` + +3. Confirm that the relevant documents are classified as such: + + ```python + input = { + "messages": convert_to_messages( + [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "1", + "name": "retrieve_blog_posts", + "args": {"query": "types of reward hacking"}, + } + ], + }, + { + "role": "tool", + "content": "reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering", + "tool_call_id": "1", + }, + ] + ) + } + grade_documents(input) + ``` + +## 5. Rewrite question + +1. Build the `rewrite_question` node. The retriever tool can return potentially irrelevant documents, which indicates a need to improve the original user question. To do so, we will call the `rewrite_question` node: + + ```python + REWRITE_PROMPT = ( + "Look at the input and try to reason about the underlying semantic intent / meaning.\n" + "Here is the initial question:" + "\n ------- \n" + "{question}" + "\n ------- \n" + "Formulate an improved question:" + ) + + + def rewrite_question(state: MessagesState): + """Rewrite the original user question.""" + messages = state["messages"] + question = messages[0].content + prompt = REWRITE_PROMPT.format(question=question) + response = response_model.invoke([{"role": "user", "content": prompt}]) + return {"messages": [{"role": "user", "content": response.content}]} + ``` + +2. Try it out: + + ```python + input = { + "messages": convert_to_messages( + [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "1", + "name": "retrieve_blog_posts", + "args": {"query": "types of reward hacking"}, + } + ], + }, + {"role": "tool", "content": "meow", "tool_call_id": "1"}, + ] + ) + } + + response = rewrite_question(input) + print(response["messages"][-1]["content"]) + ``` + + **Output:** + ``` + What are the different types of reward hacking described by Lilian Weng, and how does she explain them? + ``` + +## 6. Generate an answer + +1. Build `generate_answer` node: if we pass the grader checks, we can generate the final answer based on the original question and the retrieved context: + + ```python + GENERATE_PROMPT = ( + "You are an assistant for question-answering tasks. " + "Use the following pieces of retrieved context to answer the question. " + "If you don't know the answer, just say that you don't know. " + "Use three sentences maximum and keep the answer concise.\n" + "Question: {question} \n" + "Context: {context}" + ) + + + def generate_answer(state: MessagesState): + """Generate an answer.""" + question = state["messages"][0].content + context = state["messages"][-1].content + prompt = GENERATE_PROMPT.format(question=question, context=context) + response = response_model.invoke([{"role": "user", "content": prompt}]) + return {"messages": [response]} + ``` + +2. Try it: + + ```python + input = { + "messages": convert_to_messages( + [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "1", + "name": "retrieve_blog_posts", + "args": {"query": "types of reward hacking"}, + } + ], + }, + { + "role": "tool", + "content": "reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering", + "tool_call_id": "1", + }, + ] + ) + } + + response = generate_answer(input) + response["messages"][-1].pretty_print() + ``` + + **Output:** + ``` + ================================== Ai Message ================================== + + Lilian Weng categorizes reward hacking into two types: environment or goal misspecification, and reward tampering. She considers reward hacking as a broad concept that includes both of these categories. Reward hacking occurs when an agent exploits flaws or ambiguities in the reward function to achieve high rewards without performing the intended behaviors. + ``` + +## 7. Assemble the graph + +* Start with a `generate_query_or_respond` and determine if we need to call `retriever_tool` +* Route to next step using `tools_condition`: + * If `generate_query_or_respond` returned `tool_calls`, call `retriever_tool` to retrieve context + * Otherwise, respond directly to the user +* Grade retrieved document content for relevance to the question (`grade_documents`) and route to next step: + * If not relevant, rewrite the question using `rewrite_question` and then call `generate_query_or_respond` again + * If relevant, proceed to `generate_answer` and generate final response using the `ToolMessage` with the retrieved document context + +```python +from langgraph.graph import StateGraph, START, END +from langgraph.prebuilt import ToolNode +from langgraph.prebuilt import tools_condition + +workflow = StateGraph(MessagesState) + +# Define the nodes we will cycle between +workflow.add_node(generate_query_or_respond) +workflow.add_node("retrieve", ToolNode([retriever_tool])) +workflow.add_node(rewrite_question) +workflow.add_node(generate_answer) + +workflow.add_edge(START, "generate_query_or_respond") + +# Decide whether to retrieve +workflow.add_conditional_edges( + "generate_query_or_respond", + # Assess LLM decision (call `retriever_tool` tool or respond to the user) + tools_condition, + { + # Translate the condition outputs to nodes in our graph + "tools": "retrieve", + END: END, + }, +) + +# Edges taken after the `action` node is called. +workflow.add_conditional_edges( + "retrieve", + # Assess agent decision + grade_documents, +) +workflow.add_edge("generate_answer", END) +workflow.add_edge("rewrite_question", "generate_query_or_respond") + +# Compile +graph = workflow.compile() +``` + +Visualize the graph: + +```python +from IPython.display import Image, display + +display(Image(graph.get_graph().draw_mermaid_png())) +``` + +![Graph](assets/agentic-rag-output.png) + +## 8. Run the agentic RAG + +```python +for chunk in graph.stream( + { + "messages": [ + { + "role": "user", + "content": "What does Lilian Weng say about types of reward hacking?", + } + ] + } +): + for node, update in chunk.items(): + print("Update from node", node) + update["messages"][-1].pretty_print() + print("\n\n") +``` + +**Output:** +``` +Update from node generate_query_or_respond +================================== Ai Message ================================== +Tool Calls: + retrieve_blog_posts (call_NYu2vq4km9nNNEFqJwefWKu1) + Call ID: call_NYu2vq4km9nNNEFqJwefWKu1 + Args: + query: types of reward hacking + + + +Update from node retrieve +================================= Tool Message ================================== +Name: retrieve_blog_posts + +(Note: Some work defines reward tampering as a distinct category of misalignment behavior from reward hacking. But I consider reward hacking as a broader concept here.) +At a high level, reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering. + +Why does Reward Hacking Exist?# + +Pan et al. (2022) investigated reward hacking as a function of agent capabilities, including (1) model size, (2) action space resolution, (3) observation space noise, and (4) training time. They also proposed a taxonomy of three types of misspecified proxy rewards: + +Let's Define Reward Hacking# +Reward shaping in RL is challenging. Reward hacking occurs when an RL agent exploits flaws or ambiguities in the reward function to obtain high rewards without genuinely learning the intended behaviors or completing the task as designed. In recent years, several related concepts have been proposed, all referring to some form of reward hacking: + + + +Update from node generate_answer +================================== Ai Message ================================== + +Lilian Weng categorizes reward hacking into two types: environment or goal misspecification, and reward tampering. She considers reward hacking as a broad concept that includes both of these categories. Reward hacking occurs when an agent exploits flaws or ambiguities in the reward function to achieve high rewards without performing the intended behaviors. +``` \ No newline at end of file diff --git a/docs/docs/tutorials/sql-agent.ipynb b/docs/docs/tutorials/sql-agent.ipynb deleted file mode 100644 index 843179305..000000000 --- a/docs/docs/tutorials/sql-agent.ipynb +++ /dev/null @@ -1,876 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "cb71c4a7-9f99-4f08-be34-b3ba81ac075f", - "metadata": {}, - "source": [ - "# Build a SQL agent\n", - "\n", - "In this tutorial, we will walk through how to build an agent that can answer questions about a SQL database.\n", - "\n", - "At a high level, the agent will:\n", - "\n", - "1. Fetch the available tables from the database\n", - "2. Decide which tables are relevant to the question\n", - "3. Fetch the schemas for the relevant tables\n", - "4. Generate a query based on the question and information from the schemas\n", - "5. Double-check the query for common mistakes using an LLM\n", - "6. Execute the query and return the results\n", - "7. Correct mistakes surfaced by the database engine until the query is successful\n", - "8. Formulate a response based on the results\n", - "\n", - "!!! warning \"Security note\"\n", - "\n", - " Building Q&A systems of SQL databases requires executing model-generated SQL queries. There are inherent risks in doing this. Make sure that your database connection permissions are always scoped as narrowly as possible for your agent's needs. This will mitigate though not eliminate the risks of building a model-driven system.\n", - "\n", - "## 1. Setup\n", - "\n", - "Let's first install some dependencies. This tutorial uses SQL database and tool abstractions from [langchain-community](https://python.langchain.com/docs/concepts/architecture/#langchain-community). We will also require a LangChain [chat model](https://python.langchain.com/docs/concepts/chat_models/)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1b613286-41c3-4ca5-9514-36aac0121a5a", - "metadata": {}, - "outputs": [], - "source": [ - "%%capture --no-stderr\n", - "%pip install -U langgraph langchain_community \"langchain[openai]\"" - ] - }, - { - "cell_type": "markdown", - "id": "f5258ad0-39e1-418e-bddb-56e9aab1b43a", - "metadata": {}, - "source": [ - "
\n", - "

Set up LangSmith for LangGraph development

\n", - "

\n", - " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", - "

\n", - "
" - ] - }, - { - "cell_type": "markdown", - "id": "62886241-caa7-40bd-8867-096a97acaf40", - "metadata": {}, - "source": [ - "### Select a LLM\n", - "\n", - "First we [initialize our LLM](https://python.langchain.com/docs/how_to/chat_models_universal_init/). Any model supporting [tool-calling](https://python.langchain.com/docs/integrations/chat/#featured-providers) should work. We use OpenAI below." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "2b981efc-bcc9-49f4-aa66-4c15a76210a4", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.chat_models import init_chat_model\n", - "\n", - "llm = init_chat_model(\"openai:gpt-4.1\")" - ] - }, - { - "cell_type": "markdown", - "id": "804ca604-7ac4-4229-a3e9-3a9825eeefa4", - "metadata": {}, - "source": [ - "### Configure the database\n", - "\n", - "We will be creating a SQLite database for this tutorial. SQLite is a lightweight database that is easy to set up and use. We will be loading the `chinook` database, which is a sample database that represents a digital media store.\n", - "Find more information about the database [here](https://www.sqlitetutorial.net/sqlite-sample-database/).\n", - "\n", - "For convenience, we have hosted the database (`Chinook.db`) on a public GCS bucket." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b58ba6b7-5f80-4970-bc29-961de0e24fbd", - "metadata": {}, - "outputs": [], - "source": [ - "import requests\n", - "\n", - "url = \"https://storage.googleapis.com/benchmarks-artifacts/chinook/Chinook.db\"\n", - "\n", - "response = requests.get(url)\n", - "\n", - "if response.status_code == 200:\n", - " # Open a local file in binary write mode\n", - " with open(\"Chinook.db\", \"wb\") as file:\n", - " # Write the content of the response (the file) to the local file\n", - " file.write(response.content)\n", - " print(\"File downloaded and saved as Chinook.db\")\n", - "else:\n", - " print(f\"Failed to download the file. Status code: {response.status_code}\")" - ] - }, - { - "cell_type": "markdown", - "id": "5ae005fb-e7b0-43f1-95b2-565d19c82610", - "metadata": {}, - "source": [ - "We will use a handy SQL database wrapper available in the `langchain_community` package to interact with the database. The wrapper provides a simple interface to execute SQL queries and fetch results:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "18822c9b-6df2-4a5c-a12d-046d2b2131c9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dialect: sqlite\n", - "Available tables: ['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n", - "Sample output: [(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains')]\n" - ] - } - ], - "source": [ - "from langchain_community.utilities import SQLDatabase\n", - "\n", - "db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")\n", - "\n", - "print(f\"Dialect: {db.dialect}\")\n", - "print(f\"Available tables: {db.get_usable_table_names()}\")\n", - "print(f'Sample output: {db.run(\"SELECT * FROM Artist LIMIT 5;\")}')" - ] - }, - { - "cell_type": "markdown", - "id": "3bf47b6c-30dd-405f-8a03-21327af3c764", - "metadata": {}, - "source": [ - "### Tools for database interactions\n", - "\n", - "`langchain-community` implements some built-in tools for interacting with our `SQLDatabase`, including tools for listing tables, reading table schemas, and checking and running queries:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "aab9e00a-aa28-494a-a95a-a6638ea03bd1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "sql_db_query: Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.\n", - "\n", - "sql_db_schema: Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3\n", - "\n", - "sql_db_list_tables: Input is an empty string, output is a comma-separated list of tables in the database.\n", - "\n", - "sql_db_query_checker: Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!\n", - "\n" - ] - } - ], - "source": [ - "from langchain_community.agent_toolkits import SQLDatabaseToolkit\n", - "\n", - "toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n", - "\n", - "tools = toolkit.get_tools()\n", - "\n", - "for tool in tools:\n", - " print(f\"{tool.name}: {tool.description}\\n\")" - ] - }, - { - "cell_type": "markdown", - "id": "6baf93d3-afd5-484e-9bf7-3ff20401e06f", - "metadata": {}, - "source": [ - "## 2. Using a prebuilt agent\n", - "\n", - "Given these tools, we can initialize a pre-built agent in a single line. To customize our agents behavior, we write a descriptive system prompt." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "f6b9f10f-c6cb-43bc-b671-79aadc71280b", - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.prebuilt import create_react_agent\n", - "\n", - "system_prompt = \"\"\"\n", - "You are an agent designed to interact with a SQL database.\n", - "Given an input question, create a syntactically correct {dialect} query to run,\n", - "then look at the results of the query and return the answer. Unless the user\n", - "specifies a specific number of examples they wish to obtain, always limit your\n", - "query to at most {top_k} results.\n", - "\n", - "You can order the results by a relevant column to return the most interesting\n", - "examples in the database. Never query for all the columns from a specific table,\n", - "only ask for the relevant columns given the question.\n", - "\n", - "You MUST double check your query before executing it. If you get an error while\n", - "executing a query, rewrite the query and try again.\n", - "\n", - "DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the\n", - "database.\n", - "\n", - "To start you should ALWAYS look at the tables in the database to see what you\n", - "can query. Do NOT skip this step.\n", - "\n", - "Then you should query the schema of the most relevant tables.\n", - "\"\"\".format(\n", - " dialect=db.dialect,\n", - " top_k=5,\n", - ")\n", - "\n", - "agent = create_react_agent(\n", - " llm,\n", - " tools,\n", - " prompt=system_prompt,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "78b1c7cf-9a0f-48c3-baec-be8101bc3c77", - "metadata": {}, - "source": [ - "!!! note\n", - "\n", - " This system prompt includes a number of instructions, such as always running specific tools before or after others. In the [next section](#customizing-the-agent), we will enforce these behaviors through the graph's structure, providing us a greater degree of control and allowing us to simplify the prompt.\n", - "\n", - "\n", - "Let's run this agent on a sample query and observe its behavior:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "9317c234-6251-4723-a335-7fee6d11ac2b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================\u001b[1m Human Message \u001b[0m=================================\n", - "\n", - "Which sales agent made the most in sales in 2009?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_list_tables (call_0MfnhUYmRNVe03m6fYClaoa0)\n", - " Call ID: call_0MfnhUYmRNVe03m6fYClaoa0\n", - " Args:\n", - " tool_input:\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_list_tables\n", - "\n", - "Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_schema (call_XwI6uES0HeZ2xCRxkkdWzB3I)\n", - " Call ID: call_XwI6uES0HeZ2xCRxkkdWzB3I\n", - " Args:\n", - " table_names: Employee, Invoice, InvoiceLine\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_schema\n", - "\n", - "\n", - "CREATE TABLE \"Employee\" (\n", - "\t\"EmployeeId\" INTEGER NOT NULL, \n", - "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", - "\t\"FirstName\" NVARCHAR(20) NOT NULL, \n", - "\t\"Title\" NVARCHAR(30), \n", - "\t\"ReportsTo\" INTEGER, \n", - "\t\"BirthDate\" DATETIME, \n", - "\t\"HireDate\" DATETIME, \n", - "\t\"Address\" NVARCHAR(70), \n", - "\t\"City\" NVARCHAR(40), \n", - "\t\"State\" NVARCHAR(40), \n", - "\t\"Country\" NVARCHAR(40), \n", - "\t\"PostalCode\" NVARCHAR(10), \n", - "\t\"Phone\" NVARCHAR(24), \n", - "\t\"Fax\" NVARCHAR(24), \n", - "\t\"Email\" NVARCHAR(60), \n", - "\tPRIMARY KEY (\"EmployeeId\"), \n", - "\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Employee table:\n", - "EmployeeId\tLastName\tFirstName\tTitle\tReportsTo\tBirthDate\tHireDate\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\n", - "1\tAdams\tAndrew\tGeneral Manager\tNone\t1962-02-18 00:00:00\t2002-08-14 00:00:00\t11120 Jasper Ave NW\tEdmonton\tAB\tCanada\tT5K 2N1\t+1 (780) 428-9482\t+1 (780) 428-3457\tandrew@chinookcorp.com\n", - "2\tEdwards\tNancy\tSales Manager\t1\t1958-12-08 00:00:00\t2002-05-01 00:00:00\t825 8 Ave SW\tCalgary\tAB\tCanada\tT2P 2T3\t+1 (403) 262-3443\t+1 (403) 262-3322\tnancy@chinookcorp.com\n", - "3\tPeacock\tJane\tSales Support Agent\t2\t1973-08-29 00:00:00\t2002-04-01 00:00:00\t1111 6 Ave SW\tCalgary\tAB\tCanada\tT2P 5M5\t+1 (403) 262-3443\t+1 (403) 262-6712\tjane@chinookcorp.com\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"Invoice\" (\n", - "\t\"InvoiceId\" INTEGER NOT NULL, \n", - "\t\"CustomerId\" INTEGER NOT NULL, \n", - "\t\"InvoiceDate\" DATETIME NOT NULL, \n", - "\t\"BillingAddress\" NVARCHAR(70), \n", - "\t\"BillingCity\" NVARCHAR(40), \n", - "\t\"BillingState\" NVARCHAR(40), \n", - "\t\"BillingCountry\" NVARCHAR(40), \n", - "\t\"BillingPostalCode\" NVARCHAR(10), \n", - "\t\"Total\" NUMERIC(10, 2) NOT NULL, \n", - "\tPRIMARY KEY (\"InvoiceId\"), \n", - "\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Invoice table:\n", - "InvoiceId\tCustomerId\tInvoiceDate\tBillingAddress\tBillingCity\tBillingState\tBillingCountry\tBillingPostalCode\tTotal\n", - "1\t2\t2009-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n", - "2\t4\t2009-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n", - "3\t8\t2009-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"InvoiceLine\" (\n", - "\t\"InvoiceLineId\" INTEGER NOT NULL, \n", - "\t\"InvoiceId\" INTEGER NOT NULL, \n", - "\t\"TrackId\" INTEGER NOT NULL, \n", - "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", - "\t\"Quantity\" INTEGER NOT NULL, \n", - "\tPRIMARY KEY (\"InvoiceLineId\"), \n", - "\tFOREIGN KEY(\"TrackId\") REFERENCES \"Track\" (\"TrackId\"), \n", - "\tFOREIGN KEY(\"InvoiceId\") REFERENCES \"Invoice\" (\"InvoiceId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from InvoiceLine table:\n", - "InvoiceLineId\tInvoiceId\tTrackId\tUnitPrice\tQuantity\n", - "1\t1\t2\t0.99\t1\n", - "2\t1\t4\t0.99\t1\n", - "3\t2\t6\t0.99\t1\n", - "*/\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_schema (call_dHE5FKSycFhYIkdPKtpEk9rM)\n", - " Call ID: call_dHE5FKSycFhYIkdPKtpEk9rM\n", - " Args:\n", - " table_names: Customer\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_schema\n", - "\n", - "\n", - "CREATE TABLE \"Customer\" (\n", - "\t\"CustomerId\" INTEGER NOT NULL, \n", - "\t\"FirstName\" NVARCHAR(40) NOT NULL, \n", - "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", - "\t\"Company\" NVARCHAR(80), \n", - "\t\"Address\" NVARCHAR(70), \n", - "\t\"City\" NVARCHAR(40), \n", - "\t\"State\" NVARCHAR(40), \n", - "\t\"Country\" NVARCHAR(40), \n", - "\t\"PostalCode\" NVARCHAR(10), \n", - "\t\"Phone\" NVARCHAR(24), \n", - "\t\"Fax\" NVARCHAR(24), \n", - "\t\"Email\" NVARCHAR(60) NOT NULL, \n", - "\t\"SupportRepId\" INTEGER, \n", - "\tPRIMARY KEY (\"CustomerId\"), \n", - "\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Customer table:\n", - "CustomerId\tFirstName\tLastName\tCompany\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\tSupportRepId\n", - "1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n", - "2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n", - "3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n", - "*/\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query_checker (call_QPtWY5cUZWgWhr13Kz6eBJkU)\n", - " Call ID: call_QPtWY5cUZWgWhr13Kz6eBJkU\n", - " Args:\n", - " query: SELECT e.EmployeeId, e.FirstName, e.LastName, SUM(i.Total) as TotalSales\n", - "FROM Employee e\n", - "JOIN Customer c ON e.EmployeeId = c.SupportRepId\n", - "JOIN Invoice i ON c.CustomerId = i.CustomerId\n", - "WHERE i.InvoiceDate BETWEEN '2009-01-01' AND '2009-12-31'\n", - "GROUP BY e.EmployeeId, e.FirstName, e.LastName\n", - "ORDER BY TotalSales DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query_checker\n", - "\n", - "```sql\n", - "SELECT e.EmployeeId, e.FirstName, e.LastName, SUM(i.Total) as TotalSales\n", - "FROM Employee e\n", - "JOIN Customer c ON e.EmployeeId = c.SupportRepId\n", - "JOIN Invoice i ON c.CustomerId = i.CustomerId\n", - "WHERE i.InvoiceDate BETWEEN '2009-01-01' AND '2009-12-31'\n", - "GROUP BY e.EmployeeId, e.FirstName, e.LastName\n", - "ORDER BY TotalSales DESC\n", - "LIMIT 1;\n", - "```\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_X747YMElSeY5D3CfhE6KzLUj)\n", - " Call ID: call_X747YMElSeY5D3CfhE6KzLUj\n", - " Args:\n", - " query: SELECT e.EmployeeId, e.FirstName, e.LastName, SUM(i.Total) as TotalSales\n", - "FROM Employee e\n", - "JOIN Customer c ON e.EmployeeId = c.SupportRepId\n", - "JOIN Invoice i ON c.CustomerId = i.CustomerId\n", - "WHERE i.InvoiceDate BETWEEN '2009-01-01' AND '2009-12-31'\n", - "GROUP BY e.EmployeeId, e.FirstName, e.LastName\n", - "ORDER BY TotalSales DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query\n", - "\n", - "[(5, 'Steve', 'Johnson', 164.34)]\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "The sales agent who made the most in sales in 2009 was Steve Johnson, with total sales of 164.34.\n" - ] - } - ], - "source": [ - "question = \"Which sales agent made the most in sales in 2009?\"\n", - "\n", - "for step in agent.stream(\n", - " {\"messages\": [{\"role\": \"user\", \"content\": question}]},\n", - " stream_mode=\"values\",\n", - "):\n", - " step[\"messages\"][-1].pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "6b2afc54-0a26-40f8-bca2-01cbb2fc3443", - "metadata": {}, - "source": [ - "This worked well enough: the agent correctly listed the tables, obtained the schemas, wrote a query, checked the query, and ran it to inform its final response.\n", - "\n", - "!!! tip\n", - "\n", - " You can inspect all aspects of the above run, including steps taken, tools invoked, what prompts were seen by the LLM, and more in the [LangSmith trace](https://smith.langchain.com/public/bd594960-73e3-474b-b6f2-db039d7c713a/r)." - ] - }, - { - "cell_type": "markdown", - "id": "2ed79712-ca6b-47dc-9bc9-7cb6fc50a8aa", - "metadata": {}, - "source": [ - "## 3. Customizing the agent\n", - "\n", - "The prebuilt agent lets us get started quickly, but at each step the agent has access to the full set of tools. Above, we relied on the system prompt to constrain its behavior— for example, we instructed the agent to always start with the \"list tables\" tool, and to always run a query-checker tool before executing the query.\n", - "\n", - "We can enforce a higher degree of control in LangGraph by customizing the agent. Below, we implement a simple ReAct-agent setup, with dedicated nodes for specific tool-calls. We will use the same [state](../../concepts/low_level/#state) as the pre-built agent.\n", - "\n", - "We construct dedicated nodes for the following steps:\n", - "\n", - "- Listing DB tables\n", - "- Calling the \"get schema\" tool\n", - "- Generating a query\n", - "- Checking the query\n", - "\n", - "Putting these steps in dedicated nodes lets us (1) force tool-calls when needed, and (2) customize the prompts associated with each step." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "992f6ce6-f932-4f44-994c-c0ba5032dbd1", - "metadata": {}, - "outputs": [], - "source": [ - "from typing import Literal\n", - "from langchain_core.messages import AIMessage\n", - "from langchain_core.runnables import RunnableConfig\n", - "from langgraph.graph import END, START, MessagesState, StateGraph\n", - "from langgraph.prebuilt import ToolNode\n", - "\n", - "\n", - "get_schema_tool = next(tool for tool in tools if tool.name == \"sql_db_schema\")\n", - "get_schema_node = ToolNode([get_schema_tool], name=\"get_schema\")\n", - "\n", - "run_query_tool = next(tool for tool in tools if tool.name == \"sql_db_query\")\n", - "run_query_node = ToolNode([run_query_tool], name=\"run_query\")\n", - "\n", - "\n", - "# Example: create a predetermined tool call\n", - "def list_tables(state: MessagesState):\n", - " tool_call = {\n", - " \"name\": \"sql_db_list_tables\",\n", - " \"args\": {},\n", - " \"id\": \"abc123\",\n", - " \"type\": \"tool_call\",\n", - " }\n", - " tool_call_message = AIMessage(content=\"\", tool_calls=[tool_call])\n", - "\n", - " list_tables_tool = next(tool for tool in tools if tool.name == \"sql_db_list_tables\")\n", - " tool_message = list_tables_tool.invoke(tool_call)\n", - " response = AIMessage(f\"Available tables: {tool_message.content}\")\n", - "\n", - " return {\"messages\": [tool_call_message, tool_message, response]}\n", - "\n", - "\n", - "# Example: force a model to create a tool call\n", - "def call_get_schema(state: MessagesState):\n", - " # Note that LangChain enforces that all models accept `tool_choice=\"any\"`\n", - " # as well as `tool_choice=`.\n", - " llm_with_tools = llm.bind_tools([get_schema_tool], tool_choice=\"any\")\n", - " response = llm_with_tools.invoke(state[\"messages\"])\n", - "\n", - " return {\"messages\": [response]}\n", - "\n", - "\n", - "generate_query_system_prompt = \"\"\"\n", - "You are an agent designed to interact with a SQL database.\n", - "Given an input question, create a syntactically correct {dialect} query to run,\n", - "then look at the results of the query and return the answer. Unless the user\n", - "specifies a specific number of examples they wish to obtain, always limit your\n", - "query to at most {top_k} results.\n", - "\n", - "You can order the results by a relevant column to return the most interesting\n", - "examples in the database. Never query for all the columns from a specific table,\n", - "only ask for the relevant columns given the question.\n", - "\n", - "DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.\n", - "\"\"\".format(\n", - " dialect=db.dialect,\n", - " top_k=5,\n", - ")\n", - "\n", - "\n", - "def generate_query(state: MessagesState):\n", - " system_message = {\n", - " \"role\": \"system\",\n", - " \"content\": generate_query_system_prompt,\n", - " }\n", - " # We do not force a tool call here, to allow the model to\n", - " # respond naturally when it obtains the solution.\n", - " llm_with_tools = llm.bind_tools([run_query_tool])\n", - " response = llm_with_tools.invoke([system_message] + state[\"messages\"])\n", - "\n", - " return {\"messages\": [response]}\n", - "\n", - "\n", - "check_query_system_prompt = \"\"\"\n", - "You are a SQL expert with a strong attention to detail.\n", - "Double check the {dialect} query for common mistakes, including:\n", - "- Using NOT IN with NULL values\n", - "- Using UNION when UNION ALL should have been used\n", - "- Using BETWEEN for exclusive ranges\n", - "- Data type mismatch in predicates\n", - "- Properly quoting identifiers\n", - "- Using the correct number of arguments for functions\n", - "- Casting to the correct data type\n", - "- Using the proper columns for joins\n", - "\n", - "If there are any of the above mistakes, rewrite the query. If there are no mistakes,\n", - "just reproduce the original query.\n", - "\n", - "You will call the appropriate tool to execute the query after running this check.\n", - "\"\"\".format(dialect=db.dialect)\n", - "\n", - "\n", - "def check_query(state: MessagesState):\n", - " system_message = {\n", - " \"role\": \"system\",\n", - " \"content\": check_query_system_prompt,\n", - " }\n", - "\n", - " # Generate an artificial user message to check\n", - " tool_call = state[\"messages\"][-1].tool_calls[0]\n", - " user_message = {\"role\": \"user\", \"content\": tool_call[\"args\"][\"query\"]}\n", - " llm_with_tools = llm.bind_tools([run_query_tool], tool_choice=\"any\")\n", - " response = llm_with_tools.invoke([system_message, user_message])\n", - " response.id = state[\"messages\"][-1].id\n", - "\n", - " return {\"messages\": [response]}" - ] - }, - { - "cell_type": "markdown", - "id": "cd23a432-09c1-428c-88a7-6b4d1fe55577", - "metadata": {}, - "source": [ - "Finally, we assemble these steps into a workflow using the Graph API. We define a [conditional edge](../../concepts/low_level/#conditional-edges) at the query generation step that will route to the query checker if a query is generated, or end if there are no tool calls present, such that the LLM has delivered a response to the query." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "8b3ce09d-0eec-456d-8447-d04f79ccfc23", - "metadata": {}, - "outputs": [], - "source": [ - "def should_continue(state: MessagesState) -> Literal[END, \"check_query\"]:\n", - " messages = state[\"messages\"]\n", - " last_message = messages[-1]\n", - " if not last_message.tool_calls:\n", - " return END\n", - " else:\n", - " return \"check_query\"\n", - "\n", - "\n", - "builder = StateGraph(MessagesState)\n", - "builder.add_node(list_tables)\n", - "builder.add_node(call_get_schema)\n", - "builder.add_node(get_schema_node, \"get_schema\")\n", - "builder.add_node(generate_query)\n", - "builder.add_node(check_query)\n", - "builder.add_node(run_query_node, \"run_query\")\n", - "\n", - "builder.add_edge(START, \"list_tables\")\n", - "builder.add_edge(\"list_tables\", \"call_get_schema\")\n", - "builder.add_edge(\"call_get_schema\", \"get_schema\")\n", - "builder.add_edge(\"get_schema\", \"generate_query\")\n", - "builder.add_conditional_edges(\n", - " \"generate_query\",\n", - " should_continue,\n", - ")\n", - "builder.add_edge(\"check_query\", \"run_query\")\n", - "builder.add_edge(\"run_query\", \"generate_query\")\n", - "\n", - "agent = builder.compile()" - ] - }, - { - "cell_type": "markdown", - "id": "c377e9dd-92a7-45d4-91bf-408a6f2af8ca", - "metadata": {}, - "source": [ - "We visualize the application below:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "f728ed5f-7bcd-489e-9174-4e4725962335", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.display import Image, display\n", - "from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles\n", - "\n", - "display(Image(agent.get_graph().draw_mermaid_png()))" - ] - }, - { - "cell_type": "markdown", - "id": "977173cf-8f8d-416e-a122-aebff115f29a", - "metadata": {}, - "source": [ - "We can now invoke the graph exactly as before:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "6c800a77-2359-4011-ab0c-dad22ed333b1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================\u001b[1m Human Message \u001b[0m=================================\n", - "\n", - "Which sales agent made the most in sales in 2009?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "Available tables: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_schema (call_rMs3sF1HVcAGggGf89ZNvtLE)\n", - " Call ID: call_rMs3sF1HVcAGggGf89ZNvtLE\n", - " Args:\n", - " table_names: Employee,Invoice,Customer\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_schema\n", - "\n", - "\n", - "CREATE TABLE \"Customer\" (\n", - "\t\"CustomerId\" INTEGER NOT NULL, \n", - "\t\"FirstName\" NVARCHAR(40) NOT NULL, \n", - "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", - "\t\"Company\" NVARCHAR(80), \n", - "\t\"Address\" NVARCHAR(70), \n", - "\t\"City\" NVARCHAR(40), \n", - "\t\"State\" NVARCHAR(40), \n", - "\t\"Country\" NVARCHAR(40), \n", - "\t\"PostalCode\" NVARCHAR(10), \n", - "\t\"Phone\" NVARCHAR(24), \n", - "\t\"Fax\" NVARCHAR(24), \n", - "\t\"Email\" NVARCHAR(60) NOT NULL, \n", - "\t\"SupportRepId\" INTEGER, \n", - "\tPRIMARY KEY (\"CustomerId\"), \n", - "\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Customer table:\n", - "CustomerId\tFirstName\tLastName\tCompany\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\tSupportRepId\n", - "1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n", - "2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n", - "3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"Employee\" (\n", - "\t\"EmployeeId\" INTEGER NOT NULL, \n", - "\t\"LastName\" NVARCHAR(20) NOT NULL, \n", - "\t\"FirstName\" NVARCHAR(20) NOT NULL, \n", - "\t\"Title\" NVARCHAR(30), \n", - "\t\"ReportsTo\" INTEGER, \n", - "\t\"BirthDate\" DATETIME, \n", - "\t\"HireDate\" DATETIME, \n", - "\t\"Address\" NVARCHAR(70), \n", - "\t\"City\" NVARCHAR(40), \n", - "\t\"State\" NVARCHAR(40), \n", - "\t\"Country\" NVARCHAR(40), \n", - "\t\"PostalCode\" NVARCHAR(10), \n", - "\t\"Phone\" NVARCHAR(24), \n", - "\t\"Fax\" NVARCHAR(24), \n", - "\t\"Email\" NVARCHAR(60), \n", - "\tPRIMARY KEY (\"EmployeeId\"), \n", - "\tFOREIGN KEY(\"ReportsTo\") REFERENCES \"Employee\" (\"EmployeeId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Employee table:\n", - "EmployeeId\tLastName\tFirstName\tTitle\tReportsTo\tBirthDate\tHireDate\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\n", - "1\tAdams\tAndrew\tGeneral Manager\tNone\t1962-02-18 00:00:00\t2002-08-14 00:00:00\t11120 Jasper Ave NW\tEdmonton\tAB\tCanada\tT5K 2N1\t+1 (780) 428-9482\t+1 (780) 428-3457\tandrew@chinookcorp.com\n", - "2\tEdwards\tNancy\tSales Manager\t1\t1958-12-08 00:00:00\t2002-05-01 00:00:00\t825 8 Ave SW\tCalgary\tAB\tCanada\tT2P 2T3\t+1 (403) 262-3443\t+1 (403) 262-3322\tnancy@chinookcorp.com\n", - "3\tPeacock\tJane\tSales Support Agent\t2\t1973-08-29 00:00:00\t2002-04-01 00:00:00\t1111 6 Ave SW\tCalgary\tAB\tCanada\tT2P 5M5\t+1 (403) 262-3443\t+1 (403) 262-6712\tjane@chinookcorp.com\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"Invoice\" (\n", - "\t\"InvoiceId\" INTEGER NOT NULL, \n", - "\t\"CustomerId\" INTEGER NOT NULL, \n", - "\t\"InvoiceDate\" DATETIME NOT NULL, \n", - "\t\"BillingAddress\" NVARCHAR(70), \n", - "\t\"BillingCity\" NVARCHAR(40), \n", - "\t\"BillingState\" NVARCHAR(40), \n", - "\t\"BillingCountry\" NVARCHAR(40), \n", - "\t\"BillingPostalCode\" NVARCHAR(10), \n", - "\t\"Total\" NUMERIC(10, 2) NOT NULL, \n", - "\tPRIMARY KEY (\"InvoiceId\"), \n", - "\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Invoice table:\n", - "InvoiceId\tCustomerId\tInvoiceDate\tBillingAddress\tBillingCity\tBillingState\tBillingCountry\tBillingPostalCode\tTotal\n", - "1\t2\t2009-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n", - "2\t4\t2009-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n", - "3\t8\t2009-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n", - "*/\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_TQyoJSV78xEWHqc69PiYHjdS)\n", - " Call ID: call_TQyoJSV78xEWHqc69PiYHjdS\n", - " Args:\n", - " query: SELECT e.FirstName, e.LastName, SUM(i.Total) as TotalSales\n", - "FROM Employee e\n", - "JOIN Customer c ON e.EmployeeId = c.SupportRepId\n", - "JOIN Invoice i ON c.CustomerId = i.CustomerId\n", - "WHERE strftime('%Y', i.InvoiceDate) = '2009'\n", - "GROUP BY e.EmployeeId\n", - "ORDER BY TotalSales DESC\n", - "LIMIT 1;\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_tSQOuxc7iQ1jvLzXSofCqK4V)\n", - " Call ID: call_tSQOuxc7iQ1jvLzXSofCqK4V\n", - " Args:\n", - " query: SELECT e.FirstName, e.LastName, SUM(i.Total) as TotalSales\n", - "FROM Employee e\n", - "JOIN Customer c ON e.EmployeeId = c.SupportRepId\n", - "JOIN Invoice i ON c.CustomerId = i.CustomerId\n", - "WHERE strftime('%Y', i.InvoiceDate) = '2009'\n", - "GROUP BY e.EmployeeId\n", - "ORDER BY TotalSales DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query\n", - "\n", - "[('Steve', 'Johnson', 164.34)]\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "The sales agent who made the most in sales in 2009 was Steve Johnson, with total sales of 164.34.\n" - ] - } - ], - "source": [ - "question = \"Which sales agent made the most in sales in 2009?\"\n", - "\n", - "for step in agent.stream(\n", - " {\"messages\": [{\"role\": \"user\", \"content\": question}]},\n", - " stream_mode=\"values\",\n", - "):\n", - " step[\"messages\"][-1].pretty_print()" - ] - }, - { - "cell_type": "markdown", - "id": "fc3d8130-15c3-4c22-bb17-eb82ad41586e", - "metadata": {}, - "source": [ - "!!! tip\n", - "\n", - " See [LangSmith trace](https://smith.langchain.com/public/36a9ebbb-7cc4-4c54-b4db-cb12e124a649/r) for the above run." - ] - }, - { - "cell_type": "markdown", - "id": "838b3acf-3186-4aa1-b211-cf136e95c39d", - "metadata": {}, - "source": [ - "## Next steps\n", - "\n", - "Check out [this guide](https://docs.smith.langchain.com/evaluation/how_to_guides/langgraph) for evaluating LangGraph applications, including SQL agents like this one, using LangSmith." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/docs/tutorials/sql/output.png b/docs/docs/tutorials/sql/output.png new file mode 100644 index 000000000..006d100aa Binary files /dev/null and b/docs/docs/tutorials/sql/output.png differ diff --git a/docs/docs/tutorials/sql/sql-agent.md b/docs/docs/tutorials/sql/sql-agent.md new file mode 100644 index 000000000..84782d371 --- /dev/null +++ b/docs/docs/tutorials/sql/sql-agent.md @@ -0,0 +1,549 @@ +# Build a SQL agent + +In this tutorial, we will walk through how to build an agent that can answer questions about a SQL database. + +At a high level, the agent will: + +1. Fetch the available tables from the database +2. Decide which tables are relevant to the question +3. Fetch the schemas for the relevant tables +4. Generate a query based on the question and information from the schemas +5. Double-check the query for common mistakes using an LLM +6. Execute the query and return the results +7. Correct mistakes surfaced by the database engine until the query is successful +8. Formulate a response based on the results + +!!! warning "Security note" + Building Q&A systems of SQL databases requires executing model-generated SQL queries. There are inherent risks in doing this. Make sure that your database connection permissions are always scoped as narrowly as possible for your agent's needs. This will mitigate though not eliminate the risks of building a model-driven system. + +## 1. Setup + +Let's first install some dependencies. This tutorial uses SQL database and tool abstractions from [langchain-community](https://python.langchain.com/docs/concepts/architecture/#langchain-community). We will also require a LangChain [chat model](https://python.langchain.com/docs/concepts/chat_models/). + +```python +%%capture --no-stderr +%pip install -U langgraph langchain_community "langchain[openai]" +``` + +!!! tip + Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph. + +### Select a LLM + +First we [initialize our LLM](https://python.langchain.com/docs/how_to/chat_models_universal_init/). Any model supporting [tool-calling](https://python.langchain.com/docs/integrations/chat/#featured-providers) should work. We use OpenAI below. + +```python +from langchain.chat_models import init_chat_model + +llm = init_chat_model("openai:gpt-4.1") +``` + +### Configure the database + +We will be creating a SQLite database for this tutorial. SQLite is a lightweight database that is easy to set up and use. We will be loading the `chinook` database, which is a sample database that represents a digital media store. +Find more information about the database [here](https://www.sqlitetutorial.net/sqlite-sample-database/). + +For convenience, we have hosted the database (`Chinook.db`) on a public GCS bucket. + +```python +import requests + +url = "https://storage.googleapis.com/benchmarks-artifacts/chinook/Chinook.db" + +response = requests.get(url) + +if response.status_code == 200: + # Open a local file in binary write mode + with open("Chinook.db", "wb") as file: + # Write the content of the response (the file) to the local file + file.write(response.content) + print("File downloaded and saved as Chinook.db") +else: + print(f"Failed to download the file. Status code: {response.status_code}") +``` + +We will use a handy SQL database wrapper available in the `langchain_community` package to interact with the database. The wrapper provides a simple interface to execute SQL queries and fetch results: + +```python +from langchain_community.utilities import SQLDatabase + +db = SQLDatabase.from_uri("sqlite:///Chinook.db") + +print(f"Dialect: {db.dialect}") +print(f"Available tables: {db.get_usable_table_names()}") +print(f'Sample output: {db.run("SELECT * FROM Artist LIMIT 5;")}') +``` + +**Output:** +``` +Dialect: sqlite +Available tables: ['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track'] +Sample output: [(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains')] +``` + +### Tools for database interactions + +`langchain-community` implements some built-in tools for interacting with our `SQLDatabase`, including tools for listing tables, reading table schemas, and checking and running queries: + +```python +from langchain_community.agent_toolkits import SQLDatabaseToolkit + +toolkit = SQLDatabaseToolkit(db=db, llm=llm) + +tools = toolkit.get_tools() + +for tool in tools: + print(f"{tool.name}: {tool.description}\n") +``` + +**Output:** +``` +sql_db_query: Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields. + +sql_db_schema: Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3 + +sql_db_list_tables: Input is an empty string, output is a comma-separated list of tables in the database. + +sql_db_query_checker: Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query! + +``` + +## 2. Using a prebuilt agent + +Given these tools, we can initialize a pre-built agent in a single line. To customize our agents behavior, we write a descriptive system prompt. + +```python +from langgraph.prebuilt import create_react_agent + +system_prompt = """ +You are an agent designed to interact with a SQL database. +Given an input question, create a syntactically correct {dialect} query to run, +then look at the results of the query and return the answer. Unless the user +specifies a specific number of examples they wish to obtain, always limit your +query to at most {top_k} results. + +You can order the results by a relevant column to return the most interesting +examples in the database. Never query for all the columns from a specific table, +only ask for the relevant columns given the question. + +You MUST double check your query before executing it. If you get an error while +executing a query, rewrite the query and try again. + +DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the +database. + +To start you should ALWAYS look at the tables in the database to see what you +can query. Do NOT skip this step. + +Then you should query the schema of the most relevant tables. +""".format( + dialect=db.dialect, + top_k=5, +) + +agent = create_react_agent( + llm, + tools, + prompt=system_prompt, +) +``` + +!!! note + This system prompt includes a number of instructions, such as always running specific tools before or after others. In the [next section](#3-customizing-the-agent), we will enforce these behaviors through the graph's structure, providing us a greater degree of control and allowing us to simplify the prompt. + +Let's run this agent on a sample query and observe its behavior: + +```python +question = "Which genre on average has the longest tracks?" + +for step in agent.stream( + {"messages": [{"role": "user", "content": question}]}, + stream_mode="values", +): + step["messages"][-1].pretty_print() +``` + +**Output:** +``` +================================ Human Message ================================= + +Which genre on average has the longest tracks? +================================== Ai Message ================================== +Tool Calls: + sql_db_list_tables (call_d8lCgywSroCgpVl558nmXKwA) + Call ID: call_d8lCgywSroCgpVl558nmXKwA + Args: +================================= Tool Message ================================= +Name: sql_db_list_tables + +Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track +================================== Ai Message ================================== +Tool Calls: + sql_db_schema (call_nNf6IIUcwMYLIkE0l6uWkZHe) + Call ID: call_nNf6IIUcwMYLIkE0l6uWkZHe + Args: + table_names: Genre, Track +================================= Tool Message ================================= +Name: sql_db_schema + + +CREATE TABLE "Genre" ( + "GenreId" INTEGER NOT NULL, + "Name" NVARCHAR(120), + PRIMARY KEY ("GenreId") +) + +/* +3 rows from Genre table: +GenreId Name +1 Rock +2 Jazz +3 Metal +*/ + + +CREATE TABLE "Track" ( + "TrackId" INTEGER NOT NULL, + "Name" NVARCHAR(200) NOT NULL, + "AlbumId" INTEGER, + "MediaTypeId" INTEGER NOT NULL, + "GenreId" INTEGER, + "Composer" NVARCHAR(220), + "Milliseconds" INTEGER NOT NULL, + "Bytes" INTEGER, + "UnitPrice" NUMERIC(10, 2) NOT NULL, + PRIMARY KEY ("TrackId"), + FOREIGN KEY("MediaTypeId") REFERENCES "MediaType" ("MediaTypeId"), + FOREIGN KEY("GenreId") REFERENCES "Genre" ("GenreId"), + FOREIGN KEY("AlbumId") REFERENCES "Album" ("AlbumId") +) + +/* +3 rows from Track table: +TrackId Name AlbumId MediaTypeId GenreId Composer Milliseconds Bytes UnitPrice +1 For Those About To Rock (We Salute You) 1 1 1 Angus Young, Malcolm Young, Brian Johnson 343719 11170334 0.99 +2 Balls to the Wall 2 2 1 None 342562 5510424 0.99 +3 Fast As a Shark 3 2 1 F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman 230619 3990994 0.99 +*/ +================================== Ai Message ================================== +Tool Calls: + sql_db_query_checker (call_urTRmtiGtTxkwHtscec7Fd2K) + Call ID: call_urTRmtiGtTxkwHtscec7Fd2K + Args: + query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds +FROM Track +JOIN Genre ON Track.GenreId = Genre.GenreId +GROUP BY Genre.Name +ORDER BY AvgMilliseconds DESC +LIMIT 1; +================================= Tool Message ================================= +Name: sql_db_query_checker + +\`\`\`sql +SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds +FROM Track +JOIN Genre ON Track.GenreId = Genre.GenreId +GROUP BY Genre.Name +ORDER BY AvgMilliseconds DESC +LIMIT 1; +\`\`\` +================================== Ai Message ================================== +Tool Calls: + sql_db_query (call_RNMqyUEMv0rvy0UxSwrXY2AV) + Call ID: call_RNMqyUEMv0rvy0UxSwrXY2AV + Args: + query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds +FROM Track +JOIN Genre ON Track.GenreId = Genre.GenreId +GROUP BY Genre.Name +ORDER BY AvgMilliseconds DESC +LIMIT 1; +================================= Tool Message ================================= +Name: sql_db_query + +[('Sci Fi & Fantasy', 2911783.0384615385)] +================================== Ai Message ================================== + +The genre with the longest average track length is "Sci Fi & Fantasy," with an average duration of about 2,911,783 milliseconds (approximately 48.5 minutes) per track. +``` + +This worked well enough: the agent correctly listed the tables, obtained the schemas, wrote a query, checked the query, and ran it to inform its final response. + +!!! tip + You can inspect all aspects of the above run, including steps taken, tools invoked, what prompts were seen by the LLM, and more in the [LangSmith trace](https://smith.langchain.com/public/bd594960-73e3-474b-b6f2-db039d7c713a/r). + +## 3. Customizing the agent + +The prebuilt agent lets us get started quickly, but at each step the agent has access to the full set of tools. Above, we relied on the system prompt to constrain its behavior— for example, we instructed the agent to always start with the "list tables" tool, and to always run a query-checker tool before executing the query. + +We can enforce a higher degree of control in LangGraph by customizing the agent. Below, we implement a simple ReAct-agent setup, with dedicated nodes for specific tool-calls. We will use the same [state](../../concepts/low_level.md#state) as the pre-built agent. + +We construct dedicated nodes for the following steps: + +- Listing DB tables +- Calling the "get schema" tool +- Generating a query +- Checking the query + +Putting these steps in dedicated nodes lets us (1) force tool-calls when needed, and (2) customize the prompts associated with each step. + +```python +from typing import Literal +from langchain_core.messages import AIMessage +from langchain_core.runnables import RunnableConfig +from langgraph.graph import END, START, MessagesState, StateGraph +from langgraph.prebuilt import ToolNode + + +get_schema_tool = next(tool for tool in tools if tool.name == "sql_db_schema") +get_schema_node = ToolNode([get_schema_tool], name="get_schema") + +run_query_tool = next(tool for tool in tools if tool.name == "sql_db_query") +run_query_node = ToolNode([run_query_tool], name="run_query") + + +# Example: create a predetermined tool call +def list_tables(state: MessagesState): + tool_call = { + "name": "sql_db_list_tables", + "args": {}, + "id": "abc123", + "type": "tool_call", + } + tool_call_message = AIMessage(content="", tool_calls=[tool_call]) + + list_tables_tool = next(tool for tool in tools if tool.name == "sql_db_list_tables") + tool_message = list_tables_tool.invoke(tool_call) + response = AIMessage(f"Available tables: {tool_message.content}") + + return {"messages": [tool_call_message, tool_message, response]} + + +# Example: force a model to create a tool call +def call_get_schema(state: MessagesState): + # Note that LangChain enforces that all models accept `tool_choice="any"` + # as well as `tool_choice=`. + llm_with_tools = llm.bind_tools([get_schema_tool], tool_choice="any") + response = llm_with_tools.invoke(state["messages"]) + + return {"messages": [response]} + + +generate_query_system_prompt = """ +You are an agent designed to interact with a SQL database. +Given an input question, create a syntactically correct {dialect} query to run, +then look at the results of the query and return the answer. Unless the user +specifies a specific number of examples they wish to obtain, always limit your +query to at most {top_k} results. + +You can order the results by a relevant column to return the most interesting +examples in the database. Never query for all the columns from a specific table, +only ask for the relevant columns given the question. + +DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database. +""".format( + dialect=db.dialect, + top_k=5, +) + + +def generate_query(state: MessagesState): + system_message = { + "role": "system", + "content": generate_query_system_prompt, + } + # We do not force a tool call here, to allow the model to + # respond naturally when it obtains the solution. + llm_with_tools = llm.bind_tools([run_query_tool]) + response = llm_with_tools.invoke([system_message] + state["messages"]) + + return {"messages": [response]} + + +check_query_system_prompt = """ +You are a SQL expert with a strong attention to detail. +Double check the {dialect} query for common mistakes, including: +- Using NOT IN with NULL values +- Using UNION when UNION ALL should have been used +- Using BETWEEN for exclusive ranges +- Data type mismatch in predicates +- Properly quoting identifiers +- Using the correct number of arguments for functions +- Casting to the correct data type +- Using the proper columns for joins + +If there are any of the above mistakes, rewrite the query. If there are no mistakes, +just reproduce the original query. + +You will call the appropriate tool to execute the query after running this check. +""".format(dialect=db.dialect) + + +def check_query(state: MessagesState): + system_message = { + "role": "system", + "content": check_query_system_prompt, + } + + # Generate an artificial user message to check + tool_call = state["messages"][-1].tool_calls[0] + user_message = {"role": "user", "content": tool_call["args"]["query"]} + llm_with_tools = llm.bind_tools([run_query_tool], tool_choice="any") + response = llm_with_tools.invoke([system_message, user_message]) + response.id = state["messages"][-1].id + + return {"messages": [response]} +``` + +Finally, we assemble these steps into a workflow using the Graph API. We define a [conditional edge](../../concepts/low_level.md#conditional-edges) at the query generation step that will route to the query checker if a query is generated, or end if there are no tool calls present, such that the LLM has delivered a response to the query. + +```python +def should_continue(state: MessagesState) -> Literal[END, "check_query"]: + messages = state["messages"] + last_message = messages[-1] + if not last_message.tool_calls: + return END + else: + return "check_query" + + +builder = StateGraph(MessagesState) +builder.add_node(list_tables) +builder.add_node(call_get_schema) +builder.add_node(get_schema_node, "get_schema") +builder.add_node(generate_query) +builder.add_node(check_query) +builder.add_node(run_query_node, "run_query") + +builder.add_edge(START, "list_tables") +builder.add_edge("list_tables", "call_get_schema") +builder.add_edge("call_get_schema", "get_schema") +builder.add_edge("get_schema", "generate_query") +builder.add_conditional_edges( + "generate_query", + should_continue, +) +builder.add_edge("check_query", "run_query") +builder.add_edge("run_query", "generate_query") + +agent = builder.compile() +``` + +We visualize the application below: + +```python +from IPython.display import Image, display +from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles + +display(Image(agent.get_graph().draw_mermaid_png())) +``` + +![Graph](./output.png) + +**Note:** When you run this code, it will generate and display a visual representation of the SQL agent graph showing the flow between the different nodes (list_tables → call_get_schema → get_schema → generate_query → check_query → run_query). + +We can now invoke the graph exactly as before: + +```python +question = "Which genre on average has the longest tracks?" + +for step in agent.stream( + {"messages": [{"role": "user", "content": question}]}, + stream_mode="values", +): + step["messages"][-1].pretty_print() +``` + +**Output:** +``` +================================ Human Message ================================= + +Which genre on average has the longest tracks? +================================== Ai Message ================================== + +Available tables: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track +================================== Ai Message ================================== +Tool Calls: + sql_db_schema (call_qxKtYiHgf93AiTDin9ez5wFp) + Call ID: call_qxKtYiHgf93AiTDin9ez5wFp + Args: + table_names: Genre,Track +================================= Tool Message ================================= +Name: sql_db_schema + + +CREATE TABLE "Genre" ( + "GenreId" INTEGER NOT NULL, + "Name" NVARCHAR(120), + PRIMARY KEY ("GenreId") +) + +/* +3 rows from Genre table: +GenreId Name +1 Rock +2 Jazz +3 Metal +*/ + + +CREATE TABLE "Track" ( + "TrackId" INTEGER NOT NULL, + "Name" NVARCHAR(200) NOT NULL, + "AlbumId" INTEGER, + "MediaTypeId" INTEGER NOT NULL, + "GenreId" INTEGER, + "Composer" NVARCHAR(220), + "Milliseconds" INTEGER NOT NULL, + "Bytes" INTEGER, + "UnitPrice" NUMERIC(10, 2) NOT NULL, + PRIMARY KEY ("TrackId"), + FOREIGN KEY("MediaTypeId") REFERENCES "MediaType" ("MediaTypeId"), + FOREIGN KEY("GenreId") REFERENCES "Genre" ("GenreId"), + FOREIGN KEY("AlbumId") REFERENCES "Album" ("AlbumId") +) + +/* +3 rows from Track table: +TrackId Name AlbumId MediaTypeId GenreId Composer Milliseconds Bytes UnitPrice +1 For Those About To Rock (We Salute You) 1 1 1 Angus Young, Malcolm Young, Brian Johnson 343719 11170334 0.99 +2 Balls to the Wall 2 2 1 None 342562 5510424 0.99 +3 Fast As a Shark 3 2 1 F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman 230619 3990994 0.99 +*/ +================================== Ai Message ================================== +Tool Calls: + sql_db_query (call_RPN3GABMfb6DTaFTLlwnZxVN) + Call ID: call_RPN3GABMfb6DTaFTLlwnZxVN + Args: + query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength +FROM Track +JOIN Genre ON Track.GenreId = Genre.GenreId +GROUP BY Genre.GenreId +ORDER BY AvgTrackLength DESC +LIMIT 1; +================================== Ai Message ================================== +Tool Calls: + sql_db_query (call_PR4s8ymiF3ZQLaoZADXtdqcl) + Call ID: call_PR4s8ymiF3ZQLaoZADXtdqcl + Args: + query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength +FROM Track +JOIN Genre ON Track.GenreId = Genre.GenreId +GROUP BY Genre.GenreId +ORDER BY AvgTrackLength DESC +LIMIT 1; +================================= Tool Message ================================= +Name: sql_db_query + +[('Sci Fi & Fantasy', 2911783.0384615385)] +================================== Ai Message ================================== + +The genre with the longest tracks on average is "Sci Fi & Fantasy," with an average track length of approximately 2,911,783 milliseconds. +``` + +!!! tip + See [LangSmith trace](https://smith.langchain.com/public/94b8c9ac-12f7-4692-8706-836a1f30f1ea/r) for the above run. + +## Next steps + +Check out [this guide](https://docs.smith.langchain.com/evaluation/how_to_guides/langgraph) for evaluating LangGraph applications, including SQL agents like this one, using LangSmith. \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 7cfbb246f..a66966905 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -109,6 +109,7 @@ nav: - Agent architectures: concepts/agentic_concepts.md - Guides: + - guides/index.md - LangGraph APIs: - Graph API: - Overview: concepts/low_level.md @@ -268,25 +269,26 @@ nav: - Environment variables: cloud/reference/env_var.md - Examples: + - examples/index.md - Template applications: concepts/template_applications.md # TODO: make tutorial - - Agentic RAG: tutorials/rag/langgraph_agentic_rag.ipynb - - Agent Supervisor: tutorials/multi_agent/agent_supervisor.ipynb - - SQL agent: tutorials/sql-agent.ipynb + - Agentic RAG: tutorials/rag/langgraph_agentic_rag.md + - Agent Supervisor: tutorials/multi_agent/agent_supervisor.md + - SQL agent: tutorials/sql/sql-agent.md - Prebuilt chat UI: agents/ui.md - - Graph runs in LangSmith: how-tos/run-id-langsmith.ipynb + - Graph runs in LangSmith: how-tos/run-id-langsmith.md - LangGraph Platform: - Authentication: - tutorials/auth/getting_started.md - tutorials/auth/resource_auth.md - tutorials/auth/add_auth_server.md - Use RemoteGraph: how-tos/use-remote-graph.md - - Deploy CrewAI, AutoGen, and other frameworks: how-tos/autogen-langgraph-platform.ipynb - # combine with how-tos/autogen-integration.ipynb + - Deploy CrewAI, AutoGen, and other frameworks: how-tos/autogen-integration.md - Front-end and generative UI: - Integrate LangGraph into a React app: cloud/how-tos/use_stream_react.md - Implement generative UI with LangGraph: cloud/how-tos/generative_ui_react.md - Additional resources: + - additional-resources/index.md - agents/prebuilt.md # NOTE: prebuilt.md is auto-generated by `make build-prebuilt` - LangGraph Academy course: https://academy.langchain.com/courses/intro-to-langgraph - Case studies: adopters.md diff --git a/docs/overrides/main.html b/docs/overrides/main.html index 12a20dfbb..b3e63c56d 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -184,7 +184,12 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= visibility: hidden; } - /* Dark mode banner links */ + /* Dark mode banner styling */ + [data-md-color-scheme="slate"] .md-banner { + background-color: #CFC9FA; /* Same light purple for both modes */ + color: #000000; + } + [data-md-color-scheme="slate"] .md-banner a { color: #000000; } @@ -220,5 +225,5 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= {% endblock %} {% block announce %} -We are growing and hiring for multiple roles for LangChain, LangGraph and LangSmith. Join our team! +Our Building Ambient Agents with LangGraph course is now available on LangChain Academy! {% endblock %} diff --git a/examples/human_in_the_loop/breakpoints.ipynb b/examples/human_in_the_loop/breakpoints.ipynb deleted file mode 100644 index 0519ecba6..000000000 --- a/examples/human_in_the_loop/breakpoints.ipynb +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/extract_images.py b/extract_images.py deleted file mode 100644 index 781ba0a22..000000000 --- a/extract_images.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -""" -Script to extract images from the graph-api.ipynb notebook and save them to assets folder. -""" - -import json -import base64 -import os -from pathlib import Path - -def extract_images_from_notebook(notebook_path, assets_dir): - """Extract images from notebook and save them to assets directory.""" - - # Read the notebook - with open(notebook_path, 'r') as f: - notebook = json.load(f) - - # Create assets directory if it doesn't exist - os.makedirs(assets_dir, exist_ok=True) - - image_count = 0 - - # Process each cell - for cell_idx, cell in enumerate(notebook['cells']): - if cell['cell_type'] == 'code': - # Check if this cell contains draw_mermaid_png - source = ''.join(cell.get('source', [])) - if 'draw_mermaid_png' in source: - print(f"Found draw_mermaid_png in cell {cell_idx}") - - # Check for outputs with images - if 'outputs' in cell: - for output_idx, output in enumerate(cell['outputs']): - if output.get('output_type') == 'display_data': - data = output.get('data', {}) - - # Check for PNG data - if 'image/png' in data: - png_data = data['image/png'] - - # Decode base64 data - try: - image_bytes = base64.b64decode(png_data) - - # Generate filename - image_count += 1 - filename = f"graph_api_image_{image_count}.png" - filepath = os.path.join(assets_dir, filename) - - # Save the image - with open(filepath, 'wb') as img_file: - img_file.write(image_bytes) - - print(f"Saved image: {filepath}") - - except Exception as e: - print(f"Error decoding image {image_count}: {e}") - - print(f"Extracted {image_count} images to {assets_dir}") - return image_count - -if __name__ == "__main__": - notebook_path = "docs/docs/how-tos/graph-api.ipynb" - assets_dir = "docs/docs/how-tos/assets" - - if os.path.exists(notebook_path): - count = extract_images_from_notebook(notebook_path, assets_dir) - print(f"Successfully extracted {count} images") - else: - print(f"Notebook not found: {notebook_path}") \ No newline at end of file diff --git a/libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py b/libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py index 9fc7673b2..8775c2df5 100644 --- a/libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py +++ b/libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py @@ -452,7 +452,7 @@ class AsyncPostgresSaver(BasePostgresSaver): while True: try: yield asyncio.run_coroutine_threadsafe( - anext(aiter_), # noqa: F821 + anext(aiter_), # type: ignore[arg-type] # noqa: F821 self.loop, ).result() except StopAsyncIteration: diff --git a/libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py b/libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py index af2aacef8..16f4094ae 100644 --- a/libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py +++ b/libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py @@ -877,7 +877,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver): while True: try: yield asyncio.run_coroutine_threadsafe( - anext(aiter_), # noqa: F821 + anext(aiter_), # type: ignore[arg-type] # noqa: F821 self.loop, ).result() except StopAsyncIteration: diff --git a/libs/checkpoint-postgres/langgraph/store/postgres/base.py b/libs/checkpoint-postgres/langgraph/store/postgres/base.py index 6b57cebae..bf17c20cd 100644 --- a/libs/checkpoint-postgres/langgraph/store/postgres/base.py +++ b/libs/checkpoint-postgres/langgraph/store/postgres/base.py @@ -448,10 +448,8 @@ class BasePostgresStore(Generic[C]): score_operator, post_operator = get_distance_operator(self) post_operator = post_operator.replace("scored", "uniq") - vector_type = ( - cast(PostgresIndexConfig, self.index_config) - .get("ann_index_config", {}) - .get("vector_type", "vector") + vector_type = self.index_config.get("ann_index_config", {}).get( + "vector_type", "vector" ) # For hamming bit vectors, or “regular” vectors @@ -1141,7 +1139,7 @@ def _get_vector_type_ops(store: BasePostgresStore) -> str: if not store.index_config: return "vector_cosine_ops" - config = cast(PostgresIndexConfig, store.index_config) + config = store.index_config index_config = config.get("ann_index_config", _DEFAULT_ANN_CONFIG).copy() vector_type = cast(str, index_config.get("vector_type", "vector")) if vector_type not in ("vector", "halfvec"): diff --git a/libs/checkpoint-postgres/uv.lock b/libs/checkpoint-postgres/uv.lock index 45161991d..ff12c6faa 100644 --- a/libs/checkpoint-postgres/uv.lock +++ b/libs/checkpoint-postgres/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 2 requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version < '3.12.4'", -] [[package]] name = "annotated-types" @@ -32,11 +28,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -205,7 +201,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.12.4'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -290,7 +286,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.60" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -301,9 +297,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/75/95129aaada92980a002a31e002610a80af3c8967ae7884710372e89cdde0/langchain_core-0.3.60.tar.gz", hash = "sha256:63dd1bdf7939816115399522661ca85a2f3686a61440f2f46ebd86d1b028595b", size = 557456, upload-time = "2025-05-15T15:23:23.642Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/bc/344f5b11fdfe0e27f7064d2e829921a791461dc32e5ed285fe6325518c26/langchain_core-0.3.60-py3-none-any.whl", hash = "sha256:2ccdf06b12e699b1b0962bc02837056c075b4981c3d13f82a4d4c30bb22ea3dc", size = 437890, upload-time = "2025-05-15T15:23:22.278Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] @@ -385,7 +381,7 @@ dev = [ [[package]] name = "langsmith" -version = "0.3.42" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -396,53 +392,54 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/44/fe171c0b0fb0377b191aebf0b7779e0c7b2a53693c6a01ddad737212495d/langsmith-0.3.42.tar.gz", hash = "sha256:2b5cbc450ab808b992362aac6943bb1d285579aa68a3a8be901d30a393458f25", size = 345619, upload-time = "2025-05-03T03:07:17.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload-time = "2025-06-27T19:20:36.207Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8e/e8a58e0abaae3f3ac4702e9ca35d1fc6159711556b64ffd0e247771a3f12/langsmith-0.3.42-py3-none-any.whl", hash = "sha256:18114327f3364385dae4026ebfd57d1c1cb46d8f80931098f0f10abe533475ff", size = 360334, upload-time = "2025-05-03T03:07:15.491Z" }, + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload-time = "2025-06-27T19:20:33.839Z" }, ] [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -590,6 +587,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -702,7 +708,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.4" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -710,9 +716,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -824,9 +830,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -834,36 +849,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -934,7 +950,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -942,9 +958,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -961,27 +977,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.11.10" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -1043,23 +1059,23 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] @@ -1073,11 +1089,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] diff --git a/libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/aio.py b/libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/aio.py index 6ee30b259..1f40c6229 100644 --- a/libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/aio.py +++ b/libs/checkpoint-sqlite/langgraph/checkpoint/sqlite/aio.py @@ -203,7 +203,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]): while True: try: yield asyncio.run_coroutine_threadsafe( - anext(aiter_), # noqa: F821 + anext(aiter_), # type: ignore[arg-type] # noqa: F821 self.loop, ).result() except StopAsyncIteration: diff --git a/libs/checkpoint-sqlite/uv.lock b/libs/checkpoint-sqlite/uv.lock index f2d58d81f..a7615b59e 100644 --- a/libs/checkpoint-sqlite/uv.lock +++ b/libs/checkpoint-sqlite/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 2 requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version < '3.12.4'", -] [[package]] name = "aiosqlite" @@ -44,11 +40,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -217,7 +213,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.12.4'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -302,7 +298,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.60" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -313,9 +309,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/75/95129aaada92980a002a31e002610a80af3c8967ae7884710372e89cdde0/langchain_core-0.3.60.tar.gz", hash = "sha256:63dd1bdf7939816115399522661ca85a2f3686a61440f2f46ebd86d1b028595b", size = 557456, upload-time = "2025-05-15T15:23:23.642Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/bc/344f5b11fdfe0e27f7064d2e829921a791461dc32e5ed285fe6325518c26/langchain_core-0.3.60-py3-none-any.whl", hash = "sha256:2ccdf06b12e699b1b0962bc02837056c075b4981c3d13f82a4d4c30bb22ea3dc", size = 437890, upload-time = "2025-05-15T15:23:22.278Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] @@ -393,7 +389,7 @@ dev = [ [[package]] name = "langsmith" -version = "0.3.42" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -404,53 +400,54 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/44/fe171c0b0fb0377b191aebf0b7779e0c7b2a53693c6a01ddad737212495d/langsmith-0.3.42.tar.gz", hash = "sha256:2b5cbc450ab808b992362aac6943bb1d285579aa68a3a8be901d30a393458f25", size = 345619, upload-time = "2025-05-03T03:07:17.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload-time = "2025-06-27T19:20:36.207Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8e/e8a58e0abaae3f3ac4702e9ca35d1fc6159711556b64ffd0e247771a3f12/langsmith-0.3.42-py3-none-any.whl", hash = "sha256:18114327f3364385dae4026ebfd57d1c1cb46d8f80931098f0f10abe533475ff", size = 360334, upload-time = "2025-05-03T03:07:15.491Z" }, + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload-time = "2025-06-27T19:20:33.839Z" }, ] [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -598,6 +595,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -618,7 +624,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.4" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -626,9 +632,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -740,9 +746,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -750,36 +765,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -862,7 +878,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -870,9 +886,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -889,27 +905,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.11.10" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -983,32 +999,32 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] diff --git a/libs/checkpoint/uv.lock b/libs/checkpoint/uv.lock index 0fad33ab7..b77cf894b 100644 --- a/libs/checkpoint/uv.lock +++ b/libs/checkpoint/uv.lock @@ -2,8 +2,7 @@ version = 1 revision = 2 requires-python = ">=3.9" resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version >= '3.12' and python_full_version < '3.12.4'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", @@ -35,11 +34,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -306,7 +305,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.60" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -317,9 +316,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/75/95129aaada92980a002a31e002610a80af3c8967ae7884710372e89cdde0/langchain_core-0.3.60.tar.gz", hash = "sha256:63dd1bdf7939816115399522661ca85a2f3686a61440f2f46ebd86d1b028595b", size = 557456, upload-time = "2025-05-15T15:23:23.642Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/bc/344f5b11fdfe0e27f7064d2e829921a791461dc32e5ed285fe6325518c26/langchain_core-0.3.60-py3-none-any.whl", hash = "sha256:2ccdf06b12e699b1b0962bc02837056c075b4981c3d13f82a4d4c30bb22ea3dc", size = 437890, upload-time = "2025-05-15T15:23:22.278Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] @@ -338,10 +337,10 @@ dev = [ { name = "mypy" }, { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pandas" }, { name = "pandas-stubs", version = "2.2.2.240807", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pandas-stubs", version = "2.2.3.250527", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pandas-stubs", version = "2.3.0.250703", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-mock" }, @@ -372,7 +371,7 @@ dev = [ [[package]] name = "langsmith" -version = "0.3.42" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -383,9 +382,9 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/44/fe171c0b0fb0377b191aebf0b7779e0c7b2a53693c6a01ddad737212495d/langsmith-0.3.42.tar.gz", hash = "sha256:2b5cbc450ab808b992362aac6943bb1d285579aa68a3a8be901d30a393458f25", size = 345619, upload-time = "2025-05-03T03:07:17.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload-time = "2025-06-27T19:20:36.207Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8e/e8a58e0abaae3f3ac4702e9ca35d1fc6159711556b64ffd0e247771a3f12/langsmith-0.3.42-py3-none-any.whl", hash = "sha256:18114327f3364385dae4026ebfd57d1c1cb46d8f80931098f0f10abe533475ff", size = 360334, upload-time = "2025-05-03T03:07:15.491Z" }, + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload-time = "2025-06-27T19:20:33.839Z" }, ] [[package]] @@ -402,46 +401,47 @@ wheels = [ [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -575,65 +575,64 @@ wheels = [ [[package]] name = "numpy" -version = "2.3.0" +version = "2.3.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version >= '3.12' and python_full_version < '3.12.4'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b", size = 20390372, upload-time = "2025-06-21T12:28:33.469Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/5f/df67435257d827eb3b8af66f585223dc2c3f2eb7ad0b50cb1dae2f35f494/numpy-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c3c9fdde0fa18afa1099d6257eb82890ea4f3102847e692193b54e00312a9ae9", size = 21199688, upload-time = "2025-06-07T14:36:52.067Z" }, - { url = "https://files.pythonhosted.org/packages/e5/ce/aad219575055d6c9ef29c8c540c81e1c38815d3be1fe09cdbe53d48ee838/numpy-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46d16f72c2192da7b83984aa5455baee640e33a9f1e61e656f29adf55e406c2b", size = 14359277, upload-time = "2025-06-07T14:37:15.325Z" }, - { url = "https://files.pythonhosted.org/packages/29/6b/2d31da8e6d2ec99bed54c185337a87f8fbeccc1cd9804e38217e92f3f5e2/numpy-2.3.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a0be278be9307c4ab06b788f2a077f05e180aea817b3e41cebbd5aaf7bd85ed3", size = 5376069, upload-time = "2025-06-07T14:37:25.636Z" }, - { url = "https://files.pythonhosted.org/packages/7d/2a/6c59a062397553ec7045c53d5fcdad44e4536e54972faa2ba44153bca984/numpy-2.3.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:99224862d1412d2562248d4710126355d3a8db7672170a39d6909ac47687a8a4", size = 6913057, upload-time = "2025-06-07T14:37:37.215Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5a/8df16f258d28d033e4f359e29d3aeb54663243ac7b71504e89deeb813202/numpy-2.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2393a914db64b0ead0ab80c962e42d09d5f385802006a6c87835acb1f58adb96", size = 14568083, upload-time = "2025-06-07T14:37:59.337Z" }, - { url = "https://files.pythonhosted.org/packages/0a/92/0528a563dfc2cdccdcb208c0e241a4bb500d7cde218651ffb834e8febc50/numpy-2.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:7729c8008d55e80784bd113787ce876ca117185c579c0d626f59b87d433ea779", size = 16929402, upload-time = "2025-06-07T14:38:24.343Z" }, - { url = "https://files.pythonhosted.org/packages/e4/2f/e7a8c8d4a2212c527568d84f31587012cf5497a7271ea1f23332142f634e/numpy-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:06d4fb37a8d383b769281714897420c5cc3545c79dc427df57fc9b852ee0bf58", size = 15879193, upload-time = "2025-06-07T14:38:48.007Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c3/dada3f005953847fe35f42ac0fe746f6e1ea90b4c6775e4be605dcd7b578/numpy-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c39ec392b5db5088259c68250e342612db82dc80ce044cf16496cf14cf6bc6f8", size = 18665318, upload-time = "2025-06-07T14:39:15.794Z" }, - { url = "https://files.pythonhosted.org/packages/3b/ae/3f448517dedefc8dd64d803f9d51a8904a48df730e00a3c5fb1e75a60620/numpy-2.3.0-cp311-cp311-win32.whl", hash = "sha256:ee9d3ee70d62827bc91f3ea5eee33153212c41f639918550ac0475e3588da59f", size = 6601108, upload-time = "2025-06-07T14:39:27.176Z" }, - { url = "https://files.pythonhosted.org/packages/8c/4a/556406d2bb2b9874c8cbc840c962683ac28f21efbc9b01177d78f0199ca1/numpy-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:43c55b6a860b0eb44d42341438b03513cf3879cb3617afb749ad49307e164edd", size = 13021525, upload-time = "2025-06-07T14:39:46.637Z" }, - { url = "https://files.pythonhosted.org/packages/ed/ee/bf54278aef30335ffa9a189f869ea09e1a195b3f4b93062164a3b02678a7/numpy-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:2e6a1409eee0cb0316cb64640a49a49ca44deb1a537e6b1121dc7c458a1299a8", size = 10170327, upload-time = "2025-06-07T14:40:02.703Z" }, - { url = "https://files.pythonhosted.org/packages/89/59/9df493df81ac6f76e9f05cdbe013cdb0c9a37b434f6e594f5bd25e278908/numpy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:389b85335838155a9076e9ad7f8fdba0827496ec2d2dc32ce69ce7898bde03ba", size = 20897025, upload-time = "2025-06-07T14:40:33.558Z" }, - { url = "https://files.pythonhosted.org/packages/2f/86/4ff04335901d6cf3a6bb9c748b0097546ae5af35e455ae9b962ebff4ecd7/numpy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9498f60cd6bb8238d8eaf468a3d5bb031d34cd12556af53510f05fcf581c1b7e", size = 14129882, upload-time = "2025-06-07T14:40:55.034Z" }, - { url = "https://files.pythonhosted.org/packages/71/8d/a942cd4f959de7f08a79ab0c7e6cecb7431d5403dce78959a726f0f57aa1/numpy-2.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:622a65d40d8eb427d8e722fd410ac3ad4958002f109230bc714fa551044ebae2", size = 5110181, upload-time = "2025-06-07T14:41:04.4Z" }, - { url = "https://files.pythonhosted.org/packages/86/5d/45850982efc7b2c839c5626fb67fbbc520d5b0d7c1ba1ae3651f2f74c296/numpy-2.3.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b9446d9d8505aadadb686d51d838f2b6688c9e85636a0c3abaeb55ed54756459", size = 6647581, upload-time = "2025-06-07T14:41:14.695Z" }, - { url = "https://files.pythonhosted.org/packages/1a/c0/c871d4a83f93b00373d3eebe4b01525eee8ef10b623a335ec262b58f4dc1/numpy-2.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:50080245365d75137a2bf46151e975de63146ae6d79f7e6bd5c0e85c9931d06a", size = 14262317, upload-time = "2025-06-07T14:41:35.862Z" }, - { url = "https://files.pythonhosted.org/packages/b7/f6/bc47f5fa666d5ff4145254f9e618d56e6a4ef9b874654ca74c19113bb538/numpy-2.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c24bb4113c66936eeaa0dc1e47c74770453d34f46ee07ae4efd853a2ed1ad10a", size = 16633919, upload-time = "2025-06-07T14:42:00.622Z" }, - { url = "https://files.pythonhosted.org/packages/f5/b4/65f48009ca0c9b76df5f404fccdea5a985a1bb2e34e97f21a17d9ad1a4ba/numpy-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4d8d294287fdf685281e671886c6dcdf0291a7c19db3e5cb4178d07ccf6ecc67", size = 15567651, upload-time = "2025-06-07T14:42:24.429Z" }, - { url = "https://files.pythonhosted.org/packages/f1/62/5367855a2018578e9334ed08252ef67cc302e53edc869666f71641cad40b/numpy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6295f81f093b7f5769d1728a6bd8bf7466de2adfa771ede944ce6711382b89dc", size = 18361723, upload-time = "2025-06-07T14:42:51.167Z" }, - { url = "https://files.pythonhosted.org/packages/d4/75/5baed8cd867eabee8aad1e74d7197d73971d6a3d40c821f1848b8fab8b84/numpy-2.3.0-cp312-cp312-win32.whl", hash = "sha256:e6648078bdd974ef5d15cecc31b0c410e2e24178a6e10bf511e0557eed0f2570", size = 6318285, upload-time = "2025-06-07T14:43:02.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/49/d5781eaa1a15acb3b3a3f49dc9e2ff18d92d0ce5c2976f4ab5c0a7360250/numpy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:0898c67a58cdaaf29994bc0e2c65230fd4de0ac40afaf1584ed0b02cd74c6fdd", size = 12732594, upload-time = "2025-06-07T14:43:21.071Z" }, - { url = "https://files.pythonhosted.org/packages/c2/1c/6d343e030815c7c97a1f9fbad00211b47717c7fe446834c224bd5311e6f1/numpy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:bd8df082b6c4695753ad6193018c05aac465d634834dca47a3ae06d4bb22d9ea", size = 9891498, upload-time = "2025-06-07T14:43:36.332Z" }, - { url = "https://files.pythonhosted.org/packages/73/fc/1d67f751fd4dbafc5780244fe699bc4084268bad44b7c5deb0492473127b/numpy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5754ab5595bfa2c2387d241296e0381c21f44a4b90a776c3c1d39eede13a746a", size = 20889633, upload-time = "2025-06-07T14:44:06.839Z" }, - { url = "https://files.pythonhosted.org/packages/e8/95/73ffdb69e5c3f19ec4530f8924c4386e7ba097efc94b9c0aff607178ad94/numpy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d11fa02f77752d8099573d64e5fe33de3229b6632036ec08f7080f46b6649959", size = 14151683, upload-time = "2025-06-07T14:44:28.847Z" }, - { url = "https://files.pythonhosted.org/packages/64/d5/06d4bb31bb65a1d9c419eb5676173a2f90fd8da3c59f816cc54c640ce265/numpy-2.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:aba48d17e87688a765ab1cd557882052f238e2f36545dfa8e29e6a91aef77afe", size = 5102683, upload-time = "2025-06-07T14:44:38.417Z" }, - { url = "https://files.pythonhosted.org/packages/12/8b/6c2cef44f8ccdc231f6b56013dff1d71138c48124334aded36b1a1b30c5a/numpy-2.3.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4dc58865623023b63b10d52f18abaac3729346a7a46a778381e0e3af4b7f3beb", size = 6640253, upload-time = "2025-06-07T14:44:49.359Z" }, - { url = "https://files.pythonhosted.org/packages/62/aa/fca4bf8de3396ddb59544df9b75ffe5b73096174de97a9492d426f5cd4aa/numpy-2.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:df470d376f54e052c76517393fa443758fefcdd634645bc9c1f84eafc67087f0", size = 14258658, upload-time = "2025-06-07T14:45:10.156Z" }, - { url = "https://files.pythonhosted.org/packages/1c/12/734dce1087eed1875f2297f687e671cfe53a091b6f2f55f0c7241aad041b/numpy-2.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:87717eb24d4a8a64683b7a4e91ace04e2f5c7c77872f823f02a94feee186168f", size = 16628765, upload-time = "2025-06-07T14:45:35.076Z" }, - { url = "https://files.pythonhosted.org/packages/48/03/ffa41ade0e825cbcd5606a5669962419528212a16082763fc051a7247d76/numpy-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fa264d56882b59dcb5ea4d6ab6f31d0c58a57b41aec605848b6eb2ef4a43e8", size = 15564335, upload-time = "2025-06-07T14:45:58.797Z" }, - { url = "https://files.pythonhosted.org/packages/07/58/869398a11863310aee0ff85a3e13b4c12f20d032b90c4b3ee93c3b728393/numpy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e651756066a0eaf900916497e20e02fe1ae544187cb0fe88de981671ee7f6270", size = 18360608, upload-time = "2025-06-07T14:46:25.687Z" }, - { url = "https://files.pythonhosted.org/packages/2f/8a/5756935752ad278c17e8a061eb2127c9a3edf4ba2c31779548b336f23c8d/numpy-2.3.0-cp313-cp313-win32.whl", hash = "sha256:e43c3cce3b6ae5f94696669ff2a6eafd9a6b9332008bafa4117af70f4b88be6f", size = 6310005, upload-time = "2025-06-07T14:50:13.138Z" }, - { url = "https://files.pythonhosted.org/packages/08/60/61d60cf0dfc0bf15381eaef46366ebc0c1a787856d1db0c80b006092af84/numpy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:81ae0bf2564cf475f94be4a27ef7bcf8af0c3e28da46770fc904da9abd5279b5", size = 12729093, upload-time = "2025-06-07T14:50:31.82Z" }, - { url = "https://files.pythonhosted.org/packages/66/31/2f2f2d2b3e3c32d5753d01437240feaa32220b73258c9eef2e42a0832866/numpy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:c8738baa52505fa6e82778580b23f945e3578412554d937093eac9205e845e6e", size = 9885689, upload-time = "2025-06-07T14:50:47.888Z" }, - { url = "https://files.pythonhosted.org/packages/f1/89/c7828f23cc50f607ceb912774bb4cff225ccae7131c431398ad8400e2c98/numpy-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:39b27d8b38942a647f048b675f134dd5a567f95bfff481f9109ec308515c51d8", size = 20986612, upload-time = "2025-06-07T14:46:56.077Z" }, - { url = "https://files.pythonhosted.org/packages/dd/46/79ecf47da34c4c50eedec7511e53d57ffdfd31c742c00be7dc1d5ffdb917/numpy-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0eba4a1ea88f9a6f30f56fdafdeb8da3774349eacddab9581a21234b8535d3d3", size = 14298953, upload-time = "2025-06-07T14:47:18.053Z" }, - { url = "https://files.pythonhosted.org/packages/59/44/f6caf50713d6ff4480640bccb2a534ce1d8e6e0960c8f864947439f0ee95/numpy-2.3.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0f1f11d0a1da54927436505a5a7670b154eac27f5672afc389661013dfe3d4f", size = 5225806, upload-time = "2025-06-07T14:47:27.524Z" }, - { url = "https://files.pythonhosted.org/packages/a6/43/e1fd1aca7c97e234dd05e66de4ab7a5be54548257efcdd1bc33637e72102/numpy-2.3.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:690d0a5b60a47e1f9dcec7b77750a4854c0d690e9058b7bef3106e3ae9117808", size = 6735169, upload-time = "2025-06-07T14:47:38.057Z" }, - { url = "https://files.pythonhosted.org/packages/84/89/f76f93b06a03177c0faa7ca94d0856c4e5c4bcaf3c5f77640c9ed0303e1c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8b51ead2b258284458e570942137155978583e407babc22e3d0ed7af33ce06f8", size = 14330701, upload-time = "2025-06-07T14:47:59.113Z" }, - { url = "https://files.pythonhosted.org/packages/aa/f5/4858c3e9ff7a7d64561b20580cf7cc5d085794bd465a19604945d6501f6c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:aaf81c7b82c73bd9b45e79cfb9476cb9c29e937494bfe9092c26aece812818ad", size = 16692983, upload-time = "2025-06-07T14:48:24.196Z" }, - { url = "https://files.pythonhosted.org/packages/08/17/0e3b4182e691a10e9483bcc62b4bb8693dbf9ea5dc9ba0b77a60435074bb/numpy-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f420033a20b4f6a2a11f585f93c843ac40686a7c3fa514060a97d9de93e5e72b", size = 15641435, upload-time = "2025-06-07T14:48:47.712Z" }, - { url = "https://files.pythonhosted.org/packages/4e/d5/463279fda028d3c1efa74e7e8d507605ae87f33dbd0543cf4c4527c8b882/numpy-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d344ca32ab482bcf8735d8f95091ad081f97120546f3d250240868430ce52555", size = 18433798, upload-time = "2025-06-07T14:49:14.866Z" }, - { url = "https://files.pythonhosted.org/packages/0e/1e/7a9d98c886d4c39a2b4d3a7c026bffcf8fbcaf518782132d12a301cfc47a/numpy-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:48a2e8eaf76364c32a1feaa60d6925eaf32ed7a040183b807e02674305beef61", size = 6438632, upload-time = "2025-06-07T14:49:25.67Z" }, - { url = "https://files.pythonhosted.org/packages/fe/ab/66fc909931d5eb230107d016861824f335ae2c0533f422e654e5ff556784/numpy-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ba17f93a94e503551f154de210e4d50c5e3ee20f7e7a1b5f6ce3f22d419b93bb", size = 12868491, upload-time = "2025-06-07T14:49:44.898Z" }, - { url = "https://files.pythonhosted.org/packages/ee/e8/2c8a1c9e34d6f6d600c83d5ce5b71646c32a13f34ca5c518cc060639841c/numpy-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f14e016d9409680959691c109be98c436c6249eaf7f118b424679793607b5944", size = 9935345, upload-time = "2025-06-07T14:50:02.311Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a2/f8c1133f90eaa1c11bbbec1dc28a42054d0ce74bc2c9838c5437ba5d4980/numpy-2.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80b46117c7359de8167cc00a2c7d823bdd505e8c7727ae0871025a86d668283b", size = 21070759, upload-time = "2025-06-07T14:51:18.241Z" }, - { url = "https://files.pythonhosted.org/packages/6c/e0/4c05fc44ba28463096eee5ae2a12832c8d2759cc5bcec34ae33386d3ff83/numpy-2.3.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:5814a0f43e70c061f47abd5857d120179609ddc32a613138cbb6c4e9e2dbdda5", size = 5301054, upload-time = "2025-06-07T14:51:27.413Z" }, - { url = "https://files.pythonhosted.org/packages/8a/3b/6c06cdebe922bbc2a466fe2105f50f661238ea223972a69c7deb823821e7/numpy-2.3.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ef6c1e88fd6b81ac6d215ed71dc8cd027e54d4bf1d2682d362449097156267a2", size = 6817520, upload-time = "2025-06-07T14:51:38.015Z" }, - { url = "https://files.pythonhosted.org/packages/9d/a3/1e536797fd10eb3c5dbd2e376671667c9af19e241843548575267242ea02/numpy-2.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33a5a12a45bb82d9997e2c0b12adae97507ad7c347546190a18ff14c28bbca12", size = 14398078, upload-time = "2025-06-07T14:52:00.122Z" }, - { url = "https://files.pythonhosted.org/packages/7c/61/9d574b10d9368ecb1a0c923952aa593510a20df4940aa615b3a71337c8db/numpy-2.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:54dfc8681c1906d239e95ab1508d0a533c4a9505e52ee2d71a5472b04437ef97", size = 16751324, upload-time = "2025-06-07T14:52:25.077Z" }, - { url = "https://files.pythonhosted.org/packages/39/de/bcad52ce972dc26232629ca3a99721fd4b22c1d2bda84d5db6541913ef9c/numpy-2.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e017a8a251ff4d18d71f139e28bdc7c31edba7a507f72b1414ed902cbe48c74d", size = 12924237, upload-time = "2025-06-07T14:52:44.713Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c7/87c64d7ab426156530676000c94784ef55676df2f13b2796f97722464124/numpy-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ea9e48336a402551f52cd8f593343699003d2353daa4b72ce8d34f66b722070", size = 21199346, upload-time = "2025-06-21T11:47:47.57Z" }, + { url = "https://files.pythonhosted.org/packages/58/0e/0966c2f44beeac12af8d836e5b5f826a407cf34c45cb73ddcdfce9f5960b/numpy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccb7336eaf0e77c1635b232c141846493a588ec9ea777a7c24d7166bb8533ae", size = 14361143, upload-time = "2025-06-21T11:48:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/7d/31/6e35a247acb1bfc19226791dfc7d4c30002cd4e620e11e58b0ddf836fe52/numpy-2.3.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0bb3a4a61e1d327e035275d2a993c96fa786e4913aa089843e6a2d9dd205c66a", size = 5378989, upload-time = "2025-06-21T11:48:19.998Z" }, + { url = "https://files.pythonhosted.org/packages/b0/25/93b621219bb6f5a2d4e713a824522c69ab1f06a57cd571cda70e2e31af44/numpy-2.3.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e344eb79dab01f1e838ebb67aab09965fb271d6da6b00adda26328ac27d4a66e", size = 6912890, upload-time = "2025-06-21T11:48:31.376Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/6b06ed98d11fb32e27fb59468b42383f3877146d3ee639f733776b6ac596/numpy-2.3.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:467db865b392168ceb1ef1ffa6f5a86e62468c43e0cfb4ab6da667ede10e58db", size = 14569032, upload-time = "2025-06-21T11:48:52.563Z" }, + { url = "https://files.pythonhosted.org/packages/75/c9/9bec03675192077467a9c7c2bdd1f2e922bd01d3a69b15c3a0fdcd8548f6/numpy-2.3.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:afed2ce4a84f6b0fc6c1ce734ff368cbf5a5e24e8954a338f3bdffa0718adffb", size = 16930354, upload-time = "2025-06-21T11:49:17.473Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e2/5756a00cabcf50a3f527a0c968b2b4881c62b1379223931853114fa04cda/numpy-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0025048b3c1557a20bc80d06fdeb8cc7fc193721484cca82b2cfa072fec71a93", size = 15879605, upload-time = "2025-06-21T11:49:41.161Z" }, + { url = "https://files.pythonhosted.org/packages/ff/86/a471f65f0a86f1ca62dcc90b9fa46174dd48f50214e5446bc16a775646c5/numpy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5ee121b60aa509679b682819c602579e1df14a5b07fe95671c8849aad8f2115", size = 18666994, upload-time = "2025-06-21T11:50:08.516Z" }, + { url = "https://files.pythonhosted.org/packages/43/a6/482a53e469b32be6500aaf61cfafd1de7a0b0d484babf679209c3298852e/numpy-2.3.1-cp311-cp311-win32.whl", hash = "sha256:a8b740f5579ae4585831b3cf0e3b0425c667274f82a484866d2adf9570539369", size = 6603672, upload-time = "2025-06-21T11:50:19.584Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fb/bb613f4122c310a13ec67585c70e14b03bfc7ebabd24f4d5138b97371d7c/numpy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4580adadc53311b163444f877e0789f1c8861e2698f6b2a4ca852fda154f3ff", size = 13024015, upload-time = "2025-06-21T11:50:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/51/58/2d842825af9a0c041aca246dc92eb725e1bc5e1c9ac89712625db0c4e11c/numpy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:ec0bdafa906f95adc9a0c6f26a4871fa753f25caaa0e032578a30457bff0af6a", size = 10456989, upload-time = "2025-06-21T11:50:55.616Z" }, + { url = "https://files.pythonhosted.org/packages/c6/56/71ad5022e2f63cfe0ca93559403d0edef14aea70a841d640bd13cdba578e/numpy-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2959d8f268f3d8ee402b04a9ec4bb7604555aeacf78b360dc4ec27f1d508177d", size = 20896664, upload-time = "2025-06-21T12:15:30.845Z" }, + { url = "https://files.pythonhosted.org/packages/25/65/2db52ba049813670f7f987cc5db6dac9be7cd95e923cc6832b3d32d87cef/numpy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:762e0c0c6b56bdedfef9a8e1d4538556438288c4276901ea008ae44091954e29", size = 14131078, upload-time = "2025-06-21T12:15:52.23Z" }, + { url = "https://files.pythonhosted.org/packages/57/dd/28fa3c17b0e751047ac928c1e1b6990238faad76e9b147e585b573d9d1bd/numpy-2.3.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:867ef172a0976aaa1f1d1b63cf2090de8b636a7674607d514505fb7276ab08fc", size = 5112554, upload-time = "2025-06-21T12:16:01.434Z" }, + { url = "https://files.pythonhosted.org/packages/c9/fc/84ea0cba8e760c4644b708b6819d91784c290288c27aca916115e3311d17/numpy-2.3.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4e602e1b8682c2b833af89ba641ad4176053aaa50f5cacda1a27004352dde943", size = 6646560, upload-time = "2025-06-21T12:16:11.895Z" }, + { url = "https://files.pythonhosted.org/packages/61/b2/512b0c2ddec985ad1e496b0bd853eeb572315c0f07cd6997473ced8f15e2/numpy-2.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8e333040d069eba1652fb08962ec5b76af7f2c7bce1df7e1418c8055cf776f25", size = 14260638, upload-time = "2025-06-21T12:16:32.611Z" }, + { url = "https://files.pythonhosted.org/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660", size = 16632729, upload-time = "2025-06-21T12:16:57.439Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ff/feb4be2e5c09a3da161b412019caf47183099cbea1132fd98061808c2df2/numpy-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1b8f26d1086835f442286c1d9b64bb3974b0b1e41bb105358fd07d20872952", size = 15565330, upload-time = "2025-06-21T12:17:20.638Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6d/ceafe87587101e9ab0d370e4f6e5f3f3a85b9a697f2318738e5e7e176ce3/numpy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee8340cb48c9b7a5899d1149eece41ca535513a9698098edbade2a8e7a84da77", size = 18361734, upload-time = "2025-06-21T12:17:47.938Z" }, + { url = "https://files.pythonhosted.org/packages/2b/19/0fb49a3ea088be691f040c9bf1817e4669a339d6e98579f91859b902c636/numpy-2.3.1-cp312-cp312-win32.whl", hash = "sha256:e772dda20a6002ef7061713dc1e2585bc1b534e7909b2030b5a46dae8ff077ab", size = 6320411, upload-time = "2025-06-21T12:17:58.475Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3e/e28f4c1dd9e042eb57a3eb652f200225e311b608632bc727ae378623d4f8/numpy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfecc7822543abdea6de08758091da655ea2210b8ffa1faf116b940693d3df76", size = 12734973, upload-time = "2025-06-21T12:18:17.601Z" }, + { url = "https://files.pythonhosted.org/packages/04/a8/8a5e9079dc722acf53522b8f8842e79541ea81835e9b5483388701421073/numpy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:7be91b2239af2658653c5bb6f1b8bccafaf08226a258caf78ce44710a0160d30", size = 10191491, upload-time = "2025-06-21T12:18:33.585Z" }, + { url = "https://files.pythonhosted.org/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8", size = 20889381, upload-time = "2025-06-21T12:19:04.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e", size = 14152726, upload-time = "2025-06-21T12:19:25.599Z" }, + { url = "https://files.pythonhosted.org/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0", size = 5105145, upload-time = "2025-06-21T12:19:34.782Z" }, + { url = "https://files.pythonhosted.org/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d", size = 6639409, upload-time = "2025-06-21T12:19:45.228Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1", size = 14257630, upload-time = "2025-06-21T12:20:06.544Z" }, + { url = "https://files.pythonhosted.org/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1", size = 16627546, upload-time = "2025-06-21T12:20:31.002Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0", size = 15562538, upload-time = "2025-06-21T12:20:54.322Z" }, + { url = "https://files.pythonhosted.org/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8", size = 18360327, upload-time = "2025-06-21T12:21:21.053Z" }, + { url = "https://files.pythonhosted.org/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8", size = 6312330, upload-time = "2025-06-21T12:25:07.447Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42", size = 12731565, upload-time = "2025-06-21T12:25:26.444Z" }, + { url = "https://files.pythonhosted.org/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e", size = 10190262, upload-time = "2025-06-21T12:25:42.196Z" }, + { url = "https://files.pythonhosted.org/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8", size = 20987593, upload-time = "2025-06-21T12:21:51.664Z" }, + { url = "https://files.pythonhosted.org/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb", size = 14300523, upload-time = "2025-06-21T12:22:13.583Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee", size = 5227993, upload-time = "2025-06-21T12:22:22.53Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992", size = 6736652, upload-time = "2025-06-21T12:22:33.629Z" }, + { url = "https://files.pythonhosted.org/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c", size = 14331561, upload-time = "2025-06-21T12:22:55.056Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48", size = 16693349, upload-time = "2025-06-21T12:23:20.53Z" }, + { url = "https://files.pythonhosted.org/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee", size = 15642053, upload-time = "2025-06-21T12:23:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280", size = 18434184, upload-time = "2025-06-21T12:24:10.708Z" }, + { url = "https://files.pythonhosted.org/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e", size = 6440678, upload-time = "2025-06-21T12:24:21.596Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc", size = 12870697, upload-time = "2025-06-21T12:24:40.644Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244", size = 10260376, upload-time = "2025-06-21T12:24:56.884Z" }, + { url = "https://files.pythonhosted.org/packages/e8/34/facc13b9b42ddca30498fc51f7f73c3d0f2be179943a4b4da8686e259740/numpy-2.3.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ad506d4b09e684394c42c966ec1527f6ebc25da7f4da4b1b056606ffe446b8a3", size = 21070637, upload-time = "2025-06-21T12:26:12.518Z" }, + { url = "https://files.pythonhosted.org/packages/65/b6/41b705d9dbae04649b529fc9bd3387664c3281c7cd78b404a4efe73dcc45/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ebb8603d45bc86bbd5edb0d63e52c5fd9e7945d3a503b77e486bd88dde67a19b", size = 5304087, upload-time = "2025-06-21T12:26:22.294Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/fe3ac1902bff7a4934a22d49e1c9d71a623204d654d4cc43c6e8fe337fcb/numpy-2.3.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:15aa4c392ac396e2ad3d0a2680c0f0dee420f9fed14eef09bdb9450ee6dcb7b7", size = 6817588, upload-time = "2025-06-21T12:26:32.939Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ee/89bedf69c36ace1ac8f59e97811c1f5031e179a37e4821c3a230bf750142/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c6e0bf9d1a2f50d2b65a7cf56db37c095af17b59f6c132396f7c6d5dd76484df", size = 14399010, upload-time = "2025-06-21T12:26:54.086Z" }, + { url = "https://files.pythonhosted.org/packages/15/08/e00e7070ede29b2b176165eba18d6f9784d5349be3c0c1218338e79c27fd/numpy-2.3.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eabd7e8740d494ce2b4ea0ff05afa1b7b291e978c0ae075487c51e8bd93c0c68", size = 16752042, upload-time = "2025-06-21T12:27:19.018Z" }, + { url = "https://files.pythonhosted.org/packages/48/6b/1c6b515a83d5564b1698a61efa245727c8feecf308f4091f565988519d20/numpy-2.3.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e610832418a2bc09d974cc9fecebfa51e9532d6190223bc5ef6a7402ebf3b5cb", size = 12927246, upload-time = "2025-06-21T12:27:38.618Z" }, ] [[package]] @@ -779,7 +778,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -847,22 +846,30 @@ wheels = [ [[package]] name = "pandas-stubs" -version = "2.2.3.250527" +version = "2.3.0.250703" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version >= '3.12' and python_full_version < '3.12.4'", + "python_full_version >= '3.12'", "python_full_version == '3.11.*'", "python_full_version == '3.10.*'", ] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "numpy", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "types-pytz", marker = "python_full_version >= '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5f/0d/5fe7f7f3596eb1c2526fea151e9470f86b379183d8b9debe44b2098651ca/pandas_stubs-2.2.3.250527.tar.gz", hash = "sha256:e2d694c4e72106055295ad143664e5c99e5815b07190d1ff85b73b13ff019e63", size = 106312, upload-time = "2025-05-27T15:24:29.716Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/df/c1c51c5cec087b8f4d04669308b700e9648745a77cdd0c8c5e16520703ca/pandas_stubs-2.3.0.250703.tar.gz", hash = "sha256:fb6a8478327b16ed65c46b1541de74f5c5947f3601850caf3e885e0140584717", size = 103910, upload-time = "2025-07-02T17:49:11.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/f8/46141ba8c9d7064dc5008bfb4a6ae5bd3c30e4c61c28b5c5ed485bf358ba/pandas_stubs-2.2.3.250527-py3-none-any.whl", hash = "sha256:cd0a49a95b8c5f944e605be711042a4dd8550e2c559b43d70ba2c4b524b66163", size = 159683, upload-time = "2025-05-27T15:24:28.4Z" }, + { url = "https://files.pythonhosted.org/packages/75/cb/09d5f9bf7c8659af134ae0ffc1a349038a5d0ff93e45aedc225bde2872a3/pandas_stubs-2.3.0.250703-py3-none-any.whl", hash = "sha256:a9265fc69909f0f7a9cabc5f596d86c9d531499fed86b7838fd3278285d76b81", size = 154719, upload-time = "2025-07-02T17:49:10.697Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] @@ -885,7 +892,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.4" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -893,9 +900,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -1007,9 +1014,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1017,36 +1033,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -1138,7 +1155,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1146,9 +1163,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -1165,27 +1182,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.11.10" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -1265,11 +1282,11 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] @@ -1287,14 +1304,14 @@ wheels = [ [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] @@ -1308,11 +1325,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] diff --git a/libs/cli/examples/graphs/storm.py b/libs/cli/examples/graphs/storm.py index 184ed04ef..147f0fdac 100644 --- a/libs/cli/examples/graphs/storm.py +++ b/libs/cli/examples/graphs/storm.py @@ -285,7 +285,7 @@ class AnswerWithCitations(BaseModel): @property def as_str(self) -> str: return f"{self.answer}\n\nCitations:\n\n" + "\n".join( - f"[{i+1}]: {url}" for i, url in enumerate(self.cited_urls) + f"[{i + 1}]: {url}" for i, url in enumerate(self.cited_urls) ) @@ -553,7 +553,7 @@ async def conduct_interviews(state: ResearchState): def format_conversation(interview_state): messages = interview_state["messages"] convo = "\n".join(f"{m.name}: {m.content}" for m in messages) - return f'Conversation with {interview_state["editor"].name}\n\n' + convo + return f"Conversation with {interview_state['editor'].name}\n\n" + convo async def refine_outline(state: ResearchState): diff --git a/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py b/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py index 5ab615871..1073110cb 100644 --- a/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py +++ b/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py @@ -17,7 +17,7 @@ model_oai = ChatOpenAI(temperature=0) model_anth = model_anth.bind_tools(tools) model_oai = model_oai.bind_tools(tools) -prompt = open("prompt.txt").read() +prompt = open(Path(__file__).parent.parent / "prompt.txt").read() subprompt = open(Path(__file__).parent / "subprompt.txt").read() diff --git a/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py b/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py index 5ab615871..1073110cb 100644 --- a/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py +++ b/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py @@ -17,7 +17,7 @@ model_oai = ChatOpenAI(temperature=0) model_anth = model_anth.bind_tools(tools) model_oai = model_oai.bind_tools(tools) -prompt = open("prompt.txt").read() +prompt = open(Path(__file__).parent.parent / "prompt.txt").read() subprompt = open(Path(__file__).parent / "subprompt.txt").read() diff --git a/libs/cli/examples/langgraph.json b/libs/cli/examples/langgraph.json index 51eb14be9..0d8563e55 100644 --- a/libs/cli/examples/langgraph.json +++ b/libs/cli/examples/langgraph.json @@ -8,6 +8,7 @@ "scikit-learn", "./graphs" ], + "keep_pkg_tools": false, "graphs": { "agent": "./graphs/agent.py:graph", "storm": "./graphs/storm.py:graph" diff --git a/libs/cli/langgraph_cli/config.py b/libs/cli/langgraph_cli/config.py index 526843a38..ce1c6e8b9 100644 --- a/libs/cli/langgraph_cli/config.py +++ b/libs/cli/langgraph_cli/config.py @@ -471,21 +471,61 @@ class Config(TypedDict, total=False): """Optional. Named definitions of UI components emitted by the agent, each pointing to a JS/TS file. """ + keep_pkg_tools: Optional[Union[bool, list[str]]] + """Optional. Control whether to retain Python packaging tools in the final image. + + Allowed tools are: "pip", "setuptools", "wheel". + You can also set to true to include all packaging tools. + """ -PIP_CLEANUP_LINES = """# -- Ensure user deps didn't inadvertently overwrite langgraph-api + +_BUILD_TOOLS = ("pip", "setuptools", "wheel") + + +def _get_pip_cleanup_lines( + install_cmd: str, + to_uninstall: Optional[tuple[str]], + pip_installer: Literal["uv", "pip"], +) -> str: + commands = [ + f"""# -- Ensure user deps didn't inadvertently overwrite langgraph-api RUN mkdir -p /api/langgraph_api /api/langgraph_runtime /api/langgraph_license && \ - touch /api/langgraph_api/__init__.py /api/langgraph_runtime/__init__.py /api/langgraph_license/__init__.py +touch /api/langgraph_api/__init__.py /api/langgraph_runtime/__init__.py /api/langgraph_license/__init__.py RUN PYTHONDONTWRITEBYTECODE=1 {install_cmd} --no-cache-dir --no-deps -e /api # -- End of ensuring user deps didn't inadvertently overwrite langgraph-api -- -# -- Removing pip from the final image ~<:===~~~ -- -RUN pip uninstall -y pip setuptools wheel && \ - rm -rf /usr/local/lib/python*/site-packages/pip* /usr/local/lib/python*/site-packages/setuptools* /usr/local/lib/python*/site-packages/wheel* && \ - find /usr/local/bin -name "pip*" -delete || true -# pip removal for wolfi -RUN rm -rf /usr/lib/python*/site-packages/pip* /usr/lib/python*/site-packages/setuptools* /usr/lib/python*/site-packages/wheel* && \ - find /usr/bin -name "pip*" -delete || true -{uv_removal} -# -- End of pip removal --""" +# -- Removing build deps from the final image ~<:===~~~ --""" + ] + if to_uninstall: + for pack in to_uninstall: + if pack not in _BUILD_TOOLS: + raise ValueError( + f"Invalid build tool: {pack}; must be one of {', '.join(_BUILD_TOOLS)}" + ) + packs_str = " ".join(sorted(to_uninstall)) + commands.append(f"RUN pip uninstall -y {packs_str}") + # Ensure the directories are removed entirely + packages_rm = " ".join( + f"/usr/local/lib/python*/site-packages/{pack}*" for pack in to_uninstall + ) + if "pip" in to_uninstall: + packages_rm += ' && find /usr/local/bin -name "pip*" -delete || true' + commands.append(f"RUN rm -rf {packages_rm}") + wolfi_packages_rm = " ".join( + f"/usr/lib/python*/site-packages/{pack}*" for pack in to_uninstall + ) + if "pip" in to_uninstall: + wolfi_packages_rm += ' && find /usr/bin -name "pip*" -delete || true' + commands.append(f"RUN rm -rf {wolfi_packages_rm}") + if pip_installer == "uv": + commands.append( + f"RUN uv pip uninstall --system {packs_str} && rm /usr/bin/uv /usr/bin/uvx" + ) + else: + if pip_installer == "uv": + commands.append( + "RUN rm /usr/bin/uv /usr/bin/uvx\n# -- End of build deps removal --" + ) + return "\n".join(commands) def _parse_version(version_str: str) -> tuple[int, int]: @@ -563,6 +603,7 @@ def validate_config(config: Config) -> Config: "checkpointer": config.get("checkpointer"), "ui": config.get("ui"), "ui_config": config.get("ui_config"), + "keep_pkg_tools": config.get("keep_pkg_tools"), } if config.get("node_version"): @@ -602,8 +643,7 @@ def validate_config(config: Config) -> Config: if not config["graphs"]: raise click.UsageError( - "No graphs found in config. " - "Add at least one graph to 'graphs' dictionary." + "No graphs found in config. Add at least one graph to 'graphs' dictionary." ) # Validate image_distro config @@ -636,6 +676,22 @@ def validate_config(config: Config) -> Config: f"Invalid http.app format: '{http_conf['app']}'. " "Must be in format './path/to/file.py:attribute_name'" ) + if keep_pkg_tools := config.get("keep_pkg_tools"): + if isinstance(keep_pkg_tools, list): + for tool in keep_pkg_tools: + if tool not in _BUILD_TOOLS: + raise ValueError( + f"Invalid keep_pkg_tools: '{tool}'. " + "Must be one of 'pip', 'setuptools', 'wheel'." + ) + elif keep_pkg_tools is True: + pass + else: + raise ValueError( + f"Invalid keep_pkg_tools: '{keep_pkg_tools}'. " + "Must be bool or list[str] (with values" + " 'pip', 'setuptools', and/or 'wheel')." + ) return config @@ -1129,6 +1185,27 @@ def _image_supports_uv(base_image: str) -> bool: return version >= min_uv +def get_build_tools_to_uninstall(config: Config) -> tuple[str]: + keep_pkg_tools = config.get("keep_pkg_tools") + if not keep_pkg_tools: + return _BUILD_TOOLS + if keep_pkg_tools is True: + return () + expected = _BUILD_TOOLS + if isinstance(keep_pkg_tools, list): + for tool in keep_pkg_tools: + if tool not in expected: + raise ValueError( + f"Invalid build tool to uninstall: {tool}. Expected one of {expected}" + ) + return tuple(sorted(set(_BUILD_TOOLS) - set(keep_pkg_tools))) + else: + raise ValueError( + f"Invalid value for keep_pkg_tools: {keep_pkg_tools}." + " Expected True or a list containing any of {expected}." + ) + + def python_config_to_docker( config_path: pathlib.Path, config: Config, @@ -1136,20 +1213,18 @@ def python_config_to_docker( ) -> tuple[str, dict[str, str]]: """Generate a Dockerfile from the configuration.""" pip_installer = config.get("pip_installer", "auto") - + build_tools_to_uninstall = get_build_tools_to_uninstall(config) + if pip_installer == "auto": + if _image_supports_uv(base_image): + pip_installer = "uv" + else: + pip_installer = "pip" if pip_installer == "uv": install_cmd = "uv pip install --system" - uv_removal = "RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx" elif pip_installer == "pip": install_cmd = "pip install" - uv_removal = "" else: - if _image_supports_uv(base_image): - install_cmd = "uv pip install --system" - uv_removal = "RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx" - else: - install_cmd = "pip install" - uv_removal = "" + raise ValueError(f"Invalid pip_installer: {pip_installer}") # configure pip pip_install = f"PYTHONDONTWRITEBYTECODE=1 {install_cmd} --no-cache-dir -c /api/constraints.txt" @@ -1181,7 +1256,7 @@ def python_config_to_docker( ) for reqpath, destpath in local_deps.pip_reqs ) - pip_reqs_str += f'{os.linesep}RUN {pip_install} {" ".join("-r " + r for _,r in local_deps.pip_reqs)}' + pip_reqs_str += f"{os.linesep}RUN {pip_install} {' '.join('-r ' + r for _, r in local_deps.pip_reqs)}" pip_reqs_str = f"""# -- Installing local requirements -- {pip_reqs_str} # -- End of local requirements install --""" @@ -1298,7 +1373,11 @@ ADD {relpath} /deps/{name} js_inst_str, "", # Add pip cleanup after all installations are complete - PIP_CLEANUP_LINES.format(install_cmd=install_cmd, uv_removal=uv_removal), + _get_pip_cleanup_lines( + install_cmd=install_cmd, + to_uninstall=build_tools_to_uninstall, + pip_installer=pip_installer, + ), "", f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "", ] diff --git a/libs/cli/langgraph_cli/templates.py b/libs/cli/langgraph_cli/templates.py index cd336e255..4ea915228 100644 --- a/libs/cli/langgraph_cli/templates.py +++ b/libs/cli/langgraph_cli/templates.py @@ -123,7 +123,7 @@ def _download_repo_with_requests(repo_url: str, path: str) -> None: ) except error.HTTPError as e: click.secho( - f"❌ Error: Failed to download repository.\n" f"Details: {e}\n", + f"❌ Error: Failed to download repository.\nDetails: {e}\n", fg="red", bold=True, err=True, diff --git a/libs/cli/pyproject.toml b/libs/cli/pyproject.toml index 1a781e6f2..8c959ccab 100644 --- a/libs/cli/pyproject.toml +++ b/libs/cli/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "langgraph-cli" -version = "0.3.3" +version = "0.3.4" description = "CLI for interacting with LangGraph API" authors = [] requires-python = ">=3.9" diff --git a/libs/cli/schemas/schema.json b/libs/cli/schemas/schema.json index c069f7e9e..19d8893a4 100644 --- a/libs/cli/schemas/schema.json +++ b/libs/cli/schemas/schema.json @@ -134,6 +134,23 @@ ], "description": "Optional. Linux distribution for the base image.\n\nMust be either 'debian' or 'wolfi'. If omitted, defaults to 'debian'.\n" }, + "keep_pkg_tools": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Optional. Control whether to retain Python packaging tools in the final image.\n\nYou can also set to true to include all packaging tools.\n" + }, "pip_installer": { "anyOf": [ { @@ -298,6 +315,23 @@ ], "description": "Optional. Linux distribution for the base image.\n\nMust be either 'debian' or 'wolfi'. If omitted, defaults to 'debian'.\n" }, + "keep_pkg_tools": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Optional. Control whether to retain Python packaging tools in the final image.\n\nYou can also set to true to include all packaging tools.\n" + }, "pip_installer": { "anyOf": [ { @@ -505,7 +539,7 @@ }, "disable_meta": { "type": "boolean", - "description": "Optional. If True, all meta endpoints (/ok, /info, /metrics, /docs) are disabled.\n\nDefault is False.\n" + "description": "Optional. If True, all meta endpoints (/openapi.json, /info, /metrics, /docs) are disabled.\n\nDefault is False.\n" }, "disable_runs": { "type": "boolean", diff --git a/libs/cli/schemas/schema.v0.json b/libs/cli/schemas/schema.v0.json index c069f7e9e..19d8893a4 100644 --- a/libs/cli/schemas/schema.v0.json +++ b/libs/cli/schemas/schema.v0.json @@ -134,6 +134,23 @@ ], "description": "Optional. Linux distribution for the base image.\n\nMust be either 'debian' or 'wolfi'. If omitted, defaults to 'debian'.\n" }, + "keep_pkg_tools": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Optional. Control whether to retain Python packaging tools in the final image.\n\nYou can also set to true to include all packaging tools.\n" + }, "pip_installer": { "anyOf": [ { @@ -298,6 +315,23 @@ ], "description": "Optional. Linux distribution for the base image.\n\nMust be either 'debian' or 'wolfi'. If omitted, defaults to 'debian'.\n" }, + "keep_pkg_tools": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Optional. Control whether to retain Python packaging tools in the final image.\n\nYou can also set to true to include all packaging tools.\n" + }, "pip_installer": { "anyOf": [ { @@ -505,7 +539,7 @@ }, "disable_meta": { "type": "boolean", - "description": "Optional. If True, all meta endpoints (/ok, /info, /metrics, /docs) are disabled.\n\nDefault is False.\n" + "description": "Optional. If True, all meta endpoints (/openapi.json, /info, /metrics, /docs) are disabled.\n\nDefault is False.\n" }, "disable_runs": { "type": "boolean", diff --git a/libs/cli/schemas/version.schema.json b/libs/cli/schemas/version.schema.json new file mode 100644 index 000000000..041b130c1 --- /dev/null +++ b/libs/cli/schemas/version.schema.json @@ -0,0 +1,46 @@ +{ + "$id": "https://github.com/langchain-ai/langgraph/libs/cli/schemas/version.schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "LangGraph Platform configuration (when building via the langgraph-cli).", + "type": "object", + "oneOf": [ + { + "allOf": [ + { + "oneOf": [ + { + "properties": { + "version": { + "type": "string", + "maxLength": 0 + } + }, + "required": ["version"] + }, + { + "not": { + "required": ["version"] + } + } + ] + }, + { + "$ref": "https://raw.githubusercontent.com/langchain-ai/langgraph/main/libs/cli/schemas/schema.json" + } + ] + }, + { + "allOf": [ + { + "properties": { + "version": { "const": "v0" } + }, + "required": ["version"] + }, + { + "$ref": "https://raw.githubusercontent.com/langchain-ai/langgraph/main/libs/cli/schemas/schema.v0.json" + } + ] + } + ] +} diff --git a/libs/cli/tests/unit_tests/cli/test_cli.py b/libs/cli/tests/unit_tests/cli/test_cli.py index d07d6f7a8..e6d0a17b4 100644 --- a/libs/cli/tests/unit_tests/cli/test_cli.py +++ b/libs/cli/tests/unit_tests/cli/test_cli.py @@ -10,13 +10,14 @@ from pathlib import Path from click.testing import CliRunner from langgraph_cli.cli import cli, prepare_args_and_stdin -from langgraph_cli.config import PIP_CLEANUP_LINES, Config, validate_config +from langgraph_cli.config import Config, _get_pip_cleanup_lines, validate_config from langgraph_cli.docker import DEFAULT_POSTGRES_URI, DockerCapabilities, Version from langgraph_cli.util import clean_empty_lines -FORMATTED_CLEANUP_LINES = PIP_CLEANUP_LINES.format( +FORMATTED_CLEANUP_LINES = _get_pip_cleanup_lines( install_cmd="uv pip install --system", - uv_removal="RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx", + to_uninstall=("pip", "setuptools", "wheel"), + pip_installer="uv", ) DEFAULT_DOCKER_CAPABILITIES = DockerCapabilities( version_docker=Version(26, 1, 1), @@ -280,9 +281,9 @@ def test_version_option() -> None: assert result.exit_code == 0, "Expected exit code 0 for --version option" # Check that the output contains the correct version information - assert ( - "LangGraph CLI, version" in result.output - ), "Expected version information in output" + assert "LangGraph CLI, version" in result.output, ( + "Expected version information in output" + ) def test_dockerfile_command_basic() -> None: @@ -570,6 +571,6 @@ def test_build_generate_proper_build_context(): build_context_pattern = re.compile(r"--build-context\s+(\w+)=([^\s]+)") build_contexts = re.findall(build_context_pattern, result.output) - assert ( - len(build_contexts) == 2 - ), f"Expected 2 build contexts, but found {len(build_contexts)}" + assert len(build_contexts) == 2, ( + f"Expected 2 build contexts, but found {len(build_contexts)}" + ) diff --git a/libs/cli/tests/unit_tests/cli/test_templates.py b/libs/cli/tests/unit_tests/cli/test_templates.py index acd7651d0..cbdf4bbe1 100644 --- a/libs/cli/tests/unit_tests/cli/test_templates.py +++ b/libs/cli/tests/unit_tests/cli/test_templates.py @@ -42,18 +42,18 @@ def test_create_new_with_mocked_download(mock_urlopen: MagicMock) -> None: # Verify CLI command execution and success assert result.exit_code == 0, result.output - assert ( - "New project created" in result.output - ), "Expected success message in output." + assert "New project created" in result.output, ( + "Expected success message in output." + ) # Verify that the directory is not empty assert os.listdir(temp_dir), "Expected files to be created in temp directory." # Check for a known file in the extracted content extracted_files = [f.name for f in Path(temp_dir).glob("*")] - assert ( - "test-file.txt" in extracted_files - ), "Expected 'test-file.txt' in the extracted content." + assert "test-file.txt" in extracted_files, ( + "Expected 'test-file.txt' in the extracted content." + ) def test_invalid_template_id() -> None: @@ -65,6 +65,6 @@ def test_invalid_template_id() -> None: # Verify the command failed and proper message is displayed assert result.exit_code != 0, "Expected non-zero exit code for invalid template." - assert ( - "Template 'invalid-template-id' not found" in result.output - ), "Expected error message in output." + assert "Template 'invalid-template-id' not found" in result.output, ( + "Expected error message in output." + ) diff --git a/libs/cli/tests/unit_tests/test_config.py b/libs/cli/tests/unit_tests/test_config.py index 3971b60e2..691c1e888 100644 --- a/libs/cli/tests/unit_tests/test_config.py +++ b/libs/cli/tests/unit_tests/test_config.py @@ -9,7 +9,8 @@ import click import pytest from langgraph_cli.config import ( - PIP_CLEANUP_LINES, + _BUILD_TOOLS, + _get_pip_cleanup_lines, config_to_compose, config_to_docker, docker_tag, @@ -18,9 +19,10 @@ from langgraph_cli.config import ( ) from langgraph_cli.util import clean_empty_lines -FORMATTED_CLEANUP_LINES = PIP_CLEANUP_LINES.format( +FORMATTED_CLEANUP_LINES = _get_pip_cleanup_lines( install_cmd="uv pip install --system", - uv_removal="RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx", + to_uninstall=("pip", "setuptools", "wheel"), + pip_installer="uv", ) PATH_TO_CONFIG = pathlib.Path(__file__).parent / "test_config.json" @@ -51,6 +53,7 @@ def test_validate_config(): "http": None, "ui": None, "ui_config": None, + "keep_pkg_tools": None, **expected_config, } assert actual_config == expected_config @@ -77,6 +80,7 @@ def test_validate_config(): "http": None, "ui": None, "ui_config": None, + "keep_pkg_tools": None, } actual_config = validate_config(expected_config) assert actual_config == expected_config @@ -925,6 +929,53 @@ def test_config_to_docker_pip_installer(): assert "uv pip install --system" in docker_default +def test_config_retain_build_tools(): + graphs = {"agent": "./graphs/agent.py:graph"} + base_config = { + "python_version": "3.11", + "dependencies": ["."], + "graphs": graphs, + } + config_true = validate_config( + {**copy.deepcopy(base_config), "keep_pkg_tools": True} + ) + docker_true, _ = config_to_docker( + PATH_TO_CONFIG, config_true, "langchain/langgraph-api:0.2.47" + ) + assert not any( + "/usr/local/lib/python*/site-packages/" + pckg + "*" in docker_true + for pckg in _BUILD_TOOLS + ) + assert "RUN pip uninstall -y pip setuptools wheel" not in docker_true + config_false = validate_config( + {**copy.deepcopy(base_config), "keep_pkg_tools": False} + ) + docker_false, _ = config_to_docker( + PATH_TO_CONFIG, config_false, "langchain/langgraph-api:0.2.47" + ) + assert all( + "/usr/local/lib/python*/site-packages/" + pckg + "*" in docker_false + for pckg in _BUILD_TOOLS + ) + assert "RUN pip uninstall -y pip setuptools wheel" in docker_false + config_list = validate_config( + {**copy.deepcopy(base_config), "keep_pkg_tools": ["pip", "setuptools"]} + ) + docker_list, _ = config_to_docker( + PATH_TO_CONFIG, config_list, "langchain/langgraph-api:0.2.47" + ) + assert all( + "/usr/local/lib/python*/site-packages/" + pckg + "*" in docker_list + for pckg in ("wheel",) + ) + assert not any( + "/usr/local/lib/python*/site-packages/" + pckg + "*" in docker_list + for pckg in ("pip", "setuptools") + ) + assert "RUN pip uninstall -y wheel" in docker_list + assert "RUN pip uninstall -y pip setuptools" not in docker_list + + # config_to_compose def test_config_to_compose_simple_config(): graphs = {"agent": "./agent.py:graph"} diff --git a/libs/cli/uv.lock b/libs/cli/uv.lock index 839e68015..b312f2e06 100644 --- a/libs/cli/uv.lock +++ b/libs/cli/uv.lock @@ -2,10 +2,9 @@ version = 1 revision = 2 requires-python = ">=3.9" resolution-markers = [ - "python_full_version >= '3.12.4' and python_full_version < '4.0'", - "python_full_version >= '3.11' and python_full_version < '3.12.4'", - "python_full_version >= '4.0'", - "python_full_version < '3.11'", + "python_full_version >= '3.11'", + "python_full_version == '3.10.*'", + "python_full_version < '3.10'", ] [[package]] @@ -45,11 +44,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -199,14 +198,33 @@ wheels = [ name = "click" version = "8.1.8" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, ] +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.11'", + "python_full_version == '3.10.*'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + [[package]] name = "cloudpickle" version = "3.1.1" @@ -289,11 +307,14 @@ sdist = { url = "https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf57 [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload-time = "2024-07-12T22:26:00.161Z" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload-time = "2024-07-12T22:25:58.476Z" }, + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[package]] @@ -423,7 +444,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.66" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch", marker = "python_full_version >= '3.11'" }, @@ -434,31 +455,31 @@ dependencies = [ { name = "tenacity", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/63/470aa84393bad5d51749417af58522a691174f8b2d05843f5633d473faa0/langchain_core-0.3.66.tar.gz", hash = "sha256:350c92e792ec1401f4b740d759b95f297710a50de29e1be9fbfff8676ef62117", size = 560102, upload-time = "2025-06-20T22:08:19.532Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/c3/8080431fd7567a340d3a42e36c0bb3970a8d00d5e27bf3ca2103b3b55996/langchain_core-0.3.66-py3-none-any.whl", hash = "sha256:65cd6c3659afa4f91de7aa681397a0c53ff9282425c281e53646dd7faf16099e", size = 438874, upload-time = "2025-06-20T22:08:17.52Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] name = "langgraph" -version = "0.4.3" +version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "langchain-core", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "langchain-core", marker = "python_full_version >= '3.11'" }, { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11'" }, - { name = "langgraph-prebuilt", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-sdk", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "langgraph-prebuilt", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-sdk", marker = "python_full_version >= '3.11'" }, { name = "pydantic", marker = "python_full_version >= '3.11'" }, { name = "xxhash", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/9e/5a64602eff18a99d0216a80eff823051ffbdb7c11b5a16171cee8b1ccce5/langgraph-0.4.3.tar.gz", hash = "sha256:272d5d5903f2c2882dbeeba849846a0f2500bd83fb3734a3801ebe64c1a60bdd", size = 125407, upload-time = "2025-05-08T03:40:02.882Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/db/864d8e6c6e921f27b357980d0cfca847366238c1bb8a6bffd766f651004e/langgraph-0.5.1.tar.gz", hash = "sha256:312d341979e38034dde60e08df53505b8a196619df1266d6eacf6b002a0a65a8", size = 437339, upload-time = "2025-07-02T21:15:56.581Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/53/0a20edd9f41eb3707722444ec1b43752b792bbe904d1c8cc3ba27f8eb2c8/langgraph-0.4.3-py3-none-any.whl", hash = "sha256:dec926e034f4d440b92a3c52139cb6e9763bc1791e79a6ea53a233309cec864f", size = 151191, upload-time = "2025-05-08T03:40:01.07Z" }, + { url = "https://files.pythonhosted.org/packages/4d/fa/69e83057b7a6062c0785deccdd22610003611c16cac7b4218b4b87c4924a/langgraph-0.5.1-py3-none-any.whl", hash = "sha256:707f0cc0d2713011fff4578bf57de8226cd96bcc0679868be2f41eb0984bb5af", size = 143695, upload-time = "2025-07-02T21:15:55.148Z" }, ] [[package]] name = "langgraph-api" -version = "0.2.67" +version = "0.2.78" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cloudpickle", marker = "python_full_version >= '3.11'" }, @@ -481,30 +502,31 @@ dependencies = [ { name = "uvicorn", marker = "python_full_version >= '3.11'" }, { name = "watchfiles", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a2/36/a1ef1b9cc71450068708ebf6fc0fa5342c3e3129f37932f195b2a1c7814b/langgraph_api-0.2.67.tar.gz", hash = "sha256:68f2237fd4612d6d0e750824170a4ed9a9566b610ca2d6a605fb136bab32d908", size = 228371, upload-time = "2025-06-26T01:53:44.07Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/88/1aa91bede22d1393a53605ff13a57d6cb3ce2831eb250a8a8f814c548d2e/langgraph_api-0.2.78.tar.gz", hash = "sha256:37aad4fe764934f358dbb26d50b4acbf4180aac673499d1502b5b468cc7acba4", size = 233581, upload-time = "2025-07-02T19:11:01.154Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/b1/69e2366b16daeec87954e04e04e478308be5dde5d54cc79d0e125c4accb4/langgraph_api-0.2.67-py3-none-any.whl", hash = "sha256:0e06e6df6152e8fb3a98ca512c7c73927d688e841fe1000df6a3badc42d9b268", size = 183672, upload-time = "2025-06-26T01:53:42.794Z" }, + { url = "https://files.pythonhosted.org/packages/7e/76/46626d99c36fce0c1ee1e1581f54b29acbed5e9f2e7cf9a198c825547d91/langgraph_api-0.2.78-py3-none-any.whl", hash = "sha256:57abe7fff9763d6f4eaf4419d103f75e77dca6d271db3816777c04bd67db4449", size = 190222, upload-time = "2025-07-02T19:10:59.793Z" }, ] [[package]] name = "langgraph-checkpoint" -version = "2.0.25" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core", marker = "python_full_version >= '3.11'" }, { name = "ormsgpack", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/72/d49828e6929cb3ded1472aa3e5e4a369d292c4f21021ac683d28fbc8f4f8/langgraph_checkpoint-2.0.25.tar.gz", hash = "sha256:77a63cab7b5f84dec1d49db561326ec28bdd48bcefb7fe4ac372069d2609287b", size = 36952, upload-time = "2025-04-26T21:00:43.5Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/30/c04abcb2ac30f200dbfde5839ca3832552fe2bd852d9e85a68e47418a11c/langgraph_checkpoint-2.1.0.tar.gz", hash = "sha256:cdaa2f0b49aa130ab185c02d82f02b40299a1fbc9ac59ac20cecce09642a1abe", size = 135501, upload-time = "2025-06-16T22:05:01.918Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/52/bceb5b5348c7a60ef0625ab0a0a0a9ff5d78f0e12aed8cc55c49d5e8a8c9/langgraph_checkpoint-2.0.25-py3-none-any.whl", hash = "sha256:23416a0f5bc9dd712ac10918fc13e8c9c4530c419d2985a441df71a38fc81602", size = 42312, upload-time = "2025-04-26T21:00:42.242Z" }, + { url = "https://files.pythonhosted.org/packages/0f/41/390a97d9d0abe5b71eea2f6fb618d8adadefa674e97f837bae6cda670bc7/langgraph_checkpoint-2.1.0-py3-none-any.whl", hash = "sha256:4cea3e512081da1241396a519cbfe4c5d92836545e2c64e85b6f5c34a1b8bc61", size = 43844, upload-time = "2025-06-16T22:05:00.758Z" }, ] [[package]] name = "langgraph-cli" -version = "0.3.3" +version = "0.3.4" source = { editable = "." } dependencies = [ - { name = "click" }, + { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "langgraph-sdk", marker = "python_full_version >= '3.11'" }, ] @@ -551,20 +573,20 @@ dev = [ [[package]] name = "langgraph-prebuilt" -version = "0.1.8" +version = "0.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "langchain-core", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "langchain-core", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/57/30/f31f0e076c37d097b53e4cff5d479a3686e1991f6c86a1a4727d5d1f5489/langgraph_prebuilt-0.1.8.tar.gz", hash = "sha256:4de7659151829b2b955b6798df6800e580e617782c15c2c5b29b139697491831", size = 24543, upload-time = "2025-04-03T16:04:19.932Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/11/98134c47832fbde0caf0e06f1a104577da9215c358d7854093c1d835b272/langgraph_prebuilt-0.5.2.tar.gz", hash = "sha256:2c900a5be0d6a93ea2521e0d931697cad2b646f1fcda7aa5c39d8d7539772465", size = 117808, upload-time = "2025-06-30T19:52:48.307Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/72/9e092665502f8f52f2708065ed14fbbba3f95d1a1b65d62049b0c5fcdf00/langgraph_prebuilt-0.1.8-py3-none-any.whl", hash = "sha256:ae97b828ae00be2cefec503423aa782e1bff165e9b94592e224da132f2526968", size = 25903, upload-time = "2025-04-03T16:04:18.993Z" }, + { url = "https://files.pythonhosted.org/packages/c3/64/6bc45ab9e0e1112698ebff579fe21f5606ea65cd08266995a357e312a4d2/langgraph_prebuilt-0.5.2-py3-none-any.whl", hash = "sha256:1f4cd55deca49dffc3e5127eec12fcd244fc381321002f728afa88642d5ec59d", size = 23776, upload-time = "2025-06-30T19:52:47.494Z" }, ] [[package]] name = "langgraph-runtime-inmem" -version = "0.3.3" +version = "0.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "blockbuster", marker = "python_full_version >= '3.11'" }, @@ -574,27 +596,27 @@ dependencies = [ { name = "starlette", marker = "python_full_version >= '3.11'" }, { name = "structlog", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/c6/c6c515df38179517a187b11cc9506caac9bc7c25ab0adc1e21b463e338fd/langgraph_runtime_inmem-0.3.3.tar.gz", hash = "sha256:1b5bc8b05989f48c64c826d826e576a6e77f42349eca3382f38f8ed1d1f026e4", size = 77443, upload-time = "2025-06-24T19:50:36.235Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/17/7ff669ff44a53ab342903c2996fff75a77494af9fe56abcfbca64fe2342b/langgraph_runtime_inmem-0.3.4.tar.gz", hash = "sha256:eda7828f3ea07126e5265024b74a3fa9bf611633ad83ba3296ab9f51d89b7c0c", size = 77424, upload-time = "2025-07-01T14:45:07.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/87/1b47cf8a9a9ab8e6460203921e05f59e1e95dc0636e64a7429cd0e579a79/langgraph_runtime_inmem-0.3.3-py3-none-any.whl", hash = "sha256:ed485d520870a96a4a2e81188f2dbf993e7b96c5c65804bcdfdcb39df71be3ce", size = 29146, upload-time = "2025-06-24T19:50:35.083Z" }, + { url = "https://files.pythonhosted.org/packages/95/0e/39c13ca7229a9425a0e5744a1d3817f80d38dd5ca7703494fb9cf836ba45/langgraph_runtime_inmem-0.3.4-py3-none-any.whl", hash = "sha256:dcb9ac68ac90b3fb1ddaf666d14a367ab70e69d5bb5589b77a72c318e29104ae", size = 29139, upload-time = "2025-07-01T14:45:06.472Z" }, ] [[package]] name = "langgraph-sdk" -version = "0.1.66" +version = "0.1.72" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", marker = "python_full_version >= '3.11'" }, { name = "orjson", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/7a/5fede018d8b9100db14211cfdb94aefd0e5f2e9ae738072f3d4cc443465b/langgraph_sdk-0.1.66.tar.gz", hash = "sha256:81474ad4555a06004cc7a2f4ab477135d5eaf7db11fbcf2a69257fb2d717582e", size = 44049, upload-time = "2025-04-30T22:59:09.085Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/a6/cf13ace9bc7f0e8b13852ced0b37ece97f3140e232821c28bc852f8c1ea2/langgraph_sdk-0.1.72.tar.gz", hash = "sha256:396d8195881830700e2d54a0a9ee273e8b1173428e667502ef9c182a3cec7ab7", size = 71600, upload-time = "2025-06-27T01:12:03.788Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/06/87ce0b8043ba5a4ec8369a243f3140f8fd9d9b7aab1d8a9351711739beea/langgraph_sdk-0.1.66-py3-none-any.whl", hash = "sha256:f781c63f3e913d3d6bedb02cb84d775cda64e3cdf3282fd387bdd8faaf53c603", size = 47584, upload-time = "2025-04-30T22:59:07.953Z" }, + { url = "https://files.pythonhosted.org/packages/4b/4b/d56b51da08d168c2315cd092faa47bc83388b116756dbd6995026ec9ba3f/langgraph_sdk-0.1.72-py3-none-any.whl", hash = "sha256:925d3fcc7a26361db04f9c4beb3ec05bc36361b2a836d181ff2ab145071ec3ce", size = 50129, upload-time = "2025-06-27T01:12:02.449Z" }, ] [[package]] name = "langsmith" -version = "0.4.2" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", marker = "python_full_version >= '3.11'" }, @@ -605,9 +627,9 @@ dependencies = [ { name = "requests-toolbelt", marker = "python_full_version >= '3.11'" }, { name = "zstandard", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8a/b6/0ebc396baf6b69aeb9eb466bbeaccd504c901615e744b0ecf33b0d39a8a5/langsmith-0.4.2.tar.gz", hash = "sha256:51df086a9ae17ffa16538f52ef3bb8b3d85b0e52c84958980553cb6cadd9e565", size = 352208, upload-time = "2025-06-25T11:29:00.408Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/8d2e0fc438d2d3d8d4300f7684ea30a754344ed00d7ba9cc2705241d2a5f/langsmith-0.4.4.tar.gz", hash = "sha256:70c53bbff24a7872e88e6fa0af98270f4986a6e364f9e85db1cc5636defa4d66", size = 352105, upload-time = "2025-06-27T19:20:36.207Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/06/fdcc2e8de8934595e7fd7b3f7c93065ff25c03ddeda566823882379b66b2/langsmith-0.4.2-py3-none-any.whl", hash = "sha256:2b1a3f889e134546dc5d67e23e5e8c6be5f91fd86827276ac874e3a25a04498a", size = 367715, upload-time = "2025-06-25T11:28:58.124Z" }, + { url = "https://files.pythonhosted.org/packages/1d/33/a3337eb70d795495a299a1640d7a75f17fb917155a64309b96106e7b9452/langsmith-0.4.4-py3-none-any.whl", hash = "sha256:014c68329bd085bd6c770a6405c61bb6881f82eb554ce8c4d1984b0035fd1716", size = 367687, upload-time = "2025-06-27T19:20:33.839Z" }, ] [[package]] @@ -655,46 +677,47 @@ wheels = [ [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -787,50 +810,50 @@ wheels = [ [[package]] name = "ormsgpack" -version = "1.9.1" +version = "1.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/a7/462cf8ff5e29241868b82d3a5ec124d690eb6a6a5c6fa5bb1367b839e027/ormsgpack-1.9.1.tar.gz", hash = "sha256:3da6e63d82565e590b98178545e64f0f8506137b92bd31a2d04fd7c82baf5794", size = 56887, upload-time = "2025-03-28T07:14:38.843Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/36/44eed5ef8ce93cded76a576780bab16425ce7876f10d3e2e6265e46c21ea/ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16", size = 58629, upload-time = "2025-05-24T19:07:53.944Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/32/5f504c0695ff96aaaf0452bee522d79b5a3ee809f22fd77fdb0dd5756d86/ormsgpack-1.9.1-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:f1f804fd9c0fd84213a6022c34172f82323b34afa7052a4af18797582cf56365", size = 382793, upload-time = "2025-03-28T07:13:32.067Z" }, - { url = "https://files.pythonhosted.org/packages/1e/c6/64fe1270271b61495611f1d3068baedb57d76e0f93ce7156f3763fb79b32/ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eab5cec99c46276b37071d570aab98603f3d0309b3818da3247eb64bb95e5cfc", size = 213974, upload-time = "2025-03-28T07:13:33.92Z" }, - { url = "https://files.pythonhosted.org/packages/13/56/6666d6a9b82c7d2021fce6823ff823bc373a4e7280979c1b453317678fbc/ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c12c6bb30e6df6fc0213b77f0a5e143f371d618be2e8eb4d555340ce01c6900", size = 217200, upload-time = "2025-03-28T07:13:35.793Z" }, - { url = "https://files.pythonhosted.org/packages/5f/fb/b844ed1e69d8615163525a8403d7abd3548b3fbfa0f3a973808f36145a0f/ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994d4bbb7ee333264a3e55e30ccee063df6635d785f21a08bf52f67821454a51", size = 223648, upload-time = "2025-03-28T07:13:37.538Z" }, - { url = "https://files.pythonhosted.org/packages/f2/26/c40c3e300f9c61a5ed7a6921656dd0d2907a8174936e1e643677585e497c/ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a668a584cf4bb6e1a6ef5a35f3f0d0fdae80cfb7237344ad19a50cce8c79317b", size = 394197, upload-time = "2025-03-28T07:13:39.682Z" }, - { url = "https://files.pythonhosted.org/packages/2d/4c/7a4ae187f18e7abf7ab0662b473264a60a5aa4e9bff266f541a8855df163/ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:aaf77699203822638014c604d100f132583844d4fd01eb639a2266970c02cfdf", size = 480550, upload-time = "2025-03-28T07:13:41.156Z" }, - { url = "https://files.pythonhosted.org/packages/b1/33/5c465dfd5571f816835bb9e371987bf081b529c64ef28a72d18b0b59902d/ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:003d7e1992b447898caf25a820b3037ec68a57864b3e2f34b64693b7d60a9984", size = 396955, upload-time = "2025-03-28T07:13:43.185Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fd/8f64f477b5c6d66e9c6343d7d3f32d7063ba20ab151dd36884e6504899ab/ormsgpack-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:67fefc77e4ba9469f79426769eb4c78acf21f22bef3ab1239a72dd728036ffc2", size = 125102, upload-time = "2025-03-28T07:13:44.878Z" }, - { url = "https://files.pythonhosted.org/packages/d8/3b/388e7915a28db6ab3daedfd4937bd7b063c50dd1543068daa31c0a3b70ed/ormsgpack-1.9.1-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:16eaf32c33ab4249e242181d59e2509b8e0330d6f65c1d8bf08c3dea38fd7c02", size = 382794, upload-time = "2025-03-28T07:13:46.72Z" }, - { url = "https://files.pythonhosted.org/packages/0f/b4/3f4afba058822bf69b274e0defe507056be0340e65363c3ebcd312b01b84/ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c70f2e5b2f9975536e8f7936a9721601dc54febe363d2d82f74c9b31d4fe1c65", size = 213974, upload-time = "2025-03-28T07:13:48.488Z" }, - { url = "https://files.pythonhosted.org/packages/bf/be/f0e21366d51b6e28fc3a55425be6a125545370d3479bf25be081e83ee236/ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:17c9e18b07d69e3db2e0f8af4731040175e11bdfde78ad8e28126e9e66ec5167", size = 217200, upload-time = "2025-03-28T07:13:50.449Z" }, - { url = "https://files.pythonhosted.org/packages/cc/90/67a23c1c880a6e5552acb45f9555b642528f89c8bcf75283a2ea64ef7175/ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73538d749096bb6470328601a2be8f7bdec28849ec6fd19595c232a5848d7124", size = 223649, upload-time = "2025-03-28T07:13:52.281Z" }, - { url = "https://files.pythonhosted.org/packages/80/ad/116c1f970b5b4453e4faa52645517a2e5eaf1ab385ba09a5c54253d07d0e/ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:827ff71de228cfd6d07b9d6b47911aa61b1e8dc995dec3caf8fdcdf4f874bcd0", size = 394200, upload-time = "2025-03-28T07:13:53.691Z" }, - { url = "https://files.pythonhosted.org/packages/c5/a2/b224a5ef193628a15205e473179276b87e8290d321693e4934a05cbd6ccf/ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:7307f808b3df282c8e8ed92c6ebceeb3eea3d8eeec808438f3f212226b25e217", size = 480551, upload-time = "2025-03-28T07:13:55.442Z" }, - { url = "https://files.pythonhosted.org/packages/b5/f4/a0f528196af6ab46e6c3f3051cf7403016bdc7b7d3e673ea5b04b145be98/ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f30aad7fb083bed1c540a3c163c6a9f63a94e3c538860bf8f13386c29b560ad5", size = 396959, upload-time = "2025-03-28T07:13:56.907Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/60c6f4787e3e93f5eb34fccb163753a8771465983a579e3405152f2422fd/ormsgpack-1.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:829a1b4c5bc3c38ece0c55cf91ebc09c3b987fceb24d3f680c2bcd03fd3789a4", size = 125100, upload-time = "2025-03-28T07:13:58.607Z" }, - { url = "https://files.pythonhosted.org/packages/dd/f1/155a598cc8030526ccaaf91ba4d61530f87900645559487edba58b0a90a2/ormsgpack-1.9.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1ede445fc3fdba219bb0e0d1f289df26a9c7602016b7daac6fafe8fe4e91548f", size = 383225, upload-time = "2025-03-28T07:14:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/23/1c/ef3097ba550fad55c79525f461febdd4e0d9cc18d065248044536f09488e/ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db50b9f918e25b289114312ed775794d0978b469831b992bdc65bfe20b91fe30", size = 214056, upload-time = "2025-03-28T07:14:02.861Z" }, - { url = "https://files.pythonhosted.org/packages/27/77/64d0da25896b2cbb99505ca518c109d7dd1964d7fde14c10943731738b60/ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c7d8fc58e4333308f58ec720b1ee6b12b2b3fe2d2d8f0766ab751cb351e8757", size = 217339, upload-time = "2025-03-28T07:14:04.278Z" }, - { url = "https://files.pythonhosted.org/packages/6c/10/c3a7fd0a0068b0bb52cccbfeb5656db895d69e895a3abbc210c4b3f98ff8/ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeee6d08c040db265cb8563444aba343ecb32cbdbe2414a489dcead9f70c6765", size = 223816, upload-time = "2025-03-28T07:14:05.969Z" }, - { url = "https://files.pythonhosted.org/packages/43/e7/aee1238dba652f2116c2523d36fd1c5f9775436032be5c233108fd2a1415/ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2fbb8181c198bdc413a4e889e5200f010724eea4b6d5a9a7eee2df039ac04aca", size = 394287, upload-time = "2025-03-28T07:14:07.635Z" }, - { url = "https://files.pythonhosted.org/packages/c7/09/1b452a92376f29d7a2da7c18fb01cf09978197a8eccbb8b204e72fd5a970/ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:16488f094ac0e2250cceea6caf72962614aa432ee11dd57ef45e1ad25ece3eff", size = 480709, upload-time = "2025-03-28T07:14:09.41Z" }, - { url = "https://files.pythonhosted.org/packages/de/13/7fa9fee5a73af8a73a42bf8c2e69489605714f65f5a41454400a05e84a3b/ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:422d960bfd6ad88be20794f50ec7953d8f7a0f2df60e19d0e8feb994e2ed64ee", size = 397247, upload-time = "2025-03-28T07:14:11.261Z" }, - { url = "https://files.pythonhosted.org/packages/a1/2d/2e87cb28110db0d3bb750edd4d8719b5068852a2eef5e96b0bf376bb8a81/ormsgpack-1.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:e6e2f9eab527cf43fb4a4293e493370276b1c8716cf305689202d646c6a782ef", size = 125368, upload-time = "2025-03-28T07:14:12.665Z" }, - { url = "https://files.pythonhosted.org/packages/b8/54/0390d5d092831e4df29dbafe32402891fc14b3e6ffe5a644b16cbbc9d9bc/ormsgpack-1.9.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ac61c18d9dd085e8519b949f7e655f7fb07909fd09c53b4338dd33309012e289", size = 383226, upload-time = "2025-03-28T07:14:13.868Z" }, - { url = "https://files.pythonhosted.org/packages/47/64/8b15d262d1caefead8fb22ec144f5ff7d9505fc31c22bc34598053d46fbe/ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134840b8c6615da2c24ce77bd12a46098015c808197a9995c7a2d991e1904eec", size = 214057, upload-time = "2025-03-28T07:14:15.307Z" }, - { url = "https://files.pythonhosted.org/packages/57/00/65823609266bad4d5ed29ea753d24a3bdb01c7edaf923da80967fc31f9c5/ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38fd42618f626394b2c7713c5d4bcbc917254e9753d5d4cde460658b51b11a74", size = 217340, upload-time = "2025-03-28T07:14:16.69Z" }, - { url = "https://files.pythonhosted.org/packages/a0/51/e535c50f7f87b49110233647f55300d7975139ef5e51f1adb4c55f58c124/ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d36397333ad07b9eba4c2e271fa78951bd81afc059c85a6e9f6c0eb2de07cda", size = 223815, upload-time = "2025-03-28T07:14:18.651Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ee/393e4a6de2a62124bf589602648f295a9fb3907a0e2fe80061b88899d072/ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:603063089597917d04e4c1b1d53988a34f7dc2ff1a03adcfd1cf4ae966d5fba6", size = 394287, upload-time = "2025-03-28T07:14:20.569Z" }, - { url = "https://files.pythonhosted.org/packages/c6/d8/e56d7c3cb73a0e533e3e2a21ae5838b2aa36a9dac1ca9c861af6bae5a369/ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:94bbf2b185e0cb721ceaba20e64b7158e6caf0cecd140ca29b9f05a8d5e91e2f", size = 480707, upload-time = "2025-03-28T07:14:22.006Z" }, - { url = "https://files.pythonhosted.org/packages/e6/e0/6a3c6a6dc98583a721c54b02f5195bde8f801aebdeda9b601fa2ab30ad39/ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38f380b1e8c96a712eb302b9349347385161a8e29046868ae2bfdfcb23e2692", size = 397246, upload-time = "2025-03-28T07:14:23.868Z" }, - { url = "https://files.pythonhosted.org/packages/b0/60/0ee5d790f13507e1f75ac21fc82dc1ef29afe1f520bd0f249d65b2f4839b/ormsgpack-1.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:a4bc63fb30db94075611cedbbc3d261dd17cf2aa8ff75a0fd684cd45ca29cb1b", size = 125371, upload-time = "2025-03-28T07:14:25.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/02/ac4a2263c9aad0d455f240e1bdd41b443e5452257cf13bc188177b0dfd1f/ormsgpack-1.9.1-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e95909248bece8e88a310a913838f17ff5a39190aa4e61de909c3cd27f59744b", size = 382789, upload-time = "2025-03-28T07:14:26.774Z" }, - { url = "https://files.pythonhosted.org/packages/81/6f/e50d070ae3a6aa7cb50849d0796ac6d72c0f8f01d5a42438c9567ab352e3/ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3939188810c5c641d6b207f29994142ae2b1c70534f7839bbd972d857ac2072", size = 213967, upload-time = "2025-03-28T07:14:28.473Z" }, - { url = "https://files.pythonhosted.org/packages/55/1d/379734bca4f2d71ce11c7096d85276280cf13d1bb7243bf809b171c25cda/ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b6476344a585aea00a2acc9fd07355bf2daac04062cfdd480fa83ec3e2403b", size = 217183, upload-time = "2025-03-28T07:14:29.822Z" }, - { url = "https://files.pythonhosted.org/packages/9a/f6/036a44ada8659b1729db5f20ba50dc1945a84a50cd4fa6b3a74d0f16fab9/ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d8b9d53da82b31662ce5a3834b65479cf794a34befb9fc50baa51518383250", size = 223647, upload-time = "2025-03-28T07:14:31.487Z" }, - { url = "https://files.pythonhosted.org/packages/b9/61/5c8671ab3b7cac21076169972bad9f4faa1fdda1f70e0ae78b365894b164/ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3933d4b0c0d404ee234dbc372836d6f2d2f4b6330c2a2fb9709ba4eaebfae7ba", size = 394232, upload-time = "2025-03-28T07:14:33.254Z" }, - { url = "https://files.pythonhosted.org/packages/7b/70/6e9ba8c8c405dee5dffd86edf1188ef1a116421598e18df89dac0c499aae/ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f824e94a7969f0aee9a6847ec232cf731a03b8734951c2a774dd4762308ea2d2", size = 480582, upload-time = "2025-03-28T07:14:34.704Z" }, - { url = "https://files.pythonhosted.org/packages/a6/e1/2113022dd9236cea13f0ba850a5f8a640c0c9e3b07bfbbaf01409190068b/ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c1f3f2295374020f9650e4aa7af6403ff016a0d92778b4a48bb3901fd801232d", size = 396952, upload-time = "2025-03-28T07:14:36.128Z" }, - { url = "https://files.pythonhosted.org/packages/01/d4/58ca5de3124ac975dae1a96a475c3cb9ed70c70dfba39fd4ceca53838ee6/ormsgpack-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:92eb1b4f7b168da47f547329b4b58d16d8f19508a97ce5266567385d42d81968", size = 125107, upload-time = "2025-03-28T07:14:37.621Z" }, + { url = "https://files.pythonhosted.org/packages/fc/74/c2dd5daf069e3798d09d5746000f9b210de04df83834e5cb47f0ace51892/ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216", size = 376280, upload-time = "2025-05-24T19:06:51.3Z" }, + { url = "https://files.pythonhosted.org/packages/78/7b/30ff4bffb709e8a242005a8c4d65714fd96308ad640d31cff1b85c0d8cc4/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373", size = 204335, upload-time = "2025-05-24T19:06:53.442Z" }, + { url = "https://files.pythonhosted.org/packages/8f/3f/c95b7d142819f801a0acdbd04280e8132e43b6e5a8920173e8eb92ea0e6a/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5", size = 215373, upload-time = "2025-05-24T19:06:55.153Z" }, + { url = "https://files.pythonhosted.org/packages/ef/1a/e30f4bcf386db2015d1686d1da6110c95110294d8ea04f86091dd5eb3361/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a", size = 216469, upload-time = "2025-05-24T19:06:56.555Z" }, + { url = "https://files.pythonhosted.org/packages/96/fc/7e44aeade22b91883586f45b7278c118fd210834c069774891447f444fc9/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227", size = 384590, upload-time = "2025-05-24T19:06:58.286Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/f92c24e8446697caa83c122f10b6cf5e155eddf81ce63905c8223a260482/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7", size = 478891, upload-time = "2025-05-24T19:07:00.126Z" }, + { url = "https://files.pythonhosted.org/packages/5a/75/87449690253c64bea2b663c7c8f2dbc9ad39d73d0b38db74bdb0f3947b16/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84", size = 390121, upload-time = "2025-05-24T19:07:01.777Z" }, + { url = "https://files.pythonhosted.org/packages/69/cc/c83257faf3a5169ec29dd87121317a25711da9412ee8c1e82f2e1a00c0be/ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07", size = 121196, upload-time = "2025-05-24T19:07:03.47Z" }, + { url = "https://files.pythonhosted.org/packages/30/27/7da748bc0d7d567950a378dee5a32477ed5d15462ab186918b5f25cac1ad/ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775", size = 376275, upload-time = "2025-05-24T19:07:05.128Z" }, + { url = "https://files.pythonhosted.org/packages/7b/65/c082cc8c74a914dbd05af0341c761c73c3d9960b7432bbf9b8e1e20811af/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af", size = 204335, upload-time = "2025-05-24T19:07:06.423Z" }, + { url = "https://files.pythonhosted.org/packages/46/62/17ef7e5d9766c79355b9c594cc9328c204f1677bc35da0595cc4e46449f0/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e", size = 215372, upload-time = "2025-05-24T19:07:08.149Z" }, + { url = "https://files.pythonhosted.org/packages/4e/92/7c91e8115fc37e88d1a35e13200fda3054ff5d2e5adf017345e58cea4834/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3", size = 216470, upload-time = "2025-05-24T19:07:09.903Z" }, + { url = "https://files.pythonhosted.org/packages/2c/86/ce053c52e2517b90e390792d83e926a7a523c1bce5cc63d0a7cd05ce6cf6/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b", size = 384591, upload-time = "2025-05-24T19:07:11.24Z" }, + { url = "https://files.pythonhosted.org/packages/07/e8/2ad59f2ab222c6029e500bc966bfd2fe5cb099f8ab6b7ebeb50ddb1a6fe5/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5", size = 478892, upload-time = "2025-05-24T19:07:13.147Z" }, + { url = "https://files.pythonhosted.org/packages/f4/73/f55e4b47b7b18fd8e7789680051bf830f1e39c03f1d9ed993cd0c3e97215/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08", size = 390122, upload-time = "2025-05-24T19:07:14.557Z" }, + { url = "https://files.pythonhosted.org/packages/f7/87/073251cdb93d4c6241748568b3ad1b2a76281fb2002eed16a3a4043d61cf/ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a", size = 121197, upload-time = "2025-05-24T19:07:15.981Z" }, + { url = "https://files.pythonhosted.org/packages/99/95/f3ab1a7638f6aa9362e87916bb96087fbbc5909db57e19f12ad127560e1e/ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0", size = 376806, upload-time = "2025-05-24T19:07:17.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2b/42f559f13c0b0f647b09d749682851d47c1a7e48308c43612ae6833499c8/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6", size = 204433, upload-time = "2025-05-24T19:07:18.569Z" }, + { url = "https://files.pythonhosted.org/packages/45/42/1ca0cb4d8c80340a89a4af9e6d8951fb8ba0d076a899d2084eadf536f677/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5", size = 215547, upload-time = "2025-05-24T19:07:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/0a/38/184a570d7c44c0260bc576d1daaac35b2bfd465a50a08189518505748b9a/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07", size = 216746, upload-time = "2025-05-24T19:07:21.83Z" }, + { url = "https://files.pythonhosted.org/packages/69/2f/1aaffd08f6b7fdc2a57336a80bdfb8df24e6a65ada5aa769afecfcbc6cc6/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044", size = 384783, upload-time = "2025-05-24T19:07:23.674Z" }, + { url = "https://files.pythonhosted.org/packages/a9/63/3e53d6f43bb35e00c98f2b8ab2006d5138089ad254bc405614fbf0213502/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd", size = 479076, upload-time = "2025-05-24T19:07:25.047Z" }, + { url = "https://files.pythonhosted.org/packages/b8/19/fa1121b03b61402bb4d04e35d164e2320ef73dfb001b57748110319dd014/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0", size = 390447, upload-time = "2025-05-24T19:07:26.568Z" }, + { url = "https://files.pythonhosted.org/packages/b0/0d/73143ecb94ac4a5dcba223402139240a75dee0cc6ba8a543788a5646407a/ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722", size = 121401, upload-time = "2025-05-24T19:07:28.308Z" }, + { url = "https://files.pythonhosted.org/packages/61/f8/ec5f4e03268d0097545efaab2893aa63f171cf2959cb0ea678a5690e16a1/ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f", size = 376806, upload-time = "2025-05-24T19:07:29.555Z" }, + { url = "https://files.pythonhosted.org/packages/c1/19/b3c53284aad1e90d4d7ed8c881a373d218e16675b8b38e3569d5b40cc9b8/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643", size = 204433, upload-time = "2025-05-24T19:07:30.977Z" }, + { url = "https://files.pythonhosted.org/packages/09/0b/845c258f59df974a20a536c06cace593698491defdd3d026a8a5f9b6e745/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e", size = 215549, upload-time = "2025-05-24T19:07:32.345Z" }, + { url = "https://files.pythonhosted.org/packages/61/56/57fce8fb34ca6c9543c026ebebf08344c64dbb7b6643d6ddd5355d37e724/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c", size = 216747, upload-time = "2025-05-24T19:07:34.075Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3f/655b5f6a2475c8d209f5348cfbaaf73ce26237b92d79ef2ad439407dd0fa/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb", size = 384785, upload-time = "2025-05-24T19:07:35.83Z" }, + { url = "https://files.pythonhosted.org/packages/4b/94/687a0ad8afd17e4bce1892145d6a1111e58987ddb176810d02a1f3f18686/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935", size = 479076, upload-time = "2025-05-24T19:07:37.533Z" }, + { url = "https://files.pythonhosted.org/packages/c8/34/68925232e81e0e062a2f0ac678f62aa3b6f7009d6a759e19324dbbaebae7/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668", size = 390446, upload-time = "2025-05-24T19:07:39.469Z" }, + { url = "https://files.pythonhosted.org/packages/12/ad/f4e1a36a6d1714afb7ffb74b3ababdcb96529cf4e7a216f9f7c8eda837b6/ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69", size = 121399, upload-time = "2025-05-24T19:07:40.854Z" }, + { url = "https://files.pythonhosted.org/packages/75/8f/bb80469db9d5b10708cba6997463d140486ca7053a5d18f99b5739cfecf7/ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32", size = 376272, upload-time = "2025-05-24T19:07:42.16Z" }, + { url = "https://files.pythonhosted.org/packages/08/9c/48f714ed3d5a153f25e3b490496e6ba214aee265a82be1b61e39019ea146/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4", size = 204314, upload-time = "2025-05-24T19:07:43.444Z" }, + { url = "https://files.pythonhosted.org/packages/27/42/7f9edf6e5511120b5304c76c5d3a8b4719ff927555a6dba41b6f9d041b30/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453", size = 215386, upload-time = "2025-05-24T19:07:45.232Z" }, + { url = "https://files.pythonhosted.org/packages/40/87/41e14485857fbe4ed5a530677fe60dd6910a254825c0b1cb5b04baaa4be0/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1", size = 216466, upload-time = "2025-05-24T19:07:46.548Z" }, + { url = "https://files.pythonhosted.org/packages/cb/68/769fa1c721d8aa6799c0ce98b1711ae57de3e6379b554ebf9a11be4c62ff/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681", size = 384600, upload-time = "2025-05-24T19:07:47.945Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f9/b57fd387fe16753783a3cea0ed2471c727bbed4356d8a08e3f0340251870/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3", size = 478888, upload-time = "2025-05-24T19:07:49.801Z" }, + { url = "https://files.pythonhosted.org/packages/3e/0f/464cdfa7f9ee817c2d94485880b6c3c4b9f22df9fcbf21c303bbfebcb3ed/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d", size = 390118, upload-time = "2025-05-24T19:07:51.193Z" }, + { url = "https://files.pythonhosted.org/packages/ad/03/b9146dff5458def4c0a2b1e35c1c24e4d5e8083899aa0718b6eccba39317/ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749", size = 121199, upload-time = "2025-05-24T19:07:52.639Z" }, ] [[package]] @@ -843,12 +866,21 @@ wheels = [ ] [[package]] -name = "pluggy" -version = "1.5.0" +name = "pathspec" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] @@ -862,7 +894,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.4" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types", marker = "python_full_version >= '3.11'" }, @@ -870,9 +902,9 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, { name = "typing-inspection", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -984,6 +1016,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pyjwt" version = "2.10.1" @@ -995,7 +1036,7 @@ wheels = [ [[package]] name = "pytest" -version = "7.4.4" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1003,35 +1044,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116, upload-time = "2023-12-31T12:00:18.035Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287, upload-time = "2023-12-31T12:00:13.963Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.21.2" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/53/57663d99acaac2fcdafdc697e52a9b1b7d6fcf36616281ff9768a44e7ff3/pytest_asyncio-0.21.2.tar.gz", hash = "sha256:d67738fc232b94b326b9d060750beb16e0074210b98dd8b58a5239fa2a154f45", size = 30656, upload-time = "2024-04-29T13:23:24.738Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/ce/1e4b53c213dce25d6e8b163697fbce2d43799d76fa08eea6ad270451c370/pytest_asyncio-0.21.2-py3-none-any.whl", hash = "sha256:ab664c88bb7998f711d8039cacd4884da6430886ae8bbd4eded552ed2004f16b", size = 13368, upload-time = "2024-04-29T13:23:23.126Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -1048,11 +1091,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/36/47/ab65fc1d682befc31 [[package]] name = "python-dotenv" -version = "1.1.0" +version = "1.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, ] [[package]] @@ -1110,7 +1153,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi", marker = "python_full_version >= '3.11'" }, @@ -1118,9 +1161,9 @@ dependencies = [ { name = "idna", marker = "python_full_version >= '3.11'" }, { name = "urllib3", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -1137,27 +1180,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.6.9" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/0d/6148a48dab5662ca1d5a93b7c0d13c03abd3cc7e2f35db08410e47cef15d/ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2", size = 3095355, upload-time = "2024-10-04T13:40:28.594Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/8f/f7a0a0ef1818662efb32ed6df16078c95da7a0a3248d64c2410c1e27799f/ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd", size = 10440526, upload-time = "2024-10-04T13:39:21.747Z" }, - { url = "https://files.pythonhosted.org/packages/8b/69/b179a5faf936a9e2ab45bb412a668e4661eded964ccfa19d533f29463ef6/ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec", size = 10034612, upload-time = "2024-10-04T13:39:26.301Z" }, - { url = "https://files.pythonhosted.org/packages/c7/ef/fd1b4be979c579d191eeac37b5cfc0ec906de72c8bcd8595e2c81bb700c1/ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c", size = 9706197, upload-time = "2024-10-04T13:39:29.297Z" }, - { url = "https://files.pythonhosted.org/packages/29/61/b376d775deb5851cb48d893c568b511a6d3625ef2c129ad5698b64fb523c/ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e", size = 10751855, upload-time = "2024-10-04T13:39:33.175Z" }, - { url = "https://files.pythonhosted.org/packages/13/d7/def9e5f446d75b9a9c19b24231a3a658c075d79163b08582e56fa5dcfa38/ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577", size = 10200889, upload-time = "2024-10-04T13:39:36.867Z" }, - { url = "https://files.pythonhosted.org/packages/6c/d6/7f34160818bcb6e84ce293a5966cba368d9112ff0289b273fbb689046047/ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829", size = 11038678, upload-time = "2024-10-04T13:39:40.428Z" }, - { url = "https://files.pythonhosted.org/packages/13/34/a40ff8ae62fb1b26fb8e6fa7e64bc0e0a834b47317880de22edd6bfb54fb/ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5", size = 11808682, upload-time = "2024-10-04T13:39:52.141Z" }, - { url = "https://files.pythonhosted.org/packages/2e/6d/25a4386ae4009fc798bd10ba48c942d1b0b3e459b5403028f1214b6dd161/ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7", size = 11330446, upload-time = "2024-10-04T13:39:55.783Z" }, - { url = "https://files.pythonhosted.org/packages/f7/f6/bdf891a9200d692c94ebcd06ae5a2fa5894e522f2c66c2a12dd5d8cb2654/ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f", size = 12483048, upload-time = "2024-10-04T13:39:58.845Z" }, - { url = "https://files.pythonhosted.org/packages/a7/86/96f4252f41840e325b3fa6c48297e661abb9f564bd7dcc0572398c8daa42/ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", size = 10936855, upload-time = "2024-10-04T13:40:01.818Z" }, - { url = "https://files.pythonhosted.org/packages/45/87/801a52d26c8dbf73424238e9908b9ceac430d903c8ef35eab1b44fcfa2bd/ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb", size = 10713007, upload-time = "2024-10-04T13:40:05.384Z" }, - { url = "https://files.pythonhosted.org/packages/be/27/6f7161d90320a389695e32b6ebdbfbedde28ccbf52451e4b723d7ce744ad/ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0", size = 10274594, upload-time = "2024-10-04T13:40:08.801Z" }, - { url = "https://files.pythonhosted.org/packages/00/52/dc311775e7b5f5b19831563cb1572ecce63e62681bccc609867711fae317/ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625", size = 10608024, upload-time = "2024-10-04T13:40:11.923Z" }, - { url = "https://files.pythonhosted.org/packages/98/b6/be0a1ddcbac65a30c985cf7224c4fce786ba2c51e7efeb5178fe410ed3cf/ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039", size = 10982085, upload-time = "2024-10-04T13:40:15.539Z" }, - { url = "https://files.pythonhosted.org/packages/bb/a4/c84bc13d0b573cf7bb7d17b16d6d29f84267c92d79b2f478d4ce322e8e72/ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d", size = 8522088, upload-time = "2024-10-04T13:40:19.168Z" }, - { url = "https://files.pythonhosted.org/packages/74/be/fc352bd8ca40daae8740b54c1c3e905a7efe470d420a268cd62150248c91/ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117", size = 9359275, upload-time = "2024-10-04T13:40:22.852Z" }, - { url = "https://files.pythonhosted.org/packages/3e/14/fd026bc74ded05e2351681545a5f626e78ef831f8edce064d61acd2e6ec7/ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93", size = 8679879, upload-time = "2024-10-04T13:40:25.797Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -1185,23 +1228,24 @@ wheels = [ [[package]] name = "starlette" -version = "0.46.2" +version = "0.47.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio", marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version >= '3.11' and python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/69/662169fdb92fb96ec3eaee218cf540a629d629c86d7993d9651226a6789b/starlette-0.47.1.tar.gz", hash = "sha256:aef012dd2b6be325ffa16698f9dc533614fb1cebd593a906b90dc1025529a79b", size = 2583072, upload-time = "2025-06-21T04:03:17.337Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, + { url = "https://files.pythonhosted.org/packages/82/95/38ef0cd7fa11eaba6a99b3c4f5ac948d8bc6ff199aabd327a29cc000840c/starlette-0.47.1-py3-none-any.whl", hash = "sha256:5e11c9f5c7c3f24959edbf2dffdc01bba860228acf657129467d8a7468591527", size = 72747, upload-time = "2025-06-21T04:03:15.705Z" }, ] [[package]] name = "structlog" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/6a/b0b6d440e429d2267076c4819300d9929563b1da959cf1f68afbcd69fe45/structlog-25.3.0.tar.gz", hash = "sha256:8dab497e6f6ca962abad0c283c46744185e0c9ba900db52a423cb6db99f7abeb", size = 1367514, upload-time = "2025-04-25T16:00:39.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b9/6e672db4fec07349e7a8a8172c1a6ae235c58679ca29c3f86a61b5e59ff3/structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4", size = 1369138, upload-time = "2025-06-02T08:21:12.971Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/52/7a2c7a317b254af857464da3d60a0d3730c44f912f8c510c76a738a207fd/structlog-25.3.0-py3-none-any.whl", hash = "sha256:a341f5524004c158498c3127eecded091eb67d3a611e7a3093deca30db06e172", size = 68240, upload-time = "2025-04-25T16:00:37.295Z" }, + { url = "https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c", size = 68720, upload-time = "2025-06-02T08:21:11.43Z" }, ] [[package]] @@ -1263,45 +1307,45 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "uvicorn" -version = "0.34.2" +version = "0.35.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", marker = "python_full_version >= '3.11'" }, + { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "h11", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, + { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" }, ] [[package]] @@ -1343,83 +1387,118 @@ wheels = [ [[package]] name = "watchfiles" -version = "1.0.5" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload-time = "2025-04-08T10:36:26.722Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/d451fcc97d029f5812e898fd30a53fd8c15c7bbd058fd75cfc6beb9bd761/watchfiles-1.1.0.tar.gz", hash = "sha256:693ed7ec72cbfcee399e92c895362b6e66d63dac6b91e2c11ae03d10d503e575", size = 94406, upload-time = "2025-06-15T19:06:59.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632, upload-time = "2025-04-08T10:34:41.832Z" }, - { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734, upload-time = "2025-04-08T10:34:44.236Z" }, - { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008, upload-time = "2025-04-08T10:34:45.617Z" }, - { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029, upload-time = "2025-04-08T10:34:46.814Z" }, - { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916, upload-time = "2025-04-08T10:34:48.571Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763, upload-time = "2025-04-08T10:34:50.268Z" }, - { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891, upload-time = "2025-04-08T10:34:51.419Z" }, - { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921, upload-time = "2025-04-08T10:34:52.67Z" }, - { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422, upload-time = "2025-04-08T10:34:53.985Z" }, - { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675, upload-time = "2025-04-08T10:34:55.173Z" }, - { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921, upload-time = "2025-04-08T10:34:56.318Z" }, - { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526, upload-time = "2025-04-08T10:34:57.95Z" }, - { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336, upload-time = "2025-04-08T10:34:59.359Z" }, - { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977, upload-time = "2025-04-08T10:35:00.522Z" }, - { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232, upload-time = "2025-04-08T10:35:01.698Z" }, - { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151, upload-time = "2025-04-08T10:35:03.358Z" }, - { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054, upload-time = "2025-04-08T10:35:04.561Z" }, - { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955, upload-time = "2025-04-08T10:35:05.786Z" }, - { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234, upload-time = "2025-04-08T10:35:07.187Z" }, - { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750, upload-time = "2025-04-08T10:35:08.859Z" }, - { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591, upload-time = "2025-04-08T10:35:10.64Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370, upload-time = "2025-04-08T10:35:12.412Z" }, - { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791, upload-time = "2025-04-08T10:35:13.719Z" }, - { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622, upload-time = "2025-04-08T10:35:15.071Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699, upload-time = "2025-04-08T10:35:16.732Z" }, - { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511, upload-time = "2025-04-08T10:35:17.956Z" }, - { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715, upload-time = "2025-04-08T10:35:19.202Z" }, - { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138, upload-time = "2025-04-08T10:35:20.586Z" }, - { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592, upload-time = "2025-04-08T10:35:21.87Z" }, - { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532, upload-time = "2025-04-08T10:35:23.143Z" }, - { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865, upload-time = "2025-04-08T10:35:24.702Z" }, - { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887, upload-time = "2025-04-08T10:35:25.969Z" }, - { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498, upload-time = "2025-04-08T10:35:27.353Z" }, - { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663, upload-time = "2025-04-08T10:35:28.685Z" }, - { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410, upload-time = "2025-04-08T10:35:30.42Z" }, - { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965, upload-time = "2025-04-08T10:35:32.023Z" }, - { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693, upload-time = "2025-04-08T10:35:33.225Z" }, - { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287, upload-time = "2025-04-08T10:35:34.568Z" }, - { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload-time = "2025-04-08T10:35:35.792Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload-time = "2025-04-08T10:35:37.048Z" }, - { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload-time = "2025-04-08T10:35:38.357Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload-time = "2025-04-08T10:35:39.708Z" }, - { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload-time = "2025-04-08T10:35:41.469Z" }, - { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload-time = "2025-04-08T10:35:43.289Z" }, - { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload-time = "2025-04-08T10:35:44.574Z" }, - { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload-time = "2025-04-08T10:35:46.336Z" }, - { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload-time = "2025-04-08T10:35:48.161Z" }, - { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" }, - { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" }, - { url = "https://files.pythonhosted.org/packages/c5/95/94f3dd15557f5553261e407551c5e4d340e50161c55aa30812c79da6cb04/watchfiles-1.0.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2cfb371be97d4db374cba381b9f911dd35bb5f4c58faa7b8b7106c8853e5d225", size = 405686, upload-time = "2025-04-08T10:35:53.86Z" }, - { url = "https://files.pythonhosted.org/packages/f4/aa/b99e968153f8b70159ecca7b3daf46a6f46d97190bdaa3a449ad31b921d7/watchfiles-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a3904d88955fda461ea2531fcf6ef73584ca921415d5cfa44457a225f4a42bc1", size = 396047, upload-time = "2025-04-08T10:35:55.232Z" }, - { url = "https://files.pythonhosted.org/packages/23/cb/90d3d760ad4bc7290e313fb9236c7d60598627a25a5a72764e48d9652064/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b7a21715fb12274a71d335cff6c71fe7f676b293d322722fe708a9ec81d91f5", size = 456081, upload-time = "2025-04-08T10:35:57.102Z" }, - { url = "https://files.pythonhosted.org/packages/3e/65/79c6cebe5bcb695cdac145946ad5a09b9f66762549e82fb2d064ea960c95/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dfd6ae1c385ab481766b3c61c44aca2b3cd775f6f7c0fa93d979ddec853d29d5", size = 459838, upload-time = "2025-04-08T10:35:58.867Z" }, - { url = "https://files.pythonhosted.org/packages/3f/84/699f52632cdaa777f6df7f6f1cc02a23a75b41071b7e6765b9a412495f61/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b659576b950865fdad31fa491d31d37cf78b27113a7671d39f919828587b429b", size = 489753, upload-time = "2025-04-08T10:36:00.237Z" }, - { url = "https://files.pythonhosted.org/packages/25/68/3241f82ad414fd969de6bf3a93805682e5eb589aeab510322f2aa14462f8/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1909e0a9cd95251b15bff4261de5dd7550885bd172e3536824bf1cf6b121e200", size = 525015, upload-time = "2025-04-08T10:36:02.159Z" }, - { url = "https://files.pythonhosted.org/packages/85/c4/30d879e252f52b01660f545c193e6b81c48aac2e0eeec71263af3add905b/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:832ccc221927c860e7286c55c9b6ebcc0265d5e072f49c7f6456c7798d2b39aa", size = 503816, upload-time = "2025-04-08T10:36:03.869Z" }, - { url = "https://files.pythonhosted.org/packages/6b/7d/fa34750f6f4b1a70d96fa6b685fe2948d01e3936328ea528f182943eb373/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85fbb6102b3296926d0c62cfc9347f6237fb9400aecd0ba6bbda94cae15f2b3b", size = 456137, upload-time = "2025-04-08T10:36:05.226Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0c/a1569709aaeccb1dd74b0dd304d0de29e3ea1fdf11e08c78f489628f9ebb/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:15ac96dd567ad6c71c71f7b2c658cb22b7734901546cd50a475128ab557593ca", size = 632673, upload-time = "2025-04-08T10:36:06.752Z" }, - { url = "https://files.pythonhosted.org/packages/90/b6/645eaaca11f3ac625cf3b6e008e543acf0bf2581f68b5e205a13b05618b6/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b6227351e11c57ae997d222e13f5b6f1f0700d84b8c52304e8675d33a808382", size = 626659, upload-time = "2025-04-08T10:36:08.18Z" }, - { url = "https://files.pythonhosted.org/packages/3a/c4/e741d9b92b0a2c74b976ff78bbc9a1276b4d904c590878e8fe0ec9fecca5/watchfiles-1.0.5-cp39-cp39-win32.whl", hash = "sha256:974866e0db748ebf1eccab17862bc0f0303807ed9cda465d1324625b81293a18", size = 278471, upload-time = "2025-04-08T10:36:10.546Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/36b0cb6add99105f78931994b30bc1dd24118c0e659ab6a3ffe0dd8734d4/watchfiles-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:9848b21ae152fe79c10dd0197304ada8f7b586d3ebc3f27f43c506e5a52a863c", size = 292027, upload-time = "2025-04-08T10:36:11.901Z" }, - { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947, upload-time = "2025-04-08T10:36:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276, upload-time = "2025-04-08T10:36:15.131Z" }, - { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550, upload-time = "2025-04-08T10:36:16.635Z" }, - { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542, upload-time = "2025-04-08T10:36:18.655Z" }, - { url = "https://files.pythonhosted.org/packages/5b/84/7b69282c0df2bf2dff4e50be2c54669cddf219a5a5fb077891c00c00e5c8/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:554389562c29c2c182e3908b149095051f81d28c2fec79ad6c8997d7d63e0009", size = 405783, upload-time = "2025-04-08T10:36:20.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ae/03fca0545d99b7ea21df49bead7b51e7dca9ce3b45bb6d34530aa18c16a2/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a74add8d7727e6404d5dc4dcd7fac65d4d82f95928bbee0cf5414c900e86773e", size = 397133, upload-time = "2025-04-08T10:36:22.439Z" }, - { url = "https://files.pythonhosted.org/packages/1a/07/c2b6390003e933b2e187a3f7070c00bd87da8a58d6f2393e039b06a88c2e/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb1489f25b051a89fae574505cc26360c8e95e227a9500182a7fe0afcc500ce0", size = 456198, upload-time = "2025-04-08T10:36:23.884Z" }, - { url = "https://files.pythonhosted.org/packages/46/d3/ecc62cbd7054f0812f3a7ca7c1c9f7ba99ba45efcfc8297a9fcd2c87b31c/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0901429650652d3f0da90bad42bdafc1f9143ff3605633c455c999a2d786cac", size = 456511, upload-time = "2025-04-08T10:36:25.42Z" }, + { url = "https://files.pythonhosted.org/packages/b9/dd/579d1dc57f0f895426a1211c4ef3b0cb37eb9e642bb04bdcd962b5df206a/watchfiles-1.1.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:27f30e14aa1c1e91cb653f03a63445739919aef84c8d2517997a83155e7a2fcc", size = 405757, upload-time = "2025-06-15T19:04:51.058Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/7a0318cd874393344d48c34d53b3dd419466adf59a29ba5b51c88dd18b86/watchfiles-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3366f56c272232860ab45c77c3ca7b74ee819c8e1f6f35a7125556b198bbc6df", size = 397511, upload-time = "2025-06-15T19:04:52.79Z" }, + { url = "https://files.pythonhosted.org/packages/06/be/503514656d0555ec2195f60d810eca29b938772e9bfb112d5cd5ad6f6a9e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8412eacef34cae2836d891836a7fff7b754d6bcac61f6c12ba5ca9bc7e427b68", size = 450739, upload-time = "2025-06-15T19:04:54.203Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0d/a05dd9e5f136cdc29751816d0890d084ab99f8c17b86f25697288ca09bc7/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df670918eb7dd719642e05979fc84704af913d563fd17ed636f7c4783003fdcc", size = 458106, upload-time = "2025-06-15T19:04:55.607Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fa/9cd16e4dfdb831072b7ac39e7bea986e52128526251038eb481effe9f48e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7642b9bc4827b5518ebdb3b82698ada8c14c7661ddec5fe719f3e56ccd13c97", size = 484264, upload-time = "2025-06-15T19:04:57.009Z" }, + { url = "https://files.pythonhosted.org/packages/32/04/1da8a637c7e2b70e750a0308e9c8e662ada0cca46211fa9ef24a23937e0b/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:199207b2d3eeaeb80ef4411875a6243d9ad8bc35b07fc42daa6b801cc39cc41c", size = 597612, upload-time = "2025-06-15T19:04:58.409Z" }, + { url = "https://files.pythonhosted.org/packages/30/01/109f2762e968d3e58c95731a206e5d7d2a7abaed4299dd8a94597250153c/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a479466da6db5c1e8754caee6c262cd373e6e6c363172d74394f4bff3d84d7b5", size = 477242, upload-time = "2025-06-15T19:04:59.786Z" }, + { url = "https://files.pythonhosted.org/packages/b5/b8/46f58cf4969d3b7bc3ca35a98e739fa4085b0657a1540ccc29a1a0bc016f/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:935f9edd022ec13e447e5723a7d14456c8af254544cefbc533f6dd276c9aa0d9", size = 453148, upload-time = "2025-06-15T19:05:01.103Z" }, + { url = "https://files.pythonhosted.org/packages/a5/cd/8267594263b1770f1eb76914940d7b2d03ee55eca212302329608208e061/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8076a5769d6bdf5f673a19d51da05fc79e2bbf25e9fe755c47595785c06a8c72", size = 626574, upload-time = "2025-06-15T19:05:02.582Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2f/7f2722e85899bed337cba715723e19185e288ef361360718973f891805be/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86b1e28d4c37e89220e924305cd9f82866bb0ace666943a6e4196c5df4d58dcc", size = 624378, upload-time = "2025-06-15T19:05:03.719Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/64c88ec43d90a568234d021ab4b2a6f42a5230d772b987c3f9c00cc27b8b/watchfiles-1.1.0-cp310-cp310-win32.whl", hash = "sha256:d1caf40c1c657b27858f9774d5c0e232089bca9cb8ee17ce7478c6e9264d2587", size = 279829, upload-time = "2025-06-15T19:05:04.822Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/a9c1ed33de7af80935e4eac09570de679c6e21c07070aa99f74b4431f4d6/watchfiles-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a89c75a5b9bc329131115a409d0acc16e8da8dfd5867ba59f1dd66ae7ea8fa82", size = 292192, upload-time = "2025-06-15T19:05:06.348Z" }, + { url = "https://files.pythonhosted.org/packages/8b/78/7401154b78ab484ccaaeef970dc2af0cb88b5ba8a1b415383da444cdd8d3/watchfiles-1.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c9649dfc57cc1f9835551deb17689e8d44666315f2e82d337b9f07bd76ae3aa2", size = 405751, upload-time = "2025-06-15T19:05:07.679Z" }, + { url = "https://files.pythonhosted.org/packages/76/63/e6c3dbc1f78d001589b75e56a288c47723de28c580ad715eb116639152b5/watchfiles-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:406520216186b99374cdb58bc48e34bb74535adec160c8459894884c983a149c", size = 397313, upload-time = "2025-06-15T19:05:08.764Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/8afa359ff52e99af1632f90cbf359da46184207e893a5f179301b0c8d6df/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb45350fd1dc75cd68d3d72c47f5b513cb0578da716df5fba02fff31c69d5f2d", size = 450792, upload-time = "2025-06-15T19:05:09.869Z" }, + { url = "https://files.pythonhosted.org/packages/1d/bf/7446b401667f5c64972a57a0233be1104157fc3abf72c4ef2666c1bd09b2/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11ee4444250fcbeb47459a877e5e80ed994ce8e8d20283857fc128be1715dac7", size = 458196, upload-time = "2025-06-15T19:05:11.91Z" }, + { url = "https://files.pythonhosted.org/packages/58/2f/501ddbdfa3fa874ea5597c77eeea3d413579c29af26c1091b08d0c792280/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bda8136e6a80bdea23e5e74e09df0362744d24ffb8cd59c4a95a6ce3d142f79c", size = 484788, upload-time = "2025-06-15T19:05:13.373Z" }, + { url = "https://files.pythonhosted.org/packages/61/1e/9c18eb2eb5c953c96bc0e5f626f0e53cfef4bd19bd50d71d1a049c63a575/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b915daeb2d8c1f5cee4b970f2e2c988ce6514aace3c9296e58dd64dc9aa5d575", size = 597879, upload-time = "2025-06-15T19:05:14.725Z" }, + { url = "https://files.pythonhosted.org/packages/8b/6c/1467402e5185d89388b4486745af1e0325007af0017c3384cc786fff0542/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed8fc66786de8d0376f9f913c09e963c66e90ced9aa11997f93bdb30f7c872a8", size = 477447, upload-time = "2025-06-15T19:05:15.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a1/ec0a606bde4853d6c4a578f9391eeb3684a9aea736a8eb217e3e00aa89a1/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe4371595edf78c41ef8ac8df20df3943e13defd0efcb732b2e393b5a8a7a71f", size = 453145, upload-time = "2025-06-15T19:05:17.17Z" }, + { url = "https://files.pythonhosted.org/packages/90/b9/ef6f0c247a6a35d689fc970dc7f6734f9257451aefb30def5d100d6246a5/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b7c5f6fe273291f4d414d55b2c80d33c457b8a42677ad14b4b47ff025d0893e4", size = 626539, upload-time = "2025-06-15T19:05:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/34/44/6ffda5537085106ff5aaa762b0d130ac6c75a08015dd1621376f708c94de/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7738027989881e70e3723c75921f1efa45225084228788fc59ea8c6d732eb30d", size = 624472, upload-time = "2025-06-15T19:05:19.588Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e3/71170985c48028fa3f0a50946916a14055e741db11c2e7bc2f3b61f4d0e3/watchfiles-1.1.0-cp311-cp311-win32.whl", hash = "sha256:622d6b2c06be19f6e89b1d951485a232e3b59618def88dbeda575ed8f0d8dbf2", size = 279348, upload-time = "2025-06-15T19:05:20.856Z" }, + { url = "https://files.pythonhosted.org/packages/89/1b/3e39c68b68a7a171070f81fc2561d23ce8d6859659406842a0e4bebf3bba/watchfiles-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:48aa25e5992b61debc908a61ab4d3f216b64f44fdaa71eb082d8b2de846b7d12", size = 292607, upload-time = "2025-06-15T19:05:21.937Z" }, + { url = "https://files.pythonhosted.org/packages/61/9f/2973b7539f2bdb6ea86d2c87f70f615a71a1fc2dba2911795cea25968aea/watchfiles-1.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:00645eb79a3faa70d9cb15c8d4187bb72970b2470e938670240c7998dad9f13a", size = 285056, upload-time = "2025-06-15T19:05:23.12Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b8/858957045a38a4079203a33aaa7d23ea9269ca7761c8a074af3524fbb240/watchfiles-1.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9dc001c3e10de4725c749d4c2f2bdc6ae24de5a88a339c4bce32300a31ede179", size = 402339, upload-time = "2025-06-15T19:05:24.516Z" }, + { url = "https://files.pythonhosted.org/packages/80/28/98b222cca751ba68e88521fabd79a4fab64005fc5976ea49b53fa205d1fa/watchfiles-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9ba68ec283153dead62cbe81872d28e053745f12335d037de9cbd14bd1877f5", size = 394409, upload-time = "2025-06-15T19:05:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/86/50/dee79968566c03190677c26f7f47960aff738d32087087bdf63a5473e7df/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130fc497b8ee68dce163e4254d9b0356411d1490e868bd8790028bc46c5cc297", size = 450939, upload-time = "2025-06-15T19:05:26.494Z" }, + { url = "https://files.pythonhosted.org/packages/40/45/a7b56fb129700f3cfe2594a01aa38d033b92a33dddce86c8dfdfc1247b72/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50a51a90610d0845a5931a780d8e51d7bd7f309ebc25132ba975aca016b576a0", size = 457270, upload-time = "2025-06-15T19:05:27.466Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c8/fa5ef9476b1d02dc6b5e258f515fcaaecf559037edf8b6feffcbc097c4b8/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc44678a72ac0910bac46fa6a0de6af9ba1355669b3dfaf1ce5f05ca7a74364e", size = 483370, upload-time = "2025-06-15T19:05:28.548Z" }, + { url = "https://files.pythonhosted.org/packages/98/68/42cfcdd6533ec94f0a7aab83f759ec11280f70b11bfba0b0f885e298f9bd/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a543492513a93b001975ae283a51f4b67973662a375a403ae82f420d2c7205ee", size = 598654, upload-time = "2025-06-15T19:05:29.997Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/b2a1544224118cc28df7e59008a929e711f9c68ce7d554e171b2dc531352/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ac164e20d17cc285f2b94dc31c384bc3aa3dd5e7490473b3db043dd70fbccfd", size = 478667, upload-time = "2025-06-15T19:05:31.172Z" }, + { url = "https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f", size = 452213, upload-time = "2025-06-15T19:05:32.299Z" }, + { url = "https://files.pythonhosted.org/packages/6e/17/c8f1a36540c9a1558d4faf08e909399e8133599fa359bf52ec8fcee5be6f/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:37d3d3f7defb13f62ece99e9be912afe9dd8a0077b7c45ee5a57c74811d581a4", size = 626718, upload-time = "2025-06-15T19:05:33.415Z" }, + { url = "https://files.pythonhosted.org/packages/26/45/fb599be38b4bd38032643783d7496a26a6f9ae05dea1a42e58229a20ac13/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7080c4bb3efd70a07b1cc2df99a7aa51d98685be56be6038c3169199d0a1c69f", size = 623098, upload-time = "2025-06-15T19:05:34.534Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/fdf40e038475498e160cd167333c946e45d8563ae4dd65caf757e9ffe6b4/watchfiles-1.1.0-cp312-cp312-win32.whl", hash = "sha256:cbcf8630ef4afb05dc30107bfa17f16c0896bb30ee48fc24bf64c1f970f3b1fd", size = 279209, upload-time = "2025-06-15T19:05:35.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d3/3ae9d5124ec75143bdf088d436cba39812122edc47709cd2caafeac3266f/watchfiles-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:cbd949bdd87567b0ad183d7676feb98136cde5bb9025403794a4c0db28ed3a47", size = 292786, upload-time = "2025-06-15T19:05:36.559Z" }, + { url = "https://files.pythonhosted.org/packages/26/2f/7dd4fc8b5f2b34b545e19629b4a018bfb1de23b3a496766a2c1165ca890d/watchfiles-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:0a7d40b77f07be87c6faa93d0951a0fcd8cbca1ddff60a1b65d741bac6f3a9f6", size = 284343, upload-time = "2025-06-15T19:05:37.5Z" }, + { url = "https://files.pythonhosted.org/packages/d3/42/fae874df96595556a9089ade83be34a2e04f0f11eb53a8dbf8a8a5e562b4/watchfiles-1.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5007f860c7f1f8df471e4e04aaa8c43673429047d63205d1630880f7637bca30", size = 402004, upload-time = "2025-06-15T19:05:38.499Z" }, + { url = "https://files.pythonhosted.org/packages/fa/55/a77e533e59c3003d9803c09c44c3651224067cbe7fb5d574ddbaa31e11ca/watchfiles-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20ecc8abbd957046f1fe9562757903f5eaf57c3bce70929fda6c7711bb58074a", size = 393671, upload-time = "2025-06-15T19:05:39.52Z" }, + { url = "https://files.pythonhosted.org/packages/05/68/b0afb3f79c8e832e6571022611adbdc36e35a44e14f129ba09709aa4bb7a/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2f0498b7d2a3c072766dba3274fe22a183dbea1f99d188f1c6c72209a1063dc", size = 449772, upload-time = "2025-06-15T19:05:40.897Z" }, + { url = "https://files.pythonhosted.org/packages/ff/05/46dd1f6879bc40e1e74c6c39a1b9ab9e790bf1f5a2fe6c08b463d9a807f4/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:239736577e848678e13b201bba14e89718f5c2133dfd6b1f7846fa1b58a8532b", size = 456789, upload-time = "2025-06-15T19:05:42.045Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ca/0eeb2c06227ca7f12e50a47a3679df0cd1ba487ea19cf844a905920f8e95/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eff4b8d89f444f7e49136dc695599a591ff769300734446c0a86cba2eb2f9895", size = 482551, upload-time = "2025-06-15T19:05:43.781Z" }, + { url = "https://files.pythonhosted.org/packages/31/47/2cecbd8694095647406645f822781008cc524320466ea393f55fe70eed3b/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12b0a02a91762c08f7264e2e79542f76870c3040bbc847fb67410ab81474932a", size = 597420, upload-time = "2025-06-15T19:05:45.244Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7e/82abc4240e0806846548559d70f0b1a6dfdca75c1b4f9fa62b504ae9b083/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29e7bc2eee15cbb339c68445959108803dc14ee0c7b4eea556400131a8de462b", size = 477950, upload-time = "2025-06-15T19:05:46.332Z" }, + { url = "https://files.pythonhosted.org/packages/25/0d/4d564798a49bf5482a4fa9416dea6b6c0733a3b5700cb8a5a503c4b15853/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9481174d3ed982e269c090f780122fb59cee6c3796f74efe74e70f7780ed94c", size = 451706, upload-time = "2025-06-15T19:05:47.459Z" }, + { url = "https://files.pythonhosted.org/packages/81/b5/5516cf46b033192d544102ea07c65b6f770f10ed1d0a6d388f5d3874f6e4/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:80f811146831c8c86ab17b640801c25dc0a88c630e855e2bef3568f30434d52b", size = 625814, upload-time = "2025-06-15T19:05:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/0c/dd/7c1331f902f30669ac3e754680b6edb9a0dd06dea5438e61128111fadd2c/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:60022527e71d1d1fda67a33150ee42869042bce3d0fcc9cc49be009a9cded3fb", size = 622820, upload-time = "2025-06-15T19:05:50.088Z" }, + { url = "https://files.pythonhosted.org/packages/1b/14/36d7a8e27cd128d7b1009e7715a7c02f6c131be9d4ce1e5c3b73d0e342d8/watchfiles-1.1.0-cp313-cp313-win32.whl", hash = "sha256:32d6d4e583593cb8576e129879ea0991660b935177c0f93c6681359b3654bfa9", size = 279194, upload-time = "2025-06-15T19:05:51.186Z" }, + { url = "https://files.pythonhosted.org/packages/25/41/2dd88054b849aa546dbeef5696019c58f8e0774f4d1c42123273304cdb2e/watchfiles-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:f21af781a4a6fbad54f03c598ab620e3a77032c5878f3d780448421a6e1818c7", size = 292349, upload-time = "2025-06-15T19:05:52.201Z" }, + { url = "https://files.pythonhosted.org/packages/c8/cf/421d659de88285eb13941cf11a81f875c176f76a6d99342599be88e08d03/watchfiles-1.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:5366164391873ed76bfdf618818c82084c9db7fac82b64a20c44d335eec9ced5", size = 283836, upload-time = "2025-06-15T19:05:53.265Z" }, + { url = "https://files.pythonhosted.org/packages/45/10/6faf6858d527e3599cc50ec9fcae73590fbddc1420bd4fdccfebffeedbc6/watchfiles-1.1.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:17ab167cca6339c2b830b744eaf10803d2a5b6683be4d79d8475d88b4a8a4be1", size = 400343, upload-time = "2025-06-15T19:05:54.252Z" }, + { url = "https://files.pythonhosted.org/packages/03/20/5cb7d3966f5e8c718006d0e97dfe379a82f16fecd3caa7810f634412047a/watchfiles-1.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:328dbc9bff7205c215a7807da7c18dce37da7da718e798356212d22696404339", size = 392916, upload-time = "2025-06-15T19:05:55.264Z" }, + { url = "https://files.pythonhosted.org/packages/8c/07/d8f1176328fa9e9581b6f120b017e286d2a2d22ae3f554efd9515c8e1b49/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7208ab6e009c627b7557ce55c465c98967e8caa8b11833531fdf95799372633", size = 449582, upload-time = "2025-06-15T19:05:56.317Z" }, + { url = "https://files.pythonhosted.org/packages/66/e8/80a14a453cf6038e81d072a86c05276692a1826471fef91df7537dba8b46/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8f6f72974a19efead54195bc9bed4d850fc047bb7aa971268fd9a8387c89011", size = 456752, upload-time = "2025-06-15T19:05:57.359Z" }, + { url = "https://files.pythonhosted.org/packages/5a/25/0853b3fe0e3c2f5af9ea60eb2e781eade939760239a72c2d38fc4cc335f6/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d181ef50923c29cf0450c3cd47e2f0557b62218c50b2ab8ce2ecaa02bd97e670", size = 481436, upload-time = "2025-06-15T19:05:58.447Z" }, + { url = "https://files.pythonhosted.org/packages/fe/9e/4af0056c258b861fbb29dcb36258de1e2b857be4a9509e6298abcf31e5c9/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adb4167043d3a78280d5d05ce0ba22055c266cf8655ce942f2fb881262ff3cdf", size = 596016, upload-time = "2025-06-15T19:05:59.59Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fa/95d604b58aa375e781daf350897aaaa089cff59d84147e9ccff2447c8294/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5701dc474b041e2934a26d31d39f90fac8a3dee2322b39f7729867f932b1d4", size = 476727, upload-time = "2025-06-15T19:06:01.086Z" }, + { url = "https://files.pythonhosted.org/packages/65/95/fe479b2664f19be4cf5ceeb21be05afd491d95f142e72d26a42f41b7c4f8/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b067915e3c3936966a8607f6fe5487df0c9c4afb85226613b520890049deea20", size = 451864, upload-time = "2025-06-15T19:06:02.144Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8a/3c4af14b93a15ce55901cd7a92e1a4701910f1768c78fb30f61d2b79785b/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:9c733cda03b6d636b4219625a4acb5c6ffb10803338e437fb614fef9516825ef", size = 625626, upload-time = "2025-06-15T19:06:03.578Z" }, + { url = "https://files.pythonhosted.org/packages/da/f5/cf6aa047d4d9e128f4b7cde615236a915673775ef171ff85971d698f3c2c/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:cc08ef8b90d78bfac66f0def80240b0197008e4852c9f285907377b2947ffdcb", size = 622744, upload-time = "2025-06-15T19:06:05.066Z" }, + { url = "https://files.pythonhosted.org/packages/2c/00/70f75c47f05dea6fd30df90f047765f6fc2d6eb8b5a3921379b0b04defa2/watchfiles-1.1.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9974d2f7dc561cce3bb88dfa8eb309dab64c729de85fba32e98d75cf24b66297", size = 402114, upload-time = "2025-06-15T19:06:06.186Z" }, + { url = "https://files.pythonhosted.org/packages/53/03/acd69c48db4a1ed1de26b349d94077cca2238ff98fd64393f3e97484cae6/watchfiles-1.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c68e9f1fcb4d43798ad8814c4c1b61547b014b667216cb754e606bfade587018", size = 393879, upload-time = "2025-06-15T19:06:07.369Z" }, + { url = "https://files.pythonhosted.org/packages/2f/c8/a9a2a6f9c8baa4eceae5887fecd421e1b7ce86802bcfc8b6a942e2add834/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95ab1594377effac17110e1352989bdd7bdfca9ff0e5eeccd8c69c5389b826d0", size = 450026, upload-time = "2025-06-15T19:06:08.476Z" }, + { url = "https://files.pythonhosted.org/packages/fe/51/d572260d98388e6e2b967425c985e07d47ee6f62e6455cefb46a6e06eda5/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fba9b62da882c1be1280a7584ec4515d0a6006a94d6e5819730ec2eab60ffe12", size = 457917, upload-time = "2025-06-15T19:06:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/4258e52917bf9f12909b6ec314ff9636276f3542f9d3807d143f27309104/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3434e401f3ce0ed6b42569128b3d1e3af773d7ec18751b918b89cd49c14eaafb", size = 483602, upload-time = "2025-06-15T19:06:11.088Z" }, + { url = "https://files.pythonhosted.org/packages/84/99/bee17a5f341a4345fe7b7972a475809af9e528deba056f8963d61ea49f75/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa257a4d0d21fcbca5b5fcba9dca5a78011cb93c0323fb8855c6d2dfbc76eb77", size = 596758, upload-time = "2025-06-15T19:06:12.197Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/e4bec1d59b25b89d2b0716b41b461ed655a9a53c60dc78ad5771fda5b3e6/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd1b3879a578a8ec2076c7961076df540b9af317123f84569f5a9ddee64ce92", size = 477601, upload-time = "2025-06-15T19:06:13.391Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fa/a514292956f4a9ce3c567ec0c13cce427c158e9f272062685a8a727d08fc/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62cc7a30eeb0e20ecc5f4bd113cd69dcdb745a07c68c0370cea919f373f65d9e", size = 451936, upload-time = "2025-06-15T19:06:14.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/5d/c3bf927ec3bbeb4566984eba8dd7a8eb69569400f5509904545576741f88/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:891c69e027748b4a73847335d208e374ce54ca3c335907d381fde4e41661b13b", size = 626243, upload-time = "2025-06-15T19:06:16.232Z" }, + { url = "https://files.pythonhosted.org/packages/e6/65/6e12c042f1a68c556802a84d54bb06d35577c81e29fba14019562479159c/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:12fe8eaffaf0faa7906895b4f8bb88264035b3f0243275e0bf24af0436b27259", size = 623073, upload-time = "2025-06-15T19:06:17.457Z" }, + { url = "https://files.pythonhosted.org/packages/89/ab/7f79d9bf57329e7cbb0a6fd4c7bd7d0cee1e4a8ef0041459f5409da3506c/watchfiles-1.1.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bfe3c517c283e484843cb2e357dd57ba009cff351edf45fb455b5fbd1f45b15f", size = 400872, upload-time = "2025-06-15T19:06:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/df/d5/3f7bf9912798e9e6c516094db6b8932df53b223660c781ee37607030b6d3/watchfiles-1.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a9ccbf1f129480ed3044f540c0fdbc4ee556f7175e5ab40fe077ff6baf286d4e", size = 392877, upload-time = "2025-06-15T19:06:19.55Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c5/54ec7601a2798604e01c75294770dbee8150e81c6e471445d7601610b495/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba0e3255b0396cac3cc7bbace76404dd72b5438bf0d8e7cefa2f79a7f3649caa", size = 449645, upload-time = "2025-06-15T19:06:20.66Z" }, + { url = "https://files.pythonhosted.org/packages/0a/04/c2f44afc3b2fce21ca0b7802cbd37ed90a29874f96069ed30a36dfe57c2b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4281cd9fce9fc0a9dbf0fc1217f39bf9cf2b4d315d9626ef1d4e87b84699e7e8", size = 457424, upload-time = "2025-06-15T19:06:21.712Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b0/eec32cb6c14d248095261a04f290636da3df3119d4040ef91a4a50b29fa5/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d2404af8db1329f9a3c9b79ff63e0ae7131986446901582067d9304ae8aaf7f", size = 481584, upload-time = "2025-06-15T19:06:22.777Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/ca4bb71c68a937d7145aa25709e4f5d68eb7698a25ce266e84b55d591bbd/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e78b6ed8165996013165eeabd875c5dfc19d41b54f94b40e9fff0eb3193e5e8e", size = 596675, upload-time = "2025-06-15T19:06:24.226Z" }, + { url = "https://files.pythonhosted.org/packages/a1/dd/b0e4b7fb5acf783816bc950180a6cd7c6c1d2cf7e9372c0ea634e722712b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:249590eb75ccc117f488e2fabd1bfa33c580e24b96f00658ad88e38844a040bb", size = 477363, upload-time = "2025-06-15T19:06:25.42Z" }, + { url = "https://files.pythonhosted.org/packages/69/c4/088825b75489cb5b6a761a4542645718893d395d8c530b38734f19da44d2/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05686b5487cfa2e2c28ff1aa370ea3e6c5accfe6435944ddea1e10d93872147", size = 452240, upload-time = "2025-06-15T19:06:26.552Z" }, + { url = "https://files.pythonhosted.org/packages/10/8c/22b074814970eeef43b7c44df98c3e9667c1f7bf5b83e0ff0201b0bd43f9/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d0e10e6f8f6dc5762adee7dece33b722282e1f59aa6a55da5d493a97282fedd8", size = 625607, upload-time = "2025-06-15T19:06:27.606Z" }, + { url = "https://files.pythonhosted.org/packages/32/fa/a4f5c2046385492b2273213ef815bf71a0d4c1943b784fb904e184e30201/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:af06c863f152005c7592df1d6a7009c836a247c9d8adb78fef8575a5a98699db", size = 623315, upload-time = "2025-06-15T19:06:29.076Z" }, + { url = "https://files.pythonhosted.org/packages/47/8a/a45db804b9f0740f8408626ab2bca89c3136432e57c4673b50180bf85dd9/watchfiles-1.1.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:865c8e95713744cf5ae261f3067861e9da5f1370ba91fc536431e29b418676fa", size = 406400, upload-time = "2025-06-15T19:06:30.233Z" }, + { url = "https://files.pythonhosted.org/packages/64/06/a08684f628fb41addd451845aceedc2407dc3d843b4b060a7c4350ddee0c/watchfiles-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42f92befc848bb7a19658f21f3e7bae80d7d005d13891c62c2cd4d4d0abb3433", size = 397920, upload-time = "2025-06-15T19:06:31.315Z" }, + { url = "https://files.pythonhosted.org/packages/79/e6/e10d5675af653b1b07d4156906858041149ca222edaf8995877f2605ba9e/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa0cc8365ab29487eb4f9979fd41b22549853389e22d5de3f134a6796e1b05a4", size = 451196, upload-time = "2025-06-15T19:06:32.435Z" }, + { url = "https://files.pythonhosted.org/packages/f6/8a/facd6988100cd0f39e89f6c550af80edb28e3a529e1ee662e750663e6b36/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90ebb429e933645f3da534c89b29b665e285048973b4d2b6946526888c3eb2c7", size = 458218, upload-time = "2025-06-15T19:06:33.503Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/34cbcbc4d0f2f8f9cc243007e65d741ae039f7a11ef8ec6e9cd25bee08d1/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c588c45da9b08ab3da81d08d7987dae6d2a3badd63acdb3e206a42dbfa7cb76f", size = 484851, upload-time = "2025-06-15T19:06:34.541Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1f/f59faa9fc4b0e36dbcdd28a18c430416443b309d295d8b82e18192d120ad/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c55b0f9f68590115c25272b06e63f0824f03d4fc7d6deed43d8ad5660cabdbf", size = 599520, upload-time = "2025-06-15T19:06:35.785Z" }, + { url = "https://files.pythonhosted.org/packages/83/72/3637abecb3bf590529f5154ca000924003e5f4bbb9619744feeaf6f0b70b/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd17a1e489f02ce9117b0de3c0b1fab1c3e2eedc82311b299ee6b6faf6c23a29", size = 477956, upload-time = "2025-06-15T19:06:36.965Z" }, + { url = "https://files.pythonhosted.org/packages/f7/f3/d14ffd9acc0c1bd4790378995e320981423263a5d70bd3929e2e0dc87fff/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da71945c9ace018d8634822f16cbc2a78323ef6c876b1d34bbf5d5222fd6a72e", size = 453196, upload-time = "2025-06-15T19:06:38.024Z" }, + { url = "https://files.pythonhosted.org/packages/7f/38/78ad77bd99e20c0fdc82262be571ef114fc0beef9b43db52adb939768c38/watchfiles-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:51556d5004887045dba3acdd1fdf61dddea2be0a7e18048b5e853dcd37149b86", size = 627479, upload-time = "2025-06-15T19:06:39.442Z" }, + { url = "https://files.pythonhosted.org/packages/e6/cf/549d50a22fcc83f1017c6427b1c76c053233f91b526f4ad7a45971e70c0b/watchfiles-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04e4ed5d1cd3eae68c89bcc1a485a109f39f2fd8de05f705e98af6b5f1861f1f", size = 624414, upload-time = "2025-06-15T19:06:40.859Z" }, + { url = "https://files.pythonhosted.org/packages/72/de/57d6e40dc9140af71c12f3a9fc2d3efc5529d93981cd4d265d484d7c9148/watchfiles-1.1.0-cp39-cp39-win32.whl", hash = "sha256:c600e85f2ffd9f1035222b1a312aff85fd11ea39baff1d705b9b047aad2ce267", size = 280020, upload-time = "2025-06-15T19:06:41.89Z" }, + { url = "https://files.pythonhosted.org/packages/88/bb/7d287fc2a762396b128a0fca2dbae29386e0a242b81d1046daf389641db3/watchfiles-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3aba215958d88182e8d2acba0fdaf687745180974946609119953c0e112397dc", size = 292758, upload-time = "2025-06-15T19:06:43.251Z" }, + { url = "https://files.pythonhosted.org/packages/be/7c/a3d7c55cfa377c2f62c4ae3c6502b997186bc5e38156bafcb9b653de9a6d/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a6fd40bbb50d24976eb275ccb55cd1951dfb63dbc27cae3066a6ca5f4beabd5", size = 406748, upload-time = "2025-06-15T19:06:44.2Z" }, + { url = "https://files.pythonhosted.org/packages/38/d0/c46f1b2c0ca47f3667b144de6f0515f6d1c670d72f2ca29861cac78abaa1/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9f811079d2f9795b5d48b55a37aa7773680a5659afe34b54cc1d86590a51507d", size = 398801, upload-time = "2025-06-15T19:06:45.774Z" }, + { url = "https://files.pythonhosted.org/packages/70/9c/9a6a42e97f92eeed77c3485a43ea96723900aefa3ac739a8c73f4bff2cd7/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2726d7bfd9f76158c84c10a409b77a320426540df8c35be172444394b17f7ea", size = 451528, upload-time = "2025-06-15T19:06:46.791Z" }, + { url = "https://files.pythonhosted.org/packages/51/7b/98c7f4f7ce7ff03023cf971cd84a3ee3b790021ae7584ffffa0eb2554b96/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df32d59cb9780f66d165a9a7a26f19df2c7d24e3bd58713108b41d0ff4f929c6", size = 454095, upload-time = "2025-06-15T19:06:48.211Z" }, + { url = "https://files.pythonhosted.org/packages/8c/6b/686dcf5d3525ad17b384fd94708e95193529b460a1b7bf40851f1328ec6e/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0ece16b563b17ab26eaa2d52230c9a7ae46cf01759621f4fbbca280e438267b3", size = 406910, upload-time = "2025-06-15T19:06:49.335Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d3/71c2dcf81dc1edcf8af9f4d8d63b1316fb0a2dd90cbfd427e8d9dd584a90/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:51b81e55d40c4b4aa8658427a3ee7ea847c591ae9e8b81ef94a90b668999353c", size = 398816, upload-time = "2025-06-15T19:06:50.433Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fa/12269467b2fc006f8fce4cd6c3acfa77491dd0777d2a747415f28ccc8c60/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2bcdc54ea267fe72bfc7d83c041e4eb58d7d8dc6f578dfddb52f037ce62f432", size = 451584, upload-time = "2025-06-15T19:06:51.834Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/254cea30f918f489db09d6a8435a7de7047f8cb68584477a515f160541d6/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923fec6e5461c42bd7e3fd5ec37492c6f3468be0499bc0707b4bbbc16ac21792", size = 454009, upload-time = "2025-06-15T19:06:52.896Z" }, + { url = "https://files.pythonhosted.org/packages/48/93/5c96bdb65e7f88f7da40645f34c0a3c317a2931ed82161e93c91e8eddd27/watchfiles-1.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7b3443f4ec3ba5aa00b0e9fa90cf31d98321cbff8b925a7c7b84161619870bc9", size = 406640, upload-time = "2025-06-15T19:06:54.868Z" }, + { url = "https://files.pythonhosted.org/packages/e3/25/09204836e93e1b99cce88802ce87264a1d20610c7a8f6de24def27ad95b1/watchfiles-1.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7049e52167fc75fc3cc418fc13d39a8e520cbb60ca08b47f6cedb85e181d2f2a", size = 398543, upload-time = "2025-06-15T19:06:55.95Z" }, + { url = "https://files.pythonhosted.org/packages/5e/dc/6f324a6f32c5ab73b54311b5f393a79df34c1584b8d2404cf7e6d780aa5d/watchfiles-1.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54062ef956807ba806559b3c3d52105ae1827a0d4ab47b621b31132b6b7e2866", size = 451787, upload-time = "2025-06-15T19:06:56.998Z" }, + { url = "https://files.pythonhosted.org/packages/45/5d/1d02ef4caa4ec02389e72d5594cdf9c67f1800a7c380baa55063c30c6598/watchfiles-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a7bd57a1bb02f9d5c398c0c1675384e7ab1dd39da0ca50b7f09af45fa435277", size = 454272, upload-time = "2025-06-15T19:06:58.055Z" }, ] [[package]] diff --git a/libs/langgraph/bench/react_agent.py b/libs/langgraph/bench/react_agent.py index a6f84f2dc..59e60fb95 100644 --- a/libs/langgraph/bench/react_agent.py +++ b/libs/langgraph/bench/react_agent.py @@ -15,7 +15,7 @@ from langgraph.pregel import Pregel def react_agent(n_tools: int, checkpointer: Optional[BaseCheckpointSaver]) -> Pregel: - class FakeFuntionChatModel(FakeMessagesListChatModel): + class FakeFunctionChatModel(FakeMessagesListChatModel): def bind_tools(self, functions: list): return self @@ -40,7 +40,7 @@ def react_agent(n_tools: int, checkpointer: Optional[BaseCheckpointSaver]) -> Pr description="", ) - model = FakeFuntionChatModel( + model = FakeFunctionChatModel( responses=[ AIMessage( content="", diff --git a/libs/langgraph/langgraph/constants.py b/libs/langgraph/langgraph/constants.py index ac53718e1..f524de39f 100644 --- a/libs/langgraph/langgraph/constants.py +++ b/libs/langgraph/langgraph/constants.py @@ -119,7 +119,6 @@ RESERVED = { CONFIG_KEY_STREAM, CONFIG_KEY_STREAM_WRITER, CONFIG_KEY_STORE, - CONFIG_KEY_CHECKPOINT_MAP, CONFIG_KEY_RESUMING, CONFIG_KEY_TASK_ID, CONFIG_KEY_CHECKPOINT_MAP, diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index d95c4fd51..095e73c24 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -59,7 +59,7 @@ StreamMode = Literal[ - `"messages"`: Emit LLM messages token-by-token together with metadata for any LLM invocations inside nodes or tasks. - `"checkpoints"`: Emit an event when a checkpoint is created, in the same format as returned by get_state(). - `"tasks"`: Emit events when tasks start and finish, including their results and errors. -- `"debug"`: Emit "checlkpoints" and "tasks" events, for debugging purposes. +- `"debug"`: Emit "checkpoints" and "tasks" events, for debugging purposes. """ StreamWriter = Callable[[Any], None] diff --git a/libs/langgraph/langgraph/utils/runnable.py b/libs/langgraph/langgraph/utils/runnable.py index 3ca48aec3..4274c8134 100644 --- a/libs/langgraph/langgraph/utils/runnable.py +++ b/libs/langgraph/langgraph/utils/runnable.py @@ -83,7 +83,7 @@ def _unset_config_context(token: Token[RunnableConfig | None], run: Any = None) """Set the child Runnable config + tracing context. Args: - config: The config to set. + token: The config token to reset. """ var_child_runnable_config.reset(token) if run is not None: diff --git a/libs/langgraph/tests/__snapshots__/test_large_cases.ambr b/libs/langgraph/tests/__snapshots__/test_large_cases.ambr index 56b3fb6aa..3b3b383ff 100644 --- a/libs/langgraph/tests/__snapshots__/test_large_cases.ambr +++ b/libs/langgraph/tests/__snapshots__/test_large_cases.ambr @@ -218,7 +218,7 @@ "id": [ "tests", "test_large_cases", - "FakeFuntionChatModel" + "FakeFunctionChatModel" ], "name": "agent" } diff --git a/libs/langgraph/tests/test_large_cases.py b/libs/langgraph/tests/test_large_cases.py index 81de033ba..e642d07da 100644 --- a/libs/langgraph/tests/test_large_cases.py +++ b/libs/langgraph/tests/test_large_cases.py @@ -2377,7 +2377,7 @@ def test_message_graph( from langchain_core.outputs import ChatGeneration, ChatResult from langchain_core.tools import tool - class FakeFuntionChatModel(FakeMessagesListChatModel): + class FakeFunctionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): return self @@ -2403,7 +2403,7 @@ def test_message_graph( tools = [search_api] - model = FakeFuntionChatModel( + model = FakeFunctionChatModel( responses=[ AIMessage( content="", @@ -3100,7 +3100,7 @@ def test_root_graph( from langchain_core.outputs import ChatGeneration, ChatResult from langchain_core.tools import tool - class FakeFuntionChatModel(FakeMessagesListChatModel): + class FakeFunctionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): return self @@ -3126,7 +3126,7 @@ def test_root_graph( tools = [search_api] - model = FakeFuntionChatModel( + model = FakeFunctionChatModel( responses=[ AIMessage( content="", diff --git a/libs/langgraph/tests/test_large_cases_async.py b/libs/langgraph/tests/test_large_cases_async.py index 824624680..29f92d8b9 100644 --- a/libs/langgraph/tests/test_large_cases_async.py +++ b/libs/langgraph/tests/test_large_cases_async.py @@ -2066,7 +2066,7 @@ async def test_message_graph(async_checkpointer: BaseCheckpointSaver) -> None: from langchain_core.messages import AIMessage, HumanMessage from langchain_core.tools import tool - class FakeFuntionChatModel(FakeMessagesListChatModel): + class FakeFunctionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): return self @@ -2077,7 +2077,7 @@ async def test_message_graph(async_checkpointer: BaseCheckpointSaver) -> None: tools = [search_api] - model = FakeFuntionChatModel( + model = FakeFunctionChatModel( responses=[ AIMessage( content="", diff --git a/libs/langgraph/tests/test_runnable.py b/libs/langgraph/tests/test_runnable.py index 1dd8e35cc..d36755416 100644 --- a/libs/langgraph/tests/test_runnable.py +++ b/libs/langgraph/tests/test_runnable.py @@ -85,7 +85,7 @@ def test_runnable_callable_injectable_arguments() -> None: """ # Test Optional[BaseStore] annotation. - def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP007 + def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP045 """Test function that accepts an optional store parameter.""" assert store is None return "success" @@ -159,7 +159,7 @@ async def test_runnable_callable_injectable_arguments_async() -> None: """ # Test Optional[BaseStore] annotation. - def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP007 + def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP045 """Test function that accepts an optional store parameter.""" assert store is None return "success" diff --git a/libs/langgraph/uv.lock b/libs/langgraph/uv.lock index 897d89862..2762e3fe1 100644 --- a/libs/langgraph/uv.lock +++ b/libs/langgraph/uv.lock @@ -2,10 +2,7 @@ version = 1 revision = 2 requires-python = ">=3.9" resolution-markers = [ - "python_full_version >= '3.13' and python_full_version < '4.0'", - "python_full_version >= '3.12.4' and python_full_version < '3.13'", - "python_full_version >= '3.11' and python_full_version < '3.12.4'", - "python_full_version >= '4.0'", + "python_full_version >= '3.11'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", ] @@ -57,14 +54,14 @@ wheels = [ [[package]] name = "argon2-cffi" -version = "23.1.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798, upload-time = "2023-08-15T14:13:12.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124, upload-time = "2023-08-15T14:13:10.752Z" }, + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, ] [[package]] @@ -175,7 +172,7 @@ name = "blockbuster" version = "1.5.24" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "forbiddenfruit", marker = "python_full_version >= '3.11' and python_full_version < '4.0' and implementation_name == 'cpython'" }, + { name = "forbiddenfruit", marker = "python_full_version >= '3.11' and implementation_name == 'cpython'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/35/c8/1e456a043179f2aef10bcaafea79f6d06c0ac45cc994767a54f680509f3b/blockbuster-1.5.24.tar.gz", hash = "sha256:97645775761a5d425666ec0bc99629b65c7eccdc2f770d2439850682567af4ec", size = 51245, upload-time = "2025-03-18T10:12:06.398Z" } wheels = [ @@ -184,11 +181,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -354,10 +351,7 @@ name = "click" version = "8.2.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and python_full_version < '4.0'", - "python_full_version >= '3.12.4' and python_full_version < '3.13'", - "python_full_version >= '3.11' and python_full_version < '3.12.4'", - "python_full_version >= '4.0'", + "python_full_version >= '3.11'", "python_full_version == '3.10.*'", ] dependencies = [ @@ -400,76 +394,76 @@ wheels = [ [[package]] name = "coverage" -version = "7.8.2" +version = "7.9.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/07/998afa4a0ecdf9b1981ae05415dad2d4e7716e1b1f00abbd91691ac09ac9/coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27", size = 812759, upload-time = "2025-05-23T11:39:57.856Z" } +sdist = { url = "https://files.pythonhosted.org/packages/04/b7/c0465ca253df10a9e8dae0692a4ae6e9726d245390aaef92360e1d6d3832/coverage-7.9.2.tar.gz", hash = "sha256:997024fa51e3290264ffd7492ec97d0690293ccd2b45a6cd7d82d945a4a80c8b", size = 813556, upload-time = "2025-07-03T10:54:15.101Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/6b/7dd06399a5c0b81007e3a6af0395cd60e6a30f959f8d407d3ee04642e896/coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a", size = 211573, upload-time = "2025-05-23T11:37:47.207Z" }, - { url = "https://files.pythonhosted.org/packages/f0/df/2b24090820a0bac1412955fb1a4dade6bc3b8dcef7b899c277ffaf16916d/coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be", size = 212006, upload-time = "2025-05-23T11:37:50.289Z" }, - { url = "https://files.pythonhosted.org/packages/c5/c4/e4e3b998e116625562a872a342419652fa6ca73f464d9faf9f52f1aff427/coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3", size = 241128, upload-time = "2025-05-23T11:37:52.229Z" }, - { url = "https://files.pythonhosted.org/packages/b1/67/b28904afea3e87a895da850ba587439a61699bf4b73d04d0dfd99bbd33b4/coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6", size = 239026, upload-time = "2025-05-23T11:37:53.846Z" }, - { url = "https://files.pythonhosted.org/packages/8c/0f/47bf7c5630d81bc2cd52b9e13043685dbb7c79372a7f5857279cc442b37c/coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622", size = 240172, upload-time = "2025-05-23T11:37:55.711Z" }, - { url = "https://files.pythonhosted.org/packages/ba/38/af3eb9d36d85abc881f5aaecf8209383dbe0fa4cac2d804c55d05c51cb04/coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c", size = 240086, upload-time = "2025-05-23T11:37:57.724Z" }, - { url = "https://files.pythonhosted.org/packages/9e/64/c40c27c2573adeba0fe16faf39a8aa57368a1f2148865d6bb24c67eadb41/coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3", size = 238792, upload-time = "2025-05-23T11:37:59.737Z" }, - { url = "https://files.pythonhosted.org/packages/8e/ab/b7c85146f15457671c1412afca7c25a5696d7625e7158002aa017e2d7e3c/coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404", size = 239096, upload-time = "2025-05-23T11:38:01.693Z" }, - { url = "https://files.pythonhosted.org/packages/d3/50/9446dad1310905fb1dc284d60d4320a5b25d4e3e33f9ea08b8d36e244e23/coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7", size = 214144, upload-time = "2025-05-23T11:38:03.68Z" }, - { url = "https://files.pythonhosted.org/packages/23/ed/792e66ad7b8b0df757db8d47af0c23659cdb5a65ef7ace8b111cacdbee89/coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347", size = 215043, upload-time = "2025-05-23T11:38:05.217Z" }, - { url = "https://files.pythonhosted.org/packages/6a/4d/1ff618ee9f134d0de5cc1661582c21a65e06823f41caf801aadf18811a8e/coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9", size = 211692, upload-time = "2025-05-23T11:38:08.485Z" }, - { url = "https://files.pythonhosted.org/packages/96/fa/c3c1b476de96f2bc7a8ca01a9f1fcb51c01c6b60a9d2c3e66194b2bdb4af/coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879", size = 212115, upload-time = "2025-05-23T11:38:09.989Z" }, - { url = "https://files.pythonhosted.org/packages/f7/c2/5414c5a1b286c0f3881ae5adb49be1854ac5b7e99011501f81c8c1453065/coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a", size = 244740, upload-time = "2025-05-23T11:38:11.947Z" }, - { url = "https://files.pythonhosted.org/packages/cd/46/1ae01912dfb06a642ef3dd9cf38ed4996fda8fe884dab8952da616f81a2b/coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5", size = 242429, upload-time = "2025-05-23T11:38:13.955Z" }, - { url = "https://files.pythonhosted.org/packages/06/58/38c676aec594bfe2a87c7683942e5a30224791d8df99bcc8439fde140377/coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11", size = 244218, upload-time = "2025-05-23T11:38:15.631Z" }, - { url = "https://files.pythonhosted.org/packages/80/0c/95b1023e881ce45006d9abc250f76c6cdab7134a1c182d9713878dfefcb2/coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a", size = 243865, upload-time = "2025-05-23T11:38:17.622Z" }, - { url = "https://files.pythonhosted.org/packages/57/37/0ae95989285a39e0839c959fe854a3ae46c06610439350d1ab860bf020ac/coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb", size = 242038, upload-time = "2025-05-23T11:38:19.966Z" }, - { url = "https://files.pythonhosted.org/packages/4d/82/40e55f7c0eb5e97cc62cbd9d0746fd24e8caf57be5a408b87529416e0c70/coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54", size = 242567, upload-time = "2025-05-23T11:38:21.912Z" }, - { url = "https://files.pythonhosted.org/packages/f9/35/66a51adc273433a253989f0d9cc7aa6bcdb4855382cf0858200afe578861/coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a", size = 214194, upload-time = "2025-05-23T11:38:23.571Z" }, - { url = "https://files.pythonhosted.org/packages/f6/8f/a543121f9f5f150eae092b08428cb4e6b6d2d134152c3357b77659d2a605/coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975", size = 215109, upload-time = "2025-05-23T11:38:25.137Z" }, - { url = "https://files.pythonhosted.org/packages/77/65/6cc84b68d4f35186463cd7ab1da1169e9abb59870c0f6a57ea6aba95f861/coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53", size = 213521, upload-time = "2025-05-23T11:38:27.123Z" }, - { url = "https://files.pythonhosted.org/packages/8d/2a/1da1ada2e3044fcd4a3254fb3576e160b8fe5b36d705c8a31f793423f763/coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c", size = 211876, upload-time = "2025-05-23T11:38:29.01Z" }, - { url = "https://files.pythonhosted.org/packages/70/e9/3d715ffd5b6b17a8be80cd14a8917a002530a99943cc1939ad5bb2aa74b9/coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1", size = 212130, upload-time = "2025-05-23T11:38:30.675Z" }, - { url = "https://files.pythonhosted.org/packages/a0/02/fdce62bb3c21649abfd91fbdcf041fb99be0d728ff00f3f9d54d97ed683e/coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279", size = 246176, upload-time = "2025-05-23T11:38:32.395Z" }, - { url = "https://files.pythonhosted.org/packages/a7/52/decbbed61e03b6ffe85cd0fea360a5e04a5a98a7423f292aae62423b8557/coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99", size = 243068, upload-time = "2025-05-23T11:38:33.989Z" }, - { url = "https://files.pythonhosted.org/packages/38/6c/d0e9c0cce18faef79a52778219a3c6ee8e336437da8eddd4ab3dbd8fadff/coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20", size = 245328, upload-time = "2025-05-23T11:38:35.568Z" }, - { url = "https://files.pythonhosted.org/packages/f0/70/f703b553a2f6b6c70568c7e398ed0789d47f953d67fbba36a327714a7bca/coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2", size = 245099, upload-time = "2025-05-23T11:38:37.627Z" }, - { url = "https://files.pythonhosted.org/packages/ec/fb/4cbb370dedae78460c3aacbdad9d249e853f3bc4ce5ff0e02b1983d03044/coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57", size = 243314, upload-time = "2025-05-23T11:38:39.238Z" }, - { url = "https://files.pythonhosted.org/packages/39/9f/1afbb2cb9c8699b8bc38afdce00a3b4644904e6a38c7bf9005386c9305ec/coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f", size = 244489, upload-time = "2025-05-23T11:38:40.845Z" }, - { url = "https://files.pythonhosted.org/packages/79/fa/f3e7ec7d220bff14aba7a4786ae47043770cbdceeea1803083059c878837/coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8", size = 214366, upload-time = "2025-05-23T11:38:43.551Z" }, - { url = "https://files.pythonhosted.org/packages/54/aa/9cbeade19b7e8e853e7ffc261df885d66bf3a782c71cba06c17df271f9e6/coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223", size = 215165, upload-time = "2025-05-23T11:38:45.148Z" }, - { url = "https://files.pythonhosted.org/packages/c4/73/e2528bf1237d2448f882bbebaec5c3500ef07301816c5c63464b9da4d88a/coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f", size = 213548, upload-time = "2025-05-23T11:38:46.74Z" }, - { url = "https://files.pythonhosted.org/packages/1a/93/eb6400a745ad3b265bac36e8077fdffcf0268bdbbb6c02b7220b624c9b31/coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca", size = 211898, upload-time = "2025-05-23T11:38:49.066Z" }, - { url = "https://files.pythonhosted.org/packages/1b/7c/bdbf113f92683024406a1cd226a199e4200a2001fc85d6a6e7e299e60253/coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d", size = 212171, upload-time = "2025-05-23T11:38:51.207Z" }, - { url = "https://files.pythonhosted.org/packages/91/22/594513f9541a6b88eb0dba4d5da7d71596dadef6b17a12dc2c0e859818a9/coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85", size = 245564, upload-time = "2025-05-23T11:38:52.857Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f4/2860fd6abeebd9f2efcfe0fd376226938f22afc80c1943f363cd3c28421f/coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257", size = 242719, upload-time = "2025-05-23T11:38:54.529Z" }, - { url = "https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108", size = 244634, upload-time = "2025-05-23T11:38:57.326Z" }, - { url = "https://files.pythonhosted.org/packages/3b/70/7f4e919039ab7d944276c446b603eea84da29ebcf20984fb1fdf6e602028/coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0", size = 244824, upload-time = "2025-05-23T11:38:59.421Z" }, - { url = "https://files.pythonhosted.org/packages/26/45/36297a4c0cea4de2b2c442fe32f60c3991056c59cdc3cdd5346fbb995c97/coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050", size = 242872, upload-time = "2025-05-23T11:39:01.049Z" }, - { url = "https://files.pythonhosted.org/packages/a4/71/e041f1b9420f7b786b1367fa2a375703889ef376e0d48de9f5723fb35f11/coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48", size = 244179, upload-time = "2025-05-23T11:39:02.709Z" }, - { url = "https://files.pythonhosted.org/packages/bd/db/3c2bf49bdc9de76acf2491fc03130c4ffc51469ce2f6889d2640eb563d77/coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7", size = 214393, upload-time = "2025-05-23T11:39:05.457Z" }, - { url = "https://files.pythonhosted.org/packages/c6/dc/947e75d47ebbb4b02d8babb1fad4ad381410d5bc9da7cfca80b7565ef401/coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3", size = 215194, upload-time = "2025-05-23T11:39:07.171Z" }, - { url = "https://files.pythonhosted.org/packages/90/31/a980f7df8a37eaf0dc60f932507fda9656b3a03f0abf188474a0ea188d6d/coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7", size = 213580, upload-time = "2025-05-23T11:39:08.862Z" }, - { url = "https://files.pythonhosted.org/packages/8a/6a/25a37dd90f6c95f59355629417ebcb74e1c34e38bb1eddf6ca9b38b0fc53/coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008", size = 212734, upload-time = "2025-05-23T11:39:11.109Z" }, - { url = "https://files.pythonhosted.org/packages/36/8b/3a728b3118988725f40950931abb09cd7f43b3c740f4640a59f1db60e372/coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36", size = 212959, upload-time = "2025-05-23T11:39:12.751Z" }, - { url = "https://files.pythonhosted.org/packages/53/3c/212d94e6add3a3c3f412d664aee452045ca17a066def8b9421673e9482c4/coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46", size = 257024, upload-time = "2025-05-23T11:39:15.569Z" }, - { url = "https://files.pythonhosted.org/packages/a4/40/afc03f0883b1e51bbe804707aae62e29c4e8c8bbc365c75e3e4ddeee9ead/coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be", size = 252867, upload-time = "2025-05-23T11:39:17.64Z" }, - { url = "https://files.pythonhosted.org/packages/18/a2/3699190e927b9439c6ded4998941a3c1d6fa99e14cb28d8536729537e307/coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740", size = 255096, upload-time = "2025-05-23T11:39:19.328Z" }, - { url = "https://files.pythonhosted.org/packages/b4/06/16e3598b9466456b718eb3e789457d1a5b8bfb22e23b6e8bbc307df5daf0/coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625", size = 256276, upload-time = "2025-05-23T11:39:21.077Z" }, - { url = "https://files.pythonhosted.org/packages/a7/d5/4b5a120d5d0223050a53d2783c049c311eea1709fa9de12d1c358e18b707/coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b", size = 254478, upload-time = "2025-05-23T11:39:22.838Z" }, - { url = "https://files.pythonhosted.org/packages/ba/85/f9ecdb910ecdb282b121bfcaa32fa8ee8cbd7699f83330ee13ff9bbf1a85/coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199", size = 255255, upload-time = "2025-05-23T11:39:24.644Z" }, - { url = "https://files.pythonhosted.org/packages/50/63/2d624ac7d7ccd4ebbd3c6a9eba9d7fc4491a1226071360d59dd84928ccb2/coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8", size = 215109, upload-time = "2025-05-23T11:39:26.722Z" }, - { url = "https://files.pythonhosted.org/packages/22/5e/7053b71462e970e869111c1853afd642212568a350eba796deefdfbd0770/coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d", size = 216268, upload-time = "2025-05-23T11:39:28.429Z" }, - { url = "https://files.pythonhosted.org/packages/07/69/afa41aa34147655543dbe96994f8a246daf94b361ccf5edfd5df62ce066a/coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b", size = 214071, upload-time = "2025-05-23T11:39:30.55Z" }, - { url = "https://files.pythonhosted.org/packages/71/1e/388267ad9c6aa126438acc1ceafede3bb746afa9872e3ec5f0691b7d5efa/coverage-7.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:496948261eaac5ac9cf43f5d0a9f6eb7a6d4cb3bedb2c5d294138142f5c18f2a", size = 211566, upload-time = "2025-05-23T11:39:32.333Z" }, - { url = "https://files.pythonhosted.org/packages/8f/a5/acc03e5cf0bba6357f5e7c676343de40fbf431bb1e115fbebf24b2f7f65e/coverage-7.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eacd2de0d30871eff893bab0b67840a96445edcb3c8fd915e6b11ac4b2f3fa6d", size = 211996, upload-time = "2025-05-23T11:39:34.512Z" }, - { url = "https://files.pythonhosted.org/packages/5b/a2/0fc0a9f6b7c24fa4f1d7210d782c38cb0d5e692666c36eaeae9a441b6755/coverage-7.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b039ffddc99ad65d5078ef300e0c7eed08c270dc26570440e3ef18beb816c1ca", size = 240741, upload-time = "2025-05-23T11:39:36.252Z" }, - { url = "https://files.pythonhosted.org/packages/e6/da/1c6ba2cf259710eed8916d4fd201dccc6be7380ad2b3b9f63ece3285d809/coverage-7.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e49824808d4375ede9dd84e9961a59c47f9113039f1a525e6be170aa4f5c34d", size = 238672, upload-time = "2025-05-23T11:39:38.03Z" }, - { url = "https://files.pythonhosted.org/packages/ac/51/c8fae0dc3ca421e6e2509503696f910ff333258db672800c3bdef256265a/coverage-7.8.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b069938961dfad881dc2f8d02b47645cd2f455d3809ba92a8a687bf513839787", size = 239769, upload-time = "2025-05-23T11:39:40.24Z" }, - { url = "https://files.pythonhosted.org/packages/59/8e/b97042ae92c59f40be0c989df090027377ba53f2d6cef73c9ca7685c26a6/coverage-7.8.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:de77c3ba8bb686d1c411e78ee1b97e6e0b963fb98b1637658dd9ad2c875cf9d7", size = 239555, upload-time = "2025-05-23T11:39:42.3Z" }, - { url = "https://files.pythonhosted.org/packages/47/35/b8893e682d6e96b1db2af5997fc13ef62219426fb17259d6844c693c5e00/coverage-7.8.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1676628065a498943bd3f64f099bb573e08cf1bc6088bbe33cf4424e0876f4b3", size = 237768, upload-time = "2025-05-23T11:39:44.069Z" }, - { url = "https://files.pythonhosted.org/packages/03/6c/023b0b9a764cb52d6243a4591dcb53c4caf4d7340445113a1f452bb80591/coverage-7.8.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8e1a26e7e50076e35f7afafde570ca2b4d7900a491174ca357d29dece5aacee7", size = 238757, upload-time = "2025-05-23T11:39:46.195Z" }, - { url = "https://files.pythonhosted.org/packages/03/ed/3af7e4d721bd61a8df7de6de9e8a4271e67f3d9e086454558fd9f48eb4f6/coverage-7.8.2-cp39-cp39-win32.whl", hash = "sha256:6782a12bf76fa61ad9350d5a6ef5f3f020b57f5e6305cbc663803f2ebd0f270a", size = 214166, upload-time = "2025-05-23T11:39:47.934Z" }, - { url = "https://files.pythonhosted.org/packages/9d/30/ee774b626773750dc6128354884652507df3c59d6aa8431526107e595227/coverage-7.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:1efa4166ba75ccefd647f2d78b64f53f14fb82622bc94c5a5cb0a622f50f1c9e", size = 215050, upload-time = "2025-05-23T11:39:50.252Z" }, - { url = "https://files.pythonhosted.org/packages/69/2f/572b29496d8234e4a7773200dd835a0d32d9e171f2d974f3fe04a9dbc271/coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837", size = 203636, upload-time = "2025-05-23T11:39:52.002Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1a/0b9c32220ad694d66062f571cc5cedfa9997b64a591e8a500bb63de1bd40/coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32", size = 203623, upload-time = "2025-05-23T11:39:53.846Z" }, + { url = "https://files.pythonhosted.org/packages/a1/0d/5c2114fd776c207bd55068ae8dc1bef63ecd1b767b3389984a8e58f2b926/coverage-7.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:66283a192a14a3854b2e7f3418d7db05cdf411012ab7ff5db98ff3b181e1f912", size = 212039, upload-time = "2025-07-03T10:52:38.955Z" }, + { url = "https://files.pythonhosted.org/packages/cf/ad/dc51f40492dc2d5fcd31bb44577bc0cc8920757d6bc5d3e4293146524ef9/coverage-7.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e01d138540ef34fcf35c1aa24d06c3de2a4cffa349e29a10056544f35cca15f", size = 212428, upload-time = "2025-07-03T10:52:41.36Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a3/55cb3ff1b36f00df04439c3993d8529193cdf165a2467bf1402539070f16/coverage-7.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f22627c1fe2745ee98d3ab87679ca73a97e75ca75eb5faee48660d060875465f", size = 241534, upload-time = "2025-07-03T10:52:42.956Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c9/a8410b91b6be4f6e9c2e9f0dce93749b6b40b751d7065b4410bf89cb654b/coverage-7.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b1c2d8363247b46bd51f393f86c94096e64a1cf6906803fa8d5a9d03784bdbf", size = 239408, upload-time = "2025-07-03T10:52:44.199Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c4/6f3e56d467c612b9070ae71d5d3b114c0b899b5788e1ca3c93068ccb7018/coverage-7.9.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c10c882b114faf82dbd33e876d0cbd5e1d1ebc0d2a74ceef642c6152f3f4d547", size = 240552, upload-time = "2025-07-03T10:52:45.477Z" }, + { url = "https://files.pythonhosted.org/packages/fd/20/04eda789d15af1ce79bce5cc5fd64057c3a0ac08fd0576377a3096c24663/coverage-7.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:de3c0378bdf7066c3988d66cd5232d161e933b87103b014ab1b0b4676098fa45", size = 240464, upload-time = "2025-07-03T10:52:46.809Z" }, + { url = "https://files.pythonhosted.org/packages/a9/5a/217b32c94cc1a0b90f253514815332d08ec0812194a1ce9cca97dda1cd20/coverage-7.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1e2f097eae0e5991e7623958a24ced3282676c93c013dde41399ff63e230fcf2", size = 239134, upload-time = "2025-07-03T10:52:48.149Z" }, + { url = "https://files.pythonhosted.org/packages/34/73/1d019c48f413465eb5d3b6898b6279e87141c80049f7dbf73fd020138549/coverage-7.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28dc1f67e83a14e7079b6cea4d314bc8b24d1aed42d3582ff89c0295f09b181e", size = 239405, upload-time = "2025-07-03T10:52:49.687Z" }, + { url = "https://files.pythonhosted.org/packages/49/6c/a2beca7aa2595dad0c0d3f350382c381c92400efe5261e2631f734a0e3fe/coverage-7.9.2-cp310-cp310-win32.whl", hash = "sha256:bf7d773da6af9e10dbddacbf4e5cab13d06d0ed93561d44dae0188a42c65be7e", size = 214519, upload-time = "2025-07-03T10:52:51.036Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c8/91e5e4a21f9a51e2c7cdd86e587ae01a4fcff06fc3fa8cde4d6f7cf68df4/coverage-7.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:0c0378ba787681ab1897f7c89b415bd56b0b2d9a47e5a3d8dc0ea55aac118d6c", size = 215400, upload-time = "2025-07-03T10:52:52.313Z" }, + { url = "https://files.pythonhosted.org/packages/39/40/916786453bcfafa4c788abee4ccd6f592b5b5eca0cd61a32a4e5a7ef6e02/coverage-7.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a7a56a2964a9687b6aba5b5ced6971af308ef6f79a91043c05dd4ee3ebc3e9ba", size = 212152, upload-time = "2025-07-03T10:52:53.562Z" }, + { url = "https://files.pythonhosted.org/packages/9f/66/cc13bae303284b546a030762957322bbbff1ee6b6cb8dc70a40f8a78512f/coverage-7.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123d589f32c11d9be7fe2e66d823a236fe759b0096f5db3fb1b75b2fa414a4fa", size = 212540, upload-time = "2025-07-03T10:52:55.196Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3c/d56a764b2e5a3d43257c36af4a62c379df44636817bb5f89265de4bf8bd7/coverage-7.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:333b2e0ca576a7dbd66e85ab402e35c03b0b22f525eed82681c4b866e2e2653a", size = 245097, upload-time = "2025-07-03T10:52:56.509Z" }, + { url = "https://files.pythonhosted.org/packages/b1/46/bd064ea8b3c94eb4ca5d90e34d15b806cba091ffb2b8e89a0d7066c45791/coverage-7.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:326802760da234baf9f2f85a39e4a4b5861b94f6c8d95251f699e4f73b1835dc", size = 242812, upload-time = "2025-07-03T10:52:57.842Z" }, + { url = "https://files.pythonhosted.org/packages/43/02/d91992c2b29bc7afb729463bc918ebe5f361be7f1daae93375a5759d1e28/coverage-7.9.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19e7be4cfec248df38ce40968c95d3952fbffd57b400d4b9bb580f28179556d2", size = 244617, upload-time = "2025-07-03T10:52:59.239Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4f/8fadff6bf56595a16d2d6e33415841b0163ac660873ed9a4e9046194f779/coverage-7.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0b4a4cb73b9f2b891c1788711408ef9707666501ba23684387277ededab1097c", size = 244263, upload-time = "2025-07-03T10:53:00.601Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d2/e0be7446a2bba11739edb9f9ba4eff30b30d8257370e237418eb44a14d11/coverage-7.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2c8937fa16c8c9fbbd9f118588756e7bcdc7e16a470766a9aef912dd3f117dbd", size = 242314, upload-time = "2025-07-03T10:53:01.932Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7d/dcbac9345000121b8b57a3094c2dfcf1ccc52d8a14a40c1d4bc89f936f80/coverage-7.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:42da2280c4d30c57a9b578bafd1d4494fa6c056d4c419d9689e66d775539be74", size = 242904, upload-time = "2025-07-03T10:53:03.478Z" }, + { url = "https://files.pythonhosted.org/packages/41/58/11e8db0a0c0510cf31bbbdc8caf5d74a358b696302a45948d7c768dfd1cf/coverage-7.9.2-cp311-cp311-win32.whl", hash = "sha256:14fa8d3da147f5fdf9d298cacc18791818f3f1a9f542c8958b80c228320e90c6", size = 214553, upload-time = "2025-07-03T10:53:05.174Z" }, + { url = "https://files.pythonhosted.org/packages/3a/7d/751794ec8907a15e257136e48dc1021b1f671220ecccfd6c4eaf30802714/coverage-7.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:549cab4892fc82004f9739963163fd3aac7a7b0df430669b75b86d293d2df2a7", size = 215441, upload-time = "2025-07-03T10:53:06.472Z" }, + { url = "https://files.pythonhosted.org/packages/62/5b/34abcedf7b946c1c9e15b44f326cb5b0da852885312b30e916f674913428/coverage-7.9.2-cp311-cp311-win_arm64.whl", hash = "sha256:c2667a2b913e307f06aa4e5677f01a9746cd08e4b35e14ebcde6420a9ebb4c62", size = 213873, upload-time = "2025-07-03T10:53:07.699Z" }, + { url = "https://files.pythonhosted.org/packages/53/d7/7deefc6fd4f0f1d4c58051f4004e366afc9e7ab60217ac393f247a1de70a/coverage-7.9.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ae9eb07f1cfacd9cfe8eaee6f4ff4b8a289a668c39c165cd0c8548484920ffc0", size = 212344, upload-time = "2025-07-03T10:53:09.3Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/ee03c95d32be4d519e6a02e601267769ce2e9a91fc8faa1b540e3626c680/coverage-7.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9ce85551f9a1119f02adc46d3014b5ee3f765deac166acf20dbb851ceb79b6f3", size = 212580, upload-time = "2025-07-03T10:53:11.52Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9f/826fa4b544b27620086211b87a52ca67592622e1f3af9e0a62c87aea153a/coverage-7.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8f6389ac977c5fb322e0e38885fbbf901743f79d47f50db706e7644dcdcb6e1", size = 246383, upload-time = "2025-07-03T10:53:13.134Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b3/4477aafe2a546427b58b9c540665feff874f4db651f4d3cb21b308b3a6d2/coverage-7.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d9eae8cdfcd58fe7893b88993723583a6ce4dfbfd9f29e001922544f95615", size = 243400, upload-time = "2025-07-03T10:53:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/f8/c2/efffa43778490c226d9d434827702f2dfbc8041d79101a795f11cbb2cf1e/coverage-7.9.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fae939811e14e53ed8a9818dad51d434a41ee09df9305663735f2e2d2d7d959b", size = 245591, upload-time = "2025-07-03T10:53:15.872Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e7/a59888e882c9a5f0192d8627a30ae57910d5d449c80229b55e7643c078c4/coverage-7.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:31991156251ec202c798501e0a42bbdf2169dcb0f137b1f5c0f4267f3fc68ef9", size = 245402, upload-time = "2025-07-03T10:53:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/92/a5/72fcd653ae3d214927edc100ce67440ed8a0a1e3576b8d5e6d066ed239db/coverage-7.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d0d67963f9cbfc7c7f96d4ac74ed60ecbebd2ea6eeb51887af0f8dce205e545f", size = 243583, upload-time = "2025-07-03T10:53:18.781Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f5/84e70e4df28f4a131d580d7d510aa1ffd95037293da66fd20d446090a13b/coverage-7.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:49b752a2858b10580969ec6af6f090a9a440a64a301ac1528d7ca5f7ed497f4d", size = 244815, upload-time = "2025-07-03T10:53:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/39/e7/d73d7cbdbd09fdcf4642655ae843ad403d9cbda55d725721965f3580a314/coverage-7.9.2-cp312-cp312-win32.whl", hash = "sha256:88d7598b8ee130f32f8a43198ee02edd16d7f77692fa056cb779616bbea1b355", size = 214719, upload-time = "2025-07-03T10:53:21.521Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d6/7486dcc3474e2e6ad26a2af2db7e7c162ccd889c4c68fa14ea8ec189c9e9/coverage-7.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:9dfb070f830739ee49d7c83e4941cc767e503e4394fdecb3b54bfdac1d7662c0", size = 215509, upload-time = "2025-07-03T10:53:22.853Z" }, + { url = "https://files.pythonhosted.org/packages/b7/34/0439f1ae2593b0346164d907cdf96a529b40b7721a45fdcf8b03c95fcd90/coverage-7.9.2-cp312-cp312-win_arm64.whl", hash = "sha256:4e2c058aef613e79df00e86b6d42a641c877211384ce5bd07585ed7ba71ab31b", size = 213910, upload-time = "2025-07-03T10:53:24.472Z" }, + { url = "https://files.pythonhosted.org/packages/94/9d/7a8edf7acbcaa5e5c489a646226bed9591ee1c5e6a84733c0140e9ce1ae1/coverage-7.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:985abe7f242e0d7bba228ab01070fde1d6c8fa12f142e43debe9ed1dde686038", size = 212367, upload-time = "2025-07-03T10:53:25.811Z" }, + { url = "https://files.pythonhosted.org/packages/e8/9e/5cd6f130150712301f7e40fb5865c1bc27b97689ec57297e568d972eec3c/coverage-7.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c3939264a76d44fde7f213924021ed31f55ef28111a19649fec90c0f109e6d", size = 212632, upload-time = "2025-07-03T10:53:27.075Z" }, + { url = "https://files.pythonhosted.org/packages/a8/de/6287a2c2036f9fd991c61cefa8c64e57390e30c894ad3aa52fac4c1e14a8/coverage-7.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae5d563e970dbe04382f736ec214ef48103d1b875967c89d83c6e3f21706d5b3", size = 245793, upload-time = "2025-07-03T10:53:28.408Z" }, + { url = "https://files.pythonhosted.org/packages/06/cc/9b5a9961d8160e3cb0b558c71f8051fe08aa2dd4b502ee937225da564ed1/coverage-7.9.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdd612e59baed2a93c8843c9a7cb902260f181370f1d772f4842987535071d14", size = 243006, upload-time = "2025-07-03T10:53:29.754Z" }, + { url = "https://files.pythonhosted.org/packages/49/d9/4616b787d9f597d6443f5588619c1c9f659e1f5fc9eebf63699eb6d34b78/coverage-7.9.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:256ea87cb2a1ed992bcdfc349d8042dcea1b80436f4ddf6e246d6bee4b5d73b6", size = 244990, upload-time = "2025-07-03T10:53:31.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/83/801cdc10f137b2d02b005a761661649ffa60eb173dcdaeb77f571e4dc192/coverage-7.9.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f44ae036b63c8ea432f610534a2668b0c3aee810e7037ab9d8ff6883de480f5b", size = 245157, upload-time = "2025-07-03T10:53:32.717Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a4/41911ed7e9d3ceb0ffb019e7635468df7499f5cc3edca5f7dfc078e9c5ec/coverage-7.9.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:82d76ad87c932935417a19b10cfe7abb15fd3f923cfe47dbdaa74ef4e503752d", size = 243128, upload-time = "2025-07-03T10:53:34.009Z" }, + { url = "https://files.pythonhosted.org/packages/10/41/344543b71d31ac9cb00a664d5d0c9ef134a0fe87cb7d8430003b20fa0b7d/coverage-7.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:619317bb86de4193debc712b9e59d5cffd91dc1d178627ab2a77b9870deb2868", size = 244511, upload-time = "2025-07-03T10:53:35.434Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/3b68c77e4812105e2a060f6946ba9e6f898ddcdc0d2bfc8b4b152a9ae522/coverage-7.9.2-cp313-cp313-win32.whl", hash = "sha256:0a07757de9feb1dfafd16ab651e0f628fd7ce551604d1bf23e47e1ddca93f08a", size = 214765, upload-time = "2025-07-03T10:53:36.787Z" }, + { url = "https://files.pythonhosted.org/packages/06/a2/7fac400f6a346bb1a4004eb2a76fbff0e242cd48926a2ce37a22a6a1d917/coverage-7.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:115db3d1f4d3f35f5bb021e270edd85011934ff97c8797216b62f461dd69374b", size = 215536, upload-time = "2025-07-03T10:53:38.188Z" }, + { url = "https://files.pythonhosted.org/packages/08/47/2c6c215452b4f90d87017e61ea0fd9e0486bb734cb515e3de56e2c32075f/coverage-7.9.2-cp313-cp313-win_arm64.whl", hash = "sha256:48f82f889c80af8b2a7bb6e158d95a3fbec6a3453a1004d04e4f3b5945a02694", size = 213943, upload-time = "2025-07-03T10:53:39.492Z" }, + { url = "https://files.pythonhosted.org/packages/a3/46/e211e942b22d6af5e0f323faa8a9bc7c447a1cf1923b64c47523f36ed488/coverage-7.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:55a28954545f9d2f96870b40f6c3386a59ba8ed50caf2d949676dac3ecab99f5", size = 213088, upload-time = "2025-07-03T10:53:40.874Z" }, + { url = "https://files.pythonhosted.org/packages/d2/2f/762551f97e124442eccd907bf8b0de54348635b8866a73567eb4e6417acf/coverage-7.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cdef6504637731a63c133bb2e6f0f0214e2748495ec15fe42d1e219d1b133f0b", size = 213298, upload-time = "2025-07-03T10:53:42.218Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b7/76d2d132b7baf7360ed69be0bcab968f151fa31abe6d067f0384439d9edb/coverage-7.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcd5ebe66c7a97273d5d2ddd4ad0ed2e706b39630ed4b53e713d360626c3dbb3", size = 256541, upload-time = "2025-07-03T10:53:43.823Z" }, + { url = "https://files.pythonhosted.org/packages/a0/17/392b219837d7ad47d8e5974ce5f8dc3deb9f99a53b3bd4d123602f960c81/coverage-7.9.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9303aed20872d7a3c9cb39c5d2b9bdbe44e3a9a1aecb52920f7e7495410dfab8", size = 252761, upload-time = "2025-07-03T10:53:45.19Z" }, + { url = "https://files.pythonhosted.org/packages/d5/77/4256d3577fe1b0daa8d3836a1ebe68eaa07dd2cbaf20cf5ab1115d6949d4/coverage-7.9.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc18ea9e417a04d1920a9a76fe9ebd2f43ca505b81994598482f938d5c315f46", size = 254917, upload-time = "2025-07-03T10:53:46.931Z" }, + { url = "https://files.pythonhosted.org/packages/53/99/fc1a008eef1805e1ddb123cf17af864743354479ea5129a8f838c433cc2c/coverage-7.9.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6406cff19880aaaadc932152242523e892faff224da29e241ce2fca329866584", size = 256147, upload-time = "2025-07-03T10:53:48.289Z" }, + { url = "https://files.pythonhosted.org/packages/92/c0/f63bf667e18b7f88c2bdb3160870e277c4874ced87e21426128d70aa741f/coverage-7.9.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d0d4f6ecdf37fcc19c88fec3e2277d5dee740fb51ffdd69b9579b8c31e4232e", size = 254261, upload-time = "2025-07-03T10:53:49.99Z" }, + { url = "https://files.pythonhosted.org/packages/8c/32/37dd1c42ce3016ff8ec9e4b607650d2e34845c0585d3518b2a93b4830c1a/coverage-7.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c33624f50cf8de418ab2b4d6ca9eda96dc45b2c4231336bac91454520e8d1fac", size = 255099, upload-time = "2025-07-03T10:53:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/da/2e/af6b86f7c95441ce82f035b3affe1cd147f727bbd92f563be35e2d585683/coverage-7.9.2-cp313-cp313t-win32.whl", hash = "sha256:1df6b76e737c6a92210eebcb2390af59a141f9e9430210595251fbaf02d46926", size = 215440, upload-time = "2025-07-03T10:53:52.808Z" }, + { url = "https://files.pythonhosted.org/packages/4d/bb/8a785d91b308867f6b2e36e41c569b367c00b70c17f54b13ac29bcd2d8c8/coverage-7.9.2-cp313-cp313t-win_amd64.whl", hash = "sha256:f5fd54310b92741ebe00d9c0d1d7b2b27463952c022da6d47c175d246a98d1bd", size = 216537, upload-time = "2025-07-03T10:53:54.273Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a0/a6bffb5e0f41a47279fd45a8f3155bf193f77990ae1c30f9c224b61cacb0/coverage-7.9.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c48c2375287108c887ee87d13b4070a381c6537d30e8487b24ec721bf2a781cb", size = 214398, upload-time = "2025-07-03T10:53:56.715Z" }, + { url = "https://files.pythonhosted.org/packages/62/ab/b4b06662ccaa00ca7bbee967b7035a33a58b41efb92d8c89a6c523a2ccd5/coverage-7.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddc39510ac922a5c4c27849b739f875d3e1d9e590d1e7b64c98dadf037a16cce", size = 212037, upload-time = "2025-07-03T10:53:58.055Z" }, + { url = "https://files.pythonhosted.org/packages/bb/5e/04619995657acc898d15bfad42b510344b3a74d4d5bc34f2e279d46c781c/coverage-7.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a535c0c7364acd55229749c2b3e5eebf141865de3a8f697076a3291985f02d30", size = 212412, upload-time = "2025-07-03T10:53:59.451Z" }, + { url = "https://files.pythonhosted.org/packages/14/e7/1465710224dc6d31c534e7714cbd907210622a044adc81c810e72eea873f/coverage-7.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df0f9ef28e0f20c767ccdccfc5ae5f83a6f4a2fbdfbcbcc8487a8a78771168c8", size = 241164, upload-time = "2025-07-03T10:54:00.852Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f2/44c6fbd2794afeb9ab6c0a14d3c088ab1dae3dff3df2624609981237bbb4/coverage-7.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f3da12e0ccbcb348969221d29441ac714bbddc4d74e13923d3d5a7a0bebef7a", size = 239032, upload-time = "2025-07-03T10:54:02.25Z" }, + { url = "https://files.pythonhosted.org/packages/6a/d2/7a79845429c0aa2e6788bc45c26a2e3052fa91082c9ea1dea56fb531952c/coverage-7.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a17eaf46f56ae0f870f14a3cbc2e4632fe3771eab7f687eda1ee59b73d09fe4", size = 240148, upload-time = "2025-07-03T10:54:03.618Z" }, + { url = "https://files.pythonhosted.org/packages/9c/7d/2731d1b4c9c672d82d30d218224dfc62939cf3800bc8aba0258fefb191f5/coverage-7.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:669135a9d25df55d1ed56a11bf555f37c922cf08d80799d4f65d77d7d6123fcf", size = 239875, upload-time = "2025-07-03T10:54:05.022Z" }, + { url = "https://files.pythonhosted.org/packages/1b/83/685958715429a9da09cf172c15750ca5c795dd7259466f2645403696557b/coverage-7.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9d3a700304d01a627df9db4322dc082a0ce1e8fc74ac238e2af39ced4c083193", size = 238127, upload-time = "2025-07-03T10:54:06.366Z" }, + { url = "https://files.pythonhosted.org/packages/34/ff/161a4313308b3783126790adfae1970adbe4886fda8788792e435249910a/coverage-7.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:71ae8b53855644a0b1579d4041304ddc9995c7b21c8a1f16753c4d8903b4dfed", size = 239064, upload-time = "2025-07-03T10:54:07.878Z" }, + { url = "https://files.pythonhosted.org/packages/17/14/fe33f41b2e80811021de059621f44c01ebe4d6b08bdb82d54a514488e933/coverage-7.9.2-cp39-cp39-win32.whl", hash = "sha256:dd7a57b33b5cf27acb491e890720af45db05589a80c1ffc798462a765be6d4d7", size = 214522, upload-time = "2025-07-03T10:54:09.331Z" }, + { url = "https://files.pythonhosted.org/packages/6e/30/63d850ec31b5c6f6a7b4e853016375b846258300320eda29376e2786ceeb/coverage-7.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f65bb452e579d5540c8b37ec105dd54d8b9307b07bcaa186818c104ffda22441", size = 215419, upload-time = "2025-07-03T10:54:10.681Z" }, + { url = "https://files.pythonhosted.org/packages/d7/85/f8bbefac27d286386961c25515431482a425967e23d3698b75a250872924/coverage-7.9.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:8a1166db2fb62473285bcb092f586e081e92656c7dfa8e9f62b4d39d7e6b5050", size = 204013, upload-time = "2025-07-03T10:54:12.084Z" }, + { url = "https://files.pythonhosted.org/packages/3c/38/bbe2e63902847cf79036ecc75550d0698af31c91c7575352eb25190d0fb3/coverage-7.9.2-py3-none-any.whl", hash = "sha256:e425cd5b00f6fc0ed7cdbd766c70be8baab4b7839e4d4fe5fac48581dd968ea4", size = 204005, upload-time = "2025-07-03T10:54:13.491Z" }, ] [package.optional-dependencies] @@ -482,7 +476,7 @@ name = "cryptography" version = "44.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cffi", marker = "python_full_version >= '3.11' and python_full_version < '4.0' and platform_python_implementation != 'PyPy'" }, + { name = "cffi", marker = "python_full_version >= '3.11' and platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/d6/1411ab4d6108ab167d06254c5be517681f1e331f90edf1379895bcb87020/cryptography-44.0.3.tar.gz", hash = "sha256:fe19d8bc5536a91a24a8133328880a41831b6c5df54599a8417b62fe015d3053", size = 711096, upload-time = "2025-05-02T19:36:04.667Z" } wheels = [ @@ -676,7 +670,7 @@ name = "importlib-metadata" version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp", marker = "python_full_version < '3.10'" }, + { name = "zipp", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ @@ -701,8 +695,8 @@ dependencies = [ { name = "comm" }, { name = "debugpy" }, { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "ipython", version = "8.36.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "ipython", version = "9.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, + { name = "ipython", version = "9.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-client" }, { name = "jupyter-core" }, { name = "matplotlib-inline" }, @@ -745,7 +739,7 @@ wheels = [ [[package]] name = "ipython" -version = "8.36.0" +version = "8.37.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version == '3.10.*'", @@ -763,20 +757,17 @@ dependencies = [ { name = "traitlets", marker = "python_full_version == '3.10.*'" }, { name = "typing-extensions", marker = "python_full_version == '3.10.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a2/9f/d9a73710df947b7804bd9d93509463fb3a89e0ddc99c9fcc67279cddbeb6/ipython-8.36.0.tar.gz", hash = "sha256:24658e9fe5c5c819455043235ba59cfffded4a35936eefceceab6b192f7092ff", size = 5604997, upload-time = "2025-04-25T18:03:38.031Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/d7/c1c9f371790b3a181e343c4815a361e5a0cc7d90ef6642d64ba5d05de289/ipython-8.36.0-py3-none-any.whl", hash = "sha256:12b913914d010dcffa2711505ec8be4bf0180742d97f1e5175e51f22086428c1", size = 831074, upload-time = "2025-04-25T18:03:34.951Z" }, + { url = "https://files.pythonhosted.org/packages/91/d0/274fbf7b0b12643cbbc001ce13e6a5b1607ac4929d1b11c72460152c9fc3/ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2", size = 831864, upload-time = "2025-05-31T16:39:06.38Z" }, ] [[package]] name = "ipython" -version = "9.2.0" +version = "9.4.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.13' and python_full_version < '4.0'", - "python_full_version >= '3.12.4' and python_full_version < '3.13'", - "python_full_version >= '3.11' and python_full_version < '3.12.4'", - "python_full_version >= '4.0'", + "python_full_version >= '3.11'", ] dependencies = [ { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, @@ -791,9 +782,9 @@ dependencies = [ { name = "traitlets", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9d/02/63a84444a7409b3c0acd1de9ffe524660e0e5d82ee473e78b45e5bfb64a4/ipython-9.2.0.tar.gz", hash = "sha256:62a9373dbc12f28f9feaf4700d052195bf89806279fc8ca11f3f54017d04751b", size = 4424394, upload-time = "2025-04-25T17:55:40.498Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/80/406f9e3bde1c1fd9bf5a0be9d090f8ae623e401b7670d8f6fdf2ab679891/ipython-9.4.0.tar.gz", hash = "sha256:c033c6d4e7914c3d9768aabe76bbe87ba1dc66a92a05db6bfa1125d81f2ee270", size = 4385338, upload-time = "2025-07-01T11:11:30.606Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/ce/5e897ee51b7d26ab4e47e5105e7368d40ce6cfae2367acdf3165396d50be/ipython-9.2.0-py3-none-any.whl", hash = "sha256:fef5e33c4a1ae0759e0bba5917c9db4eb8c53fee917b6a526bd973e1ca5159f6", size = 604277, upload-time = "2025-04-25T17:55:37.625Z" }, + { url = "https://files.pythonhosted.org/packages/63/f8/0031ee2b906a15a33d6bfc12dd09c3dfa966b3cb5b284ecfb7549e6ac3c4/ipython-9.4.0-py3-none-any.whl", hash = "sha256:25850f025a446d9b359e8d296ba175a36aedd32e83ca9b5060430fe16801f066", size = 611021, upload-time = "2025-07-01T11:11:27.85Z" }, ] [[package]] @@ -815,8 +806,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "comm" }, { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "ipython", version = "8.36.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "ipython", version = "9.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, + { name = "ipython", version = "9.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyterlab-widgets" }, { name = "traitlets" }, { name = "widgetsnbextension" }, @@ -1015,8 +1006,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ipykernel" }, { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "ipython", version = "8.36.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "ipython", version = "9.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, + { name = "ipython", version = "9.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jupyter-client" }, { name = "jupyter-core" }, { name = "prompt-toolkit" }, @@ -1120,7 +1111,7 @@ wheels = [ [[package]] name = "jupyterlab" -version = "4.4.3" +version = "4.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1139,9 +1130,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/2d/d1678dcf2db66cb4a38a80d9e5fcf48c349f3ac12f2d38882993353ae768/jupyterlab-4.4.3.tar.gz", hash = "sha256:a94c32fd7f8b93e82a49dc70a6ec45a5c18281ca2a7228d12765e4e210e5bca2", size = 23032376, upload-time = "2025-05-26T11:18:00.996Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/4d/7ca5b46ea56742880d71a768a9e6fb8f8482228427eb89492d55c5d0bb7d/jupyterlab-4.4.4.tar.gz", hash = "sha256:163fee1ef702e0a057f75d2eed3ed1da8a986d59eb002cbeb6f0c2779e6cd153", size = 23044296, upload-time = "2025-06-28T13:07:20.708Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/4d/7dd5c2ffbb960930452a031dc8410746183c924580f2ab4e68ceb5b3043f/jupyterlab-4.4.3-py3-none-any.whl", hash = "sha256:164302f6d4b6c44773dfc38d585665a4db401a16e5296c37df5cba63904fbdea", size = 12295480, upload-time = "2025-05-26T11:17:56.607Z" }, + { url = "https://files.pythonhosted.org/packages/f8/82/66910ce0995dbfdb33609f41c99fe32ce483b9624a3e7d672af14ff63b9f/jupyterlab-4.4.4-py3-none-any.whl", hash = "sha256:711611e4f59851152eb93316c3547c3ec6291f16bb455f1f4fa380d25637e0dd", size = 12296310, upload-time = "2025-06-28T13:07:15.676Z" }, ] [[package]] @@ -1183,7 +1174,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.67" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -1194,9 +1185,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/40/875af0194024d0006874f061958fa417d3500bbfdc9a57e1bd1c2f4e6ed2/langchain_core-0.3.67.tar.gz", hash = "sha256:2c14aa44a0e78e014e96d7f2f8916ac109d0a0ba87ed67ee25bf7296bed7e7ba", size = 561952, upload-time = "2025-06-30T17:09:35.142Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/2b/a0d283089c6d08c12d47dca39a55029ff714e939ec04f4560420426ab613/langchain_core-0.3.67-py3-none-any.whl", hash = "sha256:b699f1f24b24fa2747c05e2daa280aa64478a51e01a4e82c7f8e20b6167dfa99", size = 440237, upload-time = "2025-06-30T17:09:33.323Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] @@ -1280,32 +1271,32 @@ dev = [ [[package]] name = "langgraph-api" -version = "0.2.36" +version = "0.2.78" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cloudpickle", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "cryptography", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "httpx", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "jsonschema-rs", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langchain-core", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-sdk", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langsmith", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "orjson", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "pyjwt", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "sse-starlette", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "starlette", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "structlog", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "tenacity", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "truststore", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "uvicorn", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "watchfiles", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "cloudpickle", marker = "python_full_version >= '3.11'" }, + { name = "cryptography", marker = "python_full_version >= '3.11'" }, + { name = "httpx", marker = "python_full_version >= '3.11'" }, + { name = "jsonschema-rs", marker = "python_full_version >= '3.11'" }, + { name = "langchain-core", marker = "python_full_version >= '3.11'" }, + { name = "langgraph", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-sdk", marker = "python_full_version >= '3.11'" }, + { name = "langsmith", marker = "python_full_version >= '3.11'" }, + { name = "orjson", marker = "python_full_version >= '3.11'" }, + { name = "pyjwt", marker = "python_full_version >= '3.11'" }, + { name = "sse-starlette", marker = "python_full_version >= '3.11'" }, + { name = "starlette", marker = "python_full_version >= '3.11'" }, + { name = "structlog", marker = "python_full_version >= '3.11'" }, + { name = "tenacity", marker = "python_full_version >= '3.11'" }, + { name = "truststore", marker = "python_full_version >= '3.11'" }, + { name = "uvicorn", marker = "python_full_version >= '3.11'" }, + { name = "watchfiles", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/57/ea1a163198909f0e8713584d49858ef8884f2d1f14273fd3c40344480606/langgraph_api-0.2.36.tar.gz", hash = "sha256:5d45dce8733b954e61b142abc28d0962a37b03ffc578e20f2ccbc98d48579ece", size = 213623, upload-time = "2025-05-29T20:55:34.628Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/88/1aa91bede22d1393a53605ff13a57d6cb3ce2831eb250a8a8f814c548d2e/langgraph_api-0.2.78.tar.gz", hash = "sha256:37aad4fe764934f358dbb26d50b4acbf4180aac673499d1502b5b468cc7acba4", size = 233581, upload-time = "2025-07-02T19:11:01.154Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/b7/0d05bbcd42a9070aa200e6001b466ef29d274c4715b654d4f6741a7ed8f5/langgraph_api-0.2.36-py3-none-any.whl", hash = "sha256:e01579d4322c9ce65d0eb8361092a301bcd12d375adb2e806274c7692fe3d8da", size = 177962, upload-time = "2025-05-29T20:55:33.446Z" }, + { url = "https://files.pythonhosted.org/packages/7e/76/46626d99c36fce0c1ee1e1581f54b29acbed5e9f2e7cf9a198c825547d91/langgraph_api-0.2.78-py3-none-any.whl", hash = "sha256:57abe7fff9763d6f4eaf4419d103f75e77dca6d271db3816777c04bd67db4449", size = 190222, upload-time = "2025-07-02T19:10:59.793Z" }, ] [[package]] @@ -1403,21 +1394,22 @@ dev = [ [[package]] name = "langgraph-cli" -version = "0.2.10" +version = "0.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "langgraph-sdk", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8d/5e/b12bc8140cd4f797ad7f596bf90558994fd6891df8974bc3fc4747eabdc7/langgraph_cli-0.2.10.tar.gz", hash = "sha256:0c215b364daeaf10de681e4960ecaafc7c9cd2a4100b41052d78d95cababf422", size = 31690, upload-time = "2025-05-09T20:18:27.542Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/c2/53aaae208a3a08f727ef9d03edfd8f499403e017fc451c8ca5b52e95c930/langgraph_cli-0.3.3.tar.gz", hash = "sha256:120adc44064786bb11f1376a7b324b2125276a2e2c3a04bbfab7b8c1622ad4d7", size = 722842, upload-time = "2025-06-13T20:17:52.639Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/06/7151d7c8d6c2bccc0919ddb35a63caf3707b96c94561f47f14b08d73ef5e/langgraph_cli-0.2.10-py3-none-any.whl", hash = "sha256:4aaa8d828d8d3bf0f55d2b2a36b2d9944021d65a4b06ed708c6d5eea725f65a7", size = 34833, upload-time = "2025-05-09T20:18:26.173Z" }, + { url = "https://files.pythonhosted.org/packages/50/aa/f52742987a30f9f2d80c00e1caccb310185dd511d07b56c3e611fe31adb5/langgraph_cli-0.3.3-py3-none-any.whl", hash = "sha256:a0c6b04d6a37191431ede17f7a358f1944c6e5ac9e1b7d2004b9f973fe940094", size = 35880, upload-time = "2025-06-13T20:17:51.437Z" }, ] [package.optional-dependencies] inmem = [ - { name = "langgraph-api", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "langgraph-api", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11'" }, { name = "python-dotenv" }, ] @@ -1454,19 +1446,19 @@ dev = [ [[package]] name = "langgraph-runtime-inmem" -version = "0.2.0" +version = "0.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "blockbuster", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "sse-starlette", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "starlette", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "structlog", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "blockbuster", marker = "python_full_version >= '3.11'" }, + { name = "langgraph", marker = "python_full_version >= '3.11'" }, + { name = "langgraph-checkpoint", marker = "python_full_version >= '3.11'" }, + { name = "sse-starlette", marker = "python_full_version >= '3.11'" }, + { name = "starlette", marker = "python_full_version >= '3.11'" }, + { name = "structlog", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/8b/54452b0336674afe0ddbba0d5f52ddb323d9fa838e5bab694e1947697323/langgraph_runtime_inmem-0.2.0.tar.gz", hash = "sha256:3eed0bd7e241fbad6c7954e8494ddb133af7587f110c7eb4e3be15df5731a05a", size = 72666, upload-time = "2025-05-21T21:22:12.022Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/17/7ff669ff44a53ab342903c2996fff75a77494af9fe56abcfbca64fe2342b/langgraph_runtime_inmem-0.3.4.tar.gz", hash = "sha256:eda7828f3ea07126e5265024b74a3fa9bf611633ad83ba3296ab9f51d89b7c0c", size = 77424, upload-time = "2025-07-01T14:45:07.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/1f/5676d5237b0682257957338f5f7ee1f063f6d33fa158f878ad926800e95d/langgraph_runtime_inmem-0.2.0-py3-none-any.whl", hash = "sha256:6ad30c493d5963afbeac3136560303fba205b3850c5181f57f1794d8ecb8a461", size = 28406, upload-time = "2025-05-21T21:22:10.674Z" }, + { url = "https://files.pythonhosted.org/packages/95/0e/39c13ca7229a9425a0e5744a1d3817f80d38dd5ca7703494fb9cf836ba45/langgraph_runtime_inmem-0.3.4-py3-none-any.whl", hash = "sha256:dcb9ac68ac90b3fb1ddaf666d14a367ab70e69d5bb5589b77a72c318e29104ae", size = 29139, upload-time = "2025-07-01T14:45:06.472Z" }, ] [[package]] @@ -1607,7 +1599,7 @@ wheels = [ [[package]] name = "mypy" -version = "1.16.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, @@ -1615,39 +1607,39 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/38/13c2f1abae94d5ea0354e146b95a1be9b2137a0d506728e0da037c4276f6/mypy-1.16.0.tar.gz", hash = "sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab", size = 3323139, upload-time = "2025-05-29T13:46:12.532Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/5e/a0485f0608a3d67029d3d73cec209278b025e3493a3acfda3ef3a88540fd/mypy-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c", size = 10967416, upload-time = "2025-05-29T13:34:17.783Z" }, - { url = "https://files.pythonhosted.org/packages/4b/53/5837c221f74c0d53a4bfc3003296f8179c3a2a7f336d7de7bbafbe96b688/mypy-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571", size = 10087654, upload-time = "2025-05-29T13:32:37.878Z" }, - { url = "https://files.pythonhosted.org/packages/29/59/5fd2400352c3093bed4c09017fe671d26bc5bb7e6ef2d4bf85f2a2488104/mypy-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491", size = 11875192, upload-time = "2025-05-29T13:34:54.281Z" }, - { url = "https://files.pythonhosted.org/packages/ad/3e/4bfec74663a64c2012f3e278dbc29ffe82b121bc551758590d1b6449ec0c/mypy-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777", size = 12612939, upload-time = "2025-05-29T13:33:14.766Z" }, - { url = "https://files.pythonhosted.org/packages/88/1f/fecbe3dcba4bf2ca34c26ca016383a9676711907f8db4da8354925cbb08f/mypy-1.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b", size = 12874719, upload-time = "2025-05-29T13:21:52.09Z" }, - { url = "https://files.pythonhosted.org/packages/f3/51/c2d280601cd816c43dfa512a759270d5a5ef638d7ac9bea9134c8305a12f/mypy-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93", size = 9487053, upload-time = "2025-05-29T13:33:29.797Z" }, - { url = "https://files.pythonhosted.org/packages/24/c4/ff2f79db7075c274fe85b5fff8797d29c6b61b8854c39e3b7feb556aa377/mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab", size = 10884498, upload-time = "2025-05-29T13:18:54.066Z" }, - { url = "https://files.pythonhosted.org/packages/02/07/12198e83006235f10f6a7808917376b5d6240a2fd5dce740fe5d2ebf3247/mypy-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2", size = 10011755, upload-time = "2025-05-29T13:34:00.851Z" }, - { url = "https://files.pythonhosted.org/packages/f1/9b/5fd5801a72b5d6fb6ec0105ea1d0e01ab2d4971893076e558d4b6d6b5f80/mypy-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff", size = 11800138, upload-time = "2025-05-29T13:32:55.082Z" }, - { url = "https://files.pythonhosted.org/packages/2e/81/a117441ea5dfc3746431e51d78a4aca569c677aa225bca2cc05a7c239b61/mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666", size = 12533156, upload-time = "2025-05-29T13:19:12.963Z" }, - { url = "https://files.pythonhosted.org/packages/3f/38/88ec57c6c86014d3f06251e00f397b5a7daa6888884d0abf187e4f5f587f/mypy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c", size = 12742426, upload-time = "2025-05-29T13:20:22.72Z" }, - { url = "https://files.pythonhosted.org/packages/bd/53/7e9d528433d56e6f6f77ccf24af6ce570986c2d98a5839e4c2009ef47283/mypy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b", size = 9478319, upload-time = "2025-05-29T13:21:17.582Z" }, - { url = "https://files.pythonhosted.org/packages/70/cf/158e5055e60ca2be23aec54a3010f89dcffd788732634b344fc9cb1e85a0/mypy-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13", size = 11062927, upload-time = "2025-05-29T13:35:52.328Z" }, - { url = "https://files.pythonhosted.org/packages/94/34/cfff7a56be1609f5d10ef386342ce3494158e4d506516890142007e6472c/mypy-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090", size = 10083082, upload-time = "2025-05-29T13:35:33.378Z" }, - { url = "https://files.pythonhosted.org/packages/b3/7f/7242062ec6288c33d8ad89574df87c3903d394870e5e6ba1699317a65075/mypy-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1", size = 11828306, upload-time = "2025-05-29T13:21:02.164Z" }, - { url = "https://files.pythonhosted.org/packages/6f/5f/b392f7b4f659f5b619ce5994c5c43caab3d80df2296ae54fa888b3d17f5a/mypy-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8", size = 12702764, upload-time = "2025-05-29T13:20:42.826Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c0/7646ef3a00fa39ac9bc0938626d9ff29d19d733011be929cfea59d82d136/mypy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730", size = 12896233, upload-time = "2025-05-29T13:18:37.446Z" }, - { url = "https://files.pythonhosted.org/packages/6d/38/52f4b808b3fef7f0ef840ee8ff6ce5b5d77381e65425758d515cdd4f5bb5/mypy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec", size = 9565547, upload-time = "2025-05-29T13:20:02.836Z" }, - { url = "https://files.pythonhosted.org/packages/97/9c/ca03bdbefbaa03b264b9318a98950a9c683e06472226b55472f96ebbc53d/mypy-1.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b", size = 11059753, upload-time = "2025-05-29T13:18:18.167Z" }, - { url = "https://files.pythonhosted.org/packages/36/92/79a969b8302cfe316027c88f7dc6fee70129490a370b3f6eb11d777749d0/mypy-1.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0", size = 10073338, upload-time = "2025-05-29T13:19:48.079Z" }, - { url = "https://files.pythonhosted.org/packages/14/9b/a943f09319167da0552d5cd722104096a9c99270719b1afeea60d11610aa/mypy-1.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b", size = 11827764, upload-time = "2025-05-29T13:46:04.47Z" }, - { url = "https://files.pythonhosted.org/packages/ec/64/ff75e71c65a0cb6ee737287c7913ea155845a556c64144c65b811afdb9c7/mypy-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d", size = 12701356, upload-time = "2025-05-29T13:35:13.553Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ad/0e93c18987a1182c350f7a5fab70550852f9fabe30ecb63bfbe51b602074/mypy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52", size = 12900745, upload-time = "2025-05-29T13:17:24.409Z" }, - { url = "https://files.pythonhosted.org/packages/28/5d/036c278d7a013e97e33f08c047fe5583ab4f1fc47c9a49f985f1cdd2a2d7/mypy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb", size = 9572200, upload-time = "2025-05-29T13:33:44.92Z" }, - { url = "https://files.pythonhosted.org/packages/bd/eb/c0759617fe2159aee7a653f13cceafbf7f0b6323b4197403f2e587ca947d/mypy-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3", size = 10956081, upload-time = "2025-05-29T13:19:32.264Z" }, - { url = "https://files.pythonhosted.org/packages/70/35/df3c74a2967bdf86edea58b265feeec181d693432faed1c3b688b7c231e3/mypy-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92", size = 10084422, upload-time = "2025-05-29T13:18:01.437Z" }, - { url = "https://files.pythonhosted.org/packages/b3/07/145ffe29f4b577219943b7b1dc0a71df7ead3c5bed4898686bd87c5b5cc2/mypy-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436", size = 11879670, upload-time = "2025-05-29T13:17:45.971Z" }, - { url = "https://files.pythonhosted.org/packages/c6/94/0421562d6b046e22986758c9ae31865d10ea0ba607ae99b32c9d18b16f66/mypy-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2", size = 12610528, upload-time = "2025-05-29T13:34:36.983Z" }, - { url = "https://files.pythonhosted.org/packages/1a/f1/39a22985b78c766a594ae1e0bbb6f8bdf5f31ea8d0c52291a3c211fd3cd5/mypy-1.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20", size = 12871923, upload-time = "2025-05-29T13:32:21.823Z" }, - { url = "https://files.pythonhosted.org/packages/f3/8e/84db4fb0d01f43d2c82fa9072ca72a42c49e52d58f44307bbd747c977bc2/mypy-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21", size = 9482931, upload-time = "2025-05-29T13:21:32.326Z" }, - { url = "https://files.pythonhosted.org/packages/99/a3/6ed10530dec8e0fdc890d81361260c9ef1f5e5c217ad8c9b21ecb2b8366b/mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031", size = 2265773, upload-time = "2025-05-29T13:35:18.762Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -1726,7 +1718,7 @@ wheels = [ [[package]] name = "notebook" -version = "7.4.3" +version = "7.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, @@ -1735,9 +1727,9 @@ dependencies = [ { name = "notebook-shim" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/21/4f83b15e483da4f4f63928edd0cb08b6e7d33f8a15c23b116a90c44c6235/notebook-7.4.3.tar.gz", hash = "sha256:a1567481cd3853f2610ee0ecf5dfa12bb508e878ee8f92152c134ef7f0568a76", size = 13881668, upload-time = "2025-05-26T14:27:21.656Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/4e/a40b5a94eb01fc51746db7854296d88b84905ab18ee0fcef853a60d708a3/notebook-7.4.4.tar.gz", hash = "sha256:392fd501e266f2fb3466c6fcd3331163a2184968cb5c5accf90292e01dfe528c", size = 13883628, upload-time = "2025-06-30T13:04:18.099Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/1b/16c809d799e3ddd7a97c8b43734f79624b74ddef9707e7d92275a13777bc/notebook-7.4.3-py3-none-any.whl", hash = "sha256:9cdeee954e04101cadb195d90e2ab62b7c9286c1d4f858bf3bb54e40df16c0c3", size = 14286402, upload-time = "2025-05-26T14:27:17.339Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c0/e64d2047fd752249b0b69f6aee2a7049eb94e7273e5baabc8b8ad05cc068/notebook-7.4.4-py3-none-any.whl", hash = "sha256:32840f7f777b6bff79bb101159336e9b332bdbfba1495b8739e34d1d65cbc1c0", size = 14288000, upload-time = "2025-06-30T13:04:14.584Z" }, ] [[package]] @@ -1956,11 +1948,11 @@ wheels = [ [[package]] name = "prometheus-client" -version = "0.22.0" +version = "0.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5b/5a/3fa1fa7e91a203759aaf316be394f70f2ef598d589b9785a8611b6094c00/prometheus_client-0.22.0.tar.gz", hash = "sha256:18da1d2241ac2d10c8d2110f13eedcd5c7c0c8af18c926e8731f04fc10cd575c", size = 74443, upload-time = "2025-05-16T20:50:18.333Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/c7/cee159ba3d7192e84a4c166ec1752f44a5fa859ac0eeda2d73a1da65ab47/prometheus_client-0.22.0-py3-none-any.whl", hash = "sha256:c8951bbe64e62b96cd8e8f5d917279d1b9b91ab766793f33d4dce6c228558713", size = 62658, upload-time = "2025-05-16T20:50:16.978Z" }, + { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, ] [[package]] @@ -2290,11 +2282,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.1" +version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] @@ -2320,7 +2312,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -2328,24 +2320,26 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-cov" -version = "6.1.1" +version = "6.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload-time = "2025-04-05T14:07:51.592Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload-time = "2025-04-05T14:07:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, ] [[package]] @@ -2400,15 +2394,15 @@ wheels = [ [[package]] name = "pytest-xdist" -version = "3.7.0" +version = "3.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "execnet" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/dc/865845cfe987b21658e871d16e0a24e871e00884c545f246dd8f6f69edda/pytest_xdist-3.7.0.tar.gz", hash = "sha256:f9248c99a7c15b7d2f90715df93610353a485827bc06eefb6566d23f6400f126", size = 87550, upload-time = "2025-05-26T21:18:20.251Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/b2/0e802fde6f1c5b2f7ae7e9ad42b83fd4ecebac18a8a8c2f2f14e39dce6e1/pytest_xdist-3.7.0-py3-none-any.whl", hash = "sha256:7d3fbd255998265052435eb9daa4e99b62e6fb9cfb6efd1f858d4d8c0c7f0ca0", size = 46142, upload-time = "2025-05-26T21:18:18.759Z" }, + { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, ] [package.optional-dependencies] @@ -2430,11 +2424,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.1.0" +version = "1.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, ] [[package]] @@ -2539,91 +2533,77 @@ wheels = [ [[package]] name = "pyzmq" -version = "26.4.0" +version = "27.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/11/b9213d25230ac18a71b39b3723494e57adebe36e066397b961657b3b41c1/pyzmq-26.4.0.tar.gz", hash = "sha256:4bd13f85f80962f91a651a7356fe0472791a5f7a92f227822b5acf44795c626d", size = 278293, upload-time = "2025-04-04T12:05:44.049Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/06/50a4e9648b3e8b992bef8eb632e457307553a89d294103213cfd47b3da69/pyzmq-27.0.0.tar.gz", hash = "sha256:b1f08eeb9ce1510e6939b6e5dcd46a17765e2333daae78ecf4606808442e52cf", size = 280478, upload-time = "2025-06-13T14:09:07.087Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/b8/af1d814ffc3ff9730f9a970cbf216b6f078e5d251a25ef5201d7bc32a37c/pyzmq-26.4.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:0329bdf83e170ac133f44a233fc651f6ed66ef8e66693b5af7d54f45d1ef5918", size = 1339238, upload-time = "2025-04-04T12:03:07.022Z" }, - { url = "https://files.pythonhosted.org/packages/ee/e4/5aafed4886c264f2ea6064601ad39c5fc4e9b6539c6ebe598a859832eeee/pyzmq-26.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:398a825d2dea96227cf6460ce0a174cf7657d6f6827807d4d1ae9d0f9ae64315", size = 672848, upload-time = "2025-04-04T12:03:08.591Z" }, - { url = "https://files.pythonhosted.org/packages/79/39/026bf49c721cb42f1ef3ae0ee3d348212a7621d2adb739ba97599b6e4d50/pyzmq-26.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d52d62edc96787f5c1dfa6c6ccff9b581cfae5a70d94ec4c8da157656c73b5b", size = 911299, upload-time = "2025-04-04T12:03:10Z" }, - { url = "https://files.pythonhosted.org/packages/03/23/b41f936a9403b8f92325c823c0f264c6102a0687a99c820f1aaeb99c1def/pyzmq-26.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1410c3a3705db68d11eb2424d75894d41cff2f64d948ffe245dd97a9debfebf4", size = 867920, upload-time = "2025-04-04T12:03:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/c1/3e/2de5928cdadc2105e7c8f890cc5f404136b41ce5b6eae5902167f1d5641c/pyzmq-26.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7dacb06a9c83b007cc01e8e5277f94c95c453c5851aac5e83efe93e72226353f", size = 862514, upload-time = "2025-04-04T12:03:13.013Z" }, - { url = "https://files.pythonhosted.org/packages/ce/57/109569514dd32e05a61d4382bc88980c95bfd2f02e58fea47ec0ccd96de1/pyzmq-26.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6bab961c8c9b3a4dc94d26e9b2cdf84de9918931d01d6ff38c721a83ab3c0ef5", size = 1204494, upload-time = "2025-04-04T12:03:14.795Z" }, - { url = "https://files.pythonhosted.org/packages/aa/02/dc51068ff2ca70350d1151833643a598625feac7b632372d229ceb4de3e1/pyzmq-26.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a5c09413b924d96af2aa8b57e76b9b0058284d60e2fc3730ce0f979031d162a", size = 1514525, upload-time = "2025-04-04T12:03:16.246Z" }, - { url = "https://files.pythonhosted.org/packages/48/2a/a7d81873fff0645eb60afaec2b7c78a85a377af8f1d911aff045d8955bc7/pyzmq-26.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7d489ac234d38e57f458fdbd12a996bfe990ac028feaf6f3c1e81ff766513d3b", size = 1414659, upload-time = "2025-04-04T12:03:17.652Z" }, - { url = "https://files.pythonhosted.org/packages/ef/ea/813af9c42ae21845c1ccfe495bd29c067622a621e85d7cda6bc437de8101/pyzmq-26.4.0-cp310-cp310-win32.whl", hash = "sha256:dea1c8db78fb1b4b7dc9f8e213d0af3fc8ecd2c51a1d5a3ca1cde1bda034a980", size = 580348, upload-time = "2025-04-04T12:03:19.384Z" }, - { url = "https://files.pythonhosted.org/packages/20/68/318666a89a565252c81d3fed7f3b4c54bd80fd55c6095988dfa2cd04a62b/pyzmq-26.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:fa59e1f5a224b5e04dc6c101d7186058efa68288c2d714aa12d27603ae93318b", size = 643838, upload-time = "2025-04-04T12:03:20.795Z" }, - { url = "https://files.pythonhosted.org/packages/91/f8/fb1a15b5f4ecd3e588bfde40c17d32ed84b735195b5c7d1d7ce88301a16f/pyzmq-26.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:a651fe2f447672f4a815e22e74630b6b1ec3a1ab670c95e5e5e28dcd4e69bbb5", size = 559565, upload-time = "2025-04-04T12:03:22.676Z" }, - { url = "https://files.pythonhosted.org/packages/32/6d/234e3b0aa82fd0290b1896e9992f56bdddf1f97266110be54d0177a9d2d9/pyzmq-26.4.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:bfcf82644c9b45ddd7cd2a041f3ff8dce4a0904429b74d73a439e8cab1bd9e54", size = 1339723, upload-time = "2025-04-04T12:03:24.358Z" }, - { url = "https://files.pythonhosted.org/packages/4f/11/6d561efe29ad83f7149a7cd48e498e539ed09019c6cd7ecc73f4cc725028/pyzmq-26.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9bcae3979b2654d5289d3490742378b2f3ce804b0b5fd42036074e2bf35b030", size = 672645, upload-time = "2025-04-04T12:03:25.693Z" }, - { url = "https://files.pythonhosted.org/packages/19/fd/81bfe3e23f418644660bad1a90f0d22f0b3eebe33dd65a79385530bceb3d/pyzmq-26.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccdff8ac4246b6fb60dcf3982dfaeeff5dd04f36051fe0632748fc0aa0679c01", size = 910133, upload-time = "2025-04-04T12:03:27.625Z" }, - { url = "https://files.pythonhosted.org/packages/97/68/321b9c775595ea3df832a9516252b653fe32818db66fdc8fa31c9b9fce37/pyzmq-26.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4550af385b442dc2d55ab7717837812799d3674cb12f9a3aa897611839c18e9e", size = 867428, upload-time = "2025-04-04T12:03:29.004Z" }, - { url = "https://files.pythonhosted.org/packages/4e/6e/159cbf2055ef36aa2aa297e01b24523176e5b48ead283c23a94179fb2ba2/pyzmq-26.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:2f9f7ffe9db1187a253fca95191854b3fda24696f086e8789d1d449308a34b88", size = 862409, upload-time = "2025-04-04T12:03:31.032Z" }, - { url = "https://files.pythonhosted.org/packages/05/1c/45fb8db7be5a7d0cadea1070a9cbded5199a2d578de2208197e592f219bd/pyzmq-26.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3709c9ff7ba61589b7372923fd82b99a81932b592a5c7f1a24147c91da9a68d6", size = 1205007, upload-time = "2025-04-04T12:03:32.687Z" }, - { url = "https://files.pythonhosted.org/packages/f8/fa/658c7f583af6498b463f2fa600f34e298e1b330886f82f1feba0dc2dd6c3/pyzmq-26.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f8f3c30fb2d26ae5ce36b59768ba60fb72507ea9efc72f8f69fa088450cff1df", size = 1514599, upload-time = "2025-04-04T12:03:34.084Z" }, - { url = "https://files.pythonhosted.org/packages/4d/d7/44d641522353ce0a2bbd150379cb5ec32f7120944e6bfba4846586945658/pyzmq-26.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:382a4a48c8080e273427fc692037e3f7d2851959ffe40864f2db32646eeb3cef", size = 1414546, upload-time = "2025-04-04T12:03:35.478Z" }, - { url = "https://files.pythonhosted.org/packages/72/76/c8ed7263218b3d1e9bce07b9058502024188bd52cc0b0a267a9513b431fc/pyzmq-26.4.0-cp311-cp311-win32.whl", hash = "sha256:d56aad0517d4c09e3b4f15adebba8f6372c5102c27742a5bdbfc74a7dceb8fca", size = 579247, upload-time = "2025-04-04T12:03:36.846Z" }, - { url = "https://files.pythonhosted.org/packages/c3/d0/2d9abfa2571a0b1a67c0ada79a8aa1ba1cce57992d80f771abcdf99bb32c/pyzmq-26.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:963977ac8baed7058c1e126014f3fe58b3773f45c78cce7af5c26c09b6823896", size = 644727, upload-time = "2025-04-04T12:03:38.578Z" }, - { url = "https://files.pythonhosted.org/packages/0d/d1/c8ad82393be6ccedfc3c9f3adb07f8f3976e3c4802640fe3f71441941e70/pyzmq-26.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0c8e8cadc81e44cc5088fcd53b9b3b4ce9344815f6c4a03aec653509296fae3", size = 559942, upload-time = "2025-04-04T12:03:40.143Z" }, - { url = "https://files.pythonhosted.org/packages/10/44/a778555ebfdf6c7fc00816aad12d185d10a74d975800341b1bc36bad1187/pyzmq-26.4.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:5227cb8da4b6f68acfd48d20c588197fd67745c278827d5238c707daf579227b", size = 1341586, upload-time = "2025-04-04T12:03:41.954Z" }, - { url = "https://files.pythonhosted.org/packages/9c/4f/f3a58dc69ac757e5103be3bd41fb78721a5e17da7cc617ddb56d973a365c/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1c07a7fa7f7ba86554a2b1bef198c9fed570c08ee062fd2fd6a4dcacd45f905", size = 665880, upload-time = "2025-04-04T12:03:43.45Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/50230bcfb3ae5cb98bee683b6edeba1919f2565d7cc1851d3c38e2260795/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae775fa83f52f52de73183f7ef5395186f7105d5ed65b1ae65ba27cb1260de2b", size = 902216, upload-time = "2025-04-04T12:03:45.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/59/56bbdc5689be5e13727491ad2ba5efd7cd564365750514f9bc8f212eef82/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c760d0226ebd52f1e6b644a9e839b5db1e107a23f2fcd46ec0569a4fdd4e63", size = 859814, upload-time = "2025-04-04T12:03:47.188Z" }, - { url = "https://files.pythonhosted.org/packages/81/b1/57db58cfc8af592ce94f40649bd1804369c05b2190e4cbc0a2dad572baeb/pyzmq-26.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ef8c6ecc1d520debc147173eaa3765d53f06cd8dbe7bd377064cdbc53ab456f5", size = 855889, upload-time = "2025-04-04T12:03:49.223Z" }, - { url = "https://files.pythonhosted.org/packages/e8/92/47542e629cbac8f221c230a6d0f38dd3d9cff9f6f589ed45fdf572ffd726/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3150ef4084e163dec29ae667b10d96aad309b668fac6810c9e8c27cf543d6e0b", size = 1197153, upload-time = "2025-04-04T12:03:50.591Z" }, - { url = "https://files.pythonhosted.org/packages/07/e5/b10a979d1d565d54410afc87499b16c96b4a181af46e7645ab4831b1088c/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4448c9e55bf8329fa1dcedd32f661bf611214fa70c8e02fee4347bc589d39a84", size = 1507352, upload-time = "2025-04-04T12:03:52.473Z" }, - { url = "https://files.pythonhosted.org/packages/ab/58/5a23db84507ab9c01c04b1232a7a763be66e992aa2e66498521bbbc72a71/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e07dde3647afb084d985310d067a3efa6efad0621ee10826f2cb2f9a31b89d2f", size = 1406834, upload-time = "2025-04-04T12:03:54Z" }, - { url = "https://files.pythonhosted.org/packages/22/74/aaa837b331580c13b79ac39396601fb361454ee184ca85e8861914769b99/pyzmq-26.4.0-cp312-cp312-win32.whl", hash = "sha256:ba034a32ecf9af72adfa5ee383ad0fd4f4e38cdb62b13624278ef768fe5b5b44", size = 577992, upload-time = "2025-04-04T12:03:55.815Z" }, - { url = "https://files.pythonhosted.org/packages/30/0f/55f8c02c182856743b82dde46b2dc3e314edda7f1098c12a8227eeda0833/pyzmq-26.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:056a97aab4064f526ecb32f4343917a4022a5d9efb6b9df990ff72e1879e40be", size = 640466, upload-time = "2025-04-04T12:03:57.231Z" }, - { url = "https://files.pythonhosted.org/packages/e4/29/073779afc3ef6f830b8de95026ef20b2d1ec22d0324d767748d806e57379/pyzmq-26.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f23c750e485ce1eb639dbd576d27d168595908aa2d60b149e2d9e34c9df40e0", size = 556342, upload-time = "2025-04-04T12:03:59.218Z" }, - { url = "https://files.pythonhosted.org/packages/d7/20/fb2c92542488db70f833b92893769a569458311a76474bda89dc4264bd18/pyzmq-26.4.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:c43fac689880f5174d6fc864857d1247fe5cfa22b09ed058a344ca92bf5301e3", size = 1339484, upload-time = "2025-04-04T12:04:00.671Z" }, - { url = "https://files.pythonhosted.org/packages/58/29/2f06b9cabda3a6ea2c10f43e67ded3e47fc25c54822e2506dfb8325155d4/pyzmq-26.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:902aca7eba477657c5fb81c808318460328758e8367ecdd1964b6330c73cae43", size = 666106, upload-time = "2025-04-04T12:04:02.366Z" }, - { url = "https://files.pythonhosted.org/packages/77/e4/dcf62bd29e5e190bd21bfccaa4f3386e01bf40d948c239239c2f1e726729/pyzmq-26.4.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5e48a830bfd152fe17fbdeaf99ac5271aa4122521bf0d275b6b24e52ef35eb6", size = 902056, upload-time = "2025-04-04T12:04:03.919Z" }, - { url = "https://files.pythonhosted.org/packages/1a/cf/b36b3d7aea236087d20189bec1a87eeb2b66009731d7055e5c65f845cdba/pyzmq-26.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31be2b6de98c824c06f5574331f805707c667dc8f60cb18580b7de078479891e", size = 860148, upload-time = "2025-04-04T12:04:05.581Z" }, - { url = "https://files.pythonhosted.org/packages/18/a6/f048826bc87528c208e90604c3bf573801e54bd91e390cbd2dfa860e82dc/pyzmq-26.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6332452034be001bbf3206ac59c0d2a7713de5f25bb38b06519fc6967b7cf771", size = 855983, upload-time = "2025-04-04T12:04:07.096Z" }, - { url = "https://files.pythonhosted.org/packages/0a/27/454d34ab6a1d9772a36add22f17f6b85baf7c16e14325fa29e7202ca8ee8/pyzmq-26.4.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:da8c0f5dd352136853e6a09b1b986ee5278dfddfebd30515e16eae425c872b30", size = 1197274, upload-time = "2025-04-04T12:04:08.523Z" }, - { url = "https://files.pythonhosted.org/packages/f4/3d/7abfeab6b83ad38aa34cbd57c6fc29752c391e3954fd12848bd8d2ec0df6/pyzmq-26.4.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f4ccc1a0a2c9806dda2a2dd118a3b7b681e448f3bb354056cad44a65169f6d86", size = 1507120, upload-time = "2025-04-04T12:04:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/13/ff/bc8d21dbb9bc8705126e875438a1969c4f77e03fc8565d6901c7933a3d01/pyzmq-26.4.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1c0b5fceadbab461578daf8d1dcc918ebe7ddd2952f748cf30c7cf2de5d51101", size = 1406738, upload-time = "2025-04-04T12:04:12.509Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5d/d4cd85b24de71d84d81229e3bbb13392b2698432cf8fdcea5afda253d587/pyzmq-26.4.0-cp313-cp313-win32.whl", hash = "sha256:28e2b0ff5ba4b3dd11062d905682bad33385cfa3cc03e81abd7f0822263e6637", size = 577826, upload-time = "2025-04-04T12:04:14.289Z" }, - { url = "https://files.pythonhosted.org/packages/c6/6c/f289c1789d7bb6e5a3b3bef7b2a55089b8561d17132be7d960d3ff33b14e/pyzmq-26.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:23ecc9d241004c10e8b4f49d12ac064cd7000e1643343944a10df98e57bc544b", size = 640406, upload-time = "2025-04-04T12:04:15.757Z" }, - { url = "https://files.pythonhosted.org/packages/b3/99/676b8851cb955eb5236a0c1e9ec679ea5ede092bf8bf2c8a68d7e965cac3/pyzmq-26.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:1edb0385c7f025045d6e0f759d4d3afe43c17a3d898914ec6582e6f464203c08", size = 556216, upload-time = "2025-04-04T12:04:17.212Z" }, - { url = "https://files.pythonhosted.org/packages/65/c2/1fac340de9d7df71efc59d9c50fc7a635a77b103392d1842898dd023afcb/pyzmq-26.4.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:93a29e882b2ba1db86ba5dd5e88e18e0ac6b627026c5cfbec9983422011b82d4", size = 1333769, upload-time = "2025-04-04T12:04:18.665Z" }, - { url = "https://files.pythonhosted.org/packages/5c/c7/6c03637e8d742c3b00bec4f5e4cd9d1c01b2f3694c6f140742e93ca637ed/pyzmq-26.4.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb45684f276f57110bb89e4300c00f1233ca631f08f5f42528a5c408a79efc4a", size = 658826, upload-time = "2025-04-04T12:04:20.405Z" }, - { url = "https://files.pythonhosted.org/packages/a5/97/a8dca65913c0f78e0545af2bb5078aebfc142ca7d91cdaffa1fbc73e5dbd/pyzmq-26.4.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f72073e75260cb301aad4258ad6150fa7f57c719b3f498cb91e31df16784d89b", size = 891650, upload-time = "2025-04-04T12:04:22.413Z" }, - { url = "https://files.pythonhosted.org/packages/7d/7e/f63af1031eb060bf02d033732b910fe48548dcfdbe9c785e9f74a6cc6ae4/pyzmq-26.4.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be37e24b13026cfedd233bcbbccd8c0bcd2fdd186216094d095f60076201538d", size = 849776, upload-time = "2025-04-04T12:04:23.959Z" }, - { url = "https://files.pythonhosted.org/packages/f6/fa/1a009ce582802a895c0d5fe9413f029c940a0a8ee828657a3bb0acffd88b/pyzmq-26.4.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:237b283044934d26f1eeff4075f751b05d2f3ed42a257fc44386d00df6a270cf", size = 842516, upload-time = "2025-04-04T12:04:25.449Z" }, - { url = "https://files.pythonhosted.org/packages/6e/bc/f88b0bad0f7a7f500547d71e99f10336f2314e525d4ebf576a1ea4a1d903/pyzmq-26.4.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b30f862f6768b17040929a68432c8a8be77780317f45a353cb17e423127d250c", size = 1189183, upload-time = "2025-04-04T12:04:27.035Z" }, - { url = "https://files.pythonhosted.org/packages/d9/8c/db446a3dd9cf894406dec2e61eeffaa3c07c3abb783deaebb9812c4af6a5/pyzmq-26.4.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:c80fcd3504232f13617c6ab501124d373e4895424e65de8b72042333316f64a8", size = 1495501, upload-time = "2025-04-04T12:04:28.833Z" }, - { url = "https://files.pythonhosted.org/packages/05/4c/bf3cad0d64c3214ac881299c4562b815f05d503bccc513e3fd4fdc6f67e4/pyzmq-26.4.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:26a2a7451606b87f67cdeca2c2789d86f605da08b4bd616b1a9981605ca3a364", size = 1395540, upload-time = "2025-04-04T12:04:30.562Z" }, - { url = "https://files.pythonhosted.org/packages/06/91/21d3af57bc77e86e9d1e5384f256fd25cdb4c8eed4c45c8119da8120915f/pyzmq-26.4.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:a88643de8abd000ce99ca72056a1a2ae15881ee365ecb24dd1d9111e43d57842", size = 1340634, upload-time = "2025-04-04T12:04:47.661Z" }, - { url = "https://files.pythonhosted.org/packages/54/e6/58cd825023e998a0e49db7322b3211e6cf93f0796710b77d1496304c10d1/pyzmq-26.4.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a744ce209ecb557406fb928f3c8c55ce79b16c3eeb682da38ef5059a9af0848", size = 907880, upload-time = "2025-04-04T12:04:49.294Z" }, - { url = "https://files.pythonhosted.org/packages/72/83/619e44a766ef738cb7e8ed8e5a54565627801bdb027ca6dfb70762385617/pyzmq-26.4.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9434540f333332224ecb02ee6278b6c6f11ea1266b48526e73c903119b2f420f", size = 863003, upload-time = "2025-04-04T12:04:51Z" }, - { url = "https://files.pythonhosted.org/packages/b6/6a/a59af31320598bdc63d2c5a3181d14a89673c2c794540678285482e8a342/pyzmq-26.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6c6f0a23e55cd38d27d4c89add963294ea091ebcb104d7fdab0f093bc5abb1c", size = 673432, upload-time = "2025-04-04T12:04:52.611Z" }, - { url = "https://files.pythonhosted.org/packages/29/ae/64dd6c18b08ce2cb009c60f11cf01c87f323acd80344d8b059c0304a7370/pyzmq-26.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6145df55dc2309f6ef72d70576dcd5aabb0fd373311613fe85a5e547c722b780", size = 1205221, upload-time = "2025-04-04T12:04:54.31Z" }, - { url = "https://files.pythonhosted.org/packages/d0/0b/c583ab750957b025244a66948831bc9ca486d11c820da4626caf6480ee1a/pyzmq-26.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2ea81823840ef8c56e5d2f9918e4d571236294fea4d1842b302aebffb9e40997", size = 1515299, upload-time = "2025-04-04T12:04:56.063Z" }, - { url = "https://files.pythonhosted.org/packages/22/ba/95ba76292c49dd9c6dff1f127b4867033020b708d101cba6e4fc5a3d166d/pyzmq-26.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc2abc385dc37835445abe206524fbc0c9e3fce87631dfaa90918a1ba8f425eb", size = 1415366, upload-time = "2025-04-04T12:04:58.241Z" }, - { url = "https://files.pythonhosted.org/packages/6e/65/51abe36169effda26ac7400ffac96f463e09dff40d344cdc2629d9a59162/pyzmq-26.4.0-cp39-cp39-win32.whl", hash = "sha256:41a2508fe7bed4c76b4cf55aacfb8733926f59d440d9ae2b81ee8220633b4d12", size = 580773, upload-time = "2025-04-04T12:04:59.786Z" }, - { url = "https://files.pythonhosted.org/packages/89/68/d9ac94086c63a0ed8d73e9e8aec54b39f481696698a5a939a7207629fb30/pyzmq-26.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:d4000e8255d6cbce38982e5622ebb90823f3409b7ffe8aeae4337ef7d6d2612a", size = 644340, upload-time = "2025-04-04T12:05:01.389Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8f/66c261d657c1b0791ee5b372c90b1646b453adb581fcdc1dc5c94e5b03e3/pyzmq-26.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f6919d9c120488246bdc2a2f96662fa80d67b35bd6d66218f457e722b3ff64", size = 560075, upload-time = "2025-04-04T12:05:02.975Z" }, - { url = "https://files.pythonhosted.org/packages/47/03/96004704a84095f493be8d2b476641f5c967b269390173f85488a53c1c13/pyzmq-26.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:98d948288ce893a2edc5ec3c438fe8de2daa5bbbd6e2e865ec5f966e237084ba", size = 834408, upload-time = "2025-04-04T12:05:04.569Z" }, - { url = "https://files.pythonhosted.org/packages/e4/7f/68d8f3034a20505db7551cb2260248be28ca66d537a1ac9a257913d778e4/pyzmq-26.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9f34f5c9e0203ece706a1003f1492a56c06c0632d86cb77bcfe77b56aacf27b", size = 569580, upload-time = "2025-04-04T12:05:06.283Z" }, - { url = "https://files.pythonhosted.org/packages/9b/a6/2b0d6801ec33f2b2a19dd8d02e0a1e8701000fec72926e6787363567d30c/pyzmq-26.4.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80c9b48aef586ff8b698359ce22f9508937c799cc1d2c9c2f7c95996f2300c94", size = 798250, upload-time = "2025-04-04T12:05:07.88Z" }, - { url = "https://files.pythonhosted.org/packages/96/2a/0322b3437de977dcac8a755d6d7ce6ec5238de78e2e2d9353730b297cf12/pyzmq-26.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3f2a5b74009fd50b53b26f65daff23e9853e79aa86e0aa08a53a7628d92d44a", size = 756758, upload-time = "2025-04-04T12:05:09.483Z" }, - { url = "https://files.pythonhosted.org/packages/c2/33/43704f066369416d65549ccee366cc19153911bec0154da7c6b41fca7e78/pyzmq-26.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:61c5f93d7622d84cb3092d7f6398ffc77654c346545313a3737e266fc11a3beb", size = 555371, upload-time = "2025-04-04T12:05:11.062Z" }, - { url = "https://files.pythonhosted.org/packages/04/52/a70fcd5592715702248306d8e1729c10742c2eac44529984413b05c68658/pyzmq-26.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4478b14cb54a805088299c25a79f27eaf530564a7a4f72bf432a040042b554eb", size = 834405, upload-time = "2025-04-04T12:05:13.3Z" }, - { url = "https://files.pythonhosted.org/packages/25/f9/1a03f1accff16b3af1a6fa22cbf7ced074776abbf688b2e9cb4629700c62/pyzmq-26.4.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a28ac29c60e4ba84b5f58605ace8ad495414a724fe7aceb7cf06cd0598d04e1", size = 569578, upload-time = "2025-04-04T12:05:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/76/0c/3a633acd762aa6655fcb71fa841907eae0ab1e8582ff494b137266de341d/pyzmq-26.4.0-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43b03c1ceea27c6520124f4fb2ba9c647409b9abdf9a62388117148a90419494", size = 798248, upload-time = "2025-04-04T12:05:17.376Z" }, - { url = "https://files.pythonhosted.org/packages/cd/cc/6c99c84aa60ac1cc56747bed6be8ce6305b9b861d7475772e7a25ce019d3/pyzmq-26.4.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7731abd23a782851426d4e37deb2057bf9410848a4459b5ede4fe89342e687a9", size = 756757, upload-time = "2025-04-04T12:05:19.19Z" }, - { url = "https://files.pythonhosted.org/packages/13/9c/d8073bd898eb896e94c679abe82e47506e2b750eb261cf6010ced869797c/pyzmq-26.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a222ad02fbe80166b0526c038776e8042cd4e5f0dec1489a006a1df47e9040e0", size = 555371, upload-time = "2025-04-04T12:05:20.702Z" }, - { url = "https://files.pythonhosted.org/packages/af/b2/71a644b629e1a93ccae9e22a45aec9d23065dfcc24c399cb837f81cd08c2/pyzmq-26.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:552b0d2e39987733e1e9e948a0ced6ff75e0ea39ab1a1db2fc36eb60fd8760db", size = 834397, upload-time = "2025-04-04T12:05:31.217Z" }, - { url = "https://files.pythonhosted.org/packages/a9/dd/052a25651eaaff8f5fd652fb40a3abb400e71207db2d605cf6faf0eac598/pyzmq-26.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd670a8aa843f2ee637039bbd412e0d7294a5e588e1ecc9ad98b0cdc050259a4", size = 569571, upload-time = "2025-04-04T12:05:32.877Z" }, - { url = "https://files.pythonhosted.org/packages/a5/5d/201ca10b5d12ab187a418352c06d70c3e2087310af038b11056aba1359be/pyzmq-26.4.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d367b7b775a0e1e54a59a2ba3ed4d5e0a31566af97cc9154e34262777dab95ed", size = 798243, upload-time = "2025-04-04T12:05:34.91Z" }, - { url = "https://files.pythonhosted.org/packages/bd/d4/2c64e54749536ad1633400f28d71e71e19375d00ce1fe9bb1123364dc927/pyzmq-26.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112af16c406e4a93df2caef49f884f4c2bb2b558b0b5577ef0b2465d15c1abc", size = 756751, upload-time = "2025-04-04T12:05:37.12Z" }, - { url = "https://files.pythonhosted.org/packages/08/e6/34d119af43d06a8dcd88bf7a62dac69597eaba52b49ecce76ff06b40f1fd/pyzmq-26.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c76c298683f82669cab0b6da59071f55238c039738297c69f187a542c6d40099", size = 745400, upload-time = "2025-04-04T12:05:40.694Z" }, - { url = "https://files.pythonhosted.org/packages/f8/49/b5e471d74a63318e51f30d329b17d2550bdededaab55baed2e2499de7ce4/pyzmq-26.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:49b6ca2e625b46f499fb081aaf7819a177f41eeb555acb05758aa97f4f95d147", size = 555367, upload-time = "2025-04-04T12:05:42.356Z" }, + { url = "https://files.pythonhosted.org/packages/9c/09/1681d4b047626d352c083770618ac29655ab1f5c20eee31dc94c000b9b7b/pyzmq-27.0.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:b973ee650e8f442ce482c1d99ca7ab537c69098d53a3d046676a484fd710c87a", size = 1329291, upload-time = "2025-06-13T14:06:57.945Z" }, + { url = "https://files.pythonhosted.org/packages/9d/b2/9c9385225fdd54db9506ed8accbb9ea63ca813ba59d43d7f282a6a16a30b/pyzmq-27.0.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:661942bc7cd0223d569d808f2e5696d9cc120acc73bf3e88a1f1be7ab648a7e4", size = 905952, upload-time = "2025-06-13T14:07:03.232Z" }, + { url = "https://files.pythonhosted.org/packages/41/73/333c72c7ec182cdffe25649e3da1c3b9f3cf1cede63cfdc23d1384d4a601/pyzmq-27.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50360fb2a056ffd16e5f4177eee67f1dd1017332ea53fb095fe7b5bf29c70246", size = 666165, upload-time = "2025-06-13T14:07:04.667Z" }, + { url = "https://files.pythonhosted.org/packages/a5/fe/fc7b9c1a50981928e25635a926653cb755364316db59ccd6e79cfb9a0b4f/pyzmq-27.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf209a6dc4b420ed32a7093642843cbf8703ed0a7d86c16c0b98af46762ebefb", size = 853755, upload-time = "2025-06-13T14:07:06.93Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4c/740ed4b6e8fa160cd19dc5abec8db68f440564b2d5b79c1d697d9862a2f7/pyzmq-27.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c2dace4a7041cca2fba5357a2d7c97c5effdf52f63a1ef252cfa496875a3762d", size = 1654868, upload-time = "2025-06-13T14:07:08.224Z" }, + { url = "https://files.pythonhosted.org/packages/97/00/875b2ecfcfc78ab962a59bd384995186818524ea957dc8ad3144611fae12/pyzmq-27.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:63af72b2955fc77caf0a77444baa2431fcabb4370219da38e1a9f8d12aaebe28", size = 2033443, upload-time = "2025-06-13T14:07:09.653Z" }, + { url = "https://files.pythonhosted.org/packages/60/55/6dd9c470c42d713297c5f2a56f7903dc1ebdb4ab2edda996445c21651900/pyzmq-27.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e8c4adce8e37e75c4215297d7745551b8dcfa5f728f23ce09bf4e678a9399413", size = 1891288, upload-time = "2025-06-13T14:07:11.099Z" }, + { url = "https://files.pythonhosted.org/packages/28/5d/54b0ef50d40d7c65a627f4a4b4127024ba9820f2af8acd933a4d30ae192e/pyzmq-27.0.0-cp310-cp310-win32.whl", hash = "sha256:5d5ef4718ecab24f785794e0e7536436698b459bfbc19a1650ef55280119d93b", size = 567936, upload-time = "2025-06-13T14:07:12.468Z" }, + { url = "https://files.pythonhosted.org/packages/18/ea/dedca4321de748ca48d3bcdb72274d4d54e8d84ea49088d3de174bd45d88/pyzmq-27.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e40609380480b3d12c30f841323f42451c755b8fece84235236f5fe5ffca8c1c", size = 628686, upload-time = "2025-06-13T14:07:14.051Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a7/fcdeedc306e71e94ac262cba2d02337d885f5cdb7e8efced8e5ffe327808/pyzmq-27.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6b0397b0be277b46762956f576e04dc06ced265759e8c2ff41a0ee1aa0064198", size = 559039, upload-time = "2025-06-13T14:07:15.289Z" }, + { url = "https://files.pythonhosted.org/packages/44/df/84c630654106d9bd9339cdb564aa941ed41b023a0264251d6743766bb50e/pyzmq-27.0.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:21457825249b2a53834fa969c69713f8b5a79583689387a5e7aed880963ac564", size = 1332718, upload-time = "2025-06-13T14:07:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8e/f6a5461a07654d9840d256476434ae0ff08340bba562a455f231969772cb/pyzmq-27.0.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1958947983fef513e6e98eff9cb487b60bf14f588dc0e6bf35fa13751d2c8251", size = 908248, upload-time = "2025-06-13T14:07:18.033Z" }, + { url = "https://files.pythonhosted.org/packages/7c/93/82863e8d695a9a3ae424b63662733ae204a295a2627d52af2f62c2cd8af9/pyzmq-27.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0dc628b5493f9a8cd9844b8bee9732ef587ab00002157c9329e4fc0ef4d3afa", size = 668647, upload-time = "2025-06-13T14:07:19.378Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/15278769b348121eacdbfcbd8c4d40f1102f32fa6af5be1ffc032ed684be/pyzmq-27.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7bbe9e1ed2c8d3da736a15694d87c12493e54cc9dc9790796f0321794bbc91f", size = 856600, upload-time = "2025-06-13T14:07:20.906Z" }, + { url = "https://files.pythonhosted.org/packages/d4/af/1c469b3d479bd095edb28e27f12eee10b8f00b356acbefa6aeb14dd295d1/pyzmq-27.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dc1091f59143b471d19eb64f54bae4f54bcf2a466ffb66fe45d94d8d734eb495", size = 1657748, upload-time = "2025-06-13T14:07:22.549Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f4/17f965d0ee6380b1d6326da842a50e4b8b9699745161207945f3745e8cb5/pyzmq-27.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7011ade88c8e535cf140f8d1a59428676fbbce7c6e54fefce58bf117aefb6667", size = 2034311, upload-time = "2025-06-13T14:07:23.966Z" }, + { url = "https://files.pythonhosted.org/packages/e0/6e/7c391d81fa3149fd759de45d298003de6cfab343fb03e92c099821c448db/pyzmq-27.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c386339d7e3f064213aede5d03d054b237937fbca6dd2197ac8cf3b25a6b14e", size = 1893630, upload-time = "2025-06-13T14:07:25.899Z" }, + { url = "https://files.pythonhosted.org/packages/0e/e0/eaffe7a86f60e556399e224229e7769b717f72fec0706b70ab2c03aa04cb/pyzmq-27.0.0-cp311-cp311-win32.whl", hash = "sha256:0546a720c1f407b2172cb04b6b094a78773491497e3644863cf5c96c42df8cff", size = 567706, upload-time = "2025-06-13T14:07:27.595Z" }, + { url = "https://files.pythonhosted.org/packages/c9/05/89354a8cffdcce6e547d48adaaf7be17007fc75572123ff4ca90a4ca04fc/pyzmq-27.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:15f39d50bd6c9091c67315ceb878a4f531957b121d2a05ebd077eb35ddc5efed", size = 630322, upload-time = "2025-06-13T14:07:28.938Z" }, + { url = "https://files.pythonhosted.org/packages/fa/07/4ab976d5e1e63976719389cc4f3bfd248a7f5f2bb2ebe727542363c61b5f/pyzmq-27.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c5817641eebb391a2268c27fecd4162448e03538387093cdbd8bf3510c316b38", size = 558435, upload-time = "2025-06-13T14:07:30.256Z" }, + { url = "https://files.pythonhosted.org/packages/93/a7/9ad68f55b8834ede477842214feba6a4c786d936c022a67625497aacf61d/pyzmq-27.0.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:cbabc59dcfaac66655c040dfcb8118f133fb5dde185e5fc152628354c1598e52", size = 1305438, upload-time = "2025-06-13T14:07:31.676Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ee/26aa0f98665a22bc90ebe12dced1de5f3eaca05363b717f6fb229b3421b3/pyzmq-27.0.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:cb0ac5179cba4b2f94f1aa208fbb77b62c4c9bf24dd446278b8b602cf85fcda3", size = 895095, upload-time = "2025-06-13T14:07:33.104Z" }, + { url = "https://files.pythonhosted.org/packages/cf/85/c57e7ab216ecd8aa4cc7e3b83b06cc4e9cf45c87b0afc095f10cd5ce87c1/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53a48f0228eab6cbf69fde3aa3c03cbe04e50e623ef92ae395fce47ef8a76152", size = 651826, upload-time = "2025-06-13T14:07:34.831Z" }, + { url = "https://files.pythonhosted.org/packages/69/9a/9ea7e230feda9400fb0ae0d61d7d6ddda635e718d941c44eeab22a179d34/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:111db5f395e09f7e775f759d598f43cb815fc58e0147623c4816486e1a39dc22", size = 839750, upload-time = "2025-06-13T14:07:36.553Z" }, + { url = "https://files.pythonhosted.org/packages/08/66/4cebfbe71f3dfbd417011daca267539f62ed0fbc68105357b68bbb1a25b7/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c8878011653dcdc27cc2c57e04ff96f0471e797f5c19ac3d7813a245bcb24371", size = 1641357, upload-time = "2025-06-13T14:07:38.21Z" }, + { url = "https://files.pythonhosted.org/packages/ac/f6/b0f62578c08d2471c791287149cb8c2aaea414ae98c6e995c7dbe008adfb/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:c0ed2c1f335ba55b5fdc964622254917d6b782311c50e138863eda409fbb3b6d", size = 2020281, upload-time = "2025-06-13T14:07:39.599Z" }, + { url = "https://files.pythonhosted.org/packages/37/b9/4f670b15c7498495da9159edc374ec09c88a86d9cd5a47d892f69df23450/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e918d70862d4cfd4b1c187310015646a14e1f5917922ab45b29f28f345eeb6be", size = 1877110, upload-time = "2025-06-13T14:07:41.027Z" }, + { url = "https://files.pythonhosted.org/packages/66/31/9dee25c226295b740609f0d46db2fe972b23b6f5cf786360980524a3ba92/pyzmq-27.0.0-cp312-abi3-win32.whl", hash = "sha256:88b4e43cab04c3c0f0d55df3b1eef62df2b629a1a369b5289a58f6fa8b07c4f4", size = 559297, upload-time = "2025-06-13T14:07:42.533Z" }, + { url = "https://files.pythonhosted.org/packages/9b/12/52da5509800f7ff2d287b2f2b4e636e7ea0f001181cba6964ff6c1537778/pyzmq-27.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:dce4199bf5f648a902ce37e7b3afa286f305cd2ef7a8b6ec907470ccb6c8b371", size = 619203, upload-time = "2025-06-13T14:07:43.843Z" }, + { url = "https://files.pythonhosted.org/packages/93/6d/7f2e53b19d1edb1eb4f09ec7c3a1f945ca0aac272099eab757d15699202b/pyzmq-27.0.0-cp312-abi3-win_arm64.whl", hash = "sha256:56e46bbb85d52c1072b3f809cc1ce77251d560bc036d3a312b96db1afe76db2e", size = 551927, upload-time = "2025-06-13T14:07:45.51Z" }, + { url = "https://files.pythonhosted.org/packages/19/62/876b27c4ff777db4ceba1c69ea90d3c825bb4f8d5e7cd987ce5802e33c55/pyzmq-27.0.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c36ad534c0c29b4afa088dc53543c525b23c0797e01b69fef59b1a9c0e38b688", size = 1340826, upload-time = "2025-06-13T14:07:46.881Z" }, + { url = "https://files.pythonhosted.org/packages/43/69/58ef8f4f59d3bcd505260c73bee87b008850f45edca40ddaba54273c35f4/pyzmq-27.0.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:67855c14173aec36395d7777aaba3cc527b393821f30143fd20b98e1ff31fd38", size = 897283, upload-time = "2025-06-13T14:07:49.562Z" }, + { url = "https://files.pythonhosted.org/packages/43/15/93a0d0396700a60475ad3c5d42c5f1c308d3570bc94626b86c71ef9953e0/pyzmq-27.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8617c7d43cd8ccdb62aebe984bfed77ca8f036e6c3e46dd3dddda64b10f0ab7a", size = 660567, upload-time = "2025-06-13T14:07:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b3/fe055513e498ca32f64509abae19b9c9eb4d7c829e02bd8997dd51b029eb/pyzmq-27.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:67bfbcbd0a04c575e8103a6061d03e393d9f80ffdb9beb3189261e9e9bc5d5e9", size = 847681, upload-time = "2025-06-13T14:07:52.77Z" }, + { url = "https://files.pythonhosted.org/packages/b6/4f/ff15300b00b5b602191f3df06bbc8dd4164e805fdd65bb77ffbb9c5facdc/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5cd11d46d7b7e5958121b3eaf4cd8638eff3a720ec527692132f05a57f14341d", size = 1650148, upload-time = "2025-06-13T14:07:54.178Z" }, + { url = "https://files.pythonhosted.org/packages/c4/6f/84bdfff2a224a6f26a24249a342e5906993c50b0761e311e81b39aef52a7/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:b801c2e40c5aa6072c2f4876de8dccd100af6d9918d4d0d7aa54a1d982fd4f44", size = 2023768, upload-time = "2025-06-13T14:07:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/64/39/dc2db178c26a42228c5ac94a9cc595030458aa64c8d796a7727947afbf55/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:20d5cb29e8c5f76a127c75b6e7a77e846bc4b655c373baa098c26a61b7ecd0ef", size = 1885199, upload-time = "2025-06-13T14:07:57.166Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/dae7b06a1f8cdee5d8e7a63d99c5d129c401acc40410bef2cbf42025e26f/pyzmq-27.0.0-cp313-cp313t-win32.whl", hash = "sha256:a20528da85c7ac7a19b7384e8c3f8fa707841fd85afc4ed56eda59d93e3d98ad", size = 575439, upload-time = "2025-06-13T14:07:58.959Z" }, + { url = "https://files.pythonhosted.org/packages/eb/bc/1709dc55f0970cf4cb8259e435e6773f9946f41a045c2cb90e870b7072da/pyzmq-27.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d8229f2efece6a660ee211d74d91dbc2a76b95544d46c74c615e491900dc107f", size = 639933, upload-time = "2025-06-13T14:08:00.777Z" }, + { url = "https://files.pythonhosted.org/packages/19/dc/95210fe17e5d7dba89bd663e1d88f50a8003f296284731b09f1d95309a42/pyzmq-27.0.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:100f6e5052ba42b2533011d34a018a5ace34f8cac67cb03cfa37c8bdae0ca617", size = 1330656, upload-time = "2025-06-13T14:08:17.414Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7e/63f742b578316258e03ecb393d35c0964348d80834bdec8a100ed7bb9c91/pyzmq-27.0.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:bf6c6b061efd00404b9750e2cfbd9507492c8d4b3721ded76cb03786131be2ed", size = 906522, upload-time = "2025-06-13T14:08:18.945Z" }, + { url = "https://files.pythonhosted.org/packages/1f/bf/f0b2b67f5a9bfe0fbd0e978a2becd901f802306aa8e29161cb0963094352/pyzmq-27.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee05728c0b0b2484a9fc20466fa776fffb65d95f7317a3419985b8c908563861", size = 863545, upload-time = "2025-06-13T14:08:20.386Z" }, + { url = "https://files.pythonhosted.org/packages/87/0e/7d90ccd2ef577c8bae7f926acd2011a6d960eea8a068c5fd52b419206960/pyzmq-27.0.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7cdf07fe0a557b131366f80727ec8ccc4b70d89f1e3f920d94a594d598d754f0", size = 666796, upload-time = "2025-06-13T14:08:21.836Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6d/ca8007a313baa73361778773aef210f4902e68f468d1f93b6c8b908fabbd/pyzmq-27.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:90252fa2ff3a104219db1f5ced7032a7b5fc82d7c8d2fec2b9a3e6fd4e25576b", size = 1655599, upload-time = "2025-06-13T14:08:23.343Z" }, + { url = "https://files.pythonhosted.org/packages/46/de/5cb4f99d6c0dd8f33d729c9ebd49af279586e5ab127e93aa6ef0ecd08c4c/pyzmq-27.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ea6d441c513bf18c578c73c323acf7b4184507fc244762193aa3a871333c9045", size = 2034119, upload-time = "2025-06-13T14:08:26.369Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8d/57cc90c8b5f30a97a7e86ec91a3b9822ec7859d477e9c30f531fb78f4a97/pyzmq-27.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ae2b34bcfaae20c064948a4113bf8709eee89fd08317eb293ae4ebd69b4d9740", size = 1891955, upload-time = "2025-06-13T14:08:28.39Z" }, + { url = "https://files.pythonhosted.org/packages/24/f5/a7012022573188903802ab75b5314b00e5c629228f3a36fadb421a42ebff/pyzmq-27.0.0-cp39-cp39-win32.whl", hash = "sha256:5b10bd6f008937705cf6e7bf8b6ece5ca055991e3eb130bca8023e20b86aa9a3", size = 568497, upload-time = "2025-06-13T14:08:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f3/2a4b2798275a574801221d94d599ed3e26d19f6378a7364cdfa3bee53944/pyzmq-27.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:00387d12a8af4b24883895f7e6b9495dc20a66027b696536edac35cb988c38f3", size = 629315, upload-time = "2025-06-13T14:08:31.877Z" }, + { url = "https://files.pythonhosted.org/packages/da/eb/386a70314f305816142d6e8537f5557e5fd9614c03698d6c88cbd6c41190/pyzmq-27.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:4c19d39c04c29a6619adfeb19e3735c421b3bfee082f320662f52e59c47202ba", size = 559596, upload-time = "2025-06-13T14:08:33.357Z" }, + { url = "https://files.pythonhosted.org/packages/09/6f/be6523a7f3821c0b5370912ef02822c028611360e0d206dd945bdbf9eaef/pyzmq-27.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:656c1866505a5735d0660b7da6d7147174bbf59d4975fc2b7f09f43c9bc25745", size = 835950, upload-time = "2025-06-13T14:08:35Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1e/a50fdd5c15018de07ab82a61bc460841be967ee7bbe7abee3b714d66f7ac/pyzmq-27.0.0-pp310-pypy310_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:74175b9e12779382432dd1d1f5960ebe7465d36649b98a06c6b26be24d173fab", size = 799876, upload-time = "2025-06-13T14:08:36.849Z" }, + { url = "https://files.pythonhosted.org/packages/88/a1/89eb5b71f5a504f8f887aceb8e1eb3626e00c00aa8085381cdff475440dc/pyzmq-27.0.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8c6de908465697a8708e4d6843a1e884f567962fc61eb1706856545141d0cbb", size = 567400, upload-time = "2025-06-13T14:08:38.95Z" }, + { url = "https://files.pythonhosted.org/packages/56/aa/4571dbcff56cfb034bac73fde8294e123c975ce3eea89aff31bf6dc6382b/pyzmq-27.0.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c644aaacc01d0df5c7072826df45e67301f191c55f68d7b2916d83a9ddc1b551", size = 747031, upload-time = "2025-06-13T14:08:40.413Z" }, + { url = "https://files.pythonhosted.org/packages/46/e0/d25f30fe0991293c5b2f5ef3b070d35fa6d57c0c7428898c3ab4913d0297/pyzmq-27.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:10f70c1d9a446a85013a36871a296007f6fe4232b530aa254baf9da3f8328bc0", size = 544726, upload-time = "2025-06-13T14:08:41.997Z" }, + { url = "https://files.pythonhosted.org/packages/98/a6/92394373b8dbc1edc9d53c951e8d3989d518185174ee54492ec27711779d/pyzmq-27.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd1dc59763effd1576f8368047c9c31468fce0af89d76b5067641137506792ae", size = 835948, upload-time = "2025-06-13T14:08:43.516Z" }, + { url = "https://files.pythonhosted.org/packages/56/f3/4dc38d75d9995bfc18773df3e41f2a2ca9b740b06f1a15dbf404077e7588/pyzmq-27.0.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:60e8cc82d968174650c1860d7b716366caab9973787a1c060cf8043130f7d0f7", size = 799874, upload-time = "2025-06-13T14:08:45.017Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ba/64af397e0f421453dc68e31d5e0784d554bf39013a2de0872056e96e58af/pyzmq-27.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14fe7aaac86e4e93ea779a821967360c781d7ac5115b3f1a171ced77065a0174", size = 567400, upload-time = "2025-06-13T14:08:46.855Z" }, + { url = "https://files.pythonhosted.org/packages/63/87/ec956cbe98809270b59a22891d5758edae147a258e658bf3024a8254c855/pyzmq-27.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6ad0562d4e6abb785be3e4dd68599c41be821b521da38c402bc9ab2a8e7ebc7e", size = 747031, upload-time = "2025-06-13T14:08:48.419Z" }, + { url = "https://files.pythonhosted.org/packages/be/8a/4a3764a68abc02e2fbb0668d225b6fda5cd39586dd099cee8b2ed6ab0452/pyzmq-27.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:9df43a2459cd3a3563404c1456b2c4c69564daa7dbaf15724c09821a3329ce46", size = 544726, upload-time = "2025-06-13T14:08:49.903Z" }, + { url = "https://files.pythonhosted.org/packages/03/f6/11b2a6c8cd13275c31cddc3f89981a1b799a3c41dec55289fa18dede96b5/pyzmq-27.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:39ddd3ba0a641f01d8f13a3cfd4c4924eb58e660d8afe87e9061d6e8ca6f7ac3", size = 835944, upload-time = "2025-06-13T14:08:59.189Z" }, + { url = "https://files.pythonhosted.org/packages/73/34/aa39076f4e07ae1912fa4b966fe24e831e01d736d4c1c7e8a3aa28a555b5/pyzmq-27.0.0-pp39-pypy39_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8ca7e6a0388dd9e1180b14728051068f4efe83e0d2de058b5ff92c63f399a73f", size = 799869, upload-time = "2025-06-13T14:09:00.758Z" }, + { url = "https://files.pythonhosted.org/packages/65/f3/81ed6b3dd242408ee79c0d8a88734644acf208baee8666ecd7e52664cf55/pyzmq-27.0.0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2524c40891be6a3106885a3935d58452dd83eb7a5742a33cc780a1ad4c49dec0", size = 758371, upload-time = "2025-06-13T14:09:02.461Z" }, + { url = "https://files.pythonhosted.org/packages/e1/04/dac4ca674764281caf744e8adefd88f7e325e1605aba0f9a322094b903fa/pyzmq-27.0.0-pp39-pypy39_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a56e3e5bd2d62a01744fd2f1ce21d760c7c65f030e9522738d75932a14ab62a", size = 567393, upload-time = "2025-06-13T14:09:04.037Z" }, + { url = "https://files.pythonhosted.org/packages/51/8b/619a9ee2fa4d3c724fbadde946427735ade64da03894b071bbdc3b789d83/pyzmq-27.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:096af9e133fec3a72108ddefba1e42985cb3639e9de52cfd336b6fc23aa083e9", size = 544715, upload-time = "2025-06-13T14:09:05.579Z" }, ] [[package]] @@ -2642,7 +2622,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -2650,9 +2630,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -2690,151 +2670,178 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.25.1" +version = "0.26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/aa/4456d84bbb54adc6a916fb10c9b374f78ac840337644e4a5eda229c81275/rpds_py-0.26.0.tar.gz", hash = "sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0", size = 27385, upload-time = "2025-07-01T15:57:13.958Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/09/e1158988e50905b7f8306487a576b52d32aa9a87f79f7ab24ee8db8b6c05/rpds_py-0.25.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9", size = 373140, upload-time = "2025-05-21T12:42:38.834Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4b/a284321fb3c45c02fc74187171504702b2934bfe16abab89713eedfe672e/rpds_py-0.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40", size = 358860, upload-time = "2025-05-21T12:42:41.394Z" }, - { url = "https://files.pythonhosted.org/packages/4e/46/8ac9811150c75edeae9fc6fa0e70376c19bc80f8e1f7716981433905912b/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f", size = 386179, upload-time = "2025-05-21T12:42:43.213Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ec/87eb42d83e859bce91dcf763eb9f2ab117142a49c9c3d17285440edb5b69/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b", size = 400282, upload-time = "2025-05-21T12:42:44.92Z" }, - { url = "https://files.pythonhosted.org/packages/68/c8/2a38e0707d7919c8c78e1d582ab15cf1255b380bcb086ca265b73ed6db23/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa", size = 521824, upload-time = "2025-05-21T12:42:46.856Z" }, - { url = "https://files.pythonhosted.org/packages/5e/2c/6a92790243569784dde84d144bfd12bd45102f4a1c897d76375076d730ab/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e", size = 411644, upload-time = "2025-05-21T12:42:48.838Z" }, - { url = "https://files.pythonhosted.org/packages/eb/76/66b523ffc84cf47db56efe13ae7cf368dee2bacdec9d89b9baca5e2e6301/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da", size = 386955, upload-time = "2025-05-21T12:42:50.835Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b9/a362d7522feaa24dc2b79847c6175daa1c642817f4a19dcd5c91d3e2c316/rpds_py-0.25.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380", size = 421039, upload-time = "2025-05-21T12:42:52.348Z" }, - { url = "https://files.pythonhosted.org/packages/0f/c4/b5b6f70b4d719b6584716889fd3413102acf9729540ee76708d56a76fa97/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9", size = 563290, upload-time = "2025-05-21T12:42:54.404Z" }, - { url = "https://files.pythonhosted.org/packages/87/a3/2e6e816615c12a8f8662c9d8583a12eb54c52557521ef218cbe3095a8afa/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54", size = 592089, upload-time = "2025-05-21T12:42:55.976Z" }, - { url = "https://files.pythonhosted.org/packages/c0/08/9b8e1050e36ce266135994e2c7ec06e1841f1c64da739daeb8afe9cb77a4/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2", size = 558400, upload-time = "2025-05-21T12:42:58.032Z" }, - { url = "https://files.pythonhosted.org/packages/f2/df/b40b8215560b8584baccd839ff5c1056f3c57120d79ac41bd26df196da7e/rpds_py-0.25.1-cp310-cp310-win32.whl", hash = "sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24", size = 219741, upload-time = "2025-05-21T12:42:59.479Z" }, - { url = "https://files.pythonhosted.org/packages/10/99/e4c58be18cf5d8b40b8acb4122bc895486230b08f978831b16a3916bd24d/rpds_py-0.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a", size = 231553, upload-time = "2025-05-21T12:43:01.425Z" }, - { url = "https://files.pythonhosted.org/packages/95/e1/df13fe3ddbbea43567e07437f097863b20c99318ae1f58a0fe389f763738/rpds_py-0.25.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d", size = 373341, upload-time = "2025-05-21T12:43:02.978Z" }, - { url = "https://files.pythonhosted.org/packages/7a/58/deef4d30fcbcbfef3b6d82d17c64490d5c94585a2310544ce8e2d3024f83/rpds_py-0.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255", size = 359111, upload-time = "2025-05-21T12:43:05.128Z" }, - { url = "https://files.pythonhosted.org/packages/bb/7e/39f1f4431b03e96ebaf159e29a0f82a77259d8f38b2dd474721eb3a8ac9b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2", size = 386112, upload-time = "2025-05-21T12:43:07.13Z" }, - { url = "https://files.pythonhosted.org/packages/db/e7/847068a48d63aec2ae695a1646089620b3b03f8ccf9f02c122ebaf778f3c/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0", size = 400362, upload-time = "2025-05-21T12:43:08.693Z" }, - { url = "https://files.pythonhosted.org/packages/3b/3d/9441d5db4343d0cee759a7ab4d67420a476cebb032081763de934719727b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f", size = 522214, upload-time = "2025-05-21T12:43:10.694Z" }, - { url = "https://files.pythonhosted.org/packages/a2/ec/2cc5b30d95f9f1a432c79c7a2f65d85e52812a8f6cbf8768724571710786/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7", size = 411491, upload-time = "2025-05-21T12:43:12.739Z" }, - { url = "https://files.pythonhosted.org/packages/dc/6c/44695c1f035077a017dd472b6a3253553780837af2fac9b6ac25f6a5cb4d/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd", size = 386978, upload-time = "2025-05-21T12:43:14.25Z" }, - { url = "https://files.pythonhosted.org/packages/b1/74/b4357090bb1096db5392157b4e7ed8bb2417dc7799200fcbaee633a032c9/rpds_py-0.25.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65", size = 420662, upload-time = "2025-05-21T12:43:15.8Z" }, - { url = "https://files.pythonhosted.org/packages/26/dd/8cadbebf47b96e59dfe8b35868e5c38a42272699324e95ed522da09d3a40/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f", size = 563385, upload-time = "2025-05-21T12:43:17.78Z" }, - { url = "https://files.pythonhosted.org/packages/c3/ea/92960bb7f0e7a57a5ab233662f12152085c7dc0d5468534c65991a3d48c9/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d", size = 592047, upload-time = "2025-05-21T12:43:19.457Z" }, - { url = "https://files.pythonhosted.org/packages/61/ad/71aabc93df0d05dabcb4b0c749277881f8e74548582d96aa1bf24379493a/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042", size = 557863, upload-time = "2025-05-21T12:43:21.69Z" }, - { url = "https://files.pythonhosted.org/packages/93/0f/89df0067c41f122b90b76f3660028a466eb287cbe38efec3ea70e637ca78/rpds_py-0.25.1-cp311-cp311-win32.whl", hash = "sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc", size = 219627, upload-time = "2025-05-21T12:43:23.311Z" }, - { url = "https://files.pythonhosted.org/packages/7c/8d/93b1a4c1baa903d0229374d9e7aa3466d751f1d65e268c52e6039c6e338e/rpds_py-0.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4", size = 231603, upload-time = "2025-05-21T12:43:25.145Z" }, - { url = "https://files.pythonhosted.org/packages/cb/11/392605e5247bead2f23e6888e77229fbd714ac241ebbebb39a1e822c8815/rpds_py-0.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4", size = 223967, upload-time = "2025-05-21T12:43:26.566Z" }, - { url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647, upload-time = "2025-05-21T12:43:28.559Z" }, - { url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454, upload-time = "2025-05-21T12:43:30.615Z" }, - { url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665, upload-time = "2025-05-21T12:43:32.629Z" }, - { url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873, upload-time = "2025-05-21T12:43:34.576Z" }, - { url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866, upload-time = "2025-05-21T12:43:36.123Z" }, - { url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886, upload-time = "2025-05-21T12:43:38.034Z" }, - { url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666, upload-time = "2025-05-21T12:43:40.065Z" }, - { url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109, upload-time = "2025-05-21T12:43:42.263Z" }, - { url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244, upload-time = "2025-05-21T12:43:43.846Z" }, - { url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023, upload-time = "2025-05-21T12:43:45.932Z" }, - { url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634, upload-time = "2025-05-21T12:43:48.263Z" }, - { url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713, upload-time = "2025-05-21T12:43:49.897Z" }, - { url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280, upload-time = "2025-05-21T12:43:51.893Z" }, - { url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399, upload-time = "2025-05-21T12:43:53.351Z" }, - { url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498, upload-time = "2025-05-21T12:43:54.841Z" }, - { url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083, upload-time = "2025-05-21T12:43:56.428Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023, upload-time = "2025-05-21T12:43:57.995Z" }, - { url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283, upload-time = "2025-05-21T12:43:59.546Z" }, - { url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634, upload-time = "2025-05-21T12:44:01.087Z" }, - { url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233, upload-time = "2025-05-21T12:44:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375, upload-time = "2025-05-21T12:44:04.162Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537, upload-time = "2025-05-21T12:44:06.175Z" }, - { url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425, upload-time = "2025-05-21T12:44:08.242Z" }, - { url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197, upload-time = "2025-05-21T12:44:10.449Z" }, - { url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244, upload-time = "2025-05-21T12:44:12.387Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254, upload-time = "2025-05-21T12:44:14.261Z" }, - { url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741, upload-time = "2025-05-21T12:44:16.236Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830, upload-time = "2025-05-21T12:44:17.749Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668, upload-time = "2025-05-21T12:44:19.322Z" }, - { url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649, upload-time = "2025-05-21T12:44:20.962Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776, upload-time = "2025-05-21T12:44:22.516Z" }, - { url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131, upload-time = "2025-05-21T12:44:24.147Z" }, - { url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942, upload-time = "2025-05-21T12:44:25.915Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330, upload-time = "2025-05-21T12:44:27.638Z" }, - { url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339, upload-time = "2025-05-21T12:44:29.292Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077, upload-time = "2025-05-21T12:44:30.877Z" }, - { url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441, upload-time = "2025-05-21T12:44:32.541Z" }, - { url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750, upload-time = "2025-05-21T12:44:34.557Z" }, - { url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891, upload-time = "2025-05-21T12:44:37.358Z" }, - { url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718, upload-time = "2025-05-21T12:44:38.969Z" }, - { url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218, upload-time = "2025-05-21T12:44:40.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/74/716d42058ef501e2c08f27aa3ff455f6fc1bbbd19a6ab8dea07e6322d217/rpds_py-0.25.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ce4c8e485a3c59593f1a6f683cf0ea5ab1c1dc94d11eea5619e4fb5228b40fbd", size = 373475, upload-time = "2025-05-21T12:44:42.136Z" }, - { url = "https://files.pythonhosted.org/packages/e1/21/3faa9c523e2496a2505d7440b6f24c9166f37cb7ac027cac6cfbda9b4b5f/rpds_py-0.25.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8222acdb51a22929c3b2ddb236b69c59c72af4019d2cba961e2f9add9b6e634", size = 359349, upload-time = "2025-05-21T12:44:43.813Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1c/c747fe568d21b1d679079b52b926ebc4d1497457510a1773dc5fd4b7b4e2/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4593c4eae9b27d22df41cde518b4b9e4464d139e4322e2127daa9b5b981b76be", size = 386526, upload-time = "2025-05-21T12:44:45.452Z" }, - { url = "https://files.pythonhosted.org/packages/0b/cc/4a41703de4fb291f13660fa3d882cbd39db5d60497c6e7fa7f5142e5e69f/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd035756830c712b64725a76327ce80e82ed12ebab361d3a1cdc0f51ea21acb0", size = 400526, upload-time = "2025-05-21T12:44:47.011Z" }, - { url = "https://files.pythonhosted.org/packages/f1/78/60c980bedcad8418b614f0b4d6d420ecf11225b579cec0cb4e84d168b4da/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:114a07e85f32b125404f28f2ed0ba431685151c037a26032b213c882f26eb908", size = 525726, upload-time = "2025-05-21T12:44:48.838Z" }, - { url = "https://files.pythonhosted.org/packages/3f/37/f2f36b7f1314b3c3200d663decf2f8e29480492a39ab22447112aead4693/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dec21e02e6cc932538b5203d3a8bd6aa1480c98c4914cb88eea064ecdbc6396a", size = 412045, upload-time = "2025-05-21T12:44:50.433Z" }, - { url = "https://files.pythonhosted.org/packages/df/96/e03783e87a775b1242477ccbc35895f8e9b2bbdb60e199034a6da03c2687/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09eab132f41bf792c7a0ea1578e55df3f3e7f61888e340779b06050a9a3f16e9", size = 386953, upload-time = "2025-05-21T12:44:52.092Z" }, - { url = "https://files.pythonhosted.org/packages/7c/7d/1418f4b69bfb4b40481a3d84782113ad7d4cca0b38ae70b982dd5b20102a/rpds_py-0.25.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c98f126c4fc697b84c423e387337d5b07e4a61e9feac494362a59fd7a2d9ed80", size = 421144, upload-time = "2025-05-21T12:44:53.734Z" }, - { url = "https://files.pythonhosted.org/packages/b3/0e/61469912c6493ee3808012e60f4930344b974fcb6b35c4348e70b6be7bc7/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0e6a327af8ebf6baba1c10fadd04964c1965d375d318f4435d5f3f9651550f4a", size = 563730, upload-time = "2025-05-21T12:44:55.846Z" }, - { url = "https://files.pythonhosted.org/packages/f6/86/6d0a5cc56481ac61977b7c839677ed5c63d38cf0fcb3e2280843a8a6f476/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc120d1132cff853ff617754196d0ac0ae63befe7c8498bd67731ba368abe451", size = 592321, upload-time = "2025-05-21T12:44:57.514Z" }, - { url = "https://files.pythonhosted.org/packages/5d/87/d1e2453fe336f71e6aa296452a8c85c2118b587b1d25ce98014f75838a60/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:140f61d9bed7839446bdd44852e30195c8e520f81329b4201ceead4d64eb3a9f", size = 558162, upload-time = "2025-05-21T12:44:59.564Z" }, - { url = "https://files.pythonhosted.org/packages/ad/92/349f04b1644c5cef3e2e6c53b7168a28531945f9e6fca7425f6d20ddbc3c/rpds_py-0.25.1-cp39-cp39-win32.whl", hash = "sha256:9c006f3aadeda131b438c3092124bd196b66312f0caa5823ef09585a669cf449", size = 219920, upload-time = "2025-05-21T12:45:01.186Z" }, - { url = "https://files.pythonhosted.org/packages/f2/84/3969bef883a3f37ff2213795257cb7b7e93a115829670befb8de0e003031/rpds_py-0.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:a61d0b2c7c9a0ae45732a77844917b427ff16ad5464b4d4f5e4adb955f582890", size = 231452, upload-time = "2025-05-21T12:45:02.85Z" }, - { url = "https://files.pythonhosted.org/packages/78/ff/566ce53529b12b4f10c0a348d316bd766970b7060b4fd50f888be3b3b281/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28", size = 373931, upload-time = "2025-05-21T12:45:05.01Z" }, - { url = "https://files.pythonhosted.org/packages/83/5d/deba18503f7c7878e26aa696e97f051175788e19d5336b3b0e76d3ef9256/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f", size = 359074, upload-time = "2025-05-21T12:45:06.714Z" }, - { url = "https://files.pythonhosted.org/packages/0d/74/313415c5627644eb114df49c56a27edba4d40cfd7c92bd90212b3604ca84/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13", size = 387255, upload-time = "2025-05-21T12:45:08.669Z" }, - { url = "https://files.pythonhosted.org/packages/8c/c8/c723298ed6338963d94e05c0f12793acc9b91d04ed7c4ba7508e534b7385/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d", size = 400714, upload-time = "2025-05-21T12:45:10.39Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/51f1f6aa653c2e110ed482ef2ae94140d56c910378752a1b483af11019ee/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000", size = 523105, upload-time = "2025-05-21T12:45:12.273Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a4/7873d15c088ad3bff36910b29ceb0f178e4b3232c2adbe9198de68a41e63/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540", size = 411499, upload-time = "2025-05-21T12:45:13.95Z" }, - { url = "https://files.pythonhosted.org/packages/90/f3/0ce1437befe1410766d11d08239333ac1b2d940f8a64234ce48a7714669c/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b", size = 387918, upload-time = "2025-05-21T12:45:15.649Z" }, - { url = "https://files.pythonhosted.org/packages/94/d4/5551247988b2a3566afb8a9dba3f1d4a3eea47793fd83000276c1a6c726e/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e", size = 421705, upload-time = "2025-05-21T12:45:17.788Z" }, - { url = "https://files.pythonhosted.org/packages/b0/25/5960f28f847bf736cc7ee3c545a7e1d2f3b5edaf82c96fb616c2f5ed52d0/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8", size = 564489, upload-time = "2025-05-21T12:45:19.466Z" }, - { url = "https://files.pythonhosted.org/packages/02/66/1c99884a0d44e8c2904d3c4ec302f995292d5dde892c3bf7685ac1930146/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8", size = 592557, upload-time = "2025-05-21T12:45:21.362Z" }, - { url = "https://files.pythonhosted.org/packages/55/ae/4aeac84ebeffeac14abb05b3bb1d2f728d00adb55d3fb7b51c9fa772e760/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11", size = 558691, upload-time = "2025-05-21T12:45:23.084Z" }, - { url = "https://files.pythonhosted.org/packages/41/b3/728a08ff6f5e06fe3bb9af2e770e9d5fd20141af45cff8dfc62da4b2d0b3/rpds_py-0.25.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a", size = 231651, upload-time = "2025-05-21T12:45:24.72Z" }, - { url = "https://files.pythonhosted.org/packages/49/74/48f3df0715a585cbf5d34919c9c757a4c92c1a9eba059f2d334e72471f70/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954", size = 374208, upload-time = "2025-05-21T12:45:26.306Z" }, - { url = "https://files.pythonhosted.org/packages/55/b0/9b01bb11ce01ec03d05e627249cc2c06039d6aa24ea5a22a39c312167c10/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba", size = 359262, upload-time = "2025-05-21T12:45:28.322Z" }, - { url = "https://files.pythonhosted.org/packages/a9/eb/5395621618f723ebd5116c53282052943a726dba111b49cd2071f785b665/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b", size = 387366, upload-time = "2025-05-21T12:45:30.42Z" }, - { url = "https://files.pythonhosted.org/packages/68/73/3d51442bdb246db619d75039a50ea1cf8b5b4ee250c3e5cd5c3af5981cd4/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038", size = 400759, upload-time = "2025-05-21T12:45:32.516Z" }, - { url = "https://files.pythonhosted.org/packages/b7/4c/3a32d5955d7e6cb117314597bc0f2224efc798428318b13073efe306512a/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9", size = 523128, upload-time = "2025-05-21T12:45:34.396Z" }, - { url = "https://files.pythonhosted.org/packages/be/95/1ffccd3b0bb901ae60b1dd4b1be2ab98bb4eb834cd9b15199888f5702f7b/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1", size = 411597, upload-time = "2025-05-21T12:45:36.164Z" }, - { url = "https://files.pythonhosted.org/packages/ef/6d/6e6cd310180689db8b0d2de7f7d1eabf3fb013f239e156ae0d5a1a85c27f/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762", size = 388053, upload-time = "2025-05-21T12:45:38.45Z" }, - { url = "https://files.pythonhosted.org/packages/4a/87/ec4186b1fe6365ced6fa470960e68fc7804bafbe7c0cf5a36237aa240efa/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e", size = 421821, upload-time = "2025-05-21T12:45:40.732Z" }, - { url = "https://files.pythonhosted.org/packages/7a/60/84f821f6bf4e0e710acc5039d91f8f594fae0d93fc368704920d8971680d/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692", size = 564534, upload-time = "2025-05-21T12:45:42.672Z" }, - { url = "https://files.pythonhosted.org/packages/41/3a/bc654eb15d3b38f9330fe0f545016ba154d89cdabc6177b0295910cd0ebe/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf", size = 592674, upload-time = "2025-05-21T12:45:44.533Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ba/31239736f29e4dfc7a58a45955c5db852864c306131fd6320aea214d5437/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe", size = 558781, upload-time = "2025-05-21T12:45:46.281Z" }, - { url = "https://files.pythonhosted.org/packages/78/b2/198266f070c6760e0e8cd00f9f2b9c86133ceebbe7c6d114bdcfea200180/rpds_py-0.25.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:50f2c501a89c9a5f4e454b126193c5495b9fb441a75b298c60591d8a2eb92e1b", size = 373973, upload-time = "2025-05-21T12:45:48.081Z" }, - { url = "https://files.pythonhosted.org/packages/13/79/1265eae618f88aa5d5e7122bd32dd41700bafe5a8bcea404e998848cd844/rpds_py-0.25.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d779b325cc8238227c47fbc53964c8cc9a941d5dbae87aa007a1f08f2f77b23", size = 359326, upload-time = "2025-05-21T12:45:49.825Z" }, - { url = "https://files.pythonhosted.org/packages/30/ab/6913b96f3ac072e87e76e45fe938263b0ab0d78b6b2cef3f2e56067befc0/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:036ded36bedb727beeabc16dc1dad7cb154b3fa444e936a03b67a86dc6a5066e", size = 387544, upload-time = "2025-05-21T12:45:51.764Z" }, - { url = "https://files.pythonhosted.org/packages/b0/23/129ed12d25229acc6deb8cbe90baadd8762e563c267c9594eb2fcc15be0c/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:245550f5a1ac98504147cba96ffec8fabc22b610742e9150138e5d60774686d7", size = 400240, upload-time = "2025-05-21T12:45:54.061Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e0/6811a38a5efa46b7ee6ed2103c95cb9abb16991544c3b69007aa679b6944/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff7c23ba0a88cb7b104281a99476cccadf29de2a0ef5ce864959a52675b1ca83", size = 525599, upload-time = "2025-05-21T12:45:56.457Z" }, - { url = "https://files.pythonhosted.org/packages/6c/10/2dc88bcaa0d86bdb59e017a330b1972ffeeb7f5061bb5a180c9a2bb73bbf/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e37caa8cdb3b7cf24786451a0bdb853f6347b8b92005eeb64225ae1db54d1c2b", size = 411154, upload-time = "2025-05-21T12:45:58.525Z" }, - { url = "https://files.pythonhosted.org/packages/cf/d1/a72d522eb7d934fb33e9c501e6ecae00e2035af924d4ff37d964e9a3959b/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2f48ab00181600ee266a095fe815134eb456163f7d6699f525dee471f312cf", size = 388297, upload-time = "2025-05-21T12:46:00.264Z" }, - { url = "https://files.pythonhosted.org/packages/55/90/0dd7169ec74f042405b6b73512200d637a3088c156f64e1c07c18aa2fe59/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e5fc7484fa7dce57e25063b0ec9638ff02a908304f861d81ea49273e43838c1", size = 421894, upload-time = "2025-05-21T12:46:02.065Z" }, - { url = "https://files.pythonhosted.org/packages/37/e9/45170894add451783ed839c5c4a495e050aa8baa06d720364d9dff394dac/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d3c10228d6cf6fe2b63d2e7985e94f6916fa46940df46b70449e9ff9297bd3d1", size = 564409, upload-time = "2025-05-21T12:46:03.891Z" }, - { url = "https://files.pythonhosted.org/packages/59/d0/31cece9090e76fbdb50c758c165d40da604b03b37c3ba53f010bbfeb130a/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:5d9e40f32745db28c1ef7aad23f6fc458dc1e29945bd6781060f0d15628b8ddf", size = 592681, upload-time = "2025-05-21T12:46:06.009Z" }, - { url = "https://files.pythonhosted.org/packages/f1/4c/22ef535efb2beec614ba7be83e62b439eb83b0b0d7b1775e22d35af3f9b5/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:35a8d1a24b5936b35c5003313bc177403d8bdef0f8b24f28b1c4a255f94ea992", size = 558744, upload-time = "2025-05-21T12:46:07.78Z" }, - { url = "https://files.pythonhosted.org/packages/79/ff/f2150efc8daf0581d4dfaf0a2a30b08088b6df900230ee5ae4f7c8cd5163/rpds_py-0.25.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6099263f526efff9cf3883dfef505518730f7a7a93049b1d90d42e50a22b4793", size = 231305, upload-time = "2025-05-21T12:46:10.52Z" }, + { url = "https://files.pythonhosted.org/packages/b9/31/1459645f036c3dfeacef89e8e5825e430c77dde8489f3b99eaafcd4a60f5/rpds_py-0.26.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37", size = 372466, upload-time = "2025-07-01T15:53:40.55Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ff/3d0727f35836cc8773d3eeb9a46c40cc405854e36a8d2e951f3a8391c976/rpds_py-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0", size = 357825, upload-time = "2025-07-01T15:53:42.247Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/badc5e06120a54099ae287fa96d82cbb650a5f85cf247ffe19c7b157fd1f/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd", size = 381530, upload-time = "2025-07-01T15:53:43.585Z" }, + { url = "https://files.pythonhosted.org/packages/1e/a5/fa5d96a66c95d06c62d7a30707b6a4cfec696ab8ae280ee7be14e961e118/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79", size = 396933, upload-time = "2025-07-01T15:53:45.78Z" }, + { url = "https://files.pythonhosted.org/packages/00/a7/7049d66750f18605c591a9db47d4a059e112a0c9ff8de8daf8fa0f446bba/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3", size = 513973, upload-time = "2025-07-01T15:53:47.085Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f1/528d02c7d6b29d29fac8fd784b354d3571cc2153f33f842599ef0cf20dd2/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf", size = 402293, upload-time = "2025-07-01T15:53:48.117Z" }, + { url = "https://files.pythonhosted.org/packages/15/93/fde36cd6e4685df2cd08508f6c45a841e82f5bb98c8d5ecf05649522acb5/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc", size = 383787, upload-time = "2025-07-01T15:53:50.874Z" }, + { url = "https://files.pythonhosted.org/packages/69/f2/5007553aaba1dcae5d663143683c3dfd03d9395289f495f0aebc93e90f24/rpds_py-0.26.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19", size = 416312, upload-time = "2025-07-01T15:53:52.046Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/ce52c75c1e624a79e48a69e611f1c08844564e44c85db2b6f711d76d10ce/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11", size = 558403, upload-time = "2025-07-01T15:53:53.192Z" }, + { url = "https://files.pythonhosted.org/packages/79/d5/e119db99341cc75b538bf4cb80504129fa22ce216672fb2c28e4a101f4d9/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f", size = 588323, upload-time = "2025-07-01T15:53:54.336Z" }, + { url = "https://files.pythonhosted.org/packages/93/94/d28272a0b02f5fe24c78c20e13bbcb95f03dc1451b68e7830ca040c60bd6/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323", size = 554541, upload-time = "2025-07-01T15:53:55.469Z" }, + { url = "https://files.pythonhosted.org/packages/93/e0/8c41166602f1b791da892d976057eba30685486d2e2c061ce234679c922b/rpds_py-0.26.0-cp310-cp310-win32.whl", hash = "sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45", size = 220442, upload-time = "2025-07-01T15:53:56.524Z" }, + { url = "https://files.pythonhosted.org/packages/87/f0/509736bb752a7ab50fb0270c2a4134d671a7b3038030837e5536c3de0e0b/rpds_py-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84", size = 231314, upload-time = "2025-07-01T15:53:57.842Z" }, + { url = "https://files.pythonhosted.org/packages/09/4c/4ee8f7e512030ff79fda1df3243c88d70fc874634e2dbe5df13ba4210078/rpds_py-0.26.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed", size = 372610, upload-time = "2025-07-01T15:53:58.844Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9d/3dc16be00f14fc1f03c71b1d67c8df98263ab2710a2fbd65a6193214a527/rpds_py-0.26.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0", size = 358032, upload-time = "2025-07-01T15:53:59.985Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5a/7f1bf8f045da2866324a08ae80af63e64e7bfaf83bd31f865a7b91a58601/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1", size = 381525, upload-time = "2025-07-01T15:54:01.162Z" }, + { url = "https://files.pythonhosted.org/packages/45/8a/04479398c755a066ace10e3d158866beb600867cacae194c50ffa783abd0/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7", size = 397089, upload-time = "2025-07-01T15:54:02.319Z" }, + { url = "https://files.pythonhosted.org/packages/72/88/9203f47268db488a1b6d469d69c12201ede776bb728b9d9f29dbfd7df406/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6", size = 514255, upload-time = "2025-07-01T15:54:03.38Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b4/01ce5d1e853ddf81fbbd4311ab1eff0b3cf162d559288d10fd127e2588b5/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e", size = 402283, upload-time = "2025-07-01T15:54:04.923Z" }, + { url = "https://files.pythonhosted.org/packages/34/a2/004c99936997bfc644d590a9defd9e9c93f8286568f9c16cdaf3e14429a7/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d", size = 383881, upload-time = "2025-07-01T15:54:06.482Z" }, + { url = "https://files.pythonhosted.org/packages/05/1b/ef5fba4a8f81ce04c427bfd96223f92f05e6cd72291ce9d7523db3b03a6c/rpds_py-0.26.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3", size = 415822, upload-time = "2025-07-01T15:54:07.605Z" }, + { url = "https://files.pythonhosted.org/packages/16/80/5c54195aec456b292f7bd8aa61741c8232964063fd8a75fdde9c1e982328/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107", size = 558347, upload-time = "2025-07-01T15:54:08.591Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/1845c1b1fd6d827187c43afe1841d91678d7241cbdb5420a4c6de180a538/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a", size = 587956, upload-time = "2025-07-01T15:54:09.963Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ff/9e979329dd131aa73a438c077252ddabd7df6d1a7ad7b9aacf6261f10faa/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318", size = 554363, upload-time = "2025-07-01T15:54:11.073Z" }, + { url = "https://files.pythonhosted.org/packages/00/8b/d78cfe034b71ffbe72873a136e71acc7a831a03e37771cfe59f33f6de8a2/rpds_py-0.26.0-cp311-cp311-win32.whl", hash = "sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a", size = 220123, upload-time = "2025-07-01T15:54:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/94/c1/3c8c94c7dd3905dbfde768381ce98778500a80db9924731d87ddcdb117e9/rpds_py-0.26.0-cp311-cp311-win_amd64.whl", hash = "sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03", size = 231732, upload-time = "2025-07-01T15:54:13.434Z" }, + { url = "https://files.pythonhosted.org/packages/67/93/e936fbed1b734eabf36ccb5d93c6a2e9246fbb13c1da011624b7286fae3e/rpds_py-0.26.0-cp311-cp311-win_arm64.whl", hash = "sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41", size = 221917, upload-time = "2025-07-01T15:54:14.559Z" }, + { url = "https://files.pythonhosted.org/packages/ea/86/90eb87c6f87085868bd077c7a9938006eb1ce19ed4d06944a90d3560fce2/rpds_py-0.26.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d", size = 363933, upload-time = "2025-07-01T15:54:15.734Z" }, + { url = "https://files.pythonhosted.org/packages/63/78/4469f24d34636242c924626082b9586f064ada0b5dbb1e9d096ee7a8e0c6/rpds_py-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136", size = 350447, upload-time = "2025-07-01T15:54:16.922Z" }, + { url = "https://files.pythonhosted.org/packages/ad/91/c448ed45efdfdade82348d5e7995e15612754826ea640afc20915119734f/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582", size = 384711, upload-time = "2025-07-01T15:54:18.101Z" }, + { url = "https://files.pythonhosted.org/packages/ec/43/e5c86fef4be7f49828bdd4ecc8931f0287b1152c0bb0163049b3218740e7/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e", size = 400865, upload-time = "2025-07-01T15:54:19.295Z" }, + { url = "https://files.pythonhosted.org/packages/55/34/e00f726a4d44f22d5c5fe2e5ddd3ac3d7fd3f74a175607781fbdd06fe375/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15", size = 517763, upload-time = "2025-07-01T15:54:20.858Z" }, + { url = "https://files.pythonhosted.org/packages/52/1c/52dc20c31b147af724b16104500fba13e60123ea0334beba7b40e33354b4/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8", size = 406651, upload-time = "2025-07-01T15:54:22.508Z" }, + { url = "https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a", size = 386079, upload-time = "2025-07-01T15:54:23.987Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d4/7f2200c2d3ee145b65b3cddc4310d51f7da6a26634f3ac87125fd789152a/rpds_py-0.26.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323", size = 421379, upload-time = "2025-07-01T15:54:25.073Z" }, + { url = "https://files.pythonhosted.org/packages/ae/13/9fdd428b9c820869924ab62236b8688b122baa22d23efdd1c566938a39ba/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158", size = 562033, upload-time = "2025-07-01T15:54:26.225Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e1/b69686c3bcbe775abac3a4c1c30a164a2076d28df7926041f6c0eb5e8d28/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3", size = 591639, upload-time = "2025-07-01T15:54:27.424Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c9/1e3d8c8863c84a90197ac577bbc3d796a92502124c27092413426f670990/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2", size = 557105, upload-time = "2025-07-01T15:54:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c5/90c569649057622959f6dcc40f7b516539608a414dfd54b8d77e3b201ac0/rpds_py-0.26.0-cp312-cp312-win32.whl", hash = "sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44", size = 223272, upload-time = "2025-07-01T15:54:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/16/19f5d9f2a556cfed454eebe4d354c38d51c20f3db69e7b4ce6cff904905d/rpds_py-0.26.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c", size = 234995, upload-time = "2025-07-01T15:54:32.195Z" }, + { url = "https://files.pythonhosted.org/packages/83/f0/7935e40b529c0e752dfaa7880224771b51175fce08b41ab4a92eb2fbdc7f/rpds_py-0.26.0-cp312-cp312-win_arm64.whl", hash = "sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8", size = 223198, upload-time = "2025-07-01T15:54:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/6a/67/bb62d0109493b12b1c6ab00de7a5566aa84c0e44217c2d94bee1bd370da9/rpds_py-0.26.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:696764a5be111b036256c0b18cd29783fab22154690fc698062fc1b0084b511d", size = 363917, upload-time = "2025-07-01T15:54:34.755Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f3/34e6ae1925a5706c0f002a8d2d7f172373b855768149796af87bd65dcdb9/rpds_py-0.26.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e6c15d2080a63aaed876e228efe4f814bc7889c63b1e112ad46fdc8b368b9e1", size = 350073, upload-time = "2025-07-01T15:54:36.292Z" }, + { url = "https://files.pythonhosted.org/packages/75/83/1953a9d4f4e4de7fd0533733e041c28135f3c21485faaef56a8aadbd96b5/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390e3170babf42462739a93321e657444f0862c6d722a291accc46f9d21ed04e", size = 384214, upload-time = "2025-07-01T15:54:37.469Z" }, + { url = "https://files.pythonhosted.org/packages/48/0e/983ed1b792b3322ea1d065e67f4b230f3b96025f5ce3878cc40af09b7533/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7da84c2c74c0f5bc97d853d9e17bb83e2dcafcff0dc48286916001cc114379a1", size = 400113, upload-time = "2025-07-01T15:54:38.954Z" }, + { url = "https://files.pythonhosted.org/packages/69/7f/36c0925fff6f660a80be259c5b4f5e53a16851f946eb080351d057698528/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c5fe114a6dd480a510b6d3661d09d67d1622c4bf20660a474507aaee7eeeee9", size = 515189, upload-time = "2025-07-01T15:54:40.57Z" }, + { url = "https://files.pythonhosted.org/packages/13/45/cbf07fc03ba7a9b54662c9badb58294ecfb24f828b9732970bd1a431ed5c/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3100b3090269f3a7ea727b06a6080d4eb7439dca4c0e91a07c5d133bb1727ea7", size = 406998, upload-time = "2025-07-01T15:54:43.025Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b0/8fa5e36e58657997873fd6a1cf621285ca822ca75b4b3434ead047daa307/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c03c9b0c64afd0320ae57de4c982801271c0c211aa2d37f3003ff5feb75bb04", size = 385903, upload-time = "2025-07-01T15:54:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f7/b25437772f9f57d7a9fbd73ed86d0dcd76b4c7c6998348c070d90f23e315/rpds_py-0.26.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5963b72ccd199ade6ee493723d18a3f21ba7d5b957017607f815788cef50eaf1", size = 419785, upload-time = "2025-07-01T15:54:46.043Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/63ffa55743dfcb4baf2e9e77a0b11f7f97ed96a54558fcb5717a4b2cd732/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da4e873860ad5bab3291438525cae80169daecbfafe5657f7f5fb4d6b3f96b9", size = 561329, upload-time = "2025-07-01T15:54:47.64Z" }, + { url = "https://files.pythonhosted.org/packages/2f/07/1f4f5e2886c480a2346b1e6759c00278b8a69e697ae952d82ae2e6ee5db0/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5afaddaa8e8c7f1f7b4c5c725c0070b6eed0228f705b90a1732a48e84350f4e9", size = 590875, upload-time = "2025-07-01T15:54:48.9Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/e6639f1b91c3a55f8c41b47d73e6307051b6e246254a827ede730624c0f8/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4916dc96489616a6f9667e7526af8fa693c0fdb4f3acb0e5d9f4400eb06a47ba", size = 556636, upload-time = "2025-07-01T15:54:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/05/4c/b3917c45566f9f9a209d38d9b54a1833f2bb1032a3e04c66f75726f28876/rpds_py-0.26.0-cp313-cp313-win32.whl", hash = "sha256:2a343f91b17097c546b93f7999976fd6c9d5900617aa848c81d794e062ab302b", size = 222663, upload-time = "2025-07-01T15:54:52.023Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0b/0851bdd6025775aaa2365bb8de0697ee2558184c800bfef8d7aef5ccde58/rpds_py-0.26.0-cp313-cp313-win_amd64.whl", hash = "sha256:0a0b60701f2300c81b2ac88a5fb893ccfa408e1c4a555a77f908a2596eb875a5", size = 234428, upload-time = "2025-07-01T15:54:53.692Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e8/a47c64ed53149c75fb581e14a237b7b7cd18217e969c30d474d335105622/rpds_py-0.26.0-cp313-cp313-win_arm64.whl", hash = "sha256:257d011919f133a4746958257f2c75238e3ff54255acd5e3e11f3ff41fd14256", size = 222571, upload-time = "2025-07-01T15:54:54.822Z" }, + { url = "https://files.pythonhosted.org/packages/89/bf/3d970ba2e2bcd17d2912cb42874107390f72873e38e79267224110de5e61/rpds_py-0.26.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:529c8156d7506fba5740e05da8795688f87119cce330c244519cf706a4a3d618", size = 360475, upload-time = "2025-07-01T15:54:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/82/9f/283e7e2979fc4ec2d8ecee506d5a3675fce5ed9b4b7cb387ea5d37c2f18d/rpds_py-0.26.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f53ec51f9d24e9638a40cabb95078ade8c99251945dad8d57bf4aabe86ecee35", size = 346692, upload-time = "2025-07-01T15:54:58.561Z" }, + { url = "https://files.pythonhosted.org/packages/e3/03/7e50423c04d78daf391da3cc4330bdb97042fc192a58b186f2d5deb7befd/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab504c4d654e4a29558eaa5bb8cea5fdc1703ea60a8099ffd9c758472cf913f", size = 379415, upload-time = "2025-07-01T15:54:59.751Z" }, + { url = "https://files.pythonhosted.org/packages/57/00/d11ee60d4d3b16808432417951c63df803afb0e0fc672b5e8d07e9edaaae/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd0641abca296bc1a00183fe44f7fced8807ed49d501f188faa642d0e4975b83", size = 391783, upload-time = "2025-07-01T15:55:00.898Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/1069c394d9c0d6d23c5b522e1f6546b65793a22950f6e0210adcc6f97c3e/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b312fecc1d017b5327afa81d4da1480f51c68810963a7336d92203dbb3d4f1", size = 512844, upload-time = "2025-07-01T15:55:02.201Z" }, + { url = "https://files.pythonhosted.org/packages/08/3b/c4fbf0926800ed70b2c245ceca99c49f066456755f5d6eb8863c2c51e6d0/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c741107203954f6fc34d3066d213d0a0c40f7bb5aafd698fb39888af277c70d8", size = 402105, upload-time = "2025-07-01T15:55:03.698Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b0/db69b52ca07413e568dae9dc674627a22297abb144c4d6022c6d78f1e5cc/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc3e55a7db08dc9a6ed5fb7103019d2c1a38a349ac41901f9f66d7f95750942f", size = 383440, upload-time = "2025-07-01T15:55:05.398Z" }, + { url = "https://files.pythonhosted.org/packages/4c/e1/c65255ad5b63903e56b3bb3ff9dcc3f4f5c3badde5d08c741ee03903e951/rpds_py-0.26.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e851920caab2dbcae311fd28f4313c6953993893eb5c1bb367ec69d9a39e7ed", size = 412759, upload-time = "2025-07-01T15:55:08.316Z" }, + { url = "https://files.pythonhosted.org/packages/e4/22/bb731077872377a93c6e93b8a9487d0406c70208985831034ccdeed39c8e/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dfbf280da5f876d0b00c81f26bedce274e72a678c28845453885a9b3c22ae632", size = 556032, upload-time = "2025-07-01T15:55:09.52Z" }, + { url = "https://files.pythonhosted.org/packages/e0/8b/393322ce7bac5c4530fb96fc79cc9ea2f83e968ff5f6e873f905c493e1c4/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1cc81d14ddfa53d7f3906694d35d54d9d3f850ef8e4e99ee68bc0d1e5fed9a9c", size = 585416, upload-time = "2025-07-01T15:55:11.216Z" }, + { url = "https://files.pythonhosted.org/packages/49/ae/769dc372211835bf759319a7aae70525c6eb523e3371842c65b7ef41c9c6/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dca83c498b4650a91efcf7b88d669b170256bf8017a5db6f3e06c2bf031f57e0", size = 554049, upload-time = "2025-07-01T15:55:13.004Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f9/4c43f9cc203d6ba44ce3146246cdc38619d92c7bd7bad4946a3491bd5b70/rpds_py-0.26.0-cp313-cp313t-win32.whl", hash = "sha256:4d11382bcaf12f80b51d790dee295c56a159633a8e81e6323b16e55d81ae37e9", size = 218428, upload-time = "2025-07-01T15:55:14.486Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8b/9286b7e822036a4a977f2f1e851c7345c20528dbd56b687bb67ed68a8ede/rpds_py-0.26.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff110acded3c22c033e637dd8896e411c7d3a11289b2edf041f86663dbc791e9", size = 231524, upload-time = "2025-07-01T15:55:15.745Z" }, + { url = "https://files.pythonhosted.org/packages/55/07/029b7c45db910c74e182de626dfdae0ad489a949d84a468465cd0ca36355/rpds_py-0.26.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:da619979df60a940cd434084355c514c25cf8eb4cf9a508510682f6c851a4f7a", size = 364292, upload-time = "2025-07-01T15:55:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/13/d1/9b3d3f986216b4d1f584878dca15ce4797aaf5d372d738974ba737bf68d6/rpds_py-0.26.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea89a2458a1a75f87caabefe789c87539ea4e43b40f18cff526052e35bbb4fdf", size = 350334, upload-time = "2025-07-01T15:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/18/98/16d5e7bc9ec715fa9668731d0cf97f6b032724e61696e2db3d47aeb89214/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feac1045b3327a45944e7dcbeb57530339f6b17baff154df51ef8b0da34c8c12", size = 384875, upload-time = "2025-07-01T15:55:20.399Z" }, + { url = "https://files.pythonhosted.org/packages/f9/13/aa5e2b1ec5ab0e86a5c464d53514c0467bec6ba2507027d35fc81818358e/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b818a592bd69bfe437ee8368603d4a2d928c34cffcdf77c2e761a759ffd17d20", size = 399993, upload-time = "2025-07-01T15:55:21.729Z" }, + { url = "https://files.pythonhosted.org/packages/17/03/8021810b0e97923abdbab6474c8b77c69bcb4b2c58330777df9ff69dc559/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a8b0dd8648709b62d9372fc00a57466f5fdeefed666afe3fea5a6c9539a0331", size = 516683, upload-time = "2025-07-01T15:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b1/da8e61c87c2f3d836954239fdbbfb477bb7b54d74974d8f6fcb34342d166/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d3498ad0df07d81112aa6ec6c95a7e7b1ae00929fb73e7ebee0f3faaeabad2f", size = 408825, upload-time = "2025-07-01T15:55:24.207Z" }, + { url = "https://files.pythonhosted.org/packages/38/bc/1fc173edaaa0e52c94b02a655db20697cb5fa954ad5a8e15a2c784c5cbdd/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4146ccb15be237fdef10f331c568e1b0e505f8c8c9ed5d67759dac58ac246", size = 387292, upload-time = "2025-07-01T15:55:25.554Z" }, + { url = "https://files.pythonhosted.org/packages/7c/eb/3a9bb4bd90867d21916f253caf4f0d0be7098671b6715ad1cead9fe7bab9/rpds_py-0.26.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a9a63785467b2d73635957d32a4f6e73d5e4df497a16a6392fa066b753e87387", size = 420435, upload-time = "2025-07-01T15:55:27.798Z" }, + { url = "https://files.pythonhosted.org/packages/cd/16/e066dcdb56f5632713445271a3f8d3d0b426d51ae9c0cca387799df58b02/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:de4ed93a8c91debfd5a047be327b7cc8b0cc6afe32a716bbbc4aedca9e2a83af", size = 562410, upload-time = "2025-07-01T15:55:29.057Z" }, + { url = "https://files.pythonhosted.org/packages/60/22/ddbdec7eb82a0dc2e455be44c97c71c232983e21349836ce9f272e8a3c29/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:caf51943715b12af827696ec395bfa68f090a4c1a1d2509eb4e2cb69abbbdb33", size = 590724, upload-time = "2025-07-01T15:55:30.719Z" }, + { url = "https://files.pythonhosted.org/packages/2c/b4/95744085e65b7187d83f2fcb0bef70716a1ea0a9e5d8f7f39a86e5d83424/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4a59e5bc386de021f56337f757301b337d7ab58baa40174fb150accd480bc953", size = 558285, upload-time = "2025-07-01T15:55:31.981Z" }, + { url = "https://files.pythonhosted.org/packages/37/37/6309a75e464d1da2559446f9c811aa4d16343cebe3dbb73701e63f760caa/rpds_py-0.26.0-cp314-cp314-win32.whl", hash = "sha256:92c8db839367ef16a662478f0a2fe13e15f2227da3c1430a782ad0f6ee009ec9", size = 223459, upload-time = "2025-07-01T15:55:33.312Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6f/8e9c11214c46098b1d1391b7e02b70bb689ab963db3b19540cba17315291/rpds_py-0.26.0-cp314-cp314-win_amd64.whl", hash = "sha256:b0afb8cdd034150d4d9f53926226ed27ad15b7f465e93d7468caaf5eafae0d37", size = 236083, upload-time = "2025-07-01T15:55:34.933Z" }, + { url = "https://files.pythonhosted.org/packages/47/af/9c4638994dd623d51c39892edd9d08e8be8220a4b7e874fa02c2d6e91955/rpds_py-0.26.0-cp314-cp314-win_arm64.whl", hash = "sha256:ca3f059f4ba485d90c8dc75cb5ca897e15325e4e609812ce57f896607c1c0867", size = 223291, upload-time = "2025-07-01T15:55:36.202Z" }, + { url = "https://files.pythonhosted.org/packages/4d/db/669a241144460474aab03e254326b32c42def83eb23458a10d163cb9b5ce/rpds_py-0.26.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5afea17ab3a126006dc2f293b14ffc7ef3c85336cf451564a0515ed7648033da", size = 361445, upload-time = "2025-07-01T15:55:37.483Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/133f61cc5807c6c2fd086a46df0eb8f63a23f5df8306ff9f6d0fd168fecc/rpds_py-0.26.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:69f0c0a3df7fd3a7eec50a00396104bb9a843ea6d45fcc31c2d5243446ffd7a7", size = 347206, upload-time = "2025-07-01T15:55:38.828Z" }, + { url = "https://files.pythonhosted.org/packages/05/bf/0e8fb4c05f70273469eecf82f6ccf37248558526a45321644826555db31b/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:801a71f70f9813e82d2513c9a96532551fce1e278ec0c64610992c49c04c2dad", size = 380330, upload-time = "2025-07-01T15:55:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a8/060d24185d8b24d3923322f8d0ede16df4ade226a74e747b8c7c978e3dd3/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df52098cde6d5e02fa75c1f6244f07971773adb4a26625edd5c18fee906fa84d", size = 392254, upload-time = "2025-07-01T15:55:42.015Z" }, + { url = "https://files.pythonhosted.org/packages/b9/7b/7c2e8a9ee3e6bc0bae26bf29f5219955ca2fbb761dca996a83f5d2f773fe/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bc596b30f86dc6f0929499c9e574601679d0341a0108c25b9b358a042f51bca", size = 516094, upload-time = "2025-07-01T15:55:43.603Z" }, + { url = "https://files.pythonhosted.org/packages/75/d6/f61cafbed8ba1499b9af9f1777a2a199cd888f74a96133d8833ce5eaa9c5/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dfbe56b299cf5875b68eb6f0ebaadc9cac520a1989cac0db0765abfb3709c19", size = 402889, upload-time = "2025-07-01T15:55:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/92/19/c8ac0a8a8df2dd30cdec27f69298a5c13e9029500d6d76718130f5e5be10/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac64f4b2bdb4ea622175c9ab7cf09444e412e22c0e02e906978b3b488af5fde8", size = 384301, upload-time = "2025-07-01T15:55:47.098Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/6b1859898bc292a9ce5776016c7312b672da00e25cec74d7beced1027286/rpds_py-0.26.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:181ef9b6bbf9845a264f9aa45c31836e9f3c1f13be565d0d010e964c661d1e2b", size = 412891, upload-time = "2025-07-01T15:55:48.412Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b9/ceb39af29913c07966a61367b3c08b4f71fad841e32c6b59a129d5974698/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:49028aa684c144ea502a8e847d23aed5e4c2ef7cadfa7d5eaafcb40864844b7a", size = 557044, upload-time = "2025-07-01T15:55:49.816Z" }, + { url = "https://files.pythonhosted.org/packages/2f/27/35637b98380731a521f8ec4f3fd94e477964f04f6b2f8f7af8a2d889a4af/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e5d524d68a474a9688336045bbf76cb0def88549c1b2ad9dbfec1fb7cfbe9170", size = 585774, upload-time = "2025-07-01T15:55:51.192Z" }, + { url = "https://files.pythonhosted.org/packages/52/d9/3f0f105420fecd18551b678c9a6ce60bd23986098b252a56d35781b3e7e9/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1851f429b822831bd2edcbe0cfd12ee9ea77868f8d3daf267b189371671c80e", size = 554886, upload-time = "2025-07-01T15:55:52.541Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c5/347c056a90dc8dd9bc240a08c527315008e1b5042e7a4cf4ac027be9d38a/rpds_py-0.26.0-cp314-cp314t-win32.whl", hash = "sha256:7bdb17009696214c3b66bb3590c6d62e14ac5935e53e929bcdbc5a495987a84f", size = 219027, upload-time = "2025-07-01T15:55:53.874Z" }, + { url = "https://files.pythonhosted.org/packages/75/04/5302cea1aa26d886d34cadbf2dc77d90d7737e576c0065f357b96dc7a1a6/rpds_py-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f14440b9573a6f76b4ee4770c13f0b5921f71dde3b6fcb8dabbefd13b7fe05d7", size = 232821, upload-time = "2025-07-01T15:55:55.167Z" }, + { url = "https://files.pythonhosted.org/packages/fb/74/846ab687119c9d31fc21ab1346ef9233c31035ce53c0e2d43a130a0c5a5e/rpds_py-0.26.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:7a48af25d9b3c15684059d0d1fc0bc30e8eee5ca521030e2bffddcab5be40226", size = 372786, upload-time = "2025-07-01T15:55:56.512Z" }, + { url = "https://files.pythonhosted.org/packages/33/02/1f9e465cb1a6032d02b17cd117c7bd9fb6156bc5b40ffeb8053d8a2aa89c/rpds_py-0.26.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c71c2f6bf36e61ee5c47b2b9b5d47e4d1baad6426bfed9eea3e858fc6ee8806", size = 358062, upload-time = "2025-07-01T15:55:58.084Z" }, + { url = "https://files.pythonhosted.org/packages/2a/49/81a38e3c67ac943907a9711882da3d87758c82cf26b2120b8128e45d80df/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d815d48b1804ed7867b539236b6dd62997850ca1c91cad187f2ddb1b7bbef19", size = 381576, upload-time = "2025-07-01T15:55:59.422Z" }, + { url = "https://files.pythonhosted.org/packages/14/37/418f030a76ef59f41e55f9dc916af8afafa3c9e3be38df744b2014851474/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84cfbd4d4d2cdeb2be61a057a258d26b22877266dd905809e94172dff01a42ae", size = 397062, upload-time = "2025-07-01T15:56:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/47/e3/9090817a8f4388bfe58e28136e9682fa7872a06daff2b8a2f8c78786a6e1/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbaa70553ca116c77717f513e08815aec458e6b69a028d4028d403b3bc84ff37", size = 516277, upload-time = "2025-07-01T15:56:02.672Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3a/1ec3dd93250fb8023f27d49b3f92e13f679141f2e59a61563f88922c2821/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39bfea47c375f379d8e87ab4bb9eb2c836e4f2069f0f65731d85e55d74666387", size = 402604, upload-time = "2025-07-01T15:56:04.453Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/9133c06e42ec3ce637936263c50ac647f879b40a35cfad2f5d4ad418a439/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1533b7eb683fb5f38c1d68a3c78f5fdd8f1412fa6b9bf03b40f450785a0ab915", size = 383664, upload-time = "2025-07-01T15:56:05.823Z" }, + { url = "https://files.pythonhosted.org/packages/a9/10/a59ce64099cc77c81adb51f06909ac0159c19a3e2c9d9613bab171f4730f/rpds_py-0.26.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c5ab0ee51f560d179b057555b4f601b7df909ed31312d301b99f8b9fc6028284", size = 415944, upload-time = "2025-07-01T15:56:07.132Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f1/ae0c60b3be9df9d5bef3527d83b8eb4b939e3619f6dd8382840e220a27df/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e5162afc9e0d1f9cae3b577d9c29ddbab3505ab39012cb794d94a005825bde21", size = 558311, upload-time = "2025-07-01T15:56:08.484Z" }, + { url = "https://files.pythonhosted.org/packages/fb/2b/bf1498ebb3ddc5eff2fe3439da88963d1fc6e73d1277fa7ca0c72620d167/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:43f10b007033f359bc3fa9cd5e6c1e76723f056ffa9a6b5c117cc35720a80292", size = 587928, upload-time = "2025-07-01T15:56:09.946Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/e6b949edf7af5629848c06d6e544a36c9f2781e2d8d03b906de61ada04d0/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e3730a48e5622e598293eee0762b09cff34dd3f271530f47b0894891281f051d", size = 554554, upload-time = "2025-07-01T15:56:11.775Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1c/aa0298372ea898620d4706ad26b5b9e975550a4dd30bd042b0fe9ae72cce/rpds_py-0.26.0-cp39-cp39-win32.whl", hash = "sha256:4b1f66eb81eab2e0ff5775a3a312e5e2e16bf758f7b06be82fb0d04078c7ac51", size = 220273, upload-time = "2025-07-01T15:56:13.273Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b0/8b3bef6ad0b35c172d1c87e2e5c2bb027d99e2a7bc7a16f744e66cf318f3/rpds_py-0.26.0-cp39-cp39-win_amd64.whl", hash = "sha256:519067e29f67b5c90e64fb1a6b6e9d2ec0ba28705c51956637bac23a2f4ddae1", size = 231627, upload-time = "2025-07-01T15:56:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/ef/9a/1f033b0b31253d03d785b0cd905bc127e555ab496ea6b4c7c2e1f951f2fd/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958", size = 373226, upload-time = "2025-07-01T15:56:16.578Z" }, + { url = "https://files.pythonhosted.org/packages/58/29/5f88023fd6aaaa8ca3c4a6357ebb23f6f07da6079093ccf27c99efce87db/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e", size = 359230, upload-time = "2025-07-01T15:56:17.978Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6c/13eaebd28b439da6964dde22712b52e53fe2824af0223b8e403249d10405/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08", size = 382363, upload-time = "2025-07-01T15:56:19.977Z" }, + { url = "https://files.pythonhosted.org/packages/55/fc/3bb9c486b06da19448646f96147796de23c5811ef77cbfc26f17307b6a9d/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6", size = 397146, upload-time = "2025-07-01T15:56:21.39Z" }, + { url = "https://files.pythonhosted.org/packages/15/18/9d1b79eb4d18e64ba8bba9e7dec6f9d6920b639f22f07ee9368ca35d4673/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871", size = 514804, upload-time = "2025-07-01T15:56:22.78Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5a/175ad7191bdbcd28785204621b225ad70e85cdfd1e09cc414cb554633b21/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4", size = 402820, upload-time = "2025-07-01T15:56:24.584Z" }, + { url = "https://files.pythonhosted.org/packages/11/45/6a67ecf6d61c4d4aff4bc056e864eec4b2447787e11d1c2c9a0242c6e92a/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f", size = 384567, upload-time = "2025-07-01T15:56:26.064Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ba/16589da828732b46454c61858950a78fe4c931ea4bf95f17432ffe64b241/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73", size = 416520, upload-time = "2025-07-01T15:56:27.608Z" }, + { url = "https://files.pythonhosted.org/packages/81/4b/00092999fc7c0c266045e984d56b7314734cc400a6c6dc4d61a35f135a9d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f", size = 559362, upload-time = "2025-07-01T15:56:29.078Z" }, + { url = "https://files.pythonhosted.org/packages/96/0c/43737053cde1f93ac4945157f7be1428724ab943e2132a0d235a7e161d4e/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84", size = 588113, upload-time = "2025-07-01T15:56:30.485Z" }, + { url = "https://files.pythonhosted.org/packages/46/46/8e38f6161466e60a997ed7e9951ae5de131dedc3cf778ad35994b4af823d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b", size = 555429, upload-time = "2025-07-01T15:56:31.956Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ac/65da605e9f1dd643ebe615d5bbd11b6efa1d69644fc4bf623ea5ae385a82/rpds_py-0.26.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8", size = 231950, upload-time = "2025-07-01T15:56:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/51/f2/b5c85b758a00c513bb0389f8fc8e61eb5423050c91c958cdd21843faa3e6/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674", size = 373505, upload-time = "2025-07-01T15:56:34.716Z" }, + { url = "https://files.pythonhosted.org/packages/23/e0/25db45e391251118e915e541995bb5f5ac5691a3b98fb233020ba53afc9b/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696", size = 359468, upload-time = "2025-07-01T15:56:36.219Z" }, + { url = "https://files.pythonhosted.org/packages/0b/73/dd5ee6075bb6491be3a646b301dfd814f9486d924137a5098e61f0487e16/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb", size = 382680, upload-time = "2025-07-01T15:56:37.644Z" }, + { url = "https://files.pythonhosted.org/packages/2f/10/84b522ff58763a5c443f5bcedc1820240e454ce4e620e88520f04589e2ea/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88", size = 397035, upload-time = "2025-07-01T15:56:39.241Z" }, + { url = "https://files.pythonhosted.org/packages/06/ea/8667604229a10a520fcbf78b30ccc278977dcc0627beb7ea2c96b3becef0/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8", size = 514922, upload-time = "2025-07-01T15:56:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/24/e6/9ed5b625c0661c4882fc8cdf302bf8e96c73c40de99c31e0b95ed37d508c/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5", size = 402822, upload-time = "2025-07-01T15:56:42.137Z" }, + { url = "https://files.pythonhosted.org/packages/8a/58/212c7b6fd51946047fb45d3733da27e2fa8f7384a13457c874186af691b1/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7", size = 384336, upload-time = "2025-07-01T15:56:44.239Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f5/a40ba78748ae8ebf4934d4b88e77b98497378bc2c24ba55ebe87a4e87057/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b", size = 416871, upload-time = "2025-07-01T15:56:46.284Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a6/33b1fc0c9f7dcfcfc4a4353daa6308b3ece22496ceece348b3e7a7559a09/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb", size = 559439, upload-time = "2025-07-01T15:56:48.549Z" }, + { url = "https://files.pythonhosted.org/packages/71/2d/ceb3f9c12f8cfa56d34995097f6cd99da1325642c60d1b6680dd9df03ed8/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0", size = 588380, upload-time = "2025-07-01T15:56:50.086Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ed/9de62c2150ca8e2e5858acf3f4f4d0d180a38feef9fdab4078bea63d8dba/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c", size = 555334, upload-time = "2025-07-01T15:56:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/7e/78/a08e2f28e91c7e45db1150813c6d760a0fb114d5652b1373897073369e0d/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a90a13408a7a856b87be8a9f008fff53c5080eea4e4180f6c2e546e4a972fb5d", size = 373157, upload-time = "2025-07-01T15:56:53.291Z" }, + { url = "https://files.pythonhosted.org/packages/52/01/ddf51517497c8224fb0287e9842b820ed93748bc28ea74cab56a71e3dba4/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ac51b65e8dc76cf4949419c54c5528adb24fc721df722fd452e5fbc236f5c40", size = 358827, upload-time = "2025-07-01T15:56:54.963Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f4/acaefa44b83705a4fcadd68054280127c07cdb236a44a1c08b7c5adad40b/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59b2093224a18c6508d95cfdeba8db9cbfd6f3494e94793b58972933fcee4c6d", size = 382182, upload-time = "2025-07-01T15:56:56.474Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a2/d72ac03d37d33f6ff4713ca4c704da0c3b1b3a959f0bf5eb738c0ad94ea2/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f01a5d6444a3258b00dc07b6ea4733e26f8072b788bef750baa37b370266137", size = 397123, upload-time = "2025-07-01T15:56:58.272Z" }, + { url = "https://files.pythonhosted.org/packages/74/58/c053e9d1da1d3724434dd7a5f506623913e6404d396ff3cf636a910c0789/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6e2c12160c72aeda9d1283e612f68804621f448145a210f1bf1d79151c47090", size = 516285, upload-time = "2025-07-01T15:57:00.283Z" }, + { url = "https://files.pythonhosted.org/packages/94/41/c81e97ee88b38b6d1847c75f2274dee8d67cb8d5ed7ca8c6b80442dead75/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb28c1f569f8d33b2b5dcd05d0e6ef7005d8639c54c2f0be824f05aedf715255", size = 402182, upload-time = "2025-07-01T15:57:02.587Z" }, + { url = "https://files.pythonhosted.org/packages/74/74/38a176b34ce5197b4223e295f36350dd90713db13cf3c3b533e8e8f7484e/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1766b5724c3f779317d5321664a343c07773c8c5fd1532e4039e6cc7d1a815be", size = 384436, upload-time = "2025-07-01T15:57:04.125Z" }, + { url = "https://files.pythonhosted.org/packages/e4/21/f40b9a5709d7078372c87fd11335469dc4405245528b60007cd4078ed57a/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b6d9e5a2ed9c4988c8f9b28b3bc0e3e5b1aaa10c28d210a594ff3a8c02742daf", size = 417039, upload-time = "2025-07-01T15:57:05.608Z" }, + { url = "https://files.pythonhosted.org/packages/02/ee/ed835925731c7e87306faa80a3a5e17b4d0f532083155e7e00fe1cd4e242/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7a446ddaf6ca0fad9a5535b56fbfc29998bf0e0b450d174bbec0d600e1d72", size = 559111, upload-time = "2025-07-01T15:57:07.371Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/d6e9e686b8ffb6139b82eb1c319ef32ae99aeb21f7e4bf45bba44a760d09/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:eed5ac260dd545fbc20da5f4f15e7efe36a55e0e7cf706e4ec005b491a9546a0", size = 588609, upload-time = "2025-07-01T15:57:09.319Z" }, + { url = "https://files.pythonhosted.org/packages/e5/96/09bcab08fa12a69672716b7f86c672ee7f79c5319f1890c5a79dcb8e0df2/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:582462833ba7cee52e968b0341b85e392ae53d44c0f9af6a5927c80e539a8b67", size = 555212, upload-time = "2025-07-01T15:57:10.905Z" }, + { url = "https://files.pythonhosted.org/packages/2c/07/c554b6ed0064b6e0350a622714298e930b3cf5a3d445a2e25c412268abcf/rpds_py-0.26.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69a607203441e07e9a8a529cff1d5b73f6a160f22db1097211e6212a68567d11", size = 232048, upload-time = "2025-07-01T15:57:12.473Z" }, ] [[package]] name = "ruff" -version = "0.11.12" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/0a/92416b159ec00cdf11e5882a9d80d29bf84bba3dbebc51c4898bfbca1da6/ruff-0.11.12.tar.gz", hash = "sha256:43cf7f69c7d7c7d7513b9d59c5d8cafd704e05944f978614aa9faff6ac202603", size = 4202289, upload-time = "2025-05-29T13:31:40.037Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/cc/53eb79f012d15e136d40a8e8fc519ba8f55a057f60b29c2df34efd47c6e3/ruff-0.11.12-py3-none-linux_armv6l.whl", hash = "sha256:c7680aa2f0d4c4f43353d1e72123955c7a2159b8646cd43402de6d4a3a25d7cc", size = 10285597, upload-time = "2025-05-29T13:30:57.539Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d7/73386e9fb0232b015a23f62fea7503f96e29c29e6c45461d4a73bac74df9/ruff-0.11.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2cad64843da9f134565c20bcc430642de897b8ea02e2e79e6e02a76b8dcad7c3", size = 11053154, upload-time = "2025-05-29T13:31:00.865Z" }, - { url = "https://files.pythonhosted.org/packages/4e/eb/3eae144c5114e92deb65a0cb2c72326c8469e14991e9bc3ec0349da1331c/ruff-0.11.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9b6886b524a1c659cee1758140138455d3c029783d1b9e643f3624a5ee0cb0aa", size = 10403048, upload-time = "2025-05-29T13:31:03.413Z" }, - { url = "https://files.pythonhosted.org/packages/29/64/20c54b20e58b1058db6689e94731f2a22e9f7abab74e1a758dfba058b6ca/ruff-0.11.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc3a3690aad6e86c1958d3ec3c38c4594b6ecec75c1f531e84160bd827b2012", size = 10597062, upload-time = "2025-05-29T13:31:05.539Z" }, - { url = "https://files.pythonhosted.org/packages/29/3a/79fa6a9a39422a400564ca7233a689a151f1039110f0bbbabcb38106883a/ruff-0.11.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f97fdbc2549f456c65b3b0048560d44ddd540db1f27c778a938371424b49fe4a", size = 10155152, upload-time = "2025-05-29T13:31:07.986Z" }, - { url = "https://files.pythonhosted.org/packages/e5/a4/22c2c97b2340aa968af3a39bc38045e78d36abd4ed3fa2bde91c31e712e3/ruff-0.11.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74adf84960236961090e2d1348c1a67d940fd12e811a33fb3d107df61eef8fc7", size = 11723067, upload-time = "2025-05-29T13:31:10.57Z" }, - { url = "https://files.pythonhosted.org/packages/bc/cf/3e452fbd9597bcd8058856ecd42b22751749d07935793a1856d988154151/ruff-0.11.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b56697e5b8bcf1d61293ccfe63873aba08fdbcbbba839fc046ec5926bdb25a3a", size = 12460807, upload-time = "2025-05-29T13:31:12.88Z" }, - { url = "https://files.pythonhosted.org/packages/2f/ec/8f170381a15e1eb7d93cb4feef8d17334d5a1eb33fee273aee5d1f8241a3/ruff-0.11.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d47afa45e7b0eaf5e5969c6b39cbd108be83910b5c74626247e366fd7a36a13", size = 12063261, upload-time = "2025-05-29T13:31:15.236Z" }, - { url = "https://files.pythonhosted.org/packages/0d/bf/57208f8c0a8153a14652a85f4116c0002148e83770d7a41f2e90b52d2b4e/ruff-0.11.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bf9603fe1bf949de8b09a2da896f05c01ed7a187f4a386cdba6760e7f61be", size = 11329601, upload-time = "2025-05-29T13:31:18.68Z" }, - { url = "https://files.pythonhosted.org/packages/c3/56/edf942f7fdac5888094d9ffa303f12096f1a93eb46570bcf5f14c0c70880/ruff-0.11.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08033320e979df3b20dba567c62f69c45e01df708b0f9c83912d7abd3e0801cd", size = 11522186, upload-time = "2025-05-29T13:31:21.216Z" }, - { url = "https://files.pythonhosted.org/packages/ed/63/79ffef65246911ed7e2290aeece48739d9603b3a35f9529fec0fc6c26400/ruff-0.11.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:929b7706584f5bfd61d67d5070f399057d07c70585fa8c4491d78ada452d3bef", size = 10449032, upload-time = "2025-05-29T13:31:23.417Z" }, - { url = "https://files.pythonhosted.org/packages/88/19/8c9d4d8a1c2a3f5a1ea45a64b42593d50e28b8e038f1aafd65d6b43647f3/ruff-0.11.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7de4a73205dc5756b8e09ee3ed67c38312dce1aa28972b93150f5751199981b5", size = 10129370, upload-time = "2025-05-29T13:31:25.777Z" }, - { url = "https://files.pythonhosted.org/packages/bc/0f/2d15533eaa18f460530a857e1778900cd867ded67f16c85723569d54e410/ruff-0.11.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2635c2a90ac1b8ca9e93b70af59dfd1dd2026a40e2d6eebaa3efb0465dd9cf02", size = 11123529, upload-time = "2025-05-29T13:31:28.396Z" }, - { url = "https://files.pythonhosted.org/packages/4f/e2/4c2ac669534bdded835356813f48ea33cfb3a947dc47f270038364587088/ruff-0.11.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d05d6a78a89166f03f03a198ecc9d18779076ad0eec476819467acb401028c0c", size = 11577642, upload-time = "2025-05-29T13:31:30.647Z" }, - { url = "https://files.pythonhosted.org/packages/a7/9b/c9ddf7f924d5617a1c94a93ba595f4b24cb5bc50e98b94433ab3f7ad27e5/ruff-0.11.12-py3-none-win32.whl", hash = "sha256:f5a07f49767c4be4772d161bfc049c1f242db0cfe1bd976e0f0886732a4765d6", size = 10475511, upload-time = "2025-05-29T13:31:32.917Z" }, - { url = "https://files.pythonhosted.org/packages/fd/d6/74fb6d3470c1aada019ffff33c0f9210af746cca0a4de19a1f10ce54968a/ruff-0.11.12-py3-none-win_amd64.whl", hash = "sha256:5a4d9f8030d8c3a45df201d7fb3ed38d0219bccd7955268e863ee4a115fa0832", size = 11523573, upload-time = "2025-05-29T13:31:35.782Z" }, - { url = "https://files.pythonhosted.org/packages/44/42/d58086ec20f52d2b0140752ae54b355ea2be2ed46f914231136dd1effcc7/ruff-0.11.12-py3-none-win_arm64.whl", hash = "sha256:65194e37853158d368e333ba282217941029a28ea90913c67e558c611d04daa5", size = 10697770, upload-time = "2025-05-29T13:31:38.009Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -2899,9 +2906,9 @@ name = "sse-starlette" version = "2.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "starlette", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "uvicorn", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "anyio", marker = "python_full_version >= '3.11'" }, + { name = "starlette", marker = "python_full_version >= '3.11'" }, + { name = "uvicorn", marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678, upload-time = "2024-08-01T08:52:50.248Z" } wheels = [ @@ -2924,23 +2931,24 @@ wheels = [ [[package]] name = "starlette" -version = "0.47.0" +version = "0.47.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "anyio", marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version >= '3.11' and python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/d0/0332bd8a25779a0e2082b0e179805ad39afad642938b371ae0882e7f880d/starlette-0.47.0.tar.gz", hash = "sha256:1f64887e94a447fed5f23309fb6890ef23349b7e478faa7b24a851cd4eb844af", size = 2582856, upload-time = "2025-05-29T15:45:27.628Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/69/662169fdb92fb96ec3eaee218cf540a629d629c86d7993d9651226a6789b/starlette-0.47.1.tar.gz", hash = "sha256:aef012dd2b6be325ffa16698f9dc533614fb1cebd593a906b90dc1025529a79b", size = 2583072, upload-time = "2025-06-21T04:03:17.337Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/81/c60b35fe9674f63b38a8feafc414fca0da378a9dbd5fa1e0b8d23fcc7a9b/starlette-0.47.0-py3-none-any.whl", hash = "sha256:9d052d4933683af40ffd47c7465433570b4949dc937e20ad1d73b34e72f10c37", size = 72796, upload-time = "2025-05-29T15:45:26.305Z" }, + { url = "https://files.pythonhosted.org/packages/82/95/38ef0cd7fa11eaba6a99b3c4f5ac948d8bc6ff199aabd327a29cc000840c/starlette-0.47.1-py3-none-any.whl", hash = "sha256:5e11c9f5c7c3f24959edbf2dffdc01bba860228acf657129467d8a7468591527", size = 72747, upload-time = "2025-06-21T04:03:15.705Z" }, ] [[package]] name = "structlog" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/6a/b0b6d440e429d2267076c4819300d9929563b1da959cf1f68afbcd69fe45/structlog-25.3.0.tar.gz", hash = "sha256:8dab497e6f6ca962abad0c283c46744185e0c9ba900db52a423cb6db99f7abeb", size = 1367514, upload-time = "2025-04-25T16:00:39.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b9/6e672db4fec07349e7a8a8172c1a6ae235c58679ca29c3f86a61b5e59ff3/structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4", size = 1369138, upload-time = "2025-06-02T08:21:12.971Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/52/7a2c7a317b254af857464da3d60a0d3730c44f912f8c510c76a738a207fd/structlog-25.3.0-py3-none-any.whl", hash = "sha256:a341f5524004c158498c3127eecded091eb67d3a611e7a3093deca30db06e172", size = 68240, upload-time = "2025-04-25T16:00:37.295Z" }, + { url = "https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c", size = 68720, upload-time = "2025-06-02T08:21:11.43Z" }, ] [[package]] @@ -3077,23 +3085,23 @@ wheels = [ [[package]] name = "types-requests" -version = "2.32.0.20250515" +version = "2.32.4.20250611" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/c1/cdc4f9b8cfd9130fbe6276db574f114541f4231fcc6fb29648289e6e3390/types_requests-2.32.0.20250515.tar.gz", hash = "sha256:09c8b63c11318cb2460813871aaa48b671002e59fda67ca909e9883777787581", size = 23012, upload-time = "2025-05-15T03:04:31.817Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/7f/73b3a04a53b0fd2a911d4ec517940ecd6600630b559e4505cc7b68beb5a0/types_requests-2.32.4.20250611.tar.gz", hash = "sha256:741c8777ed6425830bf51e54d6abe245f79b4dcb9019f1622b773463946bf826", size = 23118, upload-time = "2025-06-11T03:11:41.272Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/0f/68a997c73a129287785f418c1ebb6004f81e46b53b3caba88c0e03fcd04a/types_requests-2.32.0.20250515-py3-none-any.whl", hash = "sha256:f8eba93b3a892beee32643ff836993f15a785816acca21ea0ffa006f05ef0fb2", size = 20635, upload-time = "2025-05-15T03:04:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl", hash = "sha256:ad2fe5d3b0cb3c2c902c8815a70e7fb2302c4b8c1f77bdcd738192cdb3878072", size = 20643, upload-time = "2025-06-11T03:11:40.186Z" }, ] [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] @@ -3128,24 +3136,24 @@ wheels = [ [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "uvicorn" -version = "0.34.2" +version = "0.35.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, - { name = "h11", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "h11", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, + { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" }, ] [[package]] @@ -3225,83 +3233,118 @@ wheels = [ [[package]] name = "watchfiles" -version = "1.0.5" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.11' and python_full_version < '4.0'" }, + { name = "anyio", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload-time = "2025-04-08T10:36:26.722Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/d451fcc97d029f5812e898fd30a53fd8c15c7bbd058fd75cfc6beb9bd761/watchfiles-1.1.0.tar.gz", hash = "sha256:693ed7ec72cbfcee399e92c895362b6e66d63dac6b91e2c11ae03d10d503e575", size = 94406, upload-time = "2025-06-15T19:06:59.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632, upload-time = "2025-04-08T10:34:41.832Z" }, - { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734, upload-time = "2025-04-08T10:34:44.236Z" }, - { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008, upload-time = "2025-04-08T10:34:45.617Z" }, - { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029, upload-time = "2025-04-08T10:34:46.814Z" }, - { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916, upload-time = "2025-04-08T10:34:48.571Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763, upload-time = "2025-04-08T10:34:50.268Z" }, - { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891, upload-time = "2025-04-08T10:34:51.419Z" }, - { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921, upload-time = "2025-04-08T10:34:52.67Z" }, - { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422, upload-time = "2025-04-08T10:34:53.985Z" }, - { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675, upload-time = "2025-04-08T10:34:55.173Z" }, - { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921, upload-time = "2025-04-08T10:34:56.318Z" }, - { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526, upload-time = "2025-04-08T10:34:57.95Z" }, - { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336, upload-time = "2025-04-08T10:34:59.359Z" }, - { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977, upload-time = "2025-04-08T10:35:00.522Z" }, - { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232, upload-time = "2025-04-08T10:35:01.698Z" }, - { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151, upload-time = "2025-04-08T10:35:03.358Z" }, - { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054, upload-time = "2025-04-08T10:35:04.561Z" }, - { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955, upload-time = "2025-04-08T10:35:05.786Z" }, - { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234, upload-time = "2025-04-08T10:35:07.187Z" }, - { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750, upload-time = "2025-04-08T10:35:08.859Z" }, - { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591, upload-time = "2025-04-08T10:35:10.64Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370, upload-time = "2025-04-08T10:35:12.412Z" }, - { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791, upload-time = "2025-04-08T10:35:13.719Z" }, - { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622, upload-time = "2025-04-08T10:35:15.071Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699, upload-time = "2025-04-08T10:35:16.732Z" }, - { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511, upload-time = "2025-04-08T10:35:17.956Z" }, - { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715, upload-time = "2025-04-08T10:35:19.202Z" }, - { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138, upload-time = "2025-04-08T10:35:20.586Z" }, - { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592, upload-time = "2025-04-08T10:35:21.87Z" }, - { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532, upload-time = "2025-04-08T10:35:23.143Z" }, - { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865, upload-time = "2025-04-08T10:35:24.702Z" }, - { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887, upload-time = "2025-04-08T10:35:25.969Z" }, - { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498, upload-time = "2025-04-08T10:35:27.353Z" }, - { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663, upload-time = "2025-04-08T10:35:28.685Z" }, - { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410, upload-time = "2025-04-08T10:35:30.42Z" }, - { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965, upload-time = "2025-04-08T10:35:32.023Z" }, - { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693, upload-time = "2025-04-08T10:35:33.225Z" }, - { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287, upload-time = "2025-04-08T10:35:34.568Z" }, - { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload-time = "2025-04-08T10:35:35.792Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload-time = "2025-04-08T10:35:37.048Z" }, - { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload-time = "2025-04-08T10:35:38.357Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload-time = "2025-04-08T10:35:39.708Z" }, - { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload-time = "2025-04-08T10:35:41.469Z" }, - { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload-time = "2025-04-08T10:35:43.289Z" }, - { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload-time = "2025-04-08T10:35:44.574Z" }, - { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload-time = "2025-04-08T10:35:46.336Z" }, - { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload-time = "2025-04-08T10:35:48.161Z" }, - { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" }, - { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" }, - { url = "https://files.pythonhosted.org/packages/c5/95/94f3dd15557f5553261e407551c5e4d340e50161c55aa30812c79da6cb04/watchfiles-1.0.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2cfb371be97d4db374cba381b9f911dd35bb5f4c58faa7b8b7106c8853e5d225", size = 405686, upload-time = "2025-04-08T10:35:53.86Z" }, - { url = "https://files.pythonhosted.org/packages/f4/aa/b99e968153f8b70159ecca7b3daf46a6f46d97190bdaa3a449ad31b921d7/watchfiles-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a3904d88955fda461ea2531fcf6ef73584ca921415d5cfa44457a225f4a42bc1", size = 396047, upload-time = "2025-04-08T10:35:55.232Z" }, - { url = "https://files.pythonhosted.org/packages/23/cb/90d3d760ad4bc7290e313fb9236c7d60598627a25a5a72764e48d9652064/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b7a21715fb12274a71d335cff6c71fe7f676b293d322722fe708a9ec81d91f5", size = 456081, upload-time = "2025-04-08T10:35:57.102Z" }, - { url = "https://files.pythonhosted.org/packages/3e/65/79c6cebe5bcb695cdac145946ad5a09b9f66762549e82fb2d064ea960c95/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dfd6ae1c385ab481766b3c61c44aca2b3cd775f6f7c0fa93d979ddec853d29d5", size = 459838, upload-time = "2025-04-08T10:35:58.867Z" }, - { url = "https://files.pythonhosted.org/packages/3f/84/699f52632cdaa777f6df7f6f1cc02a23a75b41071b7e6765b9a412495f61/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b659576b950865fdad31fa491d31d37cf78b27113a7671d39f919828587b429b", size = 489753, upload-time = "2025-04-08T10:36:00.237Z" }, - { url = "https://files.pythonhosted.org/packages/25/68/3241f82ad414fd969de6bf3a93805682e5eb589aeab510322f2aa14462f8/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1909e0a9cd95251b15bff4261de5dd7550885bd172e3536824bf1cf6b121e200", size = 525015, upload-time = "2025-04-08T10:36:02.159Z" }, - { url = "https://files.pythonhosted.org/packages/85/c4/30d879e252f52b01660f545c193e6b81c48aac2e0eeec71263af3add905b/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:832ccc221927c860e7286c55c9b6ebcc0265d5e072f49c7f6456c7798d2b39aa", size = 503816, upload-time = "2025-04-08T10:36:03.869Z" }, - { url = "https://files.pythonhosted.org/packages/6b/7d/fa34750f6f4b1a70d96fa6b685fe2948d01e3936328ea528f182943eb373/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85fbb6102b3296926d0c62cfc9347f6237fb9400aecd0ba6bbda94cae15f2b3b", size = 456137, upload-time = "2025-04-08T10:36:05.226Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0c/a1569709aaeccb1dd74b0dd304d0de29e3ea1fdf11e08c78f489628f9ebb/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:15ac96dd567ad6c71c71f7b2c658cb22b7734901546cd50a475128ab557593ca", size = 632673, upload-time = "2025-04-08T10:36:06.752Z" }, - { url = "https://files.pythonhosted.org/packages/90/b6/645eaaca11f3ac625cf3b6e008e543acf0bf2581f68b5e205a13b05618b6/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b6227351e11c57ae997d222e13f5b6f1f0700d84b8c52304e8675d33a808382", size = 626659, upload-time = "2025-04-08T10:36:08.18Z" }, - { url = "https://files.pythonhosted.org/packages/3a/c4/e741d9b92b0a2c74b976ff78bbc9a1276b4d904c590878e8fe0ec9fecca5/watchfiles-1.0.5-cp39-cp39-win32.whl", hash = "sha256:974866e0db748ebf1eccab17862bc0f0303807ed9cda465d1324625b81293a18", size = 278471, upload-time = "2025-04-08T10:36:10.546Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/36b0cb6add99105f78931994b30bc1dd24118c0e659ab6a3ffe0dd8734d4/watchfiles-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:9848b21ae152fe79c10dd0197304ada8f7b586d3ebc3f27f43c506e5a52a863c", size = 292027, upload-time = "2025-04-08T10:36:11.901Z" }, - { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947, upload-time = "2025-04-08T10:36:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276, upload-time = "2025-04-08T10:36:15.131Z" }, - { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550, upload-time = "2025-04-08T10:36:16.635Z" }, - { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542, upload-time = "2025-04-08T10:36:18.655Z" }, - { url = "https://files.pythonhosted.org/packages/5b/84/7b69282c0df2bf2dff4e50be2c54669cddf219a5a5fb077891c00c00e5c8/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:554389562c29c2c182e3908b149095051f81d28c2fec79ad6c8997d7d63e0009", size = 405783, upload-time = "2025-04-08T10:36:20.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ae/03fca0545d99b7ea21df49bead7b51e7dca9ce3b45bb6d34530aa18c16a2/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a74add8d7727e6404d5dc4dcd7fac65d4d82f95928bbee0cf5414c900e86773e", size = 397133, upload-time = "2025-04-08T10:36:22.439Z" }, - { url = "https://files.pythonhosted.org/packages/1a/07/c2b6390003e933b2e187a3f7070c00bd87da8a58d6f2393e039b06a88c2e/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb1489f25b051a89fae574505cc26360c8e95e227a9500182a7fe0afcc500ce0", size = 456198, upload-time = "2025-04-08T10:36:23.884Z" }, - { url = "https://files.pythonhosted.org/packages/46/d3/ecc62cbd7054f0812f3a7ca7c1c9f7ba99ba45efcfc8297a9fcd2c87b31c/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0901429650652d3f0da90bad42bdafc1f9143ff3605633c455c999a2d786cac", size = 456511, upload-time = "2025-04-08T10:36:25.42Z" }, + { url = "https://files.pythonhosted.org/packages/b9/dd/579d1dc57f0f895426a1211c4ef3b0cb37eb9e642bb04bdcd962b5df206a/watchfiles-1.1.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:27f30e14aa1c1e91cb653f03a63445739919aef84c8d2517997a83155e7a2fcc", size = 405757, upload-time = "2025-06-15T19:04:51.058Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/7a0318cd874393344d48c34d53b3dd419466adf59a29ba5b51c88dd18b86/watchfiles-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3366f56c272232860ab45c77c3ca7b74ee819c8e1f6f35a7125556b198bbc6df", size = 397511, upload-time = "2025-06-15T19:04:52.79Z" }, + { url = "https://files.pythonhosted.org/packages/06/be/503514656d0555ec2195f60d810eca29b938772e9bfb112d5cd5ad6f6a9e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8412eacef34cae2836d891836a7fff7b754d6bcac61f6c12ba5ca9bc7e427b68", size = 450739, upload-time = "2025-06-15T19:04:54.203Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0d/a05dd9e5f136cdc29751816d0890d084ab99f8c17b86f25697288ca09bc7/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df670918eb7dd719642e05979fc84704af913d563fd17ed636f7c4783003fdcc", size = 458106, upload-time = "2025-06-15T19:04:55.607Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fa/9cd16e4dfdb831072b7ac39e7bea986e52128526251038eb481effe9f48e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7642b9bc4827b5518ebdb3b82698ada8c14c7661ddec5fe719f3e56ccd13c97", size = 484264, upload-time = "2025-06-15T19:04:57.009Z" }, + { url = "https://files.pythonhosted.org/packages/32/04/1da8a637c7e2b70e750a0308e9c8e662ada0cca46211fa9ef24a23937e0b/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:199207b2d3eeaeb80ef4411875a6243d9ad8bc35b07fc42daa6b801cc39cc41c", size = 597612, upload-time = "2025-06-15T19:04:58.409Z" }, + { url = "https://files.pythonhosted.org/packages/30/01/109f2762e968d3e58c95731a206e5d7d2a7abaed4299dd8a94597250153c/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a479466da6db5c1e8754caee6c262cd373e6e6c363172d74394f4bff3d84d7b5", size = 477242, upload-time = "2025-06-15T19:04:59.786Z" }, + { url = "https://files.pythonhosted.org/packages/b5/b8/46f58cf4969d3b7bc3ca35a98e739fa4085b0657a1540ccc29a1a0bc016f/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:935f9edd022ec13e447e5723a7d14456c8af254544cefbc533f6dd276c9aa0d9", size = 453148, upload-time = "2025-06-15T19:05:01.103Z" }, + { url = "https://files.pythonhosted.org/packages/a5/cd/8267594263b1770f1eb76914940d7b2d03ee55eca212302329608208e061/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8076a5769d6bdf5f673a19d51da05fc79e2bbf25e9fe755c47595785c06a8c72", size = 626574, upload-time = "2025-06-15T19:05:02.582Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2f/7f2722e85899bed337cba715723e19185e288ef361360718973f891805be/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86b1e28d4c37e89220e924305cd9f82866bb0ace666943a6e4196c5df4d58dcc", size = 624378, upload-time = "2025-06-15T19:05:03.719Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/64c88ec43d90a568234d021ab4b2a6f42a5230d772b987c3f9c00cc27b8b/watchfiles-1.1.0-cp310-cp310-win32.whl", hash = "sha256:d1caf40c1c657b27858f9774d5c0e232089bca9cb8ee17ce7478c6e9264d2587", size = 279829, upload-time = "2025-06-15T19:05:04.822Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/a9c1ed33de7af80935e4eac09570de679c6e21c07070aa99f74b4431f4d6/watchfiles-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a89c75a5b9bc329131115a409d0acc16e8da8dfd5867ba59f1dd66ae7ea8fa82", size = 292192, upload-time = "2025-06-15T19:05:06.348Z" }, + { url = "https://files.pythonhosted.org/packages/8b/78/7401154b78ab484ccaaeef970dc2af0cb88b5ba8a1b415383da444cdd8d3/watchfiles-1.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c9649dfc57cc1f9835551deb17689e8d44666315f2e82d337b9f07bd76ae3aa2", size = 405751, upload-time = "2025-06-15T19:05:07.679Z" }, + { url = "https://files.pythonhosted.org/packages/76/63/e6c3dbc1f78d001589b75e56a288c47723de28c580ad715eb116639152b5/watchfiles-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:406520216186b99374cdb58bc48e34bb74535adec160c8459894884c983a149c", size = 397313, upload-time = "2025-06-15T19:05:08.764Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/8afa359ff52e99af1632f90cbf359da46184207e893a5f179301b0c8d6df/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb45350fd1dc75cd68d3d72c47f5b513cb0578da716df5fba02fff31c69d5f2d", size = 450792, upload-time = "2025-06-15T19:05:09.869Z" }, + { url = "https://files.pythonhosted.org/packages/1d/bf/7446b401667f5c64972a57a0233be1104157fc3abf72c4ef2666c1bd09b2/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11ee4444250fcbeb47459a877e5e80ed994ce8e8d20283857fc128be1715dac7", size = 458196, upload-time = "2025-06-15T19:05:11.91Z" }, + { url = "https://files.pythonhosted.org/packages/58/2f/501ddbdfa3fa874ea5597c77eeea3d413579c29af26c1091b08d0c792280/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bda8136e6a80bdea23e5e74e09df0362744d24ffb8cd59c4a95a6ce3d142f79c", size = 484788, upload-time = "2025-06-15T19:05:13.373Z" }, + { url = "https://files.pythonhosted.org/packages/61/1e/9c18eb2eb5c953c96bc0e5f626f0e53cfef4bd19bd50d71d1a049c63a575/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b915daeb2d8c1f5cee4b970f2e2c988ce6514aace3c9296e58dd64dc9aa5d575", size = 597879, upload-time = "2025-06-15T19:05:14.725Z" }, + { url = "https://files.pythonhosted.org/packages/8b/6c/1467402e5185d89388b4486745af1e0325007af0017c3384cc786fff0542/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed8fc66786de8d0376f9f913c09e963c66e90ced9aa11997f93bdb30f7c872a8", size = 477447, upload-time = "2025-06-15T19:05:15.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a1/ec0a606bde4853d6c4a578f9391eeb3684a9aea736a8eb217e3e00aa89a1/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe4371595edf78c41ef8ac8df20df3943e13defd0efcb732b2e393b5a8a7a71f", size = 453145, upload-time = "2025-06-15T19:05:17.17Z" }, + { url = "https://files.pythonhosted.org/packages/90/b9/ef6f0c247a6a35d689fc970dc7f6734f9257451aefb30def5d100d6246a5/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b7c5f6fe273291f4d414d55b2c80d33c457b8a42677ad14b4b47ff025d0893e4", size = 626539, upload-time = "2025-06-15T19:05:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/34/44/6ffda5537085106ff5aaa762b0d130ac6c75a08015dd1621376f708c94de/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7738027989881e70e3723c75921f1efa45225084228788fc59ea8c6d732eb30d", size = 624472, upload-time = "2025-06-15T19:05:19.588Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e3/71170985c48028fa3f0a50946916a14055e741db11c2e7bc2f3b61f4d0e3/watchfiles-1.1.0-cp311-cp311-win32.whl", hash = "sha256:622d6b2c06be19f6e89b1d951485a232e3b59618def88dbeda575ed8f0d8dbf2", size = 279348, upload-time = "2025-06-15T19:05:20.856Z" }, + { url = "https://files.pythonhosted.org/packages/89/1b/3e39c68b68a7a171070f81fc2561d23ce8d6859659406842a0e4bebf3bba/watchfiles-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:48aa25e5992b61debc908a61ab4d3f216b64f44fdaa71eb082d8b2de846b7d12", size = 292607, upload-time = "2025-06-15T19:05:21.937Z" }, + { url = "https://files.pythonhosted.org/packages/61/9f/2973b7539f2bdb6ea86d2c87f70f615a71a1fc2dba2911795cea25968aea/watchfiles-1.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:00645eb79a3faa70d9cb15c8d4187bb72970b2470e938670240c7998dad9f13a", size = 285056, upload-time = "2025-06-15T19:05:23.12Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b8/858957045a38a4079203a33aaa7d23ea9269ca7761c8a074af3524fbb240/watchfiles-1.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9dc001c3e10de4725c749d4c2f2bdc6ae24de5a88a339c4bce32300a31ede179", size = 402339, upload-time = "2025-06-15T19:05:24.516Z" }, + { url = "https://files.pythonhosted.org/packages/80/28/98b222cca751ba68e88521fabd79a4fab64005fc5976ea49b53fa205d1fa/watchfiles-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9ba68ec283153dead62cbe81872d28e053745f12335d037de9cbd14bd1877f5", size = 394409, upload-time = "2025-06-15T19:05:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/86/50/dee79968566c03190677c26f7f47960aff738d32087087bdf63a5473e7df/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130fc497b8ee68dce163e4254d9b0356411d1490e868bd8790028bc46c5cc297", size = 450939, upload-time = "2025-06-15T19:05:26.494Z" }, + { url = "https://files.pythonhosted.org/packages/40/45/a7b56fb129700f3cfe2594a01aa38d033b92a33dddce86c8dfdfc1247b72/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50a51a90610d0845a5931a780d8e51d7bd7f309ebc25132ba975aca016b576a0", size = 457270, upload-time = "2025-06-15T19:05:27.466Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c8/fa5ef9476b1d02dc6b5e258f515fcaaecf559037edf8b6feffcbc097c4b8/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc44678a72ac0910bac46fa6a0de6af9ba1355669b3dfaf1ce5f05ca7a74364e", size = 483370, upload-time = "2025-06-15T19:05:28.548Z" }, + { url = "https://files.pythonhosted.org/packages/98/68/42cfcdd6533ec94f0a7aab83f759ec11280f70b11bfba0b0f885e298f9bd/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a543492513a93b001975ae283a51f4b67973662a375a403ae82f420d2c7205ee", size = 598654, upload-time = "2025-06-15T19:05:29.997Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/b2a1544224118cc28df7e59008a929e711f9c68ce7d554e171b2dc531352/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ac164e20d17cc285f2b94dc31c384bc3aa3dd5e7490473b3db043dd70fbccfd", size = 478667, upload-time = "2025-06-15T19:05:31.172Z" }, + { url = "https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f", size = 452213, upload-time = "2025-06-15T19:05:32.299Z" }, + { url = "https://files.pythonhosted.org/packages/6e/17/c8f1a36540c9a1558d4faf08e909399e8133599fa359bf52ec8fcee5be6f/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:37d3d3f7defb13f62ece99e9be912afe9dd8a0077b7c45ee5a57c74811d581a4", size = 626718, upload-time = "2025-06-15T19:05:33.415Z" }, + { url = "https://files.pythonhosted.org/packages/26/45/fb599be38b4bd38032643783d7496a26a6f9ae05dea1a42e58229a20ac13/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7080c4bb3efd70a07b1cc2df99a7aa51d98685be56be6038c3169199d0a1c69f", size = 623098, upload-time = "2025-06-15T19:05:34.534Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/fdf40e038475498e160cd167333c946e45d8563ae4dd65caf757e9ffe6b4/watchfiles-1.1.0-cp312-cp312-win32.whl", hash = "sha256:cbcf8630ef4afb05dc30107bfa17f16c0896bb30ee48fc24bf64c1f970f3b1fd", size = 279209, upload-time = "2025-06-15T19:05:35.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d3/3ae9d5124ec75143bdf088d436cba39812122edc47709cd2caafeac3266f/watchfiles-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:cbd949bdd87567b0ad183d7676feb98136cde5bb9025403794a4c0db28ed3a47", size = 292786, upload-time = "2025-06-15T19:05:36.559Z" }, + { url = "https://files.pythonhosted.org/packages/26/2f/7dd4fc8b5f2b34b545e19629b4a018bfb1de23b3a496766a2c1165ca890d/watchfiles-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:0a7d40b77f07be87c6faa93d0951a0fcd8cbca1ddff60a1b65d741bac6f3a9f6", size = 284343, upload-time = "2025-06-15T19:05:37.5Z" }, + { url = "https://files.pythonhosted.org/packages/d3/42/fae874df96595556a9089ade83be34a2e04f0f11eb53a8dbf8a8a5e562b4/watchfiles-1.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5007f860c7f1f8df471e4e04aaa8c43673429047d63205d1630880f7637bca30", size = 402004, upload-time = "2025-06-15T19:05:38.499Z" }, + { url = "https://files.pythonhosted.org/packages/fa/55/a77e533e59c3003d9803c09c44c3651224067cbe7fb5d574ddbaa31e11ca/watchfiles-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20ecc8abbd957046f1fe9562757903f5eaf57c3bce70929fda6c7711bb58074a", size = 393671, upload-time = "2025-06-15T19:05:39.52Z" }, + { url = "https://files.pythonhosted.org/packages/05/68/b0afb3f79c8e832e6571022611adbdc36e35a44e14f129ba09709aa4bb7a/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2f0498b7d2a3c072766dba3274fe22a183dbea1f99d188f1c6c72209a1063dc", size = 449772, upload-time = "2025-06-15T19:05:40.897Z" }, + { url = "https://files.pythonhosted.org/packages/ff/05/46dd1f6879bc40e1e74c6c39a1b9ab9e790bf1f5a2fe6c08b463d9a807f4/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:239736577e848678e13b201bba14e89718f5c2133dfd6b1f7846fa1b58a8532b", size = 456789, upload-time = "2025-06-15T19:05:42.045Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ca/0eeb2c06227ca7f12e50a47a3679df0cd1ba487ea19cf844a905920f8e95/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eff4b8d89f444f7e49136dc695599a591ff769300734446c0a86cba2eb2f9895", size = 482551, upload-time = "2025-06-15T19:05:43.781Z" }, + { url = "https://files.pythonhosted.org/packages/31/47/2cecbd8694095647406645f822781008cc524320466ea393f55fe70eed3b/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12b0a02a91762c08f7264e2e79542f76870c3040bbc847fb67410ab81474932a", size = 597420, upload-time = "2025-06-15T19:05:45.244Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7e/82abc4240e0806846548559d70f0b1a6dfdca75c1b4f9fa62b504ae9b083/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29e7bc2eee15cbb339c68445959108803dc14ee0c7b4eea556400131a8de462b", size = 477950, upload-time = "2025-06-15T19:05:46.332Z" }, + { url = "https://files.pythonhosted.org/packages/25/0d/4d564798a49bf5482a4fa9416dea6b6c0733a3b5700cb8a5a503c4b15853/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9481174d3ed982e269c090f780122fb59cee6c3796f74efe74e70f7780ed94c", size = 451706, upload-time = "2025-06-15T19:05:47.459Z" }, + { url = "https://files.pythonhosted.org/packages/81/b5/5516cf46b033192d544102ea07c65b6f770f10ed1d0a6d388f5d3874f6e4/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:80f811146831c8c86ab17b640801c25dc0a88c630e855e2bef3568f30434d52b", size = 625814, upload-time = "2025-06-15T19:05:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/0c/dd/7c1331f902f30669ac3e754680b6edb9a0dd06dea5438e61128111fadd2c/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:60022527e71d1d1fda67a33150ee42869042bce3d0fcc9cc49be009a9cded3fb", size = 622820, upload-time = "2025-06-15T19:05:50.088Z" }, + { url = "https://files.pythonhosted.org/packages/1b/14/36d7a8e27cd128d7b1009e7715a7c02f6c131be9d4ce1e5c3b73d0e342d8/watchfiles-1.1.0-cp313-cp313-win32.whl", hash = "sha256:32d6d4e583593cb8576e129879ea0991660b935177c0f93c6681359b3654bfa9", size = 279194, upload-time = "2025-06-15T19:05:51.186Z" }, + { url = "https://files.pythonhosted.org/packages/25/41/2dd88054b849aa546dbeef5696019c58f8e0774f4d1c42123273304cdb2e/watchfiles-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:f21af781a4a6fbad54f03c598ab620e3a77032c5878f3d780448421a6e1818c7", size = 292349, upload-time = "2025-06-15T19:05:52.201Z" }, + { url = "https://files.pythonhosted.org/packages/c8/cf/421d659de88285eb13941cf11a81f875c176f76a6d99342599be88e08d03/watchfiles-1.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:5366164391873ed76bfdf618818c82084c9db7fac82b64a20c44d335eec9ced5", size = 283836, upload-time = "2025-06-15T19:05:53.265Z" }, + { url = "https://files.pythonhosted.org/packages/45/10/6faf6858d527e3599cc50ec9fcae73590fbddc1420bd4fdccfebffeedbc6/watchfiles-1.1.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:17ab167cca6339c2b830b744eaf10803d2a5b6683be4d79d8475d88b4a8a4be1", size = 400343, upload-time = "2025-06-15T19:05:54.252Z" }, + { url = "https://files.pythonhosted.org/packages/03/20/5cb7d3966f5e8c718006d0e97dfe379a82f16fecd3caa7810f634412047a/watchfiles-1.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:328dbc9bff7205c215a7807da7c18dce37da7da718e798356212d22696404339", size = 392916, upload-time = "2025-06-15T19:05:55.264Z" }, + { url = "https://files.pythonhosted.org/packages/8c/07/d8f1176328fa9e9581b6f120b017e286d2a2d22ae3f554efd9515c8e1b49/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7208ab6e009c627b7557ce55c465c98967e8caa8b11833531fdf95799372633", size = 449582, upload-time = "2025-06-15T19:05:56.317Z" }, + { url = "https://files.pythonhosted.org/packages/66/e8/80a14a453cf6038e81d072a86c05276692a1826471fef91df7537dba8b46/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8f6f72974a19efead54195bc9bed4d850fc047bb7aa971268fd9a8387c89011", size = 456752, upload-time = "2025-06-15T19:05:57.359Z" }, + { url = "https://files.pythonhosted.org/packages/5a/25/0853b3fe0e3c2f5af9ea60eb2e781eade939760239a72c2d38fc4cc335f6/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d181ef50923c29cf0450c3cd47e2f0557b62218c50b2ab8ce2ecaa02bd97e670", size = 481436, upload-time = "2025-06-15T19:05:58.447Z" }, + { url = "https://files.pythonhosted.org/packages/fe/9e/4af0056c258b861fbb29dcb36258de1e2b857be4a9509e6298abcf31e5c9/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adb4167043d3a78280d5d05ce0ba22055c266cf8655ce942f2fb881262ff3cdf", size = 596016, upload-time = "2025-06-15T19:05:59.59Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fa/95d604b58aa375e781daf350897aaaa089cff59d84147e9ccff2447c8294/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5701dc474b041e2934a26d31d39f90fac8a3dee2322b39f7729867f932b1d4", size = 476727, upload-time = "2025-06-15T19:06:01.086Z" }, + { url = "https://files.pythonhosted.org/packages/65/95/fe479b2664f19be4cf5ceeb21be05afd491d95f142e72d26a42f41b7c4f8/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b067915e3c3936966a8607f6fe5487df0c9c4afb85226613b520890049deea20", size = 451864, upload-time = "2025-06-15T19:06:02.144Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8a/3c4af14b93a15ce55901cd7a92e1a4701910f1768c78fb30f61d2b79785b/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:9c733cda03b6d636b4219625a4acb5c6ffb10803338e437fb614fef9516825ef", size = 625626, upload-time = "2025-06-15T19:06:03.578Z" }, + { url = "https://files.pythonhosted.org/packages/da/f5/cf6aa047d4d9e128f4b7cde615236a915673775ef171ff85971d698f3c2c/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:cc08ef8b90d78bfac66f0def80240b0197008e4852c9f285907377b2947ffdcb", size = 622744, upload-time = "2025-06-15T19:06:05.066Z" }, + { url = "https://files.pythonhosted.org/packages/2c/00/70f75c47f05dea6fd30df90f047765f6fc2d6eb8b5a3921379b0b04defa2/watchfiles-1.1.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9974d2f7dc561cce3bb88dfa8eb309dab64c729de85fba32e98d75cf24b66297", size = 402114, upload-time = "2025-06-15T19:06:06.186Z" }, + { url = "https://files.pythonhosted.org/packages/53/03/acd69c48db4a1ed1de26b349d94077cca2238ff98fd64393f3e97484cae6/watchfiles-1.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c68e9f1fcb4d43798ad8814c4c1b61547b014b667216cb754e606bfade587018", size = 393879, upload-time = "2025-06-15T19:06:07.369Z" }, + { url = "https://files.pythonhosted.org/packages/2f/c8/a9a2a6f9c8baa4eceae5887fecd421e1b7ce86802bcfc8b6a942e2add834/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95ab1594377effac17110e1352989bdd7bdfca9ff0e5eeccd8c69c5389b826d0", size = 450026, upload-time = "2025-06-15T19:06:08.476Z" }, + { url = "https://files.pythonhosted.org/packages/fe/51/d572260d98388e6e2b967425c985e07d47ee6f62e6455cefb46a6e06eda5/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fba9b62da882c1be1280a7584ec4515d0a6006a94d6e5819730ec2eab60ffe12", size = 457917, upload-time = "2025-06-15T19:06:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/4258e52917bf9f12909b6ec314ff9636276f3542f9d3807d143f27309104/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3434e401f3ce0ed6b42569128b3d1e3af773d7ec18751b918b89cd49c14eaafb", size = 483602, upload-time = "2025-06-15T19:06:11.088Z" }, + { url = "https://files.pythonhosted.org/packages/84/99/bee17a5f341a4345fe7b7972a475809af9e528deba056f8963d61ea49f75/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa257a4d0d21fcbca5b5fcba9dca5a78011cb93c0323fb8855c6d2dfbc76eb77", size = 596758, upload-time = "2025-06-15T19:06:12.197Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/e4bec1d59b25b89d2b0716b41b461ed655a9a53c60dc78ad5771fda5b3e6/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd1b3879a578a8ec2076c7961076df540b9af317123f84569f5a9ddee64ce92", size = 477601, upload-time = "2025-06-15T19:06:13.391Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fa/a514292956f4a9ce3c567ec0c13cce427c158e9f272062685a8a727d08fc/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62cc7a30eeb0e20ecc5f4bd113cd69dcdb745a07c68c0370cea919f373f65d9e", size = 451936, upload-time = "2025-06-15T19:06:14.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/5d/c3bf927ec3bbeb4566984eba8dd7a8eb69569400f5509904545576741f88/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:891c69e027748b4a73847335d208e374ce54ca3c335907d381fde4e41661b13b", size = 626243, upload-time = "2025-06-15T19:06:16.232Z" }, + { url = "https://files.pythonhosted.org/packages/e6/65/6e12c042f1a68c556802a84d54bb06d35577c81e29fba14019562479159c/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:12fe8eaffaf0faa7906895b4f8bb88264035b3f0243275e0bf24af0436b27259", size = 623073, upload-time = "2025-06-15T19:06:17.457Z" }, + { url = "https://files.pythonhosted.org/packages/89/ab/7f79d9bf57329e7cbb0a6fd4c7bd7d0cee1e4a8ef0041459f5409da3506c/watchfiles-1.1.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bfe3c517c283e484843cb2e357dd57ba009cff351edf45fb455b5fbd1f45b15f", size = 400872, upload-time = "2025-06-15T19:06:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/df/d5/3f7bf9912798e9e6c516094db6b8932df53b223660c781ee37607030b6d3/watchfiles-1.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a9ccbf1f129480ed3044f540c0fdbc4ee556f7175e5ab40fe077ff6baf286d4e", size = 392877, upload-time = "2025-06-15T19:06:19.55Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c5/54ec7601a2798604e01c75294770dbee8150e81c6e471445d7601610b495/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba0e3255b0396cac3cc7bbace76404dd72b5438bf0d8e7cefa2f79a7f3649caa", size = 449645, upload-time = "2025-06-15T19:06:20.66Z" }, + { url = "https://files.pythonhosted.org/packages/0a/04/c2f44afc3b2fce21ca0b7802cbd37ed90a29874f96069ed30a36dfe57c2b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4281cd9fce9fc0a9dbf0fc1217f39bf9cf2b4d315d9626ef1d4e87b84699e7e8", size = 457424, upload-time = "2025-06-15T19:06:21.712Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b0/eec32cb6c14d248095261a04f290636da3df3119d4040ef91a4a50b29fa5/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d2404af8db1329f9a3c9b79ff63e0ae7131986446901582067d9304ae8aaf7f", size = 481584, upload-time = "2025-06-15T19:06:22.777Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/ca4bb71c68a937d7145aa25709e4f5d68eb7698a25ce266e84b55d591bbd/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e78b6ed8165996013165eeabd875c5dfc19d41b54f94b40e9fff0eb3193e5e8e", size = 596675, upload-time = "2025-06-15T19:06:24.226Z" }, + { url = "https://files.pythonhosted.org/packages/a1/dd/b0e4b7fb5acf783816bc950180a6cd7c6c1d2cf7e9372c0ea634e722712b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:249590eb75ccc117f488e2fabd1bfa33c580e24b96f00658ad88e38844a040bb", size = 477363, upload-time = "2025-06-15T19:06:25.42Z" }, + { url = "https://files.pythonhosted.org/packages/69/c4/088825b75489cb5b6a761a4542645718893d395d8c530b38734f19da44d2/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05686b5487cfa2e2c28ff1aa370ea3e6c5accfe6435944ddea1e10d93872147", size = 452240, upload-time = "2025-06-15T19:06:26.552Z" }, + { url = "https://files.pythonhosted.org/packages/10/8c/22b074814970eeef43b7c44df98c3e9667c1f7bf5b83e0ff0201b0bd43f9/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d0e10e6f8f6dc5762adee7dece33b722282e1f59aa6a55da5d493a97282fedd8", size = 625607, upload-time = "2025-06-15T19:06:27.606Z" }, + { url = "https://files.pythonhosted.org/packages/32/fa/a4f5c2046385492b2273213ef815bf71a0d4c1943b784fb904e184e30201/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:af06c863f152005c7592df1d6a7009c836a247c9d8adb78fef8575a5a98699db", size = 623315, upload-time = "2025-06-15T19:06:29.076Z" }, + { url = "https://files.pythonhosted.org/packages/47/8a/a45db804b9f0740f8408626ab2bca89c3136432e57c4673b50180bf85dd9/watchfiles-1.1.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:865c8e95713744cf5ae261f3067861e9da5f1370ba91fc536431e29b418676fa", size = 406400, upload-time = "2025-06-15T19:06:30.233Z" }, + { url = "https://files.pythonhosted.org/packages/64/06/a08684f628fb41addd451845aceedc2407dc3d843b4b060a7c4350ddee0c/watchfiles-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42f92befc848bb7a19658f21f3e7bae80d7d005d13891c62c2cd4d4d0abb3433", size = 397920, upload-time = "2025-06-15T19:06:31.315Z" }, + { url = "https://files.pythonhosted.org/packages/79/e6/e10d5675af653b1b07d4156906858041149ca222edaf8995877f2605ba9e/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa0cc8365ab29487eb4f9979fd41b22549853389e22d5de3f134a6796e1b05a4", size = 451196, upload-time = "2025-06-15T19:06:32.435Z" }, + { url = "https://files.pythonhosted.org/packages/f6/8a/facd6988100cd0f39e89f6c550af80edb28e3a529e1ee662e750663e6b36/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90ebb429e933645f3da534c89b29b665e285048973b4d2b6946526888c3eb2c7", size = 458218, upload-time = "2025-06-15T19:06:33.503Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/34cbcbc4d0f2f8f9cc243007e65d741ae039f7a11ef8ec6e9cd25bee08d1/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c588c45da9b08ab3da81d08d7987dae6d2a3badd63acdb3e206a42dbfa7cb76f", size = 484851, upload-time = "2025-06-15T19:06:34.541Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1f/f59faa9fc4b0e36dbcdd28a18c430416443b309d295d8b82e18192d120ad/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c55b0f9f68590115c25272b06e63f0824f03d4fc7d6deed43d8ad5660cabdbf", size = 599520, upload-time = "2025-06-15T19:06:35.785Z" }, + { url = "https://files.pythonhosted.org/packages/83/72/3637abecb3bf590529f5154ca000924003e5f4bbb9619744feeaf6f0b70b/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd17a1e489f02ce9117b0de3c0b1fab1c3e2eedc82311b299ee6b6faf6c23a29", size = 477956, upload-time = "2025-06-15T19:06:36.965Z" }, + { url = "https://files.pythonhosted.org/packages/f7/f3/d14ffd9acc0c1bd4790378995e320981423263a5d70bd3929e2e0dc87fff/watchfiles-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da71945c9ace018d8634822f16cbc2a78323ef6c876b1d34bbf5d5222fd6a72e", size = 453196, upload-time = "2025-06-15T19:06:38.024Z" }, + { url = "https://files.pythonhosted.org/packages/7f/38/78ad77bd99e20c0fdc82262be571ef114fc0beef9b43db52adb939768c38/watchfiles-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:51556d5004887045dba3acdd1fdf61dddea2be0a7e18048b5e853dcd37149b86", size = 627479, upload-time = "2025-06-15T19:06:39.442Z" }, + { url = "https://files.pythonhosted.org/packages/e6/cf/549d50a22fcc83f1017c6427b1c76c053233f91b526f4ad7a45971e70c0b/watchfiles-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04e4ed5d1cd3eae68c89bcc1a485a109f39f2fd8de05f705e98af6b5f1861f1f", size = 624414, upload-time = "2025-06-15T19:06:40.859Z" }, + { url = "https://files.pythonhosted.org/packages/72/de/57d6e40dc9140af71c12f3a9fc2d3efc5529d93981cd4d265d484d7c9148/watchfiles-1.1.0-cp39-cp39-win32.whl", hash = "sha256:c600e85f2ffd9f1035222b1a312aff85fd11ea39baff1d705b9b047aad2ce267", size = 280020, upload-time = "2025-06-15T19:06:41.89Z" }, + { url = "https://files.pythonhosted.org/packages/88/bb/7d287fc2a762396b128a0fca2dbae29386e0a242b81d1046daf389641db3/watchfiles-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3aba215958d88182e8d2acba0fdaf687745180974946609119953c0e112397dc", size = 292758, upload-time = "2025-06-15T19:06:43.251Z" }, + { url = "https://files.pythonhosted.org/packages/be/7c/a3d7c55cfa377c2f62c4ae3c6502b997186bc5e38156bafcb9b653de9a6d/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a6fd40bbb50d24976eb275ccb55cd1951dfb63dbc27cae3066a6ca5f4beabd5", size = 406748, upload-time = "2025-06-15T19:06:44.2Z" }, + { url = "https://files.pythonhosted.org/packages/38/d0/c46f1b2c0ca47f3667b144de6f0515f6d1c670d72f2ca29861cac78abaa1/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9f811079d2f9795b5d48b55a37aa7773680a5659afe34b54cc1d86590a51507d", size = 398801, upload-time = "2025-06-15T19:06:45.774Z" }, + { url = "https://files.pythonhosted.org/packages/70/9c/9a6a42e97f92eeed77c3485a43ea96723900aefa3ac739a8c73f4bff2cd7/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2726d7bfd9f76158c84c10a409b77a320426540df8c35be172444394b17f7ea", size = 451528, upload-time = "2025-06-15T19:06:46.791Z" }, + { url = "https://files.pythonhosted.org/packages/51/7b/98c7f4f7ce7ff03023cf971cd84a3ee3b790021ae7584ffffa0eb2554b96/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df32d59cb9780f66d165a9a7a26f19df2c7d24e3bd58713108b41d0ff4f929c6", size = 454095, upload-time = "2025-06-15T19:06:48.211Z" }, + { url = "https://files.pythonhosted.org/packages/8c/6b/686dcf5d3525ad17b384fd94708e95193529b460a1b7bf40851f1328ec6e/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0ece16b563b17ab26eaa2d52230c9a7ae46cf01759621f4fbbca280e438267b3", size = 406910, upload-time = "2025-06-15T19:06:49.335Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d3/71c2dcf81dc1edcf8af9f4d8d63b1316fb0a2dd90cbfd427e8d9dd584a90/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:51b81e55d40c4b4aa8658427a3ee7ea847c591ae9e8b81ef94a90b668999353c", size = 398816, upload-time = "2025-06-15T19:06:50.433Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fa/12269467b2fc006f8fce4cd6c3acfa77491dd0777d2a747415f28ccc8c60/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2bcdc54ea267fe72bfc7d83c041e4eb58d7d8dc6f578dfddb52f037ce62f432", size = 451584, upload-time = "2025-06-15T19:06:51.834Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/254cea30f918f489db09d6a8435a7de7047f8cb68584477a515f160541d6/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923fec6e5461c42bd7e3fd5ec37492c6f3468be0499bc0707b4bbbc16ac21792", size = 454009, upload-time = "2025-06-15T19:06:52.896Z" }, + { url = "https://files.pythonhosted.org/packages/48/93/5c96bdb65e7f88f7da40645f34c0a3c317a2931ed82161e93c91e8eddd27/watchfiles-1.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7b3443f4ec3ba5aa00b0e9fa90cf31d98321cbff8b925a7c7b84161619870bc9", size = 406640, upload-time = "2025-06-15T19:06:54.868Z" }, + { url = "https://files.pythonhosted.org/packages/e3/25/09204836e93e1b99cce88802ce87264a1d20610c7a8f6de24def27ad95b1/watchfiles-1.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7049e52167fc75fc3cc418fc13d39a8e520cbb60ca08b47f6cedb85e181d2f2a", size = 398543, upload-time = "2025-06-15T19:06:55.95Z" }, + { url = "https://files.pythonhosted.org/packages/5e/dc/6f324a6f32c5ab73b54311b5f393a79df34c1584b8d2404cf7e6d780aa5d/watchfiles-1.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54062ef956807ba806559b3c3d52105ae1827a0d4ab47b621b31132b6b7e2866", size = 451787, upload-time = "2025-06-15T19:06:56.998Z" }, + { url = "https://files.pythonhosted.org/packages/45/5d/1d02ef4caa4ec02389e72d5594cdf9c67f1800a7c380baa55063c30c6598/watchfiles-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a7bd57a1bb02f9d5c398c0c1675384e7ab1dd39da0ca50b7f09af45fa435277", size = 454272, upload-time = "2025-06-15T19:06:58.055Z" }, ] [[package]] @@ -3444,11 +3487,11 @@ wheels = [ [[package]] name = "zipp" -version = "3.22.0" +version = "3.23.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/b6/7b3d16792fdf94f146bed92be90b4eb4563569eca91513c8609aebf0c167/zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5", size = 25257, upload-time = "2025-05-26T14:46:32.217Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796, upload-time = "2025-05-26T14:46:30.775Z" }, + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, ] [[package]] diff --git a/libs/prebuilt/uv.lock b/libs/prebuilt/uv.lock index 7d399a39f..4fbe095ef 100644 --- a/libs/prebuilt/uv.lock +++ b/libs/prebuilt/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 2 requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.12.4'", - "python_full_version < '3.12.4'", -] [[package]] name = "aiosqlite" @@ -44,11 +40,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -217,7 +213,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.12.4'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -302,7 +298,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.67" +version = "0.3.68" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -313,9 +309,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/40/875af0194024d0006874f061958fa417d3500bbfdc9a57e1bd1c2f4e6ed2/langchain_core-0.3.67.tar.gz", hash = "sha256:2c14aa44a0e78e014e96d7f2f8916ac109d0a0ba87ed67ee25bf7296bed7e7ba", size = 561952, upload-time = "2025-06-30T17:09:35.142Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/20/f5b18a17bfbe3416177e702ab2fd230b7d168abb17be31fb48f43f0bb772/langchain_core-0.3.68.tar.gz", hash = "sha256:312e1932ac9aa2eaf111b70fdc171776fa571d1a86c1f873dcac88a094b19c6f", size = 563041, upload-time = "2025-07-03T17:02:28.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/2b/a0d283089c6d08c12d47dca39a55029ff714e939ec04f4560420426ab613/langchain_core-0.3.67-py3-none-any.whl", hash = "sha256:b699f1f24b24fa2747c05e2daa280aa64478a51e01a4e82c7f8e20b6167dfa99", size = 440237, upload-time = "2025-06-30T17:09:33.323Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c89be0a272993bfcb762b2a356b9f55de507784c2755ad63caec25d183bf/langchain_core-0.3.68-py3-none-any.whl", hash = "sha256:5e5c1fbef419590537c91b8c2d86af896fbcbaf0d5ed7fdcdd77f7d8f3467ba0", size = 441405, upload-time = "2025-07-03T17:02:27.115Z" }, ] [[package]] @@ -555,46 +551,47 @@ wheels = [ [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -742,6 +739,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -787,7 +793,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.4" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -795,9 +801,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -909,9 +915,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -919,36 +934,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -1019,7 +1035,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1027,9 +1043,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -1046,27 +1062,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.11.10" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -1152,23 +1168,23 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] @@ -1182,11 +1198,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] diff --git a/libs/sdk-py/uv.lock b/libs/sdk-py/uv.lock index 7a53ab5ec..71015876c 100644 --- a/libs/sdk-py/uv.lock +++ b/libs/sdk-py/uv.lock @@ -19,11 +19,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -156,46 +156,47 @@ dev = [ [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, - { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, - { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, - { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, - { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, + { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, + { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, + { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, + { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, + { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, + { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, + { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, + { url = "https://files.pythonhosted.org/packages/49/5e/ed1e6a7344005df11dfd58b0fdd59ce939a0ba9f7ed37754bf20670b74db/mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069", size = 10959511, upload-time = "2025-06-16T16:47:21.945Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/a7cbc2541e91fe04f43d9e4577264b260fecedb9bccb64ffb1a34b7e6c22/mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da", size = 10075555, upload-time = "2025-06-16T16:50:14.084Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/c62b1e31a32fbd1546cca5e0a2e5f181be5761265ad1f2e94f2a306fa906/mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c", size = 11874169, upload-time = "2025-06-16T16:49:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/c8/15/db580a28034657fb6cb87af2f8996435a5b19d429ea4dcd6e1c73d418e60/mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383", size = 12610060, upload-time = "2025-06-16T16:34:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/c17f48f6843048fa92d1489d3095e99324f2a8c420f831a04ccc454e2e51/mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40", size = 12875199, upload-time = "2025-06-16T16:35:14.448Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d6/ed42167d0a42680381653fd251d877382351e1bd2c6dd8a818764be3beb1/mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b", size = 9487033, upload-time = "2025-06-16T16:49:57.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[package]] @@ -295,6 +296,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -304,9 +314,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -314,36 +333,37 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.26.0" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814, upload-time = "2024-03-21T22:14:04.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863, upload-time = "2024-03-21T22:14:02.694Z" }, + { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] @@ -360,27 +380,27 @@ sdist = { url = "https://files.pythonhosted.org/packages/36/47/ab65fc1d682befc31 [[package]] name = "ruff" -version = "0.11.10" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]] @@ -433,11 +453,11 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]]