From 07cd4d83e1215d9cff6f9ccce9ac63fed3f6df7e Mon Sep 17 00:00:00 2001 From: Andrew Nguonly Date: Thu, 3 Jul 2025 16:04:27 -0700 Subject: [PATCH 01/31] docs: Add note about preemptive compute infra (#5339) * Add note about preemtive compute infra. * Fix spelling error. --- docs/docs/concepts/langgraph_control_plane.md | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/docs/concepts/langgraph_control_plane.md b/docs/docs/concepts/langgraph_control_plane.md index f3562516c..ebc880ce5 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 From 690b6f4ea11ed699ca3de030cc14c92ee5651c03 Mon Sep 17 00:00:00 2001 From: Tat Dat Duong Date: Fri, 4 Jul 2025 16:29:38 +0200 Subject: [PATCH 02/31] fix(docs): invalid command for creating langgraph app Closes https://github.com/langchain-ai/langgraphjs/issues/1331 --- docs/docs/concepts/template_applications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From cac0cd5522b7c1d7a3c38b6402b96f1e56b6e5de Mon Sep 17 00:00:00 2001 From: Chris G Date: Mon, 7 Jul 2025 02:35:37 +0200 Subject: [PATCH 03/31] docs: update name of CompiledGraph CompiledStateGraph (#5348) The name (and type) has changed. See: https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph.compile --- docs/docs/tutorials/get-started/1-build-basic-chatbot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() From d8756f257ede24658b51c95dec315b8218adba0a Mon Sep 17 00:00:00 2001 From: Shivang Agarwal Date: Mon, 7 Jul 2025 06:06:28 +0530 Subject: [PATCH 04/31] Updated TAVILY Key Setup (#5346) --- docs/docs/tutorials/get-started/2-add-tools.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 From 269590c4d92a59daebd5f8646e9ab8cc8adff401 Mon Sep 17 00:00:00 2001 From: jessicaou Date: Sun, 6 Jul 2025 17:37:54 -0700 Subject: [PATCH 05/31] docs: update case studies (#5353) --- docs/docs/adopters.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) 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) | From 4abf94846241f3546a0194efd40e109745e7d005 Mon Sep 17 00:00:00 2001 From: lc-arjun Date: Mon, 7 Jul 2025 08:05:46 -0700 Subject: [PATCH 06/31] docs: add -tunnel flag for node server (#5373) add -tunnel flag for node server --- docs/docs/troubleshooting/studio.md | 4 +- libs/sdk-js/client.cjs | 1 + libs/sdk-js/client.d.cts | 1 + libs/sdk-js/client.d.ts | 1 + libs/sdk-js/client.js | 1 + libs/sdk-js/docs/README.md | 26 + libs/sdk-js/docs/auth/README.md | 18 + libs/sdk-js/docs/auth/classes/Auth.md | 75 +++ .../sdk-js/docs/auth/classes/HTTPException.md | 185 +++++++ .../docs/auth/interfaces/AuthEventValueMap.md | 481 ++++++++++++++++++ .../docs/auth/type-aliases/AuthFilters.md | 15 + libs/sdk-js/docs/classes/AssistantsClient.md | 385 ++++++++++++++ libs/sdk-js/docs/classes/Client.md | 98 ++++ libs/sdk-js/docs/classes/CronsClient.md | 151 ++++++ libs/sdk-js/docs/classes/RunsClient.md | 469 +++++++++++++++++ libs/sdk-js/docs/classes/StoreClient.md | 314 ++++++++++++ libs/sdk-js/docs/classes/ThreadsClient.md | 433 ++++++++++++++++ libs/sdk-js/docs/functions/getApiKey.md | 32 ++ libs/sdk-js/docs/interfaces/ClientConfig.md | 57 +++ libs/sdk-js/docs/react/README.md | 18 + libs/sdk-js/docs/react/functions/useStream.md | 27 + .../sdk-js/docs/react/interfaces/UseStream.md | 227 +++++++++ .../docs/react/interfaces/UseStreamOptions.md | 343 +++++++++++++ .../react/type-aliases/MessageMetadata.md | 42 ++ libs/sdk-js/docs/type-aliases/RequestHook.md | 25 + libs/sdk-js/index.cjs | 1 + libs/sdk-js/index.d.cts | 1 + libs/sdk-js/index.d.ts | 1 + libs/sdk-js/index.js | 1 + libs/sdk-js/react.cjs | 1 + libs/sdk-js/react.d.cts | 1 + libs/sdk-js/react.d.ts | 1 + libs/sdk-js/react.js | 1 + 33 files changed, 3435 insertions(+), 2 deletions(-) create mode 100644 libs/sdk-js/client.cjs create mode 100644 libs/sdk-js/client.d.cts create mode 100644 libs/sdk-js/client.d.ts create mode 100644 libs/sdk-js/client.js create mode 100644 libs/sdk-js/docs/README.md create mode 100644 libs/sdk-js/docs/auth/README.md create mode 100644 libs/sdk-js/docs/auth/classes/Auth.md create mode 100644 libs/sdk-js/docs/auth/classes/HTTPException.md create mode 100644 libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md create mode 100644 libs/sdk-js/docs/auth/type-aliases/AuthFilters.md create mode 100644 libs/sdk-js/docs/classes/AssistantsClient.md create mode 100644 libs/sdk-js/docs/classes/Client.md create mode 100644 libs/sdk-js/docs/classes/CronsClient.md create mode 100644 libs/sdk-js/docs/classes/RunsClient.md create mode 100644 libs/sdk-js/docs/classes/StoreClient.md create mode 100644 libs/sdk-js/docs/classes/ThreadsClient.md create mode 100644 libs/sdk-js/docs/functions/getApiKey.md create mode 100644 libs/sdk-js/docs/interfaces/ClientConfig.md create mode 100644 libs/sdk-js/docs/react/README.md create mode 100644 libs/sdk-js/docs/react/functions/useStream.md create mode 100644 libs/sdk-js/docs/react/interfaces/UseStream.md create mode 100644 libs/sdk-js/docs/react/interfaces/UseStreamOptions.md create mode 100644 libs/sdk-js/docs/react/type-aliases/MessageMetadata.md create mode 100644 libs/sdk-js/docs/type-aliases/RequestHook.md create mode 100644 libs/sdk-js/index.cjs create mode 100644 libs/sdk-js/index.d.cts create mode 100644 libs/sdk-js/index.d.ts create mode 100644 libs/sdk-js/index.js create mode 100644 libs/sdk-js/react.cjs create mode 100644 libs/sdk-js/react.d.cts create mode 100644 libs/sdk-js/react.d.ts create mode 100644 libs/sdk-js/react.js 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/libs/sdk-js/client.cjs b/libs/sdk-js/client.cjs new file mode 100644 index 000000000..680e5bd38 --- /dev/null +++ b/libs/sdk-js/client.cjs @@ -0,0 +1 @@ +module.exports = require('./dist/client.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/client.d.cts b/libs/sdk-js/client.d.cts new file mode 100644 index 000000000..1c03ff9cb --- /dev/null +++ b/libs/sdk-js/client.d.cts @@ -0,0 +1 @@ +export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/client.d.ts b/libs/sdk-js/client.d.ts new file mode 100644 index 000000000..1c03ff9cb --- /dev/null +++ b/libs/sdk-js/client.d.ts @@ -0,0 +1 @@ +export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/client.js b/libs/sdk-js/client.js new file mode 100644 index 000000000..1c03ff9cb --- /dev/null +++ b/libs/sdk-js/client.js @@ -0,0 +1 @@ +export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/docs/README.md b/libs/sdk-js/docs/README.md new file mode 100644 index 000000000..a1627b448 --- /dev/null +++ b/libs/sdk-js/docs/README.md @@ -0,0 +1,26 @@ +**@langchain/langgraph-sdk** + +*** + +# @langchain/langgraph-sdk + +## Classes + +- [AssistantsClient](classes/AssistantsClient.md) +- [Client](classes/Client.md) +- [CronsClient](classes/CronsClient.md) +- [RunsClient](classes/RunsClient.md) +- [StoreClient](classes/StoreClient.md) +- [ThreadsClient](classes/ThreadsClient.md) + +## Interfaces + +- [ClientConfig](interfaces/ClientConfig.md) + +## Type Aliases + +- [RequestHook](type-aliases/RequestHook.md) + +## Functions + +- [getApiKey](functions/getApiKey.md) diff --git a/libs/sdk-js/docs/auth/README.md b/libs/sdk-js/docs/auth/README.md new file mode 100644 index 000000000..351cb8490 --- /dev/null +++ b/libs/sdk-js/docs/auth/README.md @@ -0,0 +1,18 @@ +**@langchain/langgraph-sdk** + +*** + +# @langchain/langgraph-sdk/auth + +## Classes + +- [Auth](classes/Auth.md) +- [HTTPException](classes/HTTPException.md) + +## Interfaces + +- [AuthEventValueMap](interfaces/AuthEventValueMap.md) + +## Type Aliases + +- [AuthFilters](type-aliases/AuthFilters.md) diff --git a/libs/sdk-js/docs/auth/classes/Auth.md b/libs/sdk-js/docs/auth/classes/Auth.md new file mode 100644 index 000000000..4b4cc618a --- /dev/null +++ b/libs/sdk-js/docs/auth/classes/Auth.md @@ -0,0 +1,75 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / Auth + +# Class: Auth\ + +Defined in: [src/auth/index.ts:11](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L11) + +## Type Parameters + +• **TExtra** = \{\} + +• **TAuthReturn** *extends* `BaseAuthReturn` = `BaseAuthReturn` + +• **TUser** *extends* `BaseUser` = `ToUserLike`\<`TAuthReturn`\> + +## Constructors + +### new Auth() + +> **new Auth**\<`TExtra`, `TAuthReturn`, `TUser`\>(): [`Auth`](Auth.md)\<`TExtra`, `TAuthReturn`, `TUser`\> + +#### Returns + +[`Auth`](Auth.md)\<`TExtra`, `TAuthReturn`, `TUser`\> + +## Methods + +### authenticate() + +> **authenticate**\<`T`\>(`cb`): [`Auth`](Auth.md)\<`TExtra`, `T`\> + +Defined in: [src/auth/index.ts:25](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L25) + +#### Type Parameters + +• **T** *extends* `BaseAuthReturn` + +#### Parameters + +##### cb + +`AuthenticateCallback`\<`T`\> + +#### Returns + +[`Auth`](Auth.md)\<`TExtra`, `T`\> + +*** + +### on() + +> **on**\<`T`\>(`event`, `callback`): `this` + +Defined in: [src/auth/index.ts:32](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L32) + +#### Type Parameters + +• **T** *extends* `CallbackEvent` + +#### Parameters + +##### event + +`T` + +##### callback + +`OnCallback`\<`T`, `TUser`\> + +#### Returns + +`this` diff --git a/libs/sdk-js/docs/auth/classes/HTTPException.md b/libs/sdk-js/docs/auth/classes/HTTPException.md new file mode 100644 index 000000000..0db191af5 --- /dev/null +++ b/libs/sdk-js/docs/auth/classes/HTTPException.md @@ -0,0 +1,185 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / HTTPException + +# Class: HTTPException + +Defined in: [src/auth/error.ts:66](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L66) + +## Extends + +- `Error` + +## Constructors + +### new HTTPException() + +> **new HTTPException**(`status`, `options`?): [`HTTPException`](HTTPException.md) + +Defined in: [src/auth/error.ts:70](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L70) + +#### Parameters + +##### status + +`number` + +##### options? + +###### cause? + +`unknown` + +###### headers? + +`HeadersInit` + +###### message? + +`string` + +#### Returns + +[`HTTPException`](HTTPException.md) + +#### Overrides + +`Error.constructor` + +## Properties + +### cause? + +> `optional` **cause**: `unknown` + +Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:24 + +#### Inherited from + +`Error.cause` + +*** + +### headers + +> **headers**: `HeadersInit` + +Defined in: [src/auth/error.ts:68](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L68) + +*** + +### message + +> **message**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 + +#### Inherited from + +`Error.message` + +*** + +### name + +> **name**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 + +#### Inherited from + +`Error.name` + +*** + +### stack? + +> `optional` **stack**: `string` + +Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 + +#### Inherited from + +`Error.stack` + +*** + +### status + +> **status**: `number` + +Defined in: [src/auth/error.ts:67](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L67) + +*** + +### prepareStackTrace()? + +> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` + +Defined in: node\_modules/@types/node/globals.d.ts:28 + +Optional override for formatting stack traces + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +`Error.prepareStackTrace` + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +Defined in: node\_modules/@types/node/globals.d.ts:30 + +#### Inherited from + +`Error.stackTraceLimit` + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` + +Defined in: node\_modules/@types/node/globals.d.ts:21 + +Create .stack property on a target object + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +`Error.captureStackTrace` diff --git a/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md b/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md new file mode 100644 index 000000000..686e1a39b --- /dev/null +++ b/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md @@ -0,0 +1,481 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / AuthEventValueMap + +# Interface: AuthEventValueMap + +Defined in: [src/auth/types.ts:218](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L218) + +## Properties + +### assistants:create + +> **assistants:create**: `object` + +Defined in: [src/auth/types.ts:226](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L226) + +#### assistant\_id? + +> `optional` **assistant\_id**: `Maybe`\<`string`\> + +#### config? + +> `optional` **config**: `Maybe`\<`AssistantConfig`\> + +#### graph\_id + +> **graph\_id**: `string` + +#### if\_exists? + +> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### name? + +> `optional` **name**: `Maybe`\<`string`\> + +*** + +### assistants:delete + +> **assistants:delete**: `object` + +Defined in: [src/auth/types.ts:229](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L229) + +#### assistant\_id + +> **assistant\_id**: `string` + +*** + +### assistants:read + +> **assistants:read**: `object` + +Defined in: [src/auth/types.ts:227](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L227) + +#### assistant\_id + +> **assistant\_id**: `string` + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +*** + +### assistants:search + +> **assistants:search**: `object` + +Defined in: [src/auth/types.ts:230](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L230) + +#### graph\_id? + +> `optional` **graph\_id**: `Maybe`\<`string`\> + +#### limit? + +> `optional` **limit**: `Maybe`\<`number`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### offset? + +> `optional` **offset**: `Maybe`\<`number`\> + +*** + +### assistants:update + +> **assistants:update**: `object` + +Defined in: [src/auth/types.ts:228](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L228) + +#### assistant\_id + +> **assistant\_id**: `string` + +#### config? + +> `optional` **config**: `Maybe`\<`AssistantConfig`\> + +#### graph\_id? + +> `optional` **graph\_id**: `Maybe`\<`string`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### name? + +> `optional` **name**: `Maybe`\<`string`\> + +#### version? + +> `optional` **version**: `Maybe`\<`number`\> + +*** + +### crons:create + +> **crons:create**: `object` + +Defined in: [src/auth/types.ts:232](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L232) + +#### cron\_id? + +> `optional` **cron\_id**: `Maybe`\<`string`\> + +#### end\_time? + +> `optional` **end\_time**: `Maybe`\<`string`\> + +#### payload? + +> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### schedule + +> **schedule**: `string` + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +#### user\_id? + +> `optional` **user\_id**: `Maybe`\<`string`\> + +*** + +### crons:delete + +> **crons:delete**: `object` + +Defined in: [src/auth/types.ts:235](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L235) + +#### cron\_id + +> **cron\_id**: `string` + +*** + +### crons:read + +> **crons:read**: `object` + +Defined in: [src/auth/types.ts:233](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L233) + +#### cron\_id + +> **cron\_id**: `string` + +*** + +### crons:search + +> **crons:search**: `object` + +Defined in: [src/auth/types.ts:236](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L236) + +#### assistant\_id? + +> `optional` **assistant\_id**: `Maybe`\<`string`\> + +#### limit? + +> `optional` **limit**: `Maybe`\<`number`\> + +#### offset? + +> `optional` **offset**: `Maybe`\<`number`\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +*** + +### crons:update + +> **crons:update**: `object` + +Defined in: [src/auth/types.ts:234](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L234) + +#### cron\_id + +> **cron\_id**: `string` + +#### payload? + +> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### schedule? + +> `optional` **schedule**: `Maybe`\<`string`\> + +*** + +### store:delete + +> **store:delete**: `object` + +Defined in: [src/auth/types.ts:242](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L242) + +#### key + +> **key**: `string` + +#### namespace? + +> `optional` **namespace**: `Maybe`\<`string`[]\> + +*** + +### store:get + +> **store:get**: `object` + +Defined in: [src/auth/types.ts:239](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L239) + +#### key + +> **key**: `string` + +#### namespace + +> **namespace**: `Maybe`\<`string`[]\> + +*** + +### store:list\_namespaces + +> **store:list\_namespaces**: `object` + +Defined in: [src/auth/types.ts:241](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L241) + +#### limit? + +> `optional` **limit**: `Maybe`\<`number`\> + +#### max\_depth? + +> `optional` **max\_depth**: `Maybe`\<`number`\> + +#### namespace? + +> `optional` **namespace**: `Maybe`\<`string`[]\> + +#### offset? + +> `optional` **offset**: `Maybe`\<`number`\> + +#### suffix? + +> `optional` **suffix**: `Maybe`\<`string`[]\> + +*** + +### store:put + +> **store:put**: `object` + +Defined in: [src/auth/types.ts:238](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L238) + +#### key + +> **key**: `string` + +#### namespace + +> **namespace**: `string`[] + +#### value + +> **value**: `Record`\<`string`, `unknown`\> + +*** + +### store:search + +> **store:search**: `object` + +Defined in: [src/auth/types.ts:240](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L240) + +#### filter? + +> `optional` **filter**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### limit? + +> `optional` **limit**: `Maybe`\<`number`\> + +#### namespace? + +> `optional` **namespace**: `Maybe`\<`string`[]\> + +#### offset? + +> `optional` **offset**: `Maybe`\<`number`\> + +#### query? + +> `optional` **query**: `Maybe`\<`string`\> + +*** + +### threads:create + +> **threads:create**: `object` + +Defined in: [src/auth/types.ts:219](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L219) + +#### if\_exists? + +> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +*** + +### threads:create\_run + +> **threads:create\_run**: `object` + +Defined in: [src/auth/types.ts:224](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L224) + +#### after\_seconds? + +> `optional` **after\_seconds**: `Maybe`\<`number`\> + +#### assistant\_id + +> **assistant\_id**: `string` + +#### if\_not\_exists? + +> `optional` **if\_not\_exists**: `Maybe`\<`"reject"` \| `"create"`\> + +#### kwargs + +> **kwargs**: `Record`\<`string`, `unknown`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### multitask\_strategy? + +> `optional` **multitask\_strategy**: `Maybe`\<`"reject"` \| `"interrupt"` \| `"rollback"` \| `"enqueue"`\> + +#### prevent\_insert\_if\_inflight? + +> `optional` **prevent\_insert\_if\_inflight**: `Maybe`\<`boolean`\> + +#### run\_id + +> **run\_id**: `string` + +#### status + +> **status**: `Maybe`\<`"pending"` \| `"running"` \| `"error"` \| `"success"` \| `"timeout"` \| `"interrupted"`\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +*** + +### threads:delete + +> **threads:delete**: `object` + +Defined in: [src/auth/types.ts:222](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L222) + +#### run\_id? + +> `optional` **run\_id**: `Maybe`\<`string`\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +*** + +### threads:read + +> **threads:read**: `object` + +Defined in: [src/auth/types.ts:220](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L220) + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +*** + +### threads:search + +> **threads:search**: `object` + +Defined in: [src/auth/types.ts:223](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L223) + +#### limit? + +> `optional` **limit**: `Maybe`\<`number`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### offset? + +> `optional` **offset**: `Maybe`\<`number`\> + +#### status? + +> `optional` **status**: `Maybe`\<`"error"` \| `"interrupted"` \| `"idle"` \| `"busy"` \| `string` & `object`\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> + +#### values? + +> `optional` **values**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +*** + +### threads:update + +> **threads:update**: `object` + +Defined in: [src/auth/types.ts:221](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L221) + +#### action? + +> `optional` **action**: `Maybe`\<`"interrupt"` \| `"rollback"`\> + +#### metadata? + +> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> + +#### thread\_id? + +> `optional` **thread\_id**: `Maybe`\<`string`\> diff --git a/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md b/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md new file mode 100644 index 000000000..b9b2e1fb2 --- /dev/null +++ b/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md @@ -0,0 +1,15 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / AuthFilters + +# Type Alias: AuthFilters\ + +> **AuthFilters**\<`TKey`\>: \{ \[key in TKey\]: string \| \{ \[op in "$contains" \| "$eq"\]?: string \} \} + +Defined in: [src/auth/types.ts:367](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L367) + +## Type Parameters + +• **TKey** *extends* `string` \| `number` \| `symbol` diff --git a/libs/sdk-js/docs/classes/AssistantsClient.md b/libs/sdk-js/docs/classes/AssistantsClient.md new file mode 100644 index 000000000..571dc16e8 --- /dev/null +++ b/libs/sdk-js/docs/classes/AssistantsClient.md @@ -0,0 +1,385 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / AssistantsClient + +# Class: AssistantsClient + +Defined in: [client.ts:431](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L431) + +## Extends + +- `BaseClient` + +## Constructors + +### new AssistantsClient() + +> **new AssistantsClient**(`config`?): [`AssistantsClient`](AssistantsClient.md) + +Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`AssistantsClient`](AssistantsClient.md) + +#### Inherited from + +`BaseClient.constructor` + +## Methods + +### create() + +> **create**(`payload`): `Promise`\<`Assistant`\> + +Defined in: [client.ts:496](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L496) + +Create a new assistant. + +#### Parameters + +##### payload + +Payload for creating an assistant. + +###### assistantId? + +`string` + +###### config? + +`Config` + +###### description? + +`string` + +###### graphId + +`string` + +###### ifExists? + +`OnConflictBehavior` + +###### metadata? + +`Metadata` + +###### name? + +`string` + +#### Returns + +`Promise`\<`Assistant`\> + +The created assistant. + +*** + +### delete() + +> **delete**(`assistantId`): `Promise`\<`void`\> + +Defined in: [client.ts:552](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L552) + +Delete an assistant. + +#### Parameters + +##### assistantId + +`string` + +ID of the assistant. + +#### Returns + +`Promise`\<`void`\> + +*** + +### get() + +> **get**(`assistantId`): `Promise`\<`Assistant`\> + +Defined in: [client.ts:438](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L438) + +Get an assistant by ID. + +#### Parameters + +##### assistantId + +`string` + +The ID of the assistant. + +#### Returns + +`Promise`\<`Assistant`\> + +Assistant + +*** + +### getGraph() + +> **getGraph**(`assistantId`, `options`?): `Promise`\<`AssistantGraph`\> + +Defined in: [client.ts:448](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L448) + +Get the JSON representation of the graph assigned to a runnable + +#### Parameters + +##### assistantId + +`string` + +The ID of the assistant. + +##### options? + +###### xray? + +`number` \| `boolean` + +Whether to include subgraphs in the serialized graph representation. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included. + +#### Returns + +`Promise`\<`AssistantGraph`\> + +Serialized graph + +*** + +### getSchemas() + +> **getSchemas**(`assistantId`): `Promise`\<`GraphSchema`\> + +Defined in: [client.ts:462](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L462) + +Get the state and config schema of the graph assigned to a runnable + +#### Parameters + +##### assistantId + +`string` + +The ID of the assistant. + +#### Returns + +`Promise`\<`GraphSchema`\> + +Graph schema + +*** + +### getSubgraphs() + +> **getSubgraphs**(`assistantId`, `options`?): `Promise`\<`Subgraphs`\> + +Defined in: [client.ts:473](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L473) + +Get the schemas of an assistant by ID. + +#### Parameters + +##### assistantId + +`string` + +The ID of the assistant to get the schema of. + +##### options? + +Additional options for getting subgraphs, such as namespace or recursion extraction. + +###### namespace? + +`string` + +###### recurse? + +`boolean` + +#### Returns + +`Promise`\<`Subgraphs`\> + +The subgraphs of the assistant. + +*** + +### getVersions() + +> **getVersions**(`assistantId`, `payload`?): `Promise`\<`AssistantVersion`[]\> + +Defined in: [client.ts:590](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L590) + +List all versions of an assistant. + +#### Parameters + +##### assistantId + +`string` + +ID of the assistant. + +##### payload? + +###### limit? + +`number` + +###### metadata? + +`Metadata` + +###### offset? + +`number` + +#### Returns + +`Promise`\<`AssistantVersion`[]\> + +List of assistant versions. + +*** + +### search() + +> **search**(`query`?): `Promise`\<`Assistant`[]\> + +Defined in: [client.ts:563](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L563) + +List assistants. + +#### Parameters + +##### query? + +Query options. + +###### graphId? + +`string` + +###### limit? + +`number` + +###### metadata? + +`Metadata` + +###### offset? + +`number` + +###### sortBy? + +`AssistantSortBy` + +###### sortOrder? + +`SortOrder` + +#### Returns + +`Promise`\<`Assistant`[]\> + +List of assistants. + +*** + +### setLatest() + +> **setLatest**(`assistantId`, `version`): `Promise`\<`Assistant`\> + +Defined in: [client.ts:618](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L618) + +Change the version of an assistant. + +#### Parameters + +##### assistantId + +`string` + +ID of the assistant. + +##### version + +`number` + +The version to change to. + +#### Returns + +`Promise`\<`Assistant`\> + +The updated assistant. + +*** + +### update() + +> **update**(`assistantId`, `payload`): `Promise`\<`Assistant`\> + +Defined in: [client.ts:525](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L525) + +Update an assistant. + +#### Parameters + +##### assistantId + +`string` + +ID of the assistant. + +##### payload + +Payload for updating the assistant. + +###### config? + +`Config` + +###### description? + +`string` + +###### graphId? + +`string` + +###### metadata? + +`Metadata` + +###### name? + +`string` + +#### Returns + +`Promise`\<`Assistant`\> + +The updated assistant. diff --git a/libs/sdk-js/docs/classes/Client.md b/libs/sdk-js/docs/classes/Client.md new file mode 100644 index 000000000..b0afc23de --- /dev/null +++ b/libs/sdk-js/docs/classes/Client.md @@ -0,0 +1,98 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / Client + +# Class: Client\ + +Defined in: [client.ts:1620](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1620) + +## Type Parameters + +• **TStateType** = `DefaultValues` + +• **TUpdateType** = `TStateType` + +• **TCustomEventType** = `unknown` + +## Constructors + +### new Client() + +> **new Client**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`Client`](Client.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> + +Defined in: [client.ts:1656](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1656) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`Client`](Client.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> + +## Properties + +### ~ui + +> **~ui**: `UiClient` + +Defined in: [client.ts:1654](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1654) + +**`Internal`** + +The client for interacting with the UI. + Used by LoadExternalComponent and the API might change in the future. + +*** + +### assistants + +> **assistants**: [`AssistantsClient`](AssistantsClient.md) + +Defined in: [client.ts:1628](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1628) + +The client for interacting with assistants. + +*** + +### crons + +> **crons**: [`CronsClient`](CronsClient.md) + +Defined in: [client.ts:1643](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1643) + +The client for interacting with cron runs. + +*** + +### runs + +> **runs**: [`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> + +Defined in: [client.ts:1638](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1638) + +The client for interacting with runs. + +*** + +### store + +> **store**: [`StoreClient`](StoreClient.md) + +Defined in: [client.ts:1648](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1648) + +The client for interacting with the KV store. + +*** + +### threads + +> **threads**: [`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> + +Defined in: [client.ts:1633](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1633) + +The client for interacting with threads. diff --git a/libs/sdk-js/docs/classes/CronsClient.md b/libs/sdk-js/docs/classes/CronsClient.md new file mode 100644 index 000000000..ae0017d9c --- /dev/null +++ b/libs/sdk-js/docs/classes/CronsClient.md @@ -0,0 +1,151 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / CronsClient + +# Class: CronsClient + +Defined in: [client.ts:334](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L334) + +## Extends + +- `BaseClient` + +## Constructors + +### new CronsClient() + +> **new CronsClient**(`config`?): [`CronsClient`](CronsClient.md) + +Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`CronsClient`](CronsClient.md) + +#### Inherited from + +`BaseClient.constructor` + +## Methods + +### create() + +> **create**(`assistantId`, `payload`?): `Promise`\<`CronCreateResponse`\> + +Defined in: [client.ts:375](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L375) + +#### Parameters + +##### assistantId + +`string` + +Assistant ID to use for this cron job. + +##### payload? + +`CronsCreatePayload` + +Payload for creating a cron job. + +#### Returns + +`Promise`\<`CronCreateResponse`\> + +*** + +### createForThread() + +> **createForThread**(`threadId`, `assistantId`, `payload`?): `Promise`\<`CronCreateForThreadResponse`\> + +Defined in: [client.ts:342](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L342) + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### assistantId + +`string` + +Assistant ID to use for this cron job. + +##### payload? + +`CronsCreatePayload` + +Payload for creating a cron job. + +#### Returns + +`Promise`\<`CronCreateForThreadResponse`\> + +The created background run. + +*** + +### delete() + +> **delete**(`cronId`): `Promise`\<`void`\> + +Defined in: [client.ts:402](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L402) + +#### Parameters + +##### cronId + +`string` + +Cron ID of Cron job to delete. + +#### Returns + +`Promise`\<`void`\> + +*** + +### search() + +> **search**(`query`?): `Promise`\<`Cron`[]\> + +Defined in: [client.ts:413](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L413) + +#### Parameters + +##### query? + +Query options. + +###### assistantId? + +`string` + +###### limit? + +`number` + +###### offset? + +`number` + +###### threadId? + +`string` + +#### Returns + +`Promise`\<`Cron`[]\> + +List of crons. diff --git a/libs/sdk-js/docs/classes/RunsClient.md b/libs/sdk-js/docs/classes/RunsClient.md new file mode 100644 index 000000000..15f666453 --- /dev/null +++ b/libs/sdk-js/docs/classes/RunsClient.md @@ -0,0 +1,469 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / RunsClient + +# Class: RunsClient\ + +Defined in: [client.ts:912](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L912) + +## Extends + +- `BaseClient` + +## Type Parameters + +• **TStateType** = `DefaultValues` + +• **TUpdateType** = `TStateType` + +• **TCustomEventType** = `unknown` + +## Constructors + +### new RunsClient() + +> **new RunsClient**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> + +Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> + +#### Inherited from + +`BaseClient.constructor` + +## Methods + +### cancel() + +> **cancel**(`threadId`, `runId`, `wait`, `action`): `Promise`\<`void`\> + +Defined in: [client.ts:1227](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1227) + +Cancel a run. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### runId + +`string` + +The ID of the run. + +##### wait + +`boolean` = `false` + +Whether to block when canceling + +##### action + +`CancelAction` = `"interrupt"` + +Action to take when cancelling the run. Possible values are `interrupt` or `rollback`. Default is `interrupt`. + +#### Returns + +`Promise`\<`void`\> + +*** + +### create() + +> **create**(`threadId`, `assistantId`, `payload`?): `Promise`\<`Run`\> + +Defined in: [client.ts:1026](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1026) + +Create a run. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### assistantId + +`string` + +Assistant ID to use for this run. + +##### payload? + +`RunsCreatePayload` + +Payload for creating a run. + +#### Returns + +`Promise`\<`Run`\> + +The created run. + +*** + +### createBatch() + +> **createBatch**(`payloads`): `Promise`\<`Run`[]\> + +Defined in: [client.ts:1076](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1076) + +Create a batch of stateless background runs. + +#### Parameters + +##### payloads + +`RunsCreatePayload` & `object`[] + +An array of payloads for creating runs. + +#### Returns + +`Promise`\<`Run`[]\> + +An array of created runs. + +*** + +### delete() + +> **delete**(`threadId`, `runId`): `Promise`\<`void`\> + +Defined in: [client.ts:1329](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1329) + +Delete a run. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### runId + +`string` + +The ID of the run. + +#### Returns + +`Promise`\<`void`\> + +*** + +### get() + +> **get**(`threadId`, `runId`): `Promise`\<`Run`\> + +Defined in: [client.ts:1214](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1214) + +Get a run by ID. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### runId + +`string` + +The ID of the run. + +#### Returns + +`Promise`\<`Run`\> + +The run. + +*** + +### join() + +> **join**(`threadId`, `runId`, `options`?): `Promise`\<`void`\> + +Defined in: [client.ts:1249](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1249) + +Block until a run is done. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### runId + +`string` + +The ID of the run. + +##### options? + +###### signal? + +`AbortSignal` + +#### Returns + +`Promise`\<`void`\> + +*** + +### joinStream() + +> **joinStream**(`threadId`, `runId`, `options`?): `AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; `id`: `string`; \}\> + +Defined in: [client.ts:1274](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1274) + +Stream output from a run in real-time, until the run is done. + +#### Parameters + +##### threadId + +The ID of the thread. Can be set to `null` | `undefined` for stateless runs. + +`undefined` | `null` | `string` + +##### runId + +`string` + +The ID of the run. + +##### options? + +Additional options for controlling the stream behavior: + - signal: An AbortSignal that can be used to cancel the stream request + - lastEventId: The ID of the last event received. Can be used to reconnect to a stream without losing events. + - cancelOnDisconnect: When true, automatically cancels the run if the client disconnects from the stream + - streamMode: Controls what types of events to receive from the stream (can be a single mode or array of modes) + Must be a subset of the stream modes passed when creating the run. Background runs default to having the union of all + stream modes enabled. + +`AbortSignal` | \{ `cancelOnDisconnect`: `boolean`; `lastEventId`: `string`; `signal`: `AbortSignal`; `streamMode`: `StreamMode` \| `StreamMode`[]; \} + +#### Returns + +`AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; `id`: `string`; \}\> + +An async generator yielding stream parts. + +*** + +### list() + +> **list**(`threadId`, `options`?): `Promise`\<`Run`[]\> + +Defined in: [client.ts:1177](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1177) + +List all runs for a thread. + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### options? + +Filtering and pagination options. + +###### limit? + +`number` + +Maximum number of runs to return. +Defaults to 10 + +###### offset? + +`number` + +Offset to start from. +Defaults to 0. + +###### status? + +`RunStatus` + +Status of the run to filter by. + +#### Returns + +`Promise`\<`Run`[]\> + +List of runs. + +*** + +### stream() + +Create a run and stream the results. + +#### Param + +The ID of the thread. + +#### Param + +Assistant ID to use for this run. + +#### Param + +Payload for creating a run. + +#### Call Signature + +> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> + +Defined in: [client.ts:917](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L917) + +##### Type Parameters + +• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode` + +• **TSubgraphs** *extends* `boolean` = `false` + +##### Parameters + +###### threadId + +`null` + +###### assistantId + +`string` + +###### payload? + +`Omit`\<`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\>, `"multitaskStrategy"` \| `"onCompletion"`\> + +##### Returns + +`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> + +#### Call Signature + +> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> + +Defined in: [client.ts:935](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L935) + +##### Type Parameters + +• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode` + +• **TSubgraphs** *extends* `boolean` = `false` + +##### Parameters + +###### threadId + +`string` + +###### assistantId + +`string` + +###### payload? + +`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\> + +##### Returns + +`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> + +*** + +### wait() + +Create a run and wait for it to complete. + +#### Param + +The ID of the thread. + +#### Param + +Assistant ID to use for this run. + +#### Param + +Payload for creating a run. + +#### Call Signature + +> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\> + +Defined in: [client.ts:1093](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1093) + +##### Parameters + +###### threadId + +`null` + +###### assistantId + +`string` + +###### payload? + +`Omit`\<`RunsWaitPayload`, `"multitaskStrategy"` \| `"onCompletion"`\> + +##### Returns + +`Promise`\<`DefaultValues`\> + +#### Call Signature + +> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\> + +Defined in: [client.ts:1099](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1099) + +##### Parameters + +###### threadId + +`string` + +###### assistantId + +`string` + +###### payload? + +`RunsWaitPayload` + +##### Returns + +`Promise`\<`DefaultValues`\> diff --git a/libs/sdk-js/docs/classes/StoreClient.md b/libs/sdk-js/docs/classes/StoreClient.md new file mode 100644 index 000000000..97e223da3 --- /dev/null +++ b/libs/sdk-js/docs/classes/StoreClient.md @@ -0,0 +1,314 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / StoreClient + +# Class: StoreClient + +Defined in: [client.ts:1347](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1347) + +## Extends + +- `BaseClient` + +## Constructors + +### new StoreClient() + +> **new StoreClient**(`config`?): [`StoreClient`](StoreClient.md) + +Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`StoreClient`](StoreClient.md) + +#### Inherited from + +`BaseClient.constructor` + +## Methods + +### deleteItem() + +> **deleteItem**(`namespace`, `key`): `Promise`\<`void`\> + +Defined in: [client.ts:1468](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1468) + +Delete an item. + +#### Parameters + +##### namespace + +`string`[] + +A list of strings representing the namespace path. + +##### key + +`string` + +The unique identifier for the item. + +#### Returns + +`Promise`\<`void`\> + +Promise + +*** + +### getItem() + +> **getItem**(`namespace`, `key`, `options`?): `Promise`\<`null` \| `Item`\> + +Defined in: [client.ts:1424](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1424) + +Retrieve a single item. + +#### Parameters + +##### namespace + +`string`[] + +A list of strings representing the namespace path. + +##### key + +`string` + +The unique identifier for the item. + +##### options? + +###### refreshTtl? + +`null` \| `boolean` + +Whether to refresh the TTL on this read operation. If null, uses the store's default behavior. + +#### Returns + +`Promise`\<`null` \| `Item`\> + +Promise + +#### Example + +```typescript +const item = await client.store.getItem( + ["documents", "user123"], + "item456", + { refreshTtl: true } +); +console.log(item); +// { +// namespace: ["documents", "user123"], +// key: "item456", +// value: { title: "My Document", content: "Hello World" }, +// createdAt: "2024-07-30T12:00:00Z", +// updatedAt: "2024-07-30T12:00:00Z" +// } +``` + +*** + +### listNamespaces() + +> **listNamespaces**(`options`?): `Promise`\<`ListNamespaceResponse`\> + +Defined in: [client.ts:1564](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1564) + +List namespaces with optional match conditions. + +#### Parameters + +##### options? + +###### limit? + +`number` + +Maximum number of namespaces to return (default is 100). + +###### maxDepth? + +`number` + +Optional integer specifying the maximum depth of namespaces to return. + +###### offset? + +`number` + +Number of namespaces to skip before returning results (default is 0). + +###### prefix? + +`string`[] + +Optional list of strings representing the prefix to filter namespaces. + +###### suffix? + +`string`[] + +Optional list of strings representing the suffix to filter namespaces. + +#### Returns + +`Promise`\<`ListNamespaceResponse`\> + +Promise + +*** + +### putItem() + +> **putItem**(`namespace`, `key`, `value`, `options`?): `Promise`\<`void`\> + +Defined in: [client.ts:1368](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1368) + +Store or update an item. + +#### Parameters + +##### namespace + +`string`[] + +A list of strings representing the namespace path. + +##### key + +`string` + +The unique identifier for the item within the namespace. + +##### value + +`Record`\<`string`, `any`\> + +A dictionary containing the item's data. + +##### options? + +###### index? + +`null` \| `false` \| `string`[] + +Controls search indexing - null (use defaults), false (disable), or list of field paths to index. + +###### ttl? + +`null` \| `number` + +Optional time-to-live in minutes for the item, or null for no expiration. + +#### Returns + +`Promise`\<`void`\> + +Promise + +#### Example + +```typescript +await client.store.putItem( + ["documents", "user123"], + "item456", + { title: "My Document", content: "Hello World" }, + { ttl: 60 } // expires in 60 minutes +); +``` + +*** + +### searchItems() + +> **searchItems**(`namespacePrefix`, `options`?): `Promise`\<`SearchItemsResponse`\> + +Defined in: [client.ts:1519](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1519) + +Search for items within a namespace prefix. + +#### Parameters + +##### namespacePrefix + +`string`[] + +List of strings representing the namespace prefix. + +##### options? + +###### filter? + +`Record`\<`string`, `any`\> + +Optional dictionary of key-value pairs to filter results. + +###### limit? + +`number` + +Maximum number of items to return (default is 10). + +###### offset? + +`number` + +Number of items to skip before returning results (default is 0). + +###### query? + +`string` + +Optional search query. + +###### refreshTtl? + +`null` \| `boolean` + +Whether to refresh the TTL on items returned by this search. If null, uses the store's default behavior. + +#### Returns + +`Promise`\<`SearchItemsResponse`\> + +Promise + +#### Example + +```typescript +const results = await client.store.searchItems( + ["documents"], + { + filter: { author: "John Doe" }, + limit: 5, + refreshTtl: true + } +); +console.log(results); +// { +// items: [ +// { +// namespace: ["documents", "user123"], +// key: "item789", +// value: { title: "Another Document", author: "John Doe" }, +// createdAt: "2024-07-30T12:00:00Z", +// updatedAt: "2024-07-30T12:00:00Z" +// }, +// // ... additional items ... +// ] +// } +``` diff --git a/libs/sdk-js/docs/classes/ThreadsClient.md b/libs/sdk-js/docs/classes/ThreadsClient.md new file mode 100644 index 000000000..7dc422c98 --- /dev/null +++ b/libs/sdk-js/docs/classes/ThreadsClient.md @@ -0,0 +1,433 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / ThreadsClient + +# Class: ThreadsClient\ + +Defined in: [client.ts:626](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L626) + +## Extends + +- `BaseClient` + +## Type Parameters + +• **TStateType** = `DefaultValues` + +• **TUpdateType** = `TStateType` + +## Constructors + +### new ThreadsClient() + +> **new ThreadsClient**\<`TStateType`, `TUpdateType`\>(`config`?): [`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> + +Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) + +#### Parameters + +##### config? + +[`ClientConfig`](../interfaces/ClientConfig.md) + +#### Returns + +[`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> + +#### Inherited from + +`BaseClient.constructor` + +## Methods + +### copy() + +> **copy**(`threadId`): `Promise`\<`Thread`\<`TStateType`\>\> + +Defined in: [client.ts:703](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L703) + +Copy an existing thread + +#### Parameters + +##### threadId + +`string` + +ID of the thread to be copied + +#### Returns + +`Promise`\<`Thread`\<`TStateType`\>\> + +Newly copied thread + +*** + +### create() + +> **create**(`payload`?): `Promise`\<`Thread`\<`TStateType`\>\> + +Defined in: [client.ts:648](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L648) + +Create a new thread. + +#### Parameters + +##### payload? + +Payload for creating a thread. + +###### graphId? + +`string` + +Graph ID to associate with the thread. + +###### ifExists? + +`OnConflictBehavior` + +How to handle duplicate creation. + +**Default** + +```ts +"raise" +``` + +###### metadata? + +`Metadata` + +Metadata for the thread. + +###### supersteps? + +`object`[] + +Apply a list of supersteps when creating a thread, each containing a sequence of updates. + +Used for copying a thread between deployments. + +###### threadId? + +`string` + +ID of the thread to create. + +If not provided, a random UUID will be generated. + +#### Returns + +`Promise`\<`Thread`\<`TStateType`\>\> + +The created thread. + +*** + +### delete() + +> **delete**(`threadId`): `Promise`\<`void`\> + +Defined in: [client.ts:736](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L736) + +Delete a thread. + +#### Parameters + +##### threadId + +`string` + +ID of the thread. + +#### Returns + +`Promise`\<`void`\> + +*** + +### get() + +> **get**\<`ValuesType`\>(`threadId`): `Promise`\<`Thread`\<`ValuesType`\>\> + +Defined in: [client.ts:636](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L636) + +Get a thread by ID. + +#### Type Parameters + +• **ValuesType** = `TStateType` + +#### Parameters + +##### threadId + +`string` + +ID of the thread. + +#### Returns + +`Promise`\<`Thread`\<`ValuesType`\>\> + +The thread. + +*** + +### getHistory() + +> **getHistory**\<`ValuesType`\>(`threadId`, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>[]\> + +Defined in: [client.ts:888](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L888) + +Get all past states for a thread. + +#### Type Parameters + +• **ValuesType** = `TStateType` + +#### Parameters + +##### threadId + +`string` + +ID of the thread. + +##### options? + +Additional options. + +###### before? + +`Config` + +###### checkpoint? + +`Partial`\<`Omit`\<`Checkpoint`, `"thread_id"`\>\> + +###### limit? + +`number` + +###### metadata? + +`Metadata` + +#### Returns + +`Promise`\<`ThreadState`\<`ValuesType`\>[]\> + +List of thread states. + +*** + +### getState() + +> **getState**\<`ValuesType`\>(`threadId`, `checkpoint`?, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>\> + +Defined in: [client.ts:795](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L795) + +Get state for a thread. + +#### Type Parameters + +• **ValuesType** = `TStateType` + +#### Parameters + +##### threadId + +`string` + +ID of the thread. + +##### checkpoint? + +`string` | `Checkpoint` + +##### options? + +###### subgraphs? + +`boolean` + +#### Returns + +`Promise`\<`ThreadState`\<`ValuesType`\>\> + +Thread state. + +*** + +### patchState() + +> **patchState**(`threadIdOrConfig`, `metadata`): `Promise`\<`void`\> + +Defined in: [client.ts:858](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L858) + +Patch the metadata of a thread. + +#### Parameters + +##### threadIdOrConfig + +Thread ID or config to patch the state of. + +`string` | `Config` + +##### metadata + +`Metadata` + +Metadata to patch the state with. + +#### Returns + +`Promise`\<`void`\> + +*** + +### search() + +> **search**\<`ValuesType`\>(`query`?): `Promise`\<`Thread`\<`ValuesType`\>[]\> + +Defined in: [client.ts:748](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L748) + +List threads + +#### Type Parameters + +• **ValuesType** = `TStateType` + +#### Parameters + +##### query? + +Query options + +###### limit? + +`number` + +Maximum number of threads to return. +Defaults to 10 + +###### metadata? + +`Metadata` + +Metadata to filter threads by. + +###### offset? + +`number` + +Offset to start from. + +###### sortBy? + +`ThreadSortBy` + +Sort by. + +###### sortOrder? + +`SortOrder` + +Sort order. +Must be one of 'asc' or 'desc'. + +###### status? + +`ThreadStatus` + +Thread status to filter on. + +#### Returns + +`Promise`\<`Thread`\<`ValuesType`\>[]\> + +List of threads + +*** + +### update() + +> **update**(`threadId`, `payload`?): `Promise`\<`Thread`\<`DefaultValues`\>\> + +Defined in: [client.ts:716](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L716) + +Update a thread. + +#### Parameters + +##### threadId + +`string` + +ID of the thread. + +##### payload? + +Payload for updating the thread. + +###### metadata? + +`Metadata` + +Metadata for the thread. + +#### Returns + +`Promise`\<`Thread`\<`DefaultValues`\>\> + +The updated thread. + +*** + +### updateState() + +> **updateState**\<`ValuesType`\>(`threadId`, `options`): `Promise`\<`Pick`\<`Config`, `"configurable"`\>\> + +Defined in: [client.ts:829](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L829) + +Add state to a thread. + +#### Type Parameters + +• **ValuesType** = `TUpdateType` + +#### Parameters + +##### threadId + +`string` + +The ID of the thread. + +##### options + +###### asNode? + +`string` + +###### checkpoint? + +`Checkpoint` + +###### checkpointId? + +`string` + +###### values + +`ValuesType` + +#### Returns + +`Promise`\<`Pick`\<`Config`, `"configurable"`\>\> diff --git a/libs/sdk-js/docs/functions/getApiKey.md b/libs/sdk-js/docs/functions/getApiKey.md new file mode 100644 index 000000000..8c8e4f1fa --- /dev/null +++ b/libs/sdk-js/docs/functions/getApiKey.md @@ -0,0 +1,32 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / getApiKey + +# Function: getApiKey() + +> **getApiKey**(`apiKey`?): `undefined` \| `string` + +Defined in: [client.ts:122](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L122) + +Get the API key from the environment. +Precedence: + 1. explicit argument + 2. LANGGRAPH_API_KEY + 3. LANGSMITH_API_KEY + 4. LANGCHAIN_API_KEY + +## Parameters + +### apiKey? + +`string` + +Optional API key provided as an argument + +## Returns + +`undefined` \| `string` + +The API key if found, otherwise undefined diff --git a/libs/sdk-js/docs/interfaces/ClientConfig.md b/libs/sdk-js/docs/interfaces/ClientConfig.md new file mode 100644 index 000000000..38c402010 --- /dev/null +++ b/libs/sdk-js/docs/interfaces/ClientConfig.md @@ -0,0 +1,57 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / ClientConfig + +# Interface: ClientConfig + +Defined in: [client.ts:163](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L163) + +## Properties + +### apiKey? + +> `optional` **apiKey**: `string` + +Defined in: [client.ts:165](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L165) + +*** + +### apiUrl? + +> `optional` **apiUrl**: `string` + +Defined in: [client.ts:164](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L164) + +*** + +### callerOptions? + +> `optional` **callerOptions**: `AsyncCallerParams` + +Defined in: [client.ts:166](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L166) + +*** + +### defaultHeaders? + +> `optional` **defaultHeaders**: `Record`\<`string`, `HeaderValue`\> + +Defined in: [client.ts:168](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L168) + +*** + +### onRequest? + +> `optional` **onRequest**: [`RequestHook`](../type-aliases/RequestHook.md) + +Defined in: [client.ts:169](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L169) + +*** + +### timeoutMs? + +> `optional` **timeoutMs**: `number` + +Defined in: [client.ts:167](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L167) diff --git a/libs/sdk-js/docs/react/README.md b/libs/sdk-js/docs/react/README.md new file mode 100644 index 000000000..0933ca79b --- /dev/null +++ b/libs/sdk-js/docs/react/README.md @@ -0,0 +1,18 @@ +**@langchain/langgraph-sdk** + +*** + +# @langchain/langgraph-sdk/react + +## Interfaces + +- [UseStream](interfaces/UseStream.md) +- [UseStreamOptions](interfaces/UseStreamOptions.md) + +## Type Aliases + +- [MessageMetadata](type-aliases/MessageMetadata.md) + +## Functions + +- [useStream](functions/useStream.md) diff --git a/libs/sdk-js/docs/react/functions/useStream.md b/libs/sdk-js/docs/react/functions/useStream.md new file mode 100644 index 000000000..a9cb7d468 --- /dev/null +++ b/libs/sdk-js/docs/react/functions/useStream.md @@ -0,0 +1,27 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / useStream + +# Function: useStream() + +> **useStream**\<`StateType`, `Bag`\>(`options`): [`UseStream`](../interfaces/UseStream.md)\<`StateType`, `Bag`\> + +Defined in: [react/stream.tsx:652](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L652) + +## Type Parameters + +• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> + +• **Bag** *extends* `object` = `BagTemplate` + +## Parameters + +### options + +[`UseStreamOptions`](../interfaces/UseStreamOptions.md)\<`StateType`, `Bag`\> + +## Returns + +[`UseStream`](../interfaces/UseStream.md)\<`StateType`, `Bag`\> diff --git a/libs/sdk-js/docs/react/interfaces/UseStream.md b/libs/sdk-js/docs/react/interfaces/UseStream.md new file mode 100644 index 000000000..06d1c4375 --- /dev/null +++ b/libs/sdk-js/docs/react/interfaces/UseStream.md @@ -0,0 +1,227 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / UseStream + +# Interface: UseStream\ + +Defined in: [react/stream.tsx:529](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L529) + +## Type Parameters + +• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> + +• **Bag** *extends* `BagTemplate` = `BagTemplate` + +## Properties + +### assistantId + +> **assistantId**: `string` + +Defined in: [react/stream.tsx:614](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L614) + +The ID of the assistant to use. + +*** + +### branch + +> **branch**: `string` + +Defined in: [react/stream.tsx:564](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L564) + +The current branch of the thread. + +*** + +### client + +> **client**: `Client` + +Defined in: [react/stream.tsx:609](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L609) + +LangGraph SDK client used to send request and receive responses. + +*** + +### error + +> **error**: `unknown` + +Defined in: [react/stream.tsx:541](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L541) + +Last seen error from the thread or during streaming. + +*** + +### experimental\_branchTree + +> **experimental\_branchTree**: `Sequence`\<`StateType`\> + +Defined in: [react/stream.tsx:580](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L580) + +**`Experimental`** + +Tree of all branches for the thread. + +*** + +### getMessagesMetadata() + +> **getMessagesMetadata**: (`message`, `index`?) => `undefined` \| [`MessageMetadata`](../type-aliases/MessageMetadata.md)\<`StateType`\> + +Defined in: [react/stream.tsx:601](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L601) + +Get the metadata for a message, such as first thread state the message +was seen in and branch information. + +#### Parameters + +##### message + +`Message` + +The message to get the metadata for. + +##### index? + +`number` + +The index of the message in the thread. + +#### Returns + +`undefined` \| [`MessageMetadata`](../type-aliases/MessageMetadata.md)\<`StateType`\> + +The metadata for the message. + +*** + +### history + +> **history**: `ThreadState`\<`StateType`\>[] + +Defined in: [react/stream.tsx:574](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L574) + +Flattened history of thread states of a thread. + +*** + +### interrupt + +> **interrupt**: `undefined` \| `Interrupt`\<`GetInterruptType`\<`Bag`\>\> + +Defined in: [react/stream.tsx:585](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L585) + +Get the interrupt value for the stream if interrupted. + +*** + +### isLoading + +> **isLoading**: `boolean` + +Defined in: [react/stream.tsx:546](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L546) + +Whether the stream is currently running. + +*** + +### joinStream() + +> **joinStream**: (`runId`) => `Promise`\<`void`\> + +Defined in: [react/stream.tsx:619](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L619) + +Join an active stream. + +#### Parameters + +##### runId + +`string` + +#### Returns + +`Promise`\<`void`\> + +*** + +### messages + +> **messages**: `Message`[] + +Defined in: [react/stream.tsx:591](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L591) + +Messages inferred from the thread. +Will automatically update with incoming message chunks. + +*** + +### setBranch() + +> **setBranch**: (`branch`) => `void` + +Defined in: [react/stream.tsx:569](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L569) + +Set the branch of the thread. + +#### Parameters + +##### branch + +`string` + +#### Returns + +`void` + +*** + +### stop() + +> **stop**: () => `void` + +Defined in: [react/stream.tsx:551](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L551) + +Stops the stream. + +#### Returns + +`void` + +*** + +### submit() + +> **submit**: (`values`, `options`?) => `void` + +Defined in: [react/stream.tsx:556](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L556) + +Create and stream a run to the thread. + +#### Parameters + +##### values + +`undefined` | `null` | `GetUpdateType`\<`Bag`, `StateType`\> + +##### options? + +`SubmitOptions`\<`StateType`, `GetConfigurableType`\<`Bag`\>\> + +#### Returns + +`void` + +*** + +### values + +> **values**: `StateType` + +Defined in: [react/stream.tsx:536](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L536) + +The current values of the thread. diff --git a/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md b/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md new file mode 100644 index 000000000..9fbb6f702 --- /dev/null +++ b/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md @@ -0,0 +1,343 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / UseStreamOptions + +# Interface: UseStreamOptions\ + +Defined in: [react/stream.tsx:413](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L413) + +## Type Parameters + +• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> + +• **Bag** *extends* `BagTemplate` = `BagTemplate` + +## Properties + +### apiKey? + +> `optional` **apiKey**: `string` + +Defined in: [react/stream.tsx:435](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L435) + +The API key to use. + +*** + +### apiUrl? + +> `optional` **apiUrl**: `string` + +Defined in: [react/stream.tsx:430](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L430) + +The URL of the API to use. + +*** + +### assistantId + +> **assistantId**: `string` + +Defined in: [react/stream.tsx:420](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L420) + +The ID of the assistant to use. + +*** + +### callerOptions? + +> `optional` **callerOptions**: `AsyncCallerParams` + +Defined in: [react/stream.tsx:440](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L440) + +Custom call options, such as custom fetch implementation. + +*** + +### client? + +> `optional` **client**: `Client`\<`DefaultValues`, `DefaultValues`, `unknown`\> + +Defined in: [react/stream.tsx:425](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L425) + +Client used to send requests. + +*** + +### defaultHeaders? + +> `optional` **defaultHeaders**: `Record`\<`string`, `HeaderValue`\> + +Defined in: [react/stream.tsx:445](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L445) + +Default headers to send with requests. + +*** + +### messagesKey? + +> `optional` **messagesKey**: `string` + +Defined in: [react/stream.tsx:453](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L453) + +Specify the key within the state that contains messages. +Defaults to "messages". + +#### Default + +```ts +"messages" +``` + +*** + +### onCreated()? + +> `optional` **onCreated**: (`run`) => `void` + +Defined in: [react/stream.tsx:471](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L471) + +Callback that is called when a new stream is created. + +#### Parameters + +##### run + +`RunCallbackMeta` + +#### Returns + +`void` + +*** + +### onCustomEvent()? + +> `optional` **onCustomEvent**: (`data`, `options`) => `void` + +Defined in: [react/stream.tsx:483](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L483) + +Callback that is called when a custom event is received. + +#### Parameters + +##### data + +`GetCustomEventType`\<`Bag`\> + +##### options + +###### mutate + +(`update`) => `void` + +#### Returns + +`void` + +*** + +### onDebugEvent()? + +> `optional` **onDebugEvent**: (`data`) => `void` + +Defined in: [react/stream.tsx:507](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L507) + +**`Internal`** + +Callback that is called when a debug event is received. + This API is experimental and subject to change. + +#### Parameters + +##### data + +`unknown` + +#### Returns + +`void` + +*** + +### onError()? + +> `optional` **onError**: (`error`, `run`) => `void` + +Defined in: [react/stream.tsx:458](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L458) + +Callback that is called when an error occurs. + +#### Parameters + +##### error + +`unknown` + +##### run + +`undefined` | `RunCallbackMeta` + +#### Returns + +`void` + +*** + +### onFinish()? + +> `optional` **onFinish**: (`state`, `run`) => `void` + +Defined in: [react/stream.tsx:463](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L463) + +Callback that is called when the stream is finished. + +#### Parameters + +##### state + +`ThreadState`\<`StateType`\> + +##### run + +`undefined` | `RunCallbackMeta` + +#### Returns + +`void` + +*** + +### onLangChainEvent()? + +> `optional` **onLangChainEvent**: (`data`) => `void` + +Defined in: [react/stream.tsx:501](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L501) + +Callback that is called when a LangChain event is received. + +#### Parameters + +##### data + +###### data + +`unknown` + +###### event + +`string` & `object` \| `"on_tool_start"` \| `"on_tool_stream"` \| `"on_tool_end"` \| `"on_chat_model_start"` \| `"on_chat_model_stream"` \| `"on_chat_model_end"` \| `"on_llm_start"` \| `"on_llm_stream"` \| `"on_llm_end"` \| `"on_chain_start"` \| `"on_chain_stream"` \| `"on_chain_end"` \| `"on_retriever_start"` \| `"on_retriever_stream"` \| `"on_retriever_end"` \| `"on_prompt_start"` \| `"on_prompt_stream"` \| `"on_prompt_end"` + +###### metadata + +`Record`\<`string`, `unknown`\> + +###### name + +`string` + +###### parent_ids + +`string`[] + +###### run_id + +`string` + +###### tags + +`string`[] + +#### Returns + +`void` + +#### See + +https://langchain-ai.github.io/langgraph/cloud/how-tos/stream_events/#stream-graph-in-events-mode for more details. + +*** + +### onMetadataEvent()? + +> `optional` **onMetadataEvent**: (`data`) => `void` + +Defined in: [react/stream.tsx:495](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L495) + +Callback that is called when a metadata event is received. + +#### Parameters + +##### data + +###### run_id + +`string` + +###### thread_id + +`string` + +#### Returns + +`void` + +*** + +### onThreadId()? + +> `optional` **onThreadId**: (`threadId`) => `void` + +Defined in: [react/stream.tsx:517](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L517) + +Callback that is called when the thread ID is updated (ie when a new thread is created). + +#### Parameters + +##### threadId + +`string` + +#### Returns + +`void` + +*** + +### onUpdateEvent()? + +> `optional` **onUpdateEvent**: (`data`) => `void` + +Defined in: [react/stream.tsx:476](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L476) + +Callback that is called when an update event is received. + +#### Parameters + +##### data + +#### Returns + +`void` + +*** + +### reconnectOnMount? + +> `optional` **reconnectOnMount**: `boolean` \| () => `RunMetadataStorage` + +Defined in: [react/stream.tsx:520](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L520) + +Will reconnect the stream on mount + +*** + +### threadId? + +> `optional` **threadId**: `null` \| `string` + +Defined in: [react/stream.tsx:512](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L512) + +The ID of the thread to fetch history and current values from. diff --git a/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md b/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md new file mode 100644 index 000000000..9496a7913 --- /dev/null +++ b/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md @@ -0,0 +1,42 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / MessageMetadata + +# Type Alias: MessageMetadata\ + +> **MessageMetadata**\<`StateType`\>: `object` + +Defined in: [react/stream.tsx:169](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L169) + +## Type Parameters + +• **StateType** *extends* `Record`\<`string`, `unknown`\> + +## Type declaration + +### branch + +> **branch**: `string` \| `undefined` + +The branch of the message. + +### branchOptions + +> **branchOptions**: `string`[] \| `undefined` + +The list of branches this message is part of. +This is useful for displaying branching controls. + +### firstSeenState + +> **firstSeenState**: `ThreadState`\<`StateType`\> \| `undefined` + +The first thread state the message was seen in. + +### messageId + +> **messageId**: `string` + +The ID of the message used. diff --git a/libs/sdk-js/docs/type-aliases/RequestHook.md b/libs/sdk-js/docs/type-aliases/RequestHook.md new file mode 100644 index 000000000..53d535e2e --- /dev/null +++ b/libs/sdk-js/docs/type-aliases/RequestHook.md @@ -0,0 +1,25 @@ +[**@langchain/langgraph-sdk**](../README.md) + +*** + +[@langchain/langgraph-sdk](../README.md) / RequestHook + +# Type Alias: RequestHook() + +> **RequestHook**: (`url`, `init`) => `Promise`\<`RequestInit`\> \| `RequestInit` + +Defined in: [client.ts:158](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L158) + +## Parameters + +### url + +`URL` + +### init + +`RequestInit` + +## Returns + +`Promise`\<`RequestInit`\> \| `RequestInit` diff --git a/libs/sdk-js/index.cjs b/libs/sdk-js/index.cjs new file mode 100644 index 000000000..c84256f7a --- /dev/null +++ b/libs/sdk-js/index.cjs @@ -0,0 +1 @@ +module.exports = require('./dist/index.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/index.d.cts b/libs/sdk-js/index.d.cts new file mode 100644 index 000000000..485d17256 --- /dev/null +++ b/libs/sdk-js/index.d.cts @@ -0,0 +1 @@ +export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/index.d.ts b/libs/sdk-js/index.d.ts new file mode 100644 index 000000000..485d17256 --- /dev/null +++ b/libs/sdk-js/index.d.ts @@ -0,0 +1 @@ +export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/index.js b/libs/sdk-js/index.js new file mode 100644 index 000000000..485d17256 --- /dev/null +++ b/libs/sdk-js/index.js @@ -0,0 +1 @@ +export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.cjs b/libs/sdk-js/react.cjs new file mode 100644 index 000000000..86a38b8c3 --- /dev/null +++ b/libs/sdk-js/react.cjs @@ -0,0 +1 @@ +module.exports = require('./dist/react/index.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/react.d.cts b/libs/sdk-js/react.d.cts new file mode 100644 index 000000000..fd96c4787 --- /dev/null +++ b/libs/sdk-js/react.d.cts @@ -0,0 +1 @@ +export * from './dist/react/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.d.ts b/libs/sdk-js/react.d.ts new file mode 100644 index 000000000..fd96c4787 --- /dev/null +++ b/libs/sdk-js/react.d.ts @@ -0,0 +1 @@ +export * from './dist/react/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.js b/libs/sdk-js/react.js new file mode 100644 index 000000000..fd96c4787 --- /dev/null +++ b/libs/sdk-js/react.js @@ -0,0 +1 @@ +export * from './dist/react/index.js' \ No newline at end of file From c9966c4febc681388055a0f91f1e19532c66c8ea Mon Sep 17 00:00:00 2001 From: Andrew Nguonly Date: Mon, 7 Jul 2025 12:39:44 -0400 Subject: [PATCH 07/31] docs: Add section about data region for LGP data plane (#5378) Add section about data region. --- docs/docs/concepts/langgraph_data_plane.md | 9 +++++++++ 1 file changed, 9 insertions(+) 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: From 844417591d5368b1f5d69de0c86068ed253da45d Mon Sep 17 00:00:00 2001 From: Michael Li Date: Tue, 8 Jul 2025 05:09:00 +1000 Subject: [PATCH 08/31] fix: remove empty notebook (#5379) --- examples/human_in_the_loop/breakpoints.ipynb | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/human_in_the_loop/breakpoints.ipynb 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 From 7f57e0097575897feeff72aca9cb3d84f169efd4 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 7 Jul 2025 15:10:01 -0400 Subject: [PATCH 09/31] docs: move script into scripts (#5384) --- extract_images.py => docs/_scripts/extract_images.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename extract_images.py => docs/_scripts/extract_images.py (100%) diff --git a/extract_images.py b/docs/_scripts/extract_images.py similarity index 100% rename from extract_images.py rename to docs/_scripts/extract_images.py From 1800df7048510e9dc5330b57236420845dc07310 Mon Sep 17 00:00:00 2001 From: jito Date: Tue, 8 Jul 2025 04:25:06 +0900 Subject: [PATCH 10/31] Fix docstring for _unset_config_context function (#5374) Signed-off-by: jitokim --- libs/langgraph/langgraph/utils/runnable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From e99f6292c510fb5ee046b17a75a006f3b429447d Mon Sep 17 00:00:00 2001 From: jito Date: Tue, 8 Jul 2025 04:27:09 +0900 Subject: [PATCH 11/31] =?UTF-8?q?Fix=20typo=20in=20StreamMode=20debug=20de?= =?UTF-8?q?scription:=20checlkpoints=20=E2=86=92=20checkpoints=20(#5371)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jitokim --- libs/langgraph/langgraph/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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] From 141afa8c6278090555a51db6e425e996bbb229f1 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Tue, 8 Jul 2025 05:54:02 +1000 Subject: [PATCH 12/31] fix: remove unused import in generate_llms_text.py (#5380) --- docs/_scripts/generate_llms_text.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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) From de6c25689d03f8e2115eb8d06091e0353268d9b6 Mon Sep 17 00:00:00 2001 From: Serhii Polishchuk Date: Mon, 7 Jul 2025 22:00:57 +0200 Subject: [PATCH 13/31] dcos: Fix deprecation of TavilySearch (#5375) Fix deprecation: The class `TavilySearchResults` was deprecated in LangChain 0.3.25 and will be removed in 1.0 --- .../tutorials/multi_agent/hierarchical_agent_teams.ipynb | 6 +++--- .../tutorials/multi_agent/multi-agent-collaboration.ipynb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) 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", From f3a7925d864d6af62189f55529c9df3b5ccf1c47 Mon Sep 17 00:00:00 2001 From: jito Date: Tue, 8 Jul 2025 05:09:55 +0900 Subject: [PATCH 14/31] =?UTF-8?q?Fix=20typo:=20funtion=20=E2=86=92=20funct?= =?UTF-8?q?ion=20(#5370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix typos Signed-off-by: jitokim --- libs/langgraph/bench/react_agent.py | 4 ++-- libs/langgraph/tests/__snapshots__/test_large_cases.ambr | 2 +- libs/langgraph/tests/test_large_cases.py | 8 ++++---- libs/langgraph/tests/test_large_cases_async.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) 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/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="", From cd58fad69db699d5ee653c8d4df1469efbea4117 Mon Sep 17 00:00:00 2001 From: Lauren Hirata Singh Date: Mon, 7 Jul 2025 17:03:05 -0400 Subject: [PATCH 15/31] docs: feedback edits (#5387) --- docs/_scripts/notebook_hooks.py | 1 + docs/docs/agents/overview.md | 2 +- docs/docs/agents/tools.md | 310 ------------------------------ docs/docs/how-tos/graph-api.md | 2 +- docs/docs/how-tos/tool-calling.md | 2 + docs/overrides/main.html | 9 +- 6 files changed, 12 insertions(+), 314 deletions(-) delete mode 100644 docs/docs/agents/tools.md 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/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/how-tos/graph-api.md b/docs/docs/how-tos/graph-api.md index 2e15cacb1..3cf08f8c5 100644 --- a/docs/docs/how-tos/graph-api.md +++ b/docs/docs/how-tos/graph-api.md @@ -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 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/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 %} From c13c4746266bf41b8091c8758f0ae04349e48499 Mon Sep 17 00:00:00 2001 From: hari-dhanushkodi Date: Mon, 7 Jul 2025 17:44:57 -0400 Subject: [PATCH 16/31] docs: update lgp deployment metric list (#5388) --- docs/docs/concepts/langgraph_control_plane.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/concepts/langgraph_control_plane.md b/docs/docs/concepts/langgraph_control_plane.md index ebc880ce5..006a57df9 100644 --- a/docs/docs/concepts/langgraph_control_plane.md +++ b/docs/docs/concepts/langgraph_control_plane.md @@ -112,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. From 8118e905432748f0cfd85d2d3df0aa3dfcb74a17 Mon Sep 17 00:00:00 2001 From: ccurme Date: Mon, 7 Jul 2025 18:02:02 -0400 Subject: [PATCH 17/31] docs: update sql tutorial (#5389) --- docs/docs/tutorials/sql-agent.ipynb | 335 +++++++++------------------- 1 file changed, 109 insertions(+), 226 deletions(-) diff --git a/docs/docs/tutorials/sql-agent.ipynb b/docs/docs/tutorials/sql-agent.ipynb index 843179305..a06626f40 100644 --- a/docs/docs/tutorials/sql-agent.ipynb +++ b/docs/docs/tutorials/sql-agent.ipynb @@ -264,183 +264,109 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "Which sales agent made the most in sales in 2009?\n", + "Which genre on average has the longest tracks?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " sql_db_list_tables (call_0MfnhUYmRNVe03m6fYClaoa0)\n", - " Call ID: call_0MfnhUYmRNVe03m6fYClaoa0\n", + " sql_db_list_tables (call_d8lCgywSroCgpVl558nmXKwA)\n", + " Call ID: call_d8lCgywSroCgpVl558nmXKwA\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", + " sql_db_schema (call_nNf6IIUcwMYLIkE0l6uWkZHe)\n", + " Call ID: call_nNf6IIUcwMYLIkE0l6uWkZHe\n", " Args:\n", - " table_names: Employee, Invoice, InvoiceLine\n", + " table_names: Genre, Track\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", + "CREATE TABLE \"Genre\" (\n", + "\t\"GenreId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"GenreId\")\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", + "3 rows from Genre table:\n", + "GenreId\tName\n", + "1\tRock\n", + "2\tJazz\n", + "3\tMetal\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", + "CREATE TABLE \"Track\" (\n", "\t\"TrackId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(200) NOT NULL, \n", + "\t\"AlbumId\" INTEGER, \n", + "\t\"MediaTypeId\" INTEGER NOT NULL, \n", + "\t\"GenreId\" INTEGER, \n", + "\t\"Composer\" NVARCHAR(220), \n", + "\t\"Milliseconds\" INTEGER NOT NULL, \n", + "\t\"Bytes\" INTEGER, \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", + "\tPRIMARY KEY (\"TrackId\"), \n", + "\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \n", + "\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \n", + "\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\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", + "3 rows from Track table:\n", + "TrackId\tName\tAlbumId\tMediaTypeId\tGenreId\tComposer\tMilliseconds\tBytes\tUnitPrice\n", + "1\tFor Those About To Rock (We Salute You)\t1\t1\t1\tAngus Young, Malcolm Young, Brian Johnson\t343719\t11170334\t0.99\n", + "2\tBalls to the Wall\t2\t2\t1\tNone\t342562\t5510424\t0.99\n", + "3\tFast As a Shark\t3\t2\t1\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\t230619\t3990994\t0.99\n", "*/\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " sql_db_schema (call_dHE5FKSycFhYIkdPKtpEk9rM)\n", - " Call ID: call_dHE5FKSycFhYIkdPKtpEk9rM\n", + " sql_db_query_checker (call_urTRmtiGtTxkwHtscec7Fd2K)\n", + " Call ID: call_urTRmtiGtTxkwHtscec7Fd2K\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", + " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", + "FROM Track\n", + "JOIN Genre ON Track.GenreId = Genre.GenreId\n", + "GROUP BY Genre.Name\n", + "ORDER BY AvgMilliseconds 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", + "SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", + "FROM Track\n", + "JOIN Genre ON Track.GenreId = Genre.GenreId\n", + "GROUP BY Genre.Name\n", + "ORDER BY AvgMilliseconds 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", + " sql_db_query (call_RNMqyUEMv0rvy0UxSwrXY2AV)\n", + " Call ID: call_RNMqyUEMv0rvy0UxSwrXY2AV\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", + " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", + "FROM Track\n", + "JOIN Genre ON Track.GenreId = Genre.GenreId\n", + "GROUP BY Genre.Name\n", + "ORDER BY AvgMilliseconds DESC\n", "LIMIT 1;\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", "Name: sql_db_query\n", "\n", - "[(5, 'Steve', 'Johnson', 164.34)]\n", + "[('Sci Fi & Fantasy', 2911783.0384615385)]\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" + "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.\n" ] } ], "source": [ - "question = \"Which sales agent made the most in sales in 2009?\"\n", + "question = \"Which genre on average has the longest tracks?\"\n", "\n", "for step in agent.stream(\n", " {\"messages\": [{\"role\": \"user\", \"content\": question}]},\n", @@ -484,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "992f6ce6-f932-4f44-994c-c0ba5032dbd1", "metadata": {}, "outputs": [], @@ -606,7 +532,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "8b3ce09d-0eec-456d-8447-d04f79ccfc23", "metadata": {}, "outputs": [], @@ -652,13 +578,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "f728ed5f-7bcd-489e-9174-4e4725962335", "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "" ] @@ -684,7 +610,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "6c800a77-2359-4011-ab0c-dad22ed333b1", "metadata": {}, "outputs": [ @@ -694,135 +620,92 @@ "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", - "Which sales agent made the most in sales in 2009?\n", + "Which genre on average has the longest tracks?\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", + " sql_db_schema (call_qxKtYiHgf93AiTDin9ez5wFp)\n", + " Call ID: call_qxKtYiHgf93AiTDin9ez5wFp\n", " Args:\n", - " table_names: Employee,Invoice,Customer\n", + " table_names: Genre,Track\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", + "CREATE TABLE \"Genre\" (\n", + "\t\"GenreId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(120), \n", + "\tPRIMARY KEY (\"GenreId\")\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", + "3 rows from Genre table:\n", + "GenreId\tName\n", + "1\tRock\n", + "2\tJazz\n", + "3\tMetal\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", + "CREATE TABLE \"Track\" (\n", + "\t\"TrackId\" INTEGER NOT NULL, \n", + "\t\"Name\" NVARCHAR(200) NOT NULL, \n", + "\t\"AlbumId\" INTEGER, \n", + "\t\"MediaTypeId\" INTEGER NOT NULL, \n", + "\t\"GenreId\" INTEGER, \n", + "\t\"Composer\" NVARCHAR(220), \n", + "\t\"Milliseconds\" INTEGER NOT NULL, \n", + "\t\"Bytes\" INTEGER, \n", + "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", + "\tPRIMARY KEY (\"TrackId\"), \n", + "\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \n", + "\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \n", + "\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\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", + "3 rows from Track table:\n", + "TrackId\tName\tAlbumId\tMediaTypeId\tGenreId\tComposer\tMilliseconds\tBytes\tUnitPrice\n", + "1\tFor Those About To Rock (We Salute You)\t1\t1\t1\tAngus Young, Malcolm Young, Brian Johnson\t343719\t11170334\t0.99\n", + "2\tBalls to the Wall\t2\t2\t1\tNone\t342562\t5510424\t0.99\n", + "3\tFast As a Shark\t3\t2\t1\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\t230619\t3990994\t0.99\n", "*/\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", - " sql_db_query (call_TQyoJSV78xEWHqc69PiYHjdS)\n", - " Call ID: call_TQyoJSV78xEWHqc69PiYHjdS\n", + " sql_db_query (call_RPN3GABMfb6DTaFTLlwnZxVN)\n", + " Call ID: call_RPN3GABMfb6DTaFTLlwnZxVN\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", + " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength\n", + "FROM Track\n", + "JOIN Genre ON Track.GenreId = Genre.GenreId\n", + "GROUP BY Genre.GenreId\n", + "ORDER BY AvgTrackLength 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", + " sql_db_query (call_PR4s8ymiF3ZQLaoZADXtdqcl)\n", + " Call ID: call_PR4s8ymiF3ZQLaoZADXtdqcl\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", + " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength\n", + "FROM Track\n", + "JOIN Genre ON Track.GenreId = Genre.GenreId\n", + "GROUP BY Genre.GenreId\n", + "ORDER BY AvgTrackLength DESC\n", "LIMIT 1;\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", "Name: sql_db_query\n", "\n", - "[('Steve', 'Johnson', 164.34)]\n", + "[('Sci Fi & Fantasy', 2911783.0384615385)]\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" + "The genre with the longest tracks on average is \"Sci Fi & Fantasy,\" with an average track length of approximately 2,911,783 milliseconds.\n" ] } ], "source": [ - "question = \"Which sales agent made the most in sales in 2009?\"\n", + "question = \"Which genre on average has the longest tracks?\"\n", "\n", "for step in agent.stream(\n", " {\"messages\": [{\"role\": \"user\", \"content\": question}]},\n", @@ -838,7 +721,7 @@ "source": [ "!!! tip\n", "\n", - " See [LangSmith trace](https://smith.langchain.com/public/36a9ebbb-7cc4-4c54-b4db-cb12e124a649/r) for the above run." + " See [LangSmith trace](https://smith.langchain.com/public/94b8c9ac-12f7-4692-8706-836a1f30f1ea/r) for the above run." ] }, { From 5413f9db9f99f75ebb8a8e067ca13476fe8ebadd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 19:00:51 -0400 Subject: [PATCH 18/31] chore(deps): bump peter-evans/create-pull-request from 6 to 7 (#5365) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/uv_lock_ugprade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/uv_lock_ugprade.yml b/.github/workflows/uv_lock_ugprade.yml index 8acd39393..de079ec4c 100644 --- a/.github/workflows/uv_lock_ugprade.yml +++ b/.github/workflows/uv_lock_ugprade.yml @@ -30,7 +30,7 @@ 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`" From fa36a50444d05d6c47d79d3f96681b6d113c5b75 Mon Sep 17 00:00:00 2001 From: Fadel Akram Date: Tue, 8 Jul 2025 00:14:17 +0100 Subject: [PATCH 19/31] docs: correct link in docs/docs/how-tos/graph-api.md (#5377) Update graph-api.md --- docs/docs/how-tos/graph-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/graph-api.md b/docs/docs/how-tos/graph-api.md index 3cf08f8c5..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: @@ -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 +``` From cba4d9e3bcdc2595206200d655142f9e7f621a19 Mon Sep 17 00:00:00 2001 From: David <31293924+dreadn0ught@users.noreply.github.com> Date: Tue, 8 Jul 2025 01:18:55 +0200 Subject: [PATCH 20/31] docs: Update quick_start.md Rest API Guide (#5368) Update quick_start.md Rest API Guide The curl command in the quick start needs some minor changes to work out of the box. I hope by adding these changes then new users can get started more quickly --- docs/docs/cloud/quick_start.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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\": { From 4321ed0f870b795434e7f81f0b7cc10d3c925ca4 Mon Sep 17 00:00:00 2001 From: jito Date: Tue, 8 Jul 2025 08:19:16 +0900 Subject: [PATCH 21/31] Remove duplicate CONFIG_KEY_CHECKPOINT_MAP from RESERVED set (#5372) Signed-off-by: jitokim --- libs/langgraph/langgraph/constants.py | 1 - 1 file changed, 1 deletion(-) 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, From 4c73b176ff28485d72aa819054e0a1c8d5db2cf4 Mon Sep 17 00:00:00 2001 From: Youssef Ahmed Mohamed Abdelrahman <109446360+unauthorised-401@users.noreply.github.com> Date: Tue, 8 Jul 2025 02:22:53 +0300 Subject: [PATCH 22/31] docs: fix typo in persistence (#5329) * docs: fix typo in application_structure * docs: fix typo in persistence --- docs/docs/concepts/persistence.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 87f2e6939542eb4ce61f009071d1d06a2e7dcf11 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 23:24:32 +0000 Subject: [PATCH 23/31] chore[deps]: upgrade dependencies with `uv lock --upgrade` (#5358) * chore: upgrade dependencies with `uv lock --upgrade` * linting * upgrade PR title --------- Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com> Co-authored-by: Sydney Runkle --- .github/workflows/uv_lock_ugprade.yml | 4 +- .../langgraph/checkpoint/postgres/aio.py | 2 +- .../langgraph/checkpoint/postgres/shallow.py | 2 +- .../langgraph/store/postgres/base.py | 8 +- libs/checkpoint-postgres/uv.lock | 196 +-- .../langgraph/checkpoint/sqlite/aio.py | 2 +- libs/checkpoint-sqlite/uv.lock | 196 +-- libs/checkpoint/uv.lock | 317 ++--- libs/cli/examples/graphs/storm.py | 4 +- libs/cli/langgraph_cli/config.py | 5 +- libs/cli/langgraph_cli/templates.py | 2 +- libs/cli/tests/unit_tests/cli/test_cli.py | 12 +- .../tests/unit_tests/cli/test_templates.py | 18 +- libs/cli/uv.lock | 575 +++++---- libs/langgraph/tests/test_runnable.py | 4 +- libs/langgraph/uv.lock | 1077 +++++++++-------- libs/prebuilt/uv.lock | 190 +-- libs/sdk-py/uv.lock | 154 ++- 18 files changed, 1486 insertions(+), 1282 deletions(-) diff --git a/.github/workflows/uv_lock_ugprade.yml b/.github/workflows/uv_lock_ugprade.yml index de079ec4c..75d74890c 100644 --- a/.github/workflows/uv_lock_ugprade.yml +++ b/.github/workflows/uv_lock_ugprade.yml @@ -33,8 +33,8 @@ jobs: 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/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/langgraph_cli/config.py b/libs/cli/langgraph_cli/config.py index ece457aad..cd0356350 100644 --- a/libs/cli/langgraph_cli/config.py +++ b/libs/cli/langgraph_cli/config.py @@ -602,8 +602,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 @@ -1181,7 +1180,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 --""" 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/tests/unit_tests/cli/test_cli.py b/libs/cli/tests/unit_tests/cli/test_cli.py index d07d6f7a8..268f44e00 100644 --- a/libs/cli/tests/unit_tests/cli/test_cli.py +++ b/libs/cli/tests/unit_tests/cli/test_cli.py @@ -280,9 +280,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 +570,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/uv.lock b/libs/cli/uv.lock index 839e68015..a6a0d0270 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,22 +502,22 @@ 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]] @@ -504,7 +525,8 @@ name = "langgraph-cli" version = "0.3.3" 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/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]] From d5ab8b42e081d04a3e78c6c9d9d1ecc01688680d Mon Sep 17 00:00:00 2001 From: Nick Riley Date: Mon, 7 Jul 2025 16:31:55 -0700 Subject: [PATCH 24/31] Updated examples for SummarizationNode to account for serde with persistence layers (#5257) --- docs/docs/how-tos/memory/add-memory.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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( From 6f86a8c4cbbe04e98d980eae59e7c12bf89377ad Mon Sep 17 00:00:00 2001 From: lc-arjun Date: Tue, 8 Jul 2025 06:49:13 -0700 Subject: [PATCH 25/31] Revert "docs: add -tunnel flag for node server" (#5397) Revert "docs: add -tunnel flag for node server (#5373)" This reverts commit 4abf94846241f3546a0194efd40e109745e7d005. --- docs/docs/troubleshooting/studio.md | 4 +- libs/sdk-js/client.cjs | 1 - libs/sdk-js/client.d.cts | 1 - libs/sdk-js/client.d.ts | 1 - libs/sdk-js/client.js | 1 - libs/sdk-js/docs/README.md | 26 - libs/sdk-js/docs/auth/README.md | 18 - libs/sdk-js/docs/auth/classes/Auth.md | 75 --- .../sdk-js/docs/auth/classes/HTTPException.md | 185 ------- .../docs/auth/interfaces/AuthEventValueMap.md | 481 ------------------ .../docs/auth/type-aliases/AuthFilters.md | 15 - libs/sdk-js/docs/classes/AssistantsClient.md | 385 -------------- libs/sdk-js/docs/classes/Client.md | 98 ---- libs/sdk-js/docs/classes/CronsClient.md | 151 ------ libs/sdk-js/docs/classes/RunsClient.md | 469 ----------------- libs/sdk-js/docs/classes/StoreClient.md | 314 ------------ libs/sdk-js/docs/classes/ThreadsClient.md | 433 ---------------- libs/sdk-js/docs/functions/getApiKey.md | 32 -- libs/sdk-js/docs/interfaces/ClientConfig.md | 57 --- libs/sdk-js/docs/react/README.md | 18 - libs/sdk-js/docs/react/functions/useStream.md | 27 - .../sdk-js/docs/react/interfaces/UseStream.md | 227 --------- .../docs/react/interfaces/UseStreamOptions.md | 343 ------------- .../react/type-aliases/MessageMetadata.md | 42 -- libs/sdk-js/docs/type-aliases/RequestHook.md | 25 - libs/sdk-js/index.cjs | 1 - libs/sdk-js/index.d.cts | 1 - libs/sdk-js/index.d.ts | 1 - libs/sdk-js/index.js | 1 - libs/sdk-js/react.cjs | 1 - libs/sdk-js/react.d.cts | 1 - libs/sdk-js/react.d.ts | 1 - libs/sdk-js/react.js | 1 - 33 files changed, 2 insertions(+), 3435 deletions(-) delete mode 100644 libs/sdk-js/client.cjs delete mode 100644 libs/sdk-js/client.d.cts delete mode 100644 libs/sdk-js/client.d.ts delete mode 100644 libs/sdk-js/client.js delete mode 100644 libs/sdk-js/docs/README.md delete mode 100644 libs/sdk-js/docs/auth/README.md delete mode 100644 libs/sdk-js/docs/auth/classes/Auth.md delete mode 100644 libs/sdk-js/docs/auth/classes/HTTPException.md delete mode 100644 libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md delete mode 100644 libs/sdk-js/docs/auth/type-aliases/AuthFilters.md delete mode 100644 libs/sdk-js/docs/classes/AssistantsClient.md delete mode 100644 libs/sdk-js/docs/classes/Client.md delete mode 100644 libs/sdk-js/docs/classes/CronsClient.md delete mode 100644 libs/sdk-js/docs/classes/RunsClient.md delete mode 100644 libs/sdk-js/docs/classes/StoreClient.md delete mode 100644 libs/sdk-js/docs/classes/ThreadsClient.md delete mode 100644 libs/sdk-js/docs/functions/getApiKey.md delete mode 100644 libs/sdk-js/docs/interfaces/ClientConfig.md delete mode 100644 libs/sdk-js/docs/react/README.md delete mode 100644 libs/sdk-js/docs/react/functions/useStream.md delete mode 100644 libs/sdk-js/docs/react/interfaces/UseStream.md delete mode 100644 libs/sdk-js/docs/react/interfaces/UseStreamOptions.md delete mode 100644 libs/sdk-js/docs/react/type-aliases/MessageMetadata.md delete mode 100644 libs/sdk-js/docs/type-aliases/RequestHook.md delete mode 100644 libs/sdk-js/index.cjs delete mode 100644 libs/sdk-js/index.d.cts delete mode 100644 libs/sdk-js/index.d.ts delete mode 100644 libs/sdk-js/index.js delete mode 100644 libs/sdk-js/react.cjs delete mode 100644 libs/sdk-js/react.d.cts delete mode 100644 libs/sdk-js/react.d.ts delete mode 100644 libs/sdk-js/react.js diff --git a/docs/docs/troubleshooting/studio.md b/docs/docs/troubleshooting/studio.md index 3fcbdea7f..b06f325de 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 --tunnel + npx @langchain/langgraph-cli dev ``` 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 --tunnel + npx @langchain/langgraph-cli dev ``` The command outputs a URL in this format: diff --git a/libs/sdk-js/client.cjs b/libs/sdk-js/client.cjs deleted file mode 100644 index 680e5bd38..000000000 --- a/libs/sdk-js/client.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/client.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/client.d.cts b/libs/sdk-js/client.d.cts deleted file mode 100644 index 1c03ff9cb..000000000 --- a/libs/sdk-js/client.d.cts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/client.d.ts b/libs/sdk-js/client.d.ts deleted file mode 100644 index 1c03ff9cb..000000000 --- a/libs/sdk-js/client.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/client.js b/libs/sdk-js/client.js deleted file mode 100644 index 1c03ff9cb..000000000 --- a/libs/sdk-js/client.js +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/client.js' \ No newline at end of file diff --git a/libs/sdk-js/docs/README.md b/libs/sdk-js/docs/README.md deleted file mode 100644 index a1627b448..000000000 --- a/libs/sdk-js/docs/README.md +++ /dev/null @@ -1,26 +0,0 @@ -**@langchain/langgraph-sdk** - -*** - -# @langchain/langgraph-sdk - -## Classes - -- [AssistantsClient](classes/AssistantsClient.md) -- [Client](classes/Client.md) -- [CronsClient](classes/CronsClient.md) -- [RunsClient](classes/RunsClient.md) -- [StoreClient](classes/StoreClient.md) -- [ThreadsClient](classes/ThreadsClient.md) - -## Interfaces - -- [ClientConfig](interfaces/ClientConfig.md) - -## Type Aliases - -- [RequestHook](type-aliases/RequestHook.md) - -## Functions - -- [getApiKey](functions/getApiKey.md) diff --git a/libs/sdk-js/docs/auth/README.md b/libs/sdk-js/docs/auth/README.md deleted file mode 100644 index 351cb8490..000000000 --- a/libs/sdk-js/docs/auth/README.md +++ /dev/null @@ -1,18 +0,0 @@ -**@langchain/langgraph-sdk** - -*** - -# @langchain/langgraph-sdk/auth - -## Classes - -- [Auth](classes/Auth.md) -- [HTTPException](classes/HTTPException.md) - -## Interfaces - -- [AuthEventValueMap](interfaces/AuthEventValueMap.md) - -## Type Aliases - -- [AuthFilters](type-aliases/AuthFilters.md) diff --git a/libs/sdk-js/docs/auth/classes/Auth.md b/libs/sdk-js/docs/auth/classes/Auth.md deleted file mode 100644 index 4b4cc618a..000000000 --- a/libs/sdk-js/docs/auth/classes/Auth.md +++ /dev/null @@ -1,75 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / Auth - -# Class: Auth\ - -Defined in: [src/auth/index.ts:11](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L11) - -## Type Parameters - -• **TExtra** = \{\} - -• **TAuthReturn** *extends* `BaseAuthReturn` = `BaseAuthReturn` - -• **TUser** *extends* `BaseUser` = `ToUserLike`\<`TAuthReturn`\> - -## Constructors - -### new Auth() - -> **new Auth**\<`TExtra`, `TAuthReturn`, `TUser`\>(): [`Auth`](Auth.md)\<`TExtra`, `TAuthReturn`, `TUser`\> - -#### Returns - -[`Auth`](Auth.md)\<`TExtra`, `TAuthReturn`, `TUser`\> - -## Methods - -### authenticate() - -> **authenticate**\<`T`\>(`cb`): [`Auth`](Auth.md)\<`TExtra`, `T`\> - -Defined in: [src/auth/index.ts:25](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L25) - -#### Type Parameters - -• **T** *extends* `BaseAuthReturn` - -#### Parameters - -##### cb - -`AuthenticateCallback`\<`T`\> - -#### Returns - -[`Auth`](Auth.md)\<`TExtra`, `T`\> - -*** - -### on() - -> **on**\<`T`\>(`event`, `callback`): `this` - -Defined in: [src/auth/index.ts:32](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/index.ts#L32) - -#### Type Parameters - -• **T** *extends* `CallbackEvent` - -#### Parameters - -##### event - -`T` - -##### callback - -`OnCallback`\<`T`, `TUser`\> - -#### Returns - -`this` diff --git a/libs/sdk-js/docs/auth/classes/HTTPException.md b/libs/sdk-js/docs/auth/classes/HTTPException.md deleted file mode 100644 index 0db191af5..000000000 --- a/libs/sdk-js/docs/auth/classes/HTTPException.md +++ /dev/null @@ -1,185 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / HTTPException - -# Class: HTTPException - -Defined in: [src/auth/error.ts:66](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L66) - -## Extends - -- `Error` - -## Constructors - -### new HTTPException() - -> **new HTTPException**(`status`, `options`?): [`HTTPException`](HTTPException.md) - -Defined in: [src/auth/error.ts:70](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L70) - -#### Parameters - -##### status - -`number` - -##### options? - -###### cause? - -`unknown` - -###### headers? - -`HeadersInit` - -###### message? - -`string` - -#### Returns - -[`HTTPException`](HTTPException.md) - -#### Overrides - -`Error.constructor` - -## Properties - -### cause? - -> `optional` **cause**: `unknown` - -Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:24 - -#### Inherited from - -`Error.cause` - -*** - -### headers - -> **headers**: `HeadersInit` - -Defined in: [src/auth/error.ts:68](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L68) - -*** - -### message - -> **message**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077 - -#### Inherited from - -`Error.message` - -*** - -### name - -> **name**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076 - -#### Inherited from - -`Error.name` - -*** - -### stack? - -> `optional` **stack**: `string` - -Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078 - -#### Inherited from - -`Error.stack` - -*** - -### status - -> **status**: `number` - -Defined in: [src/auth/error.ts:67](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/error.ts#L67) - -*** - -### prepareStackTrace()? - -> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` - -Defined in: node\_modules/@types/node/globals.d.ts:28 - -Optional override for formatting stack traces - -#### Parameters - -##### err - -`Error` - -##### stackTraces - -`CallSite`[] - -#### Returns - -`any` - -#### See - -https://v8.dev/docs/stack-trace-api#customizing-stack-traces - -#### Inherited from - -`Error.prepareStackTrace` - -*** - -### stackTraceLimit - -> `static` **stackTraceLimit**: `number` - -Defined in: node\_modules/@types/node/globals.d.ts:30 - -#### Inherited from - -`Error.stackTraceLimit` - -## Methods - -### captureStackTrace() - -> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` - -Defined in: node\_modules/@types/node/globals.d.ts:21 - -Create .stack property on a target object - -#### Parameters - -##### targetObject - -`object` - -##### constructorOpt? - -`Function` - -#### Returns - -`void` - -#### Inherited from - -`Error.captureStackTrace` diff --git a/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md b/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md deleted file mode 100644 index 686e1a39b..000000000 --- a/libs/sdk-js/docs/auth/interfaces/AuthEventValueMap.md +++ /dev/null @@ -1,481 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / AuthEventValueMap - -# Interface: AuthEventValueMap - -Defined in: [src/auth/types.ts:218](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L218) - -## Properties - -### assistants:create - -> **assistants:create**: `object` - -Defined in: [src/auth/types.ts:226](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L226) - -#### assistant\_id? - -> `optional` **assistant\_id**: `Maybe`\<`string`\> - -#### config? - -> `optional` **config**: `Maybe`\<`AssistantConfig`\> - -#### graph\_id - -> **graph\_id**: `string` - -#### if\_exists? - -> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### name? - -> `optional` **name**: `Maybe`\<`string`\> - -*** - -### assistants:delete - -> **assistants:delete**: `object` - -Defined in: [src/auth/types.ts:229](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L229) - -#### assistant\_id - -> **assistant\_id**: `string` - -*** - -### assistants:read - -> **assistants:read**: `object` - -Defined in: [src/auth/types.ts:227](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L227) - -#### assistant\_id - -> **assistant\_id**: `string` - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -*** - -### assistants:search - -> **assistants:search**: `object` - -Defined in: [src/auth/types.ts:230](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L230) - -#### graph\_id? - -> `optional` **graph\_id**: `Maybe`\<`string`\> - -#### limit? - -> `optional` **limit**: `Maybe`\<`number`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### offset? - -> `optional` **offset**: `Maybe`\<`number`\> - -*** - -### assistants:update - -> **assistants:update**: `object` - -Defined in: [src/auth/types.ts:228](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L228) - -#### assistant\_id - -> **assistant\_id**: `string` - -#### config? - -> `optional` **config**: `Maybe`\<`AssistantConfig`\> - -#### graph\_id? - -> `optional` **graph\_id**: `Maybe`\<`string`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### name? - -> `optional` **name**: `Maybe`\<`string`\> - -#### version? - -> `optional` **version**: `Maybe`\<`number`\> - -*** - -### crons:create - -> **crons:create**: `object` - -Defined in: [src/auth/types.ts:232](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L232) - -#### cron\_id? - -> `optional` **cron\_id**: `Maybe`\<`string`\> - -#### end\_time? - -> `optional` **end\_time**: `Maybe`\<`string`\> - -#### payload? - -> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### schedule - -> **schedule**: `string` - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -#### user\_id? - -> `optional` **user\_id**: `Maybe`\<`string`\> - -*** - -### crons:delete - -> **crons:delete**: `object` - -Defined in: [src/auth/types.ts:235](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L235) - -#### cron\_id - -> **cron\_id**: `string` - -*** - -### crons:read - -> **crons:read**: `object` - -Defined in: [src/auth/types.ts:233](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L233) - -#### cron\_id - -> **cron\_id**: `string` - -*** - -### crons:search - -> **crons:search**: `object` - -Defined in: [src/auth/types.ts:236](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L236) - -#### assistant\_id? - -> `optional` **assistant\_id**: `Maybe`\<`string`\> - -#### limit? - -> `optional` **limit**: `Maybe`\<`number`\> - -#### offset? - -> `optional` **offset**: `Maybe`\<`number`\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -*** - -### crons:update - -> **crons:update**: `object` - -Defined in: [src/auth/types.ts:234](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L234) - -#### cron\_id - -> **cron\_id**: `string` - -#### payload? - -> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### schedule? - -> `optional` **schedule**: `Maybe`\<`string`\> - -*** - -### store:delete - -> **store:delete**: `object` - -Defined in: [src/auth/types.ts:242](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L242) - -#### key - -> **key**: `string` - -#### namespace? - -> `optional` **namespace**: `Maybe`\<`string`[]\> - -*** - -### store:get - -> **store:get**: `object` - -Defined in: [src/auth/types.ts:239](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L239) - -#### key - -> **key**: `string` - -#### namespace - -> **namespace**: `Maybe`\<`string`[]\> - -*** - -### store:list\_namespaces - -> **store:list\_namespaces**: `object` - -Defined in: [src/auth/types.ts:241](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L241) - -#### limit? - -> `optional` **limit**: `Maybe`\<`number`\> - -#### max\_depth? - -> `optional` **max\_depth**: `Maybe`\<`number`\> - -#### namespace? - -> `optional` **namespace**: `Maybe`\<`string`[]\> - -#### offset? - -> `optional` **offset**: `Maybe`\<`number`\> - -#### suffix? - -> `optional` **suffix**: `Maybe`\<`string`[]\> - -*** - -### store:put - -> **store:put**: `object` - -Defined in: [src/auth/types.ts:238](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L238) - -#### key - -> **key**: `string` - -#### namespace - -> **namespace**: `string`[] - -#### value - -> **value**: `Record`\<`string`, `unknown`\> - -*** - -### store:search - -> **store:search**: `object` - -Defined in: [src/auth/types.ts:240](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L240) - -#### filter? - -> `optional` **filter**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### limit? - -> `optional` **limit**: `Maybe`\<`number`\> - -#### namespace? - -> `optional` **namespace**: `Maybe`\<`string`[]\> - -#### offset? - -> `optional` **offset**: `Maybe`\<`number`\> - -#### query? - -> `optional` **query**: `Maybe`\<`string`\> - -*** - -### threads:create - -> **threads:create**: `object` - -Defined in: [src/auth/types.ts:219](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L219) - -#### if\_exists? - -> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -*** - -### threads:create\_run - -> **threads:create\_run**: `object` - -Defined in: [src/auth/types.ts:224](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L224) - -#### after\_seconds? - -> `optional` **after\_seconds**: `Maybe`\<`number`\> - -#### assistant\_id - -> **assistant\_id**: `string` - -#### if\_not\_exists? - -> `optional` **if\_not\_exists**: `Maybe`\<`"reject"` \| `"create"`\> - -#### kwargs - -> **kwargs**: `Record`\<`string`, `unknown`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### multitask\_strategy? - -> `optional` **multitask\_strategy**: `Maybe`\<`"reject"` \| `"interrupt"` \| `"rollback"` \| `"enqueue"`\> - -#### prevent\_insert\_if\_inflight? - -> `optional` **prevent\_insert\_if\_inflight**: `Maybe`\<`boolean`\> - -#### run\_id - -> **run\_id**: `string` - -#### status - -> **status**: `Maybe`\<`"pending"` \| `"running"` \| `"error"` \| `"success"` \| `"timeout"` \| `"interrupted"`\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -*** - -### threads:delete - -> **threads:delete**: `object` - -Defined in: [src/auth/types.ts:222](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L222) - -#### run\_id? - -> `optional` **run\_id**: `Maybe`\<`string`\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -*** - -### threads:read - -> **threads:read**: `object` - -Defined in: [src/auth/types.ts:220](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L220) - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -*** - -### threads:search - -> **threads:search**: `object` - -Defined in: [src/auth/types.ts:223](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L223) - -#### limit? - -> `optional` **limit**: `Maybe`\<`number`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### offset? - -> `optional` **offset**: `Maybe`\<`number`\> - -#### status? - -> `optional` **status**: `Maybe`\<`"error"` \| `"interrupted"` \| `"idle"` \| `"busy"` \| `string` & `object`\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> - -#### values? - -> `optional` **values**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -*** - -### threads:update - -> **threads:update**: `object` - -Defined in: [src/auth/types.ts:221](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L221) - -#### action? - -> `optional` **action**: `Maybe`\<`"interrupt"` \| `"rollback"`\> - -#### metadata? - -> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\> - -#### thread\_id? - -> `optional` **thread\_id**: `Maybe`\<`string`\> diff --git a/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md b/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md deleted file mode 100644 index b9b2e1fb2..000000000 --- a/libs/sdk-js/docs/auth/type-aliases/AuthFilters.md +++ /dev/null @@ -1,15 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / AuthFilters - -# Type Alias: AuthFilters\ - -> **AuthFilters**\<`TKey`\>: \{ \[key in TKey\]: string \| \{ \[op in "$contains" \| "$eq"\]?: string \} \} - -Defined in: [src/auth/types.ts:367](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/auth/types.ts#L367) - -## Type Parameters - -• **TKey** *extends* `string` \| `number` \| `symbol` diff --git a/libs/sdk-js/docs/classes/AssistantsClient.md b/libs/sdk-js/docs/classes/AssistantsClient.md deleted file mode 100644 index 571dc16e8..000000000 --- a/libs/sdk-js/docs/classes/AssistantsClient.md +++ /dev/null @@ -1,385 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / AssistantsClient - -# Class: AssistantsClient - -Defined in: [client.ts:431](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L431) - -## Extends - -- `BaseClient` - -## Constructors - -### new AssistantsClient() - -> **new AssistantsClient**(`config`?): [`AssistantsClient`](AssistantsClient.md) - -Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`AssistantsClient`](AssistantsClient.md) - -#### Inherited from - -`BaseClient.constructor` - -## Methods - -### create() - -> **create**(`payload`): `Promise`\<`Assistant`\> - -Defined in: [client.ts:496](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L496) - -Create a new assistant. - -#### Parameters - -##### payload - -Payload for creating an assistant. - -###### assistantId? - -`string` - -###### config? - -`Config` - -###### description? - -`string` - -###### graphId - -`string` - -###### ifExists? - -`OnConflictBehavior` - -###### metadata? - -`Metadata` - -###### name? - -`string` - -#### Returns - -`Promise`\<`Assistant`\> - -The created assistant. - -*** - -### delete() - -> **delete**(`assistantId`): `Promise`\<`void`\> - -Defined in: [client.ts:552](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L552) - -Delete an assistant. - -#### Parameters - -##### assistantId - -`string` - -ID of the assistant. - -#### Returns - -`Promise`\<`void`\> - -*** - -### get() - -> **get**(`assistantId`): `Promise`\<`Assistant`\> - -Defined in: [client.ts:438](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L438) - -Get an assistant by ID. - -#### Parameters - -##### assistantId - -`string` - -The ID of the assistant. - -#### Returns - -`Promise`\<`Assistant`\> - -Assistant - -*** - -### getGraph() - -> **getGraph**(`assistantId`, `options`?): `Promise`\<`AssistantGraph`\> - -Defined in: [client.ts:448](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L448) - -Get the JSON representation of the graph assigned to a runnable - -#### Parameters - -##### assistantId - -`string` - -The ID of the assistant. - -##### options? - -###### xray? - -`number` \| `boolean` - -Whether to include subgraphs in the serialized graph representation. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included. - -#### Returns - -`Promise`\<`AssistantGraph`\> - -Serialized graph - -*** - -### getSchemas() - -> **getSchemas**(`assistantId`): `Promise`\<`GraphSchema`\> - -Defined in: [client.ts:462](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L462) - -Get the state and config schema of the graph assigned to a runnable - -#### Parameters - -##### assistantId - -`string` - -The ID of the assistant. - -#### Returns - -`Promise`\<`GraphSchema`\> - -Graph schema - -*** - -### getSubgraphs() - -> **getSubgraphs**(`assistantId`, `options`?): `Promise`\<`Subgraphs`\> - -Defined in: [client.ts:473](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L473) - -Get the schemas of an assistant by ID. - -#### Parameters - -##### assistantId - -`string` - -The ID of the assistant to get the schema of. - -##### options? - -Additional options for getting subgraphs, such as namespace or recursion extraction. - -###### namespace? - -`string` - -###### recurse? - -`boolean` - -#### Returns - -`Promise`\<`Subgraphs`\> - -The subgraphs of the assistant. - -*** - -### getVersions() - -> **getVersions**(`assistantId`, `payload`?): `Promise`\<`AssistantVersion`[]\> - -Defined in: [client.ts:590](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L590) - -List all versions of an assistant. - -#### Parameters - -##### assistantId - -`string` - -ID of the assistant. - -##### payload? - -###### limit? - -`number` - -###### metadata? - -`Metadata` - -###### offset? - -`number` - -#### Returns - -`Promise`\<`AssistantVersion`[]\> - -List of assistant versions. - -*** - -### search() - -> **search**(`query`?): `Promise`\<`Assistant`[]\> - -Defined in: [client.ts:563](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L563) - -List assistants. - -#### Parameters - -##### query? - -Query options. - -###### graphId? - -`string` - -###### limit? - -`number` - -###### metadata? - -`Metadata` - -###### offset? - -`number` - -###### sortBy? - -`AssistantSortBy` - -###### sortOrder? - -`SortOrder` - -#### Returns - -`Promise`\<`Assistant`[]\> - -List of assistants. - -*** - -### setLatest() - -> **setLatest**(`assistantId`, `version`): `Promise`\<`Assistant`\> - -Defined in: [client.ts:618](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L618) - -Change the version of an assistant. - -#### Parameters - -##### assistantId - -`string` - -ID of the assistant. - -##### version - -`number` - -The version to change to. - -#### Returns - -`Promise`\<`Assistant`\> - -The updated assistant. - -*** - -### update() - -> **update**(`assistantId`, `payload`): `Promise`\<`Assistant`\> - -Defined in: [client.ts:525](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L525) - -Update an assistant. - -#### Parameters - -##### assistantId - -`string` - -ID of the assistant. - -##### payload - -Payload for updating the assistant. - -###### config? - -`Config` - -###### description? - -`string` - -###### graphId? - -`string` - -###### metadata? - -`Metadata` - -###### name? - -`string` - -#### Returns - -`Promise`\<`Assistant`\> - -The updated assistant. diff --git a/libs/sdk-js/docs/classes/Client.md b/libs/sdk-js/docs/classes/Client.md deleted file mode 100644 index b0afc23de..000000000 --- a/libs/sdk-js/docs/classes/Client.md +++ /dev/null @@ -1,98 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / Client - -# Class: Client\ - -Defined in: [client.ts:1620](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1620) - -## Type Parameters - -• **TStateType** = `DefaultValues` - -• **TUpdateType** = `TStateType` - -• **TCustomEventType** = `unknown` - -## Constructors - -### new Client() - -> **new Client**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`Client`](Client.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> - -Defined in: [client.ts:1656](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1656) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`Client`](Client.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> - -## Properties - -### ~ui - -> **~ui**: `UiClient` - -Defined in: [client.ts:1654](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1654) - -**`Internal`** - -The client for interacting with the UI. - Used by LoadExternalComponent and the API might change in the future. - -*** - -### assistants - -> **assistants**: [`AssistantsClient`](AssistantsClient.md) - -Defined in: [client.ts:1628](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1628) - -The client for interacting with assistants. - -*** - -### crons - -> **crons**: [`CronsClient`](CronsClient.md) - -Defined in: [client.ts:1643](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1643) - -The client for interacting with cron runs. - -*** - -### runs - -> **runs**: [`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> - -Defined in: [client.ts:1638](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1638) - -The client for interacting with runs. - -*** - -### store - -> **store**: [`StoreClient`](StoreClient.md) - -Defined in: [client.ts:1648](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1648) - -The client for interacting with the KV store. - -*** - -### threads - -> **threads**: [`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> - -Defined in: [client.ts:1633](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1633) - -The client for interacting with threads. diff --git a/libs/sdk-js/docs/classes/CronsClient.md b/libs/sdk-js/docs/classes/CronsClient.md deleted file mode 100644 index ae0017d9c..000000000 --- a/libs/sdk-js/docs/classes/CronsClient.md +++ /dev/null @@ -1,151 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / CronsClient - -# Class: CronsClient - -Defined in: [client.ts:334](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L334) - -## Extends - -- `BaseClient` - -## Constructors - -### new CronsClient() - -> **new CronsClient**(`config`?): [`CronsClient`](CronsClient.md) - -Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`CronsClient`](CronsClient.md) - -#### Inherited from - -`BaseClient.constructor` - -## Methods - -### create() - -> **create**(`assistantId`, `payload`?): `Promise`\<`CronCreateResponse`\> - -Defined in: [client.ts:375](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L375) - -#### Parameters - -##### assistantId - -`string` - -Assistant ID to use for this cron job. - -##### payload? - -`CronsCreatePayload` - -Payload for creating a cron job. - -#### Returns - -`Promise`\<`CronCreateResponse`\> - -*** - -### createForThread() - -> **createForThread**(`threadId`, `assistantId`, `payload`?): `Promise`\<`CronCreateForThreadResponse`\> - -Defined in: [client.ts:342](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L342) - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### assistantId - -`string` - -Assistant ID to use for this cron job. - -##### payload? - -`CronsCreatePayload` - -Payload for creating a cron job. - -#### Returns - -`Promise`\<`CronCreateForThreadResponse`\> - -The created background run. - -*** - -### delete() - -> **delete**(`cronId`): `Promise`\<`void`\> - -Defined in: [client.ts:402](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L402) - -#### Parameters - -##### cronId - -`string` - -Cron ID of Cron job to delete. - -#### Returns - -`Promise`\<`void`\> - -*** - -### search() - -> **search**(`query`?): `Promise`\<`Cron`[]\> - -Defined in: [client.ts:413](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L413) - -#### Parameters - -##### query? - -Query options. - -###### assistantId? - -`string` - -###### limit? - -`number` - -###### offset? - -`number` - -###### threadId? - -`string` - -#### Returns - -`Promise`\<`Cron`[]\> - -List of crons. diff --git a/libs/sdk-js/docs/classes/RunsClient.md b/libs/sdk-js/docs/classes/RunsClient.md deleted file mode 100644 index 15f666453..000000000 --- a/libs/sdk-js/docs/classes/RunsClient.md +++ /dev/null @@ -1,469 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / RunsClient - -# Class: RunsClient\ - -Defined in: [client.ts:912](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L912) - -## Extends - -- `BaseClient` - -## Type Parameters - -• **TStateType** = `DefaultValues` - -• **TUpdateType** = `TStateType` - -• **TCustomEventType** = `unknown` - -## Constructors - -### new RunsClient() - -> **new RunsClient**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> - -Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`RunsClient`](RunsClient.md)\<`TStateType`, `TUpdateType`, `TCustomEventType`\> - -#### Inherited from - -`BaseClient.constructor` - -## Methods - -### cancel() - -> **cancel**(`threadId`, `runId`, `wait`, `action`): `Promise`\<`void`\> - -Defined in: [client.ts:1227](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1227) - -Cancel a run. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### runId - -`string` - -The ID of the run. - -##### wait - -`boolean` = `false` - -Whether to block when canceling - -##### action - -`CancelAction` = `"interrupt"` - -Action to take when cancelling the run. Possible values are `interrupt` or `rollback`. Default is `interrupt`. - -#### Returns - -`Promise`\<`void`\> - -*** - -### create() - -> **create**(`threadId`, `assistantId`, `payload`?): `Promise`\<`Run`\> - -Defined in: [client.ts:1026](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1026) - -Create a run. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### assistantId - -`string` - -Assistant ID to use for this run. - -##### payload? - -`RunsCreatePayload` - -Payload for creating a run. - -#### Returns - -`Promise`\<`Run`\> - -The created run. - -*** - -### createBatch() - -> **createBatch**(`payloads`): `Promise`\<`Run`[]\> - -Defined in: [client.ts:1076](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1076) - -Create a batch of stateless background runs. - -#### Parameters - -##### payloads - -`RunsCreatePayload` & `object`[] - -An array of payloads for creating runs. - -#### Returns - -`Promise`\<`Run`[]\> - -An array of created runs. - -*** - -### delete() - -> **delete**(`threadId`, `runId`): `Promise`\<`void`\> - -Defined in: [client.ts:1329](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1329) - -Delete a run. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### runId - -`string` - -The ID of the run. - -#### Returns - -`Promise`\<`void`\> - -*** - -### get() - -> **get**(`threadId`, `runId`): `Promise`\<`Run`\> - -Defined in: [client.ts:1214](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1214) - -Get a run by ID. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### runId - -`string` - -The ID of the run. - -#### Returns - -`Promise`\<`Run`\> - -The run. - -*** - -### join() - -> **join**(`threadId`, `runId`, `options`?): `Promise`\<`void`\> - -Defined in: [client.ts:1249](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1249) - -Block until a run is done. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### runId - -`string` - -The ID of the run. - -##### options? - -###### signal? - -`AbortSignal` - -#### Returns - -`Promise`\<`void`\> - -*** - -### joinStream() - -> **joinStream**(`threadId`, `runId`, `options`?): `AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; `id`: `string`; \}\> - -Defined in: [client.ts:1274](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1274) - -Stream output from a run in real-time, until the run is done. - -#### Parameters - -##### threadId - -The ID of the thread. Can be set to `null` | `undefined` for stateless runs. - -`undefined` | `null` | `string` - -##### runId - -`string` - -The ID of the run. - -##### options? - -Additional options for controlling the stream behavior: - - signal: An AbortSignal that can be used to cancel the stream request - - lastEventId: The ID of the last event received. Can be used to reconnect to a stream without losing events. - - cancelOnDisconnect: When true, automatically cancels the run if the client disconnects from the stream - - streamMode: Controls what types of events to receive from the stream (can be a single mode or array of modes) - Must be a subset of the stream modes passed when creating the run. Background runs default to having the union of all - stream modes enabled. - -`AbortSignal` | \{ `cancelOnDisconnect`: `boolean`; `lastEventId`: `string`; `signal`: `AbortSignal`; `streamMode`: `StreamMode` \| `StreamMode`[]; \} - -#### Returns - -`AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; `id`: `string`; \}\> - -An async generator yielding stream parts. - -*** - -### list() - -> **list**(`threadId`, `options`?): `Promise`\<`Run`[]\> - -Defined in: [client.ts:1177](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1177) - -List all runs for a thread. - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### options? - -Filtering and pagination options. - -###### limit? - -`number` - -Maximum number of runs to return. -Defaults to 10 - -###### offset? - -`number` - -Offset to start from. -Defaults to 0. - -###### status? - -`RunStatus` - -Status of the run to filter by. - -#### Returns - -`Promise`\<`Run`[]\> - -List of runs. - -*** - -### stream() - -Create a run and stream the results. - -#### Param - -The ID of the thread. - -#### Param - -Assistant ID to use for this run. - -#### Param - -Payload for creating a run. - -#### Call Signature - -> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> - -Defined in: [client.ts:917](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L917) - -##### Type Parameters - -• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode` - -• **TSubgraphs** *extends* `boolean` = `false` - -##### Parameters - -###### threadId - -`null` - -###### assistantId - -`string` - -###### payload? - -`Omit`\<`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\>, `"multitaskStrategy"` \| `"onCompletion"`\> - -##### Returns - -`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> - -#### Call Signature - -> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> - -Defined in: [client.ts:935](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L935) - -##### Type Parameters - -• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode` - -• **TSubgraphs** *extends* `boolean` = `false` - -##### Parameters - -###### threadId - -`string` - -###### assistantId - -`string` - -###### payload? - -`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\> - -##### Returns - -`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\> - -*** - -### wait() - -Create a run and wait for it to complete. - -#### Param - -The ID of the thread. - -#### Param - -Assistant ID to use for this run. - -#### Param - -Payload for creating a run. - -#### Call Signature - -> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\> - -Defined in: [client.ts:1093](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1093) - -##### Parameters - -###### threadId - -`null` - -###### assistantId - -`string` - -###### payload? - -`Omit`\<`RunsWaitPayload`, `"multitaskStrategy"` \| `"onCompletion"`\> - -##### Returns - -`Promise`\<`DefaultValues`\> - -#### Call Signature - -> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\> - -Defined in: [client.ts:1099](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1099) - -##### Parameters - -###### threadId - -`string` - -###### assistantId - -`string` - -###### payload? - -`RunsWaitPayload` - -##### Returns - -`Promise`\<`DefaultValues`\> diff --git a/libs/sdk-js/docs/classes/StoreClient.md b/libs/sdk-js/docs/classes/StoreClient.md deleted file mode 100644 index 97e223da3..000000000 --- a/libs/sdk-js/docs/classes/StoreClient.md +++ /dev/null @@ -1,314 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / StoreClient - -# Class: StoreClient - -Defined in: [client.ts:1347](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1347) - -## Extends - -- `BaseClient` - -## Constructors - -### new StoreClient() - -> **new StoreClient**(`config`?): [`StoreClient`](StoreClient.md) - -Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`StoreClient`](StoreClient.md) - -#### Inherited from - -`BaseClient.constructor` - -## Methods - -### deleteItem() - -> **deleteItem**(`namespace`, `key`): `Promise`\<`void`\> - -Defined in: [client.ts:1468](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1468) - -Delete an item. - -#### Parameters - -##### namespace - -`string`[] - -A list of strings representing the namespace path. - -##### key - -`string` - -The unique identifier for the item. - -#### Returns - -`Promise`\<`void`\> - -Promise - -*** - -### getItem() - -> **getItem**(`namespace`, `key`, `options`?): `Promise`\<`null` \| `Item`\> - -Defined in: [client.ts:1424](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1424) - -Retrieve a single item. - -#### Parameters - -##### namespace - -`string`[] - -A list of strings representing the namespace path. - -##### key - -`string` - -The unique identifier for the item. - -##### options? - -###### refreshTtl? - -`null` \| `boolean` - -Whether to refresh the TTL on this read operation. If null, uses the store's default behavior. - -#### Returns - -`Promise`\<`null` \| `Item`\> - -Promise - -#### Example - -```typescript -const item = await client.store.getItem( - ["documents", "user123"], - "item456", - { refreshTtl: true } -); -console.log(item); -// { -// namespace: ["documents", "user123"], -// key: "item456", -// value: { title: "My Document", content: "Hello World" }, -// createdAt: "2024-07-30T12:00:00Z", -// updatedAt: "2024-07-30T12:00:00Z" -// } -``` - -*** - -### listNamespaces() - -> **listNamespaces**(`options`?): `Promise`\<`ListNamespaceResponse`\> - -Defined in: [client.ts:1564](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1564) - -List namespaces with optional match conditions. - -#### Parameters - -##### options? - -###### limit? - -`number` - -Maximum number of namespaces to return (default is 100). - -###### maxDepth? - -`number` - -Optional integer specifying the maximum depth of namespaces to return. - -###### offset? - -`number` - -Number of namespaces to skip before returning results (default is 0). - -###### prefix? - -`string`[] - -Optional list of strings representing the prefix to filter namespaces. - -###### suffix? - -`string`[] - -Optional list of strings representing the suffix to filter namespaces. - -#### Returns - -`Promise`\<`ListNamespaceResponse`\> - -Promise - -*** - -### putItem() - -> **putItem**(`namespace`, `key`, `value`, `options`?): `Promise`\<`void`\> - -Defined in: [client.ts:1368](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1368) - -Store or update an item. - -#### Parameters - -##### namespace - -`string`[] - -A list of strings representing the namespace path. - -##### key - -`string` - -The unique identifier for the item within the namespace. - -##### value - -`Record`\<`string`, `any`\> - -A dictionary containing the item's data. - -##### options? - -###### index? - -`null` \| `false` \| `string`[] - -Controls search indexing - null (use defaults), false (disable), or list of field paths to index. - -###### ttl? - -`null` \| `number` - -Optional time-to-live in minutes for the item, or null for no expiration. - -#### Returns - -`Promise`\<`void`\> - -Promise - -#### Example - -```typescript -await client.store.putItem( - ["documents", "user123"], - "item456", - { title: "My Document", content: "Hello World" }, - { ttl: 60 } // expires in 60 minutes -); -``` - -*** - -### searchItems() - -> **searchItems**(`namespacePrefix`, `options`?): `Promise`\<`SearchItemsResponse`\> - -Defined in: [client.ts:1519](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L1519) - -Search for items within a namespace prefix. - -#### Parameters - -##### namespacePrefix - -`string`[] - -List of strings representing the namespace prefix. - -##### options? - -###### filter? - -`Record`\<`string`, `any`\> - -Optional dictionary of key-value pairs to filter results. - -###### limit? - -`number` - -Maximum number of items to return (default is 10). - -###### offset? - -`number` - -Number of items to skip before returning results (default is 0). - -###### query? - -`string` - -Optional search query. - -###### refreshTtl? - -`null` \| `boolean` - -Whether to refresh the TTL on items returned by this search. If null, uses the store's default behavior. - -#### Returns - -`Promise`\<`SearchItemsResponse`\> - -Promise - -#### Example - -```typescript -const results = await client.store.searchItems( - ["documents"], - { - filter: { author: "John Doe" }, - limit: 5, - refreshTtl: true - } -); -console.log(results); -// { -// items: [ -// { -// namespace: ["documents", "user123"], -// key: "item789", -// value: { title: "Another Document", author: "John Doe" }, -// createdAt: "2024-07-30T12:00:00Z", -// updatedAt: "2024-07-30T12:00:00Z" -// }, -// // ... additional items ... -// ] -// } -``` diff --git a/libs/sdk-js/docs/classes/ThreadsClient.md b/libs/sdk-js/docs/classes/ThreadsClient.md deleted file mode 100644 index 7dc422c98..000000000 --- a/libs/sdk-js/docs/classes/ThreadsClient.md +++ /dev/null @@ -1,433 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / ThreadsClient - -# Class: ThreadsClient\ - -Defined in: [client.ts:626](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L626) - -## Extends - -- `BaseClient` - -## Type Parameters - -• **TStateType** = `DefaultValues` - -• **TUpdateType** = `TStateType` - -## Constructors - -### new ThreadsClient() - -> **new ThreadsClient**\<`TStateType`, `TUpdateType`\>(`config`?): [`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> - -Defined in: [client.ts:183](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L183) - -#### Parameters - -##### config? - -[`ClientConfig`](../interfaces/ClientConfig.md) - -#### Returns - -[`ThreadsClient`](ThreadsClient.md)\<`TStateType`, `TUpdateType`\> - -#### Inherited from - -`BaseClient.constructor` - -## Methods - -### copy() - -> **copy**(`threadId`): `Promise`\<`Thread`\<`TStateType`\>\> - -Defined in: [client.ts:703](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L703) - -Copy an existing thread - -#### Parameters - -##### threadId - -`string` - -ID of the thread to be copied - -#### Returns - -`Promise`\<`Thread`\<`TStateType`\>\> - -Newly copied thread - -*** - -### create() - -> **create**(`payload`?): `Promise`\<`Thread`\<`TStateType`\>\> - -Defined in: [client.ts:648](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L648) - -Create a new thread. - -#### Parameters - -##### payload? - -Payload for creating a thread. - -###### graphId? - -`string` - -Graph ID to associate with the thread. - -###### ifExists? - -`OnConflictBehavior` - -How to handle duplicate creation. - -**Default** - -```ts -"raise" -``` - -###### metadata? - -`Metadata` - -Metadata for the thread. - -###### supersteps? - -`object`[] - -Apply a list of supersteps when creating a thread, each containing a sequence of updates. - -Used for copying a thread between deployments. - -###### threadId? - -`string` - -ID of the thread to create. - -If not provided, a random UUID will be generated. - -#### Returns - -`Promise`\<`Thread`\<`TStateType`\>\> - -The created thread. - -*** - -### delete() - -> **delete**(`threadId`): `Promise`\<`void`\> - -Defined in: [client.ts:736](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L736) - -Delete a thread. - -#### Parameters - -##### threadId - -`string` - -ID of the thread. - -#### Returns - -`Promise`\<`void`\> - -*** - -### get() - -> **get**\<`ValuesType`\>(`threadId`): `Promise`\<`Thread`\<`ValuesType`\>\> - -Defined in: [client.ts:636](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L636) - -Get a thread by ID. - -#### Type Parameters - -• **ValuesType** = `TStateType` - -#### Parameters - -##### threadId - -`string` - -ID of the thread. - -#### Returns - -`Promise`\<`Thread`\<`ValuesType`\>\> - -The thread. - -*** - -### getHistory() - -> **getHistory**\<`ValuesType`\>(`threadId`, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>[]\> - -Defined in: [client.ts:888](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L888) - -Get all past states for a thread. - -#### Type Parameters - -• **ValuesType** = `TStateType` - -#### Parameters - -##### threadId - -`string` - -ID of the thread. - -##### options? - -Additional options. - -###### before? - -`Config` - -###### checkpoint? - -`Partial`\<`Omit`\<`Checkpoint`, `"thread_id"`\>\> - -###### limit? - -`number` - -###### metadata? - -`Metadata` - -#### Returns - -`Promise`\<`ThreadState`\<`ValuesType`\>[]\> - -List of thread states. - -*** - -### getState() - -> **getState**\<`ValuesType`\>(`threadId`, `checkpoint`?, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>\> - -Defined in: [client.ts:795](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L795) - -Get state for a thread. - -#### Type Parameters - -• **ValuesType** = `TStateType` - -#### Parameters - -##### threadId - -`string` - -ID of the thread. - -##### checkpoint? - -`string` | `Checkpoint` - -##### options? - -###### subgraphs? - -`boolean` - -#### Returns - -`Promise`\<`ThreadState`\<`ValuesType`\>\> - -Thread state. - -*** - -### patchState() - -> **patchState**(`threadIdOrConfig`, `metadata`): `Promise`\<`void`\> - -Defined in: [client.ts:858](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L858) - -Patch the metadata of a thread. - -#### Parameters - -##### threadIdOrConfig - -Thread ID or config to patch the state of. - -`string` | `Config` - -##### metadata - -`Metadata` - -Metadata to patch the state with. - -#### Returns - -`Promise`\<`void`\> - -*** - -### search() - -> **search**\<`ValuesType`\>(`query`?): `Promise`\<`Thread`\<`ValuesType`\>[]\> - -Defined in: [client.ts:748](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L748) - -List threads - -#### Type Parameters - -• **ValuesType** = `TStateType` - -#### Parameters - -##### query? - -Query options - -###### limit? - -`number` - -Maximum number of threads to return. -Defaults to 10 - -###### metadata? - -`Metadata` - -Metadata to filter threads by. - -###### offset? - -`number` - -Offset to start from. - -###### sortBy? - -`ThreadSortBy` - -Sort by. - -###### sortOrder? - -`SortOrder` - -Sort order. -Must be one of 'asc' or 'desc'. - -###### status? - -`ThreadStatus` - -Thread status to filter on. - -#### Returns - -`Promise`\<`Thread`\<`ValuesType`\>[]\> - -List of threads - -*** - -### update() - -> **update**(`threadId`, `payload`?): `Promise`\<`Thread`\<`DefaultValues`\>\> - -Defined in: [client.ts:716](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L716) - -Update a thread. - -#### Parameters - -##### threadId - -`string` - -ID of the thread. - -##### payload? - -Payload for updating the thread. - -###### metadata? - -`Metadata` - -Metadata for the thread. - -#### Returns - -`Promise`\<`Thread`\<`DefaultValues`\>\> - -The updated thread. - -*** - -### updateState() - -> **updateState**\<`ValuesType`\>(`threadId`, `options`): `Promise`\<`Pick`\<`Config`, `"configurable"`\>\> - -Defined in: [client.ts:829](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L829) - -Add state to a thread. - -#### Type Parameters - -• **ValuesType** = `TUpdateType` - -#### Parameters - -##### threadId - -`string` - -The ID of the thread. - -##### options - -###### asNode? - -`string` - -###### checkpoint? - -`Checkpoint` - -###### checkpointId? - -`string` - -###### values - -`ValuesType` - -#### Returns - -`Promise`\<`Pick`\<`Config`, `"configurable"`\>\> diff --git a/libs/sdk-js/docs/functions/getApiKey.md b/libs/sdk-js/docs/functions/getApiKey.md deleted file mode 100644 index 8c8e4f1fa..000000000 --- a/libs/sdk-js/docs/functions/getApiKey.md +++ /dev/null @@ -1,32 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / getApiKey - -# Function: getApiKey() - -> **getApiKey**(`apiKey`?): `undefined` \| `string` - -Defined in: [client.ts:122](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L122) - -Get the API key from the environment. -Precedence: - 1. explicit argument - 2. LANGGRAPH_API_KEY - 3. LANGSMITH_API_KEY - 4. LANGCHAIN_API_KEY - -## Parameters - -### apiKey? - -`string` - -Optional API key provided as an argument - -## Returns - -`undefined` \| `string` - -The API key if found, otherwise undefined diff --git a/libs/sdk-js/docs/interfaces/ClientConfig.md b/libs/sdk-js/docs/interfaces/ClientConfig.md deleted file mode 100644 index 38c402010..000000000 --- a/libs/sdk-js/docs/interfaces/ClientConfig.md +++ /dev/null @@ -1,57 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / ClientConfig - -# Interface: ClientConfig - -Defined in: [client.ts:163](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L163) - -## Properties - -### apiKey? - -> `optional` **apiKey**: `string` - -Defined in: [client.ts:165](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L165) - -*** - -### apiUrl? - -> `optional` **apiUrl**: `string` - -Defined in: [client.ts:164](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L164) - -*** - -### callerOptions? - -> `optional` **callerOptions**: `AsyncCallerParams` - -Defined in: [client.ts:166](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L166) - -*** - -### defaultHeaders? - -> `optional` **defaultHeaders**: `Record`\<`string`, `HeaderValue`\> - -Defined in: [client.ts:168](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L168) - -*** - -### onRequest? - -> `optional` **onRequest**: [`RequestHook`](../type-aliases/RequestHook.md) - -Defined in: [client.ts:169](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L169) - -*** - -### timeoutMs? - -> `optional` **timeoutMs**: `number` - -Defined in: [client.ts:167](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L167) diff --git a/libs/sdk-js/docs/react/README.md b/libs/sdk-js/docs/react/README.md deleted file mode 100644 index 0933ca79b..000000000 --- a/libs/sdk-js/docs/react/README.md +++ /dev/null @@ -1,18 +0,0 @@ -**@langchain/langgraph-sdk** - -*** - -# @langchain/langgraph-sdk/react - -## Interfaces - -- [UseStream](interfaces/UseStream.md) -- [UseStreamOptions](interfaces/UseStreamOptions.md) - -## Type Aliases - -- [MessageMetadata](type-aliases/MessageMetadata.md) - -## Functions - -- [useStream](functions/useStream.md) diff --git a/libs/sdk-js/docs/react/functions/useStream.md b/libs/sdk-js/docs/react/functions/useStream.md deleted file mode 100644 index a9cb7d468..000000000 --- a/libs/sdk-js/docs/react/functions/useStream.md +++ /dev/null @@ -1,27 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / useStream - -# Function: useStream() - -> **useStream**\<`StateType`, `Bag`\>(`options`): [`UseStream`](../interfaces/UseStream.md)\<`StateType`, `Bag`\> - -Defined in: [react/stream.tsx:652](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L652) - -## Type Parameters - -• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> - -• **Bag** *extends* `object` = `BagTemplate` - -## Parameters - -### options - -[`UseStreamOptions`](../interfaces/UseStreamOptions.md)\<`StateType`, `Bag`\> - -## Returns - -[`UseStream`](../interfaces/UseStream.md)\<`StateType`, `Bag`\> diff --git a/libs/sdk-js/docs/react/interfaces/UseStream.md b/libs/sdk-js/docs/react/interfaces/UseStream.md deleted file mode 100644 index 06d1c4375..000000000 --- a/libs/sdk-js/docs/react/interfaces/UseStream.md +++ /dev/null @@ -1,227 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / UseStream - -# Interface: UseStream\ - -Defined in: [react/stream.tsx:529](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L529) - -## Type Parameters - -• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> - -• **Bag** *extends* `BagTemplate` = `BagTemplate` - -## Properties - -### assistantId - -> **assistantId**: `string` - -Defined in: [react/stream.tsx:614](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L614) - -The ID of the assistant to use. - -*** - -### branch - -> **branch**: `string` - -Defined in: [react/stream.tsx:564](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L564) - -The current branch of the thread. - -*** - -### client - -> **client**: `Client` - -Defined in: [react/stream.tsx:609](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L609) - -LangGraph SDK client used to send request and receive responses. - -*** - -### error - -> **error**: `unknown` - -Defined in: [react/stream.tsx:541](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L541) - -Last seen error from the thread or during streaming. - -*** - -### experimental\_branchTree - -> **experimental\_branchTree**: `Sequence`\<`StateType`\> - -Defined in: [react/stream.tsx:580](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L580) - -**`Experimental`** - -Tree of all branches for the thread. - -*** - -### getMessagesMetadata() - -> **getMessagesMetadata**: (`message`, `index`?) => `undefined` \| [`MessageMetadata`](../type-aliases/MessageMetadata.md)\<`StateType`\> - -Defined in: [react/stream.tsx:601](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L601) - -Get the metadata for a message, such as first thread state the message -was seen in and branch information. - -#### Parameters - -##### message - -`Message` - -The message to get the metadata for. - -##### index? - -`number` - -The index of the message in the thread. - -#### Returns - -`undefined` \| [`MessageMetadata`](../type-aliases/MessageMetadata.md)\<`StateType`\> - -The metadata for the message. - -*** - -### history - -> **history**: `ThreadState`\<`StateType`\>[] - -Defined in: [react/stream.tsx:574](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L574) - -Flattened history of thread states of a thread. - -*** - -### interrupt - -> **interrupt**: `undefined` \| `Interrupt`\<`GetInterruptType`\<`Bag`\>\> - -Defined in: [react/stream.tsx:585](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L585) - -Get the interrupt value for the stream if interrupted. - -*** - -### isLoading - -> **isLoading**: `boolean` - -Defined in: [react/stream.tsx:546](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L546) - -Whether the stream is currently running. - -*** - -### joinStream() - -> **joinStream**: (`runId`) => `Promise`\<`void`\> - -Defined in: [react/stream.tsx:619](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L619) - -Join an active stream. - -#### Parameters - -##### runId - -`string` - -#### Returns - -`Promise`\<`void`\> - -*** - -### messages - -> **messages**: `Message`[] - -Defined in: [react/stream.tsx:591](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L591) - -Messages inferred from the thread. -Will automatically update with incoming message chunks. - -*** - -### setBranch() - -> **setBranch**: (`branch`) => `void` - -Defined in: [react/stream.tsx:569](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L569) - -Set the branch of the thread. - -#### Parameters - -##### branch - -`string` - -#### Returns - -`void` - -*** - -### stop() - -> **stop**: () => `void` - -Defined in: [react/stream.tsx:551](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L551) - -Stops the stream. - -#### Returns - -`void` - -*** - -### submit() - -> **submit**: (`values`, `options`?) => `void` - -Defined in: [react/stream.tsx:556](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L556) - -Create and stream a run to the thread. - -#### Parameters - -##### values - -`undefined` | `null` | `GetUpdateType`\<`Bag`, `StateType`\> - -##### options? - -`SubmitOptions`\<`StateType`, `GetConfigurableType`\<`Bag`\>\> - -#### Returns - -`void` - -*** - -### values - -> **values**: `StateType` - -Defined in: [react/stream.tsx:536](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L536) - -The current values of the thread. diff --git a/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md b/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md deleted file mode 100644 index 9fbb6f702..000000000 --- a/libs/sdk-js/docs/react/interfaces/UseStreamOptions.md +++ /dev/null @@ -1,343 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / UseStreamOptions - -# Interface: UseStreamOptions\ - -Defined in: [react/stream.tsx:413](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L413) - -## Type Parameters - -• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\> - -• **Bag** *extends* `BagTemplate` = `BagTemplate` - -## Properties - -### apiKey? - -> `optional` **apiKey**: `string` - -Defined in: [react/stream.tsx:435](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L435) - -The API key to use. - -*** - -### apiUrl? - -> `optional` **apiUrl**: `string` - -Defined in: [react/stream.tsx:430](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L430) - -The URL of the API to use. - -*** - -### assistantId - -> **assistantId**: `string` - -Defined in: [react/stream.tsx:420](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L420) - -The ID of the assistant to use. - -*** - -### callerOptions? - -> `optional` **callerOptions**: `AsyncCallerParams` - -Defined in: [react/stream.tsx:440](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L440) - -Custom call options, such as custom fetch implementation. - -*** - -### client? - -> `optional` **client**: `Client`\<`DefaultValues`, `DefaultValues`, `unknown`\> - -Defined in: [react/stream.tsx:425](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L425) - -Client used to send requests. - -*** - -### defaultHeaders? - -> `optional` **defaultHeaders**: `Record`\<`string`, `HeaderValue`\> - -Defined in: [react/stream.tsx:445](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L445) - -Default headers to send with requests. - -*** - -### messagesKey? - -> `optional` **messagesKey**: `string` - -Defined in: [react/stream.tsx:453](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L453) - -Specify the key within the state that contains messages. -Defaults to "messages". - -#### Default - -```ts -"messages" -``` - -*** - -### onCreated()? - -> `optional` **onCreated**: (`run`) => `void` - -Defined in: [react/stream.tsx:471](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L471) - -Callback that is called when a new stream is created. - -#### Parameters - -##### run - -`RunCallbackMeta` - -#### Returns - -`void` - -*** - -### onCustomEvent()? - -> `optional` **onCustomEvent**: (`data`, `options`) => `void` - -Defined in: [react/stream.tsx:483](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L483) - -Callback that is called when a custom event is received. - -#### Parameters - -##### data - -`GetCustomEventType`\<`Bag`\> - -##### options - -###### mutate - -(`update`) => `void` - -#### Returns - -`void` - -*** - -### onDebugEvent()? - -> `optional` **onDebugEvent**: (`data`) => `void` - -Defined in: [react/stream.tsx:507](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L507) - -**`Internal`** - -Callback that is called when a debug event is received. - This API is experimental and subject to change. - -#### Parameters - -##### data - -`unknown` - -#### Returns - -`void` - -*** - -### onError()? - -> `optional` **onError**: (`error`, `run`) => `void` - -Defined in: [react/stream.tsx:458](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L458) - -Callback that is called when an error occurs. - -#### Parameters - -##### error - -`unknown` - -##### run - -`undefined` | `RunCallbackMeta` - -#### Returns - -`void` - -*** - -### onFinish()? - -> `optional` **onFinish**: (`state`, `run`) => `void` - -Defined in: [react/stream.tsx:463](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L463) - -Callback that is called when the stream is finished. - -#### Parameters - -##### state - -`ThreadState`\<`StateType`\> - -##### run - -`undefined` | `RunCallbackMeta` - -#### Returns - -`void` - -*** - -### onLangChainEvent()? - -> `optional` **onLangChainEvent**: (`data`) => `void` - -Defined in: [react/stream.tsx:501](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L501) - -Callback that is called when a LangChain event is received. - -#### Parameters - -##### data - -###### data - -`unknown` - -###### event - -`string` & `object` \| `"on_tool_start"` \| `"on_tool_stream"` \| `"on_tool_end"` \| `"on_chat_model_start"` \| `"on_chat_model_stream"` \| `"on_chat_model_end"` \| `"on_llm_start"` \| `"on_llm_stream"` \| `"on_llm_end"` \| `"on_chain_start"` \| `"on_chain_stream"` \| `"on_chain_end"` \| `"on_retriever_start"` \| `"on_retriever_stream"` \| `"on_retriever_end"` \| `"on_prompt_start"` \| `"on_prompt_stream"` \| `"on_prompt_end"` - -###### metadata - -`Record`\<`string`, `unknown`\> - -###### name - -`string` - -###### parent_ids - -`string`[] - -###### run_id - -`string` - -###### tags - -`string`[] - -#### Returns - -`void` - -#### See - -https://langchain-ai.github.io/langgraph/cloud/how-tos/stream_events/#stream-graph-in-events-mode for more details. - -*** - -### onMetadataEvent()? - -> `optional` **onMetadataEvent**: (`data`) => `void` - -Defined in: [react/stream.tsx:495](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L495) - -Callback that is called when a metadata event is received. - -#### Parameters - -##### data - -###### run_id - -`string` - -###### thread_id - -`string` - -#### Returns - -`void` - -*** - -### onThreadId()? - -> `optional` **onThreadId**: (`threadId`) => `void` - -Defined in: [react/stream.tsx:517](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L517) - -Callback that is called when the thread ID is updated (ie when a new thread is created). - -#### Parameters - -##### threadId - -`string` - -#### Returns - -`void` - -*** - -### onUpdateEvent()? - -> `optional` **onUpdateEvent**: (`data`) => `void` - -Defined in: [react/stream.tsx:476](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L476) - -Callback that is called when an update event is received. - -#### Parameters - -##### data - -#### Returns - -`void` - -*** - -### reconnectOnMount? - -> `optional` **reconnectOnMount**: `boolean` \| () => `RunMetadataStorage` - -Defined in: [react/stream.tsx:520](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L520) - -Will reconnect the stream on mount - -*** - -### threadId? - -> `optional` **threadId**: `null` \| `string` - -Defined in: [react/stream.tsx:512](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L512) - -The ID of the thread to fetch history and current values from. diff --git a/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md b/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md deleted file mode 100644 index 9496a7913..000000000 --- a/libs/sdk-js/docs/react/type-aliases/MessageMetadata.md +++ /dev/null @@ -1,42 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / MessageMetadata - -# Type Alias: MessageMetadata\ - -> **MessageMetadata**\<`StateType`\>: `object` - -Defined in: [react/stream.tsx:169](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/react/stream.tsx#L169) - -## Type Parameters - -• **StateType** *extends* `Record`\<`string`, `unknown`\> - -## Type declaration - -### branch - -> **branch**: `string` \| `undefined` - -The branch of the message. - -### branchOptions - -> **branchOptions**: `string`[] \| `undefined` - -The list of branches this message is part of. -This is useful for displaying branching controls. - -### firstSeenState - -> **firstSeenState**: `ThreadState`\<`StateType`\> \| `undefined` - -The first thread state the message was seen in. - -### messageId - -> **messageId**: `string` - -The ID of the message used. diff --git a/libs/sdk-js/docs/type-aliases/RequestHook.md b/libs/sdk-js/docs/type-aliases/RequestHook.md deleted file mode 100644 index 53d535e2e..000000000 --- a/libs/sdk-js/docs/type-aliases/RequestHook.md +++ /dev/null @@ -1,25 +0,0 @@ -[**@langchain/langgraph-sdk**](../README.md) - -*** - -[@langchain/langgraph-sdk](../README.md) / RequestHook - -# Type Alias: RequestHook() - -> **RequestHook**: (`url`, `init`) => `Promise`\<`RequestInit`\> \| `RequestInit` - -Defined in: [client.ts:158](https://github.com/langchain-ai/langgraph/blob/a7ea5e44ce12e3618d1a766587163afbfe424e04/libs/sdk-js/src/client.ts#L158) - -## Parameters - -### url - -`URL` - -### init - -`RequestInit` - -## Returns - -`Promise`\<`RequestInit`\> \| `RequestInit` diff --git a/libs/sdk-js/index.cjs b/libs/sdk-js/index.cjs deleted file mode 100644 index c84256f7a..000000000 --- a/libs/sdk-js/index.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/index.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/index.d.cts b/libs/sdk-js/index.d.cts deleted file mode 100644 index 485d17256..000000000 --- a/libs/sdk-js/index.d.cts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/index.d.ts b/libs/sdk-js/index.d.ts deleted file mode 100644 index 485d17256..000000000 --- a/libs/sdk-js/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/index.js b/libs/sdk-js/index.js deleted file mode 100644 index 485d17256..000000000 --- a/libs/sdk-js/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.cjs b/libs/sdk-js/react.cjs deleted file mode 100644 index 86a38b8c3..000000000 --- a/libs/sdk-js/react.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/react/index.cjs'); \ No newline at end of file diff --git a/libs/sdk-js/react.d.cts b/libs/sdk-js/react.d.cts deleted file mode 100644 index fd96c4787..000000000 --- a/libs/sdk-js/react.d.cts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/react/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.d.ts b/libs/sdk-js/react.d.ts deleted file mode 100644 index fd96c4787..000000000 --- a/libs/sdk-js/react.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/react/index.js' \ No newline at end of file diff --git a/libs/sdk-js/react.js b/libs/sdk-js/react.js deleted file mode 100644 index fd96c4787..000000000 --- a/libs/sdk-js/react.js +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/react/index.js' \ No newline at end of file From 1f1d032430a29800709929890cebf445615ab0c0 Mon Sep 17 00:00:00 2001 From: lc-arjun Date: Tue, 8 Jul 2025 06:59:02 -0700 Subject: [PATCH 26/31] docs: add tunnel flag to node server docs (#5398) --- docs/docs/troubleshooting/studio.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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: From f21fc056bff70d7e5c8dd7553577a1a26238713a Mon Sep 17 00:00:00 2001 From: Lauren Hirata Singh Date: Tue, 8 Jul 2025 10:36:47 -0400 Subject: [PATCH 27/31] docs: Convert example notebooks (#5381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Agentic RAG * Fix formatting * Agent supervisor * fix links * SQL agent * Graph Runs in LS * fix format * Autogen + LG tutorial * fixes * update sql * remove old notebooks * docs: Add section about data region for LGP data plane (#5378) Add section about data region. * fix: remove empty notebook (#5379) * Fix docstring for _unset_config_context function (#5374) Signed-off-by: jitokim * Fix typo in StreamMode debug description: checlkpoints → checkpoints (#5371) Signed-off-by: jitokim * fix: remove unused import in generate_llms_text.py (#5380) * dcos: Fix deprecation of TavilySearch (#5375) Fix deprecation: The class `TavilySearchResults` was deprecated in LangChain 0.3.25 and will be removed in 1.0 * Fix typo: funtion → function (#5370) fix typos Signed-off-by: jitokim * docs: feedback edits (#5387) * docs: update lgp deployment metric list (#5388) * chore(deps): bump peter-evans/create-pull-request from 6 to 7 (#5365) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: correct link in docs/docs/how-tos/graph-api.md (#5377) Update graph-api.md * docs: Update quick_start.md Rest API Guide (#5368) Update quick_start.md Rest API Guide The curl command in the quick start needs some minor changes to work out of the box. I hope by adding these changes then new users can get started more quickly * Remove duplicate CONFIG_KEY_CHECKPOINT_MAP from RESERVED set (#5372) Signed-off-by: jitokim * docs: fix typo in persistence (#5329) * docs: fix typo in application_structure * docs: fix typo in persistence * chore[deps]: upgrade dependencies with `uv lock --upgrade` (#5358) * chore: upgrade dependencies with `uv lock --upgrade` * linting * upgrade PR title --------- Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com> Co-authored-by: Sydney Runkle * Updated examples for SummarizationNode to account for serde with persistence layers (#5257) * docs: move script into scripts (#5384) * docs: update sql tutorial (#5389) --------- Signed-off-by: jitokim Signed-off-by: dependabot[bot] Co-authored-by: Andrew Nguonly Co-authored-by: Michael Li Co-authored-by: jito Co-authored-by: Serhii Polishchuk Co-authored-by: hari-dhanushkodi Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fadel Akram Co-authored-by: David <31293924+dreadn0ught@users.noreply.github.com> Co-authored-by: Youssef Ahmed Mohamed Abdelrahman <109446360+unauthorised-401@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com> Co-authored-by: Sydney Runkle Co-authored-by: Nick Riley Co-authored-by: Eugene Yurtsev Co-authored-by: ccurme --- CONTRIBUTING.md | 2 +- docs/docs/concepts/multi_agent.md | 4 +- .../410e0089-2ab8-46bb-a61a-827187fd46b3.png | Bin 0 -> 75818 bytes docs/docs/how-tos/assets/autogen-output.png | Bin 0 -> 5919 bytes .../d38d1f2b-0f4c-4707-b531-a3c749de987f.png | Bin 0 -> 53669 bytes docs/docs/how-tos/autogen-integration.ipynb | 406 ----- docs/docs/how-tos/autogen-integration.md | 321 ++++ .../how-tos/autogen-langgraph-platform.ipynb | 171 -- docs/docs/how-tos/multi_agent.ipynb | 657 -------- docs/docs/how-tos/multi_agent.md | 2 +- docs/docs/how-tos/run-id-langsmith.ipynb | 274 ---- docs/docs/how-tos/run-id-langsmith.md | 155 ++ .../multi_agent/agent_supervisor.ipynb | 1403 ----------------- .../tutorials/multi_agent/agent_supervisor.md | 812 ++++++++++ .../tutorials/multi_agent/assets/diagram.png | Bin 0 -> 25505 bytes .../multi_agent/assets/multi-output.png | Bin 0 -> 14338 bytes .../tutorials/multi_agent/assets/output.png | Bin 0 -> 14338 bytes docs/docs/tutorials/overview.md | 8 +- .../rag/assets/agentic-rag-output.png | Bin 0 -> 81761 bytes .../screenshot_2024_02_14_3_43_58_pm.png | Bin 0 -> 104631 bytes .../tutorials/rag/langgraph_agentic_rag.ipynb | 928 ----------- .../tutorials/rag/langgraph_agentic_rag.md | 522 ++++++ docs/docs/tutorials/sql/output.png | Bin 0 -> 20460 bytes docs/docs/tutorials/sql/sql-agent.md | 549 +++++++ docs/mkdocs.yml | 11 +- 25 files changed, 2372 insertions(+), 3853 deletions(-) create mode 100644 docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png create mode 100644 docs/docs/how-tos/assets/autogen-output.png create mode 100644 docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png delete mode 100644 docs/docs/how-tos/autogen-integration.ipynb create mode 100644 docs/docs/how-tos/autogen-integration.md delete mode 100644 docs/docs/how-tos/autogen-langgraph-platform.ipynb delete mode 100644 docs/docs/how-tos/multi_agent.ipynb delete mode 100644 docs/docs/how-tos/run-id-langsmith.ipynb create mode 100644 docs/docs/how-tos/run-id-langsmith.md delete mode 100644 docs/docs/tutorials/multi_agent/agent_supervisor.ipynb create mode 100644 docs/docs/tutorials/multi_agent/agent_supervisor.md create mode 100644 docs/docs/tutorials/multi_agent/assets/diagram.png create mode 100644 docs/docs/tutorials/multi_agent/assets/multi-output.png create mode 100644 docs/docs/tutorials/multi_agent/assets/output.png create mode 100644 docs/docs/tutorials/rag/assets/agentic-rag-output.png create mode 100644 docs/docs/tutorials/rag/assets/screenshot_2024_02_14_3_43_58_pm.png delete mode 100644 docs/docs/tutorials/rag/langgraph_agentic_rag.ipynb create mode 100644 docs/docs/tutorials/rag/langgraph_agentic_rag.md create mode 100644 docs/docs/tutorials/sql/output.png create mode 100644 docs/docs/tutorials/sql/sql-agent.md 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/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/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 0000000000000000000000000000000000000000..9bd66e5654ae1f2d93b2329d3a37bcf853a93177 GIT binary patch literal 75818 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 z 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 TWM}4D1|aZs^>bP0l+XkKi8@46 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..02106782e87441467253e6f9c4b62a7e407c562e GIT binary patch literal 5919 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 literal 0 HcmV?d00001 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/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", - "\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/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..ba8f84ff6 --- /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](../../agents/tools.md#define-simple-tools): + +```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 0000000000000000000000000000000000000000..8aaad47591014bf58887f4697663a977a8141ae9 GIT binary patch literal 25505 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 ZJpWr-)bP~I#WZA4@kcTbbM9-u{a-{_0=57E literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..65402f1e047a8b2767e3162bb7e9b9f2497ab761 GIT binary patch literal 104631 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%0Ag{=VjqA7f@stk$0!V*--xvZQmVFbsPR4 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 U@L>6#8U`TnboFyt=akR{0ODduAOHXW literal 0 HcmV?d00001 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": [ - "" - ] - }, - { - "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/output.png b/docs/docs/tutorials/sql/output.png new file mode 100644 index 0000000000000000000000000000000000000000..006d100aad6a03be8929fe5af5806217e83f79e7 GIT binary patch literal 20460 zcmcG$byOT}m-ZWZ5(q&O91| z0l(>o{qTG8GWf)Ce2=M)kQv4mGYb>3yaS^EQ{B38m+>}FC|AuM)02;iS<1B zE`?0_B=?Q%6IoK|6R04^Qw~4tXVxgozTwzsOjLXj96UIva3l&7L~x1is#_+k|BZ~5 zF>Z>3hTu{df76%8<<710u#Mwp6SVL>Fu}WQYz&eDO*5QR+>%)E|CHODoR!t+`u#JIa%j(~Ya-uN>=3AhaU$q(Ds(qC+Qm(-+Z!T8^phh1@O=bG= zz23-Pl`g3SHe0^VP<2IAM~J)78S_mbR+lkK#1MqvcI8FGkN;Zs#c;O&m^3h7<+Fbl zN?w#886?Ns$o)G#q{&D~u@lV~%l72Xl9qKa>8w(hYw0AC(N5jPZ>BQ@1DR5PcX0Hr zLVAIrhdo*1k41DpN&O60B02)3$_53D7aJY-HA9mUT(Qz4rDlQc9OtY283aggWPd-y zNmyXdoJFlNsLNHe+GQWa6kPmNmf>$Lh)YlM+M%RdYP9f3DNoOKTl_PPDKcdP%@BKJ zfg?*ow|y+E5LEo8*%f;*2)p&wVMbZ>4XkGCEtTLoSDdqZ#ZUDVWXd}+U5$c6A62tl z!TYUk@8?JxgQ9hLi9clB{R4 z_n{R`-SUO#i6E^)k4W&)eQUr>_Vl@fD8Ke+t0&>=o2#pt%7wi#RLrhtTLnsm=DmSXdgIkI8zi#x6XqSqogW&6I`ZZCkyD2u$=LAGAM7i;Ls)do~mn?qcxYm3rJ> zjAToN6LGU~ak-8cC>BD(dl z_bBC3hVCR|sqasE8Cas@h`Aj@aGrc*-hP+*m$LnlhwN4Om2s@MjW-lWKtRC8#>Qf% z68N4T5KSp(xzNBF8!DL%qK+N$%{RH(gutNC&vDqANfH=tmj}EyEA2mjBHP*7xn6Db zCm%N54z#!X=0r!01dyGdpZf(|hk0V0&3+R>TK4tIE>N@8Ef`7rx}z8t7KY73jZ^Qq z52<&wC}>hHRNlWI&kNf*JZyH{pP4Mtrlg?A$;xu-mVZj)8+{@FRlz+~ybt>(%2ySU zqBHEiLNX4yQYqk)8O%#tC?Ut}o`9<-vzj@s{f=z%xUI5Ud}t5EIxKO#IosYI%~dH< zjoc}AyVy%)HB;Wm#@1B+d4}4aFLKFh>x=b39vcjb0!6>xOZsSNXgIc)ML`w{8!J+? zTWD}ObgBl~7pj!-*{+H2T$NQ;X0=A+z^X~9UQ&o$h;Rab?K99(^TWhg!9Zy=S8`sE z*=PVexMMJtA8*506fG(`+OISByQ?KLgNJqt8hg7)Vekb_5wJo7V1=IU(%xfhc|yiJ zWBDv7CnxK@DkWM9IPt9#u;R+!z!$fWzWygAW2?EEe{q)fe*^$8W?zqchwo0L& zjgK#7CXOXUA~-KRU?w#HgQOUgjS`yA<91I2vrB?EhgK>$#q_M$qB?sDp8R+WuAQ8uXOn2m`4h=%%qb&Lr*cppN&$#yHiA> zAKok0ns9Kvs_&c9RP#H!8`#3a#DqrIvc{5)$P(yloyfUp8S@Qk>^h%<%}6P|Qaoue z%Xa!*8e+wpGQInM55?TTTxx}1x4t5=KF=+!F?I;fxE-)ruCeE!Rf0|AslWQO&GPl# zD))8xq&v(&z{T3)+LP4M7*@jC+{7E>6Xiefv{jyqaFD8isZ7AWO|I`%n&JYbM0_%c zV1sy8K8o%noi}r#6_wF$h-&bT-Q?pBYeC|6k%B|bQ1@#_dd@H7*%|4=NuIS&^j;@I zvR^n=#r3ogFH?aH48QC9UnZ6TZV*_l9C=^970%$i0IaKQ0JAu^|SDXh6Z|#nutSfmSOrUbGm<4 z7ynuUw(Vb3zF6NC|9Rp3?;qf-Z(%`)8JJ)x#NjR0($Z2h$N9f{X-QwJ{-^viRTebS z-CNMJ%ggGD3asD`Q$(G9choy}OZ_?|a!PCAPneA^r=khy$jE7_qN1YDkJAz zEN^co)>4a&8uZ4&l?ri3C6Fntv&6!QtE#G!0y;Z8xzx>>e6eakR6aRJwAxJ#1Gvek z%YQAL9n8T?$AeQ-9h}}^Zj1JS}==# zMCPx}SAbHmC)SL@!L>);uKc>#J_ddpmH4hI`|J$Wz;ofasPqGri;m}mM0$Xzp(WK> zht7kmF7!Tcu7BZ!K7In&aS9o&DDVJCnvFgRT zd)#YS9m{J}ly4EQ3J^z;8XA(r&Cp4go3k&yeoISfd3oY5AN{Ob#WGCy>&|HgVb?x6 zhx7G~=eG_`O?<$m2j?>hy$roL%H#4}DXn*U%*f7_y>D9~< z?@5o_tp1e8>0zwJr(Wy&dS`o^-DJ-8_tLOrHdFnoeuE$amrqGhu(fY`l}f~H@~+f# z{{mE;ojdsc9T8Te@p1uE_IxsnrOnxqnhIX^9$N``*zN$D%~EEvT1+sCOF>R9ll)LC zO|N}CeuK8_7*iteGB78Ro=%!{UhP?3EPBqh=-!A>pX9s6*t^@l3P0RC>WK{w#vLqB zhEK%xyXDFzI&GiS#unlkIYGaaiFlp&@1?Ez%Hd#QV&maWHmJR$q{MUOFg#lmMN95A zu%#~g1fuHbYj0->=+6e_H#I$#YHqJD^Y-?Z%!V}DM*I0?myV}B{fI%baJjTR-x-?p zdUx{NbSm2pBPnf7yV>S?uU4DeVK2@l!0o~!^Tc{9;tPv~_K40_#9%xvjM@Gu!Pocd zGF*{j{ZjA^aJi}7+{BQOayz7qoQxL{uIDpgkMpylPCi@%R*~59jaded6#mfA(6`0t z1VlvHYU#Gw)JfYY>olo64m_tD`T6-{Lqtc-%SoIm#M?-xD;*VttUGI~Hn`7#-8fd5 zOzrf1qVcvWmBU8AcLFgn!3Lf~7!SvJ#IRf4QOFQ0bX0Wq5ooJIV$w<-4yP$jQC_}$ z)S{7>lVkYuh4gf!y7cm441mp<{%&!7JNc6EEPH=Y6g{T#yn znupS8vfQAjtbyBWnI+roqNoGK?}vf?T2qCfU=B-XSC?YE+(tGyKBv4|YBR-R*8XPj zZBn9<3zWXta{3&M!)cG)l8b_Tmdl5)Gc!Hyu;QCI=5aG}S<6UysX~W0AuS=H{5eLD zsXMWvxuIgl2kFssaEdFP{p0uG;ri}miQ~bHB&EmoNvv^XWO`(HI6GR<8c&EscX}$jrAGQQIMhu9 zay=Q%?-vk2#Ortzcqv4Ekdj-?ujd!bpk4bl+e}`5sVo(JzS%3+AlUJ64{j9x5Ko`F zSmE@J2$h%h{ADN+dqUlhavoWyOOz0myouJ_49i#(#SJ2k%H05qclnx|Yil_vd*oD7->3Me@wX=h6z+LNc@vbO~HbF8a}D~9=K-72@6nSAprgv#Z?tZ0`I+E@?{ zZ{BVEjdul)?9PBeLu(_*e&#&2Z8V_<e`@SEzh~rsH-n#1nGHh+ z=OUxkX4zn3s3cuWyvUT;{@qwcl)0abYQ?Xd-!xz>`?h}5(dqsW{{L+r|H-Dfd<*50 zG5PRT3V$t1m3D%iy5R(MdCbIc;v_Bp6{;=en!}I47p<@STFZ(&b&I%^LJ!Y2B<)qp z?Oq5etG;5^ID@Oq)!rhh#Lz>KDUW{7 z&c2K17W=nO{9j&&Pl@i$zp{Y;nfeGkf^#m36)M9&VZM_23kgYGO)XG(dovdf-*;N{ z=(5Lad+C@aX}{SiwQA3W+rahzw7%c(@=4!XEv*^f+(1V(G8|5_eXK33S_rMZKg z(U=(08KseDw1EcpP7awm7p7L)VwHUrY4Vj!l5?83*mJR;(^Ve!;&~WxY!gV@YN0KU zNydl!t4-~2*1TgJ67*)kT;K^c8EK>593N6IjMd@~WM>*ws(-kPs`7TpM_?>>;x&DASnxRAV9+3KoIJgj}TfOMu|^1zqH@1{s*-3UoDJOxL*+w zUwJcd)3@4p4ahj{&Gl4v1!{+}Swb|kL0>EY&Y*B|?y*qe#QjoD0D&7cGMXDsp#OY% z3EKxC_ZIn649M>NNDe=;&Z(|p6%5}BcboPuO3oHchi9LcwEP_q8u;wGT%R5 zA06;6Hha8NXwt}jwQ6){^=-1&E{@GI##3p_Zc~nkr)D=cwIn5lkM}mBB{NoXy=p(X z>TpU>Dj$W*b*#NO)xgchsUXdAy6$4d%E)*#C&v)&9m_kmGrL6TxVBv~tA#7LDneXU zcyOw~z)k02)JU$%QgiqItV}W%gpibR?Pg=EV)1He-9D?(6&dsia1;@30*WA?-pmhP zw`v%-7ZWFEt=gz^YIq{qT+e#o<;R(}|ENxsgV))?W)6biTLTa^95~q!Gp<2ptub$;{cHf$eor$%K_^b*8&tkKKkWrejL8yzP!J7G>D)^&qO~O=R{dsh{Dw z6%iEg_h4+6Q))ekN^p`Vh5R(D*?=%Ltgo+6jTpvv&uqc!x+d(3A||$(w)8c1Q_fEW zP%o!|WVHW{pH#)L&1nC7Qz~wNfXf-R14ODK|6N8}+HRq?q$IpBSUq$HVUmR67?knm zc25gWp>TY@{<2WBkX{A@pYaDZGT1lnv(EYGu~6myo?37yYN+vW-?sMI&gcUm1d`az z`k8{Z9`5}|tlGxMLsPzp#EztU+|<9s39*j=CVG%&p zfqmUHNE|t6C6I&D+Xk~^_up!iO+w+ucY@#*7TK4wXy;jJ%vS|%!YSRt;k9U5f;K#j5C&uwtXsD=% z{52md>-nC+V7PJQEExHTl+vFlC_tp5h#?~GYJDw!9i$mxc~**RL+y}k8zd2MBN zofaCM@Tj{qZ$o*~nvW$d-M_NBx{xY2E@&FAKpAwzNOinw<@I&bW}}~q zt@ST*-=HLVm|K;_DAnmrjtebxcfvya5fc;B^3Ky>{w7u%ey7`=F+SZ`{C>zyK3g&+ znxe0VC%P`*wi(G)ER!9%0G|dMC2shq!Hefaf?Vm9>eF3v#PV|fM@MJdSbAL;>D6~@ zF>8JMygPCFk1-f723Ch#_h*rYv%M9px2qiQbIz>Bc7daiM z6c#b07J~`gv67A*;YVyCO9|t{sV>>eo3kn8Cz0)BZ z(N}ct$KxX{Q|pDsTfF_d3s^Fq7x(V68ePC-Y+G@jItMAK=XLz)ws_u;I=#&aZ=ZU8 zmy?Kf!uyeo3^Fg?Yb>JcVLc?EEz24v+M&U$b3c7sfZ+13FEQ~rg=_++ zxiiU5NVW*t4tx5>^n%Ci=Q?moYI2!qOEr9`1(u2;_Ut$DLwzn*?9pXChI zFIp@$UHFkdrke#Sc7(eMF@^EhPsTnc9MM47j&AguZK3^eje^3Y=x%hC0FAAxrDYO+ zaL;C;B@_TIG@Rd7#Cv~Za|yiJ?xYpj8RaJ4T$lijMZ!tLB#VlK)&Zr;(3Wt}Pvprl zjC{uT>^fVQ>X-F3OaAm~Q;4nWQgV{3*BOx4*FHN?&HCyL2-!GJew0LZP`%p=BO{fU zB(KLIzu^QGo&3($l)WNApF#Y^eJ;f0^##dXtoKxySF5<- z_e7c#9=Fd&0g1adu@+d7@5J6KGNx~E=<)J{+)VXjk*BLae`SX_AKhHey zDI`z-e`68@C!PhXxd`RC?ta@)NpA_8vP0ej5WSMRrHs~MDZSuygb_J%W& z{zd58tahTKqbCJiTwDNT*RT#{`LCw4y=g!;f2Y7k5h>AXOh5;K9s`|vRhB1&P`I?B zVsu?MI=x!isG}>7prp=W``yt^a?1Qe*Qo$C+NYIg^fQbD`RXb6IBuKOze~S=O2mxK zkrVvL=lU{=I#jxMoXPOdensl!73{hnEnnMIn}~q6P`bT?-fg*NCB{}No7pKpc_XW7 zb9y#=w1i!Pu8evz-mj>`^rCQbIBK1J%)(v}oJW1-fElIsrl7hqBoq|TAgg-~Xx>*X zp0CKtehRciNOrW8V5)fvaX1K?XZ7?5gbTEkR;qN07OHx-$p^`bONxt33brU@XHj%y zm)`;E9`FeN)AjzZCgML10N7XM*J@&T^Q|ZE=ojD~%DsM_1LJXk3V43yAm!)vxJeM; z6G+A?$Hm31vprv#t$t)-VcEG+JFKahl8PU+dR%@(7Zl=N@432D?_?z+B2rfuN6e)! z4ah2%W}DHo)ZS)|Qp@|E)h_yt(o?rfORIZN7$8p|aC)VJz6gO#UY>%HyO@|5i&=IU zpB)(+TW3Ff?q{4_kEG!5ccfR5L7U%;gln3Gjr3^u@|NG$LzL=P(x7h&E>n98iiAUILRb276Kd)kbHh{R8-V1 zPrld<_PoU`$Nd|i7fMSkD=P!XU2H9s81y<`kQ3$gWsNC}undZHSi!i?MaUF@CTUv- zs8iJ7JX#)UNlDk!8=QXgiAvVSUKW$N)`f*gEvr>gI>1P5;rMP!r|(S`85gHq*1D)9 z`TV($>9}d*iBvNsNwy$Gw2Lbk3s=DgQVYT%Avv5ogfcBHEmb;i@1gJ4E0<{1SE{SY z4W2bBm_VUWje*7=rG&h_0QE7gDgd;p;Y{Dyox+_*lJmnIm6BPZN+DcrZCN1{lbD1= z?(pr|P|Jcuf|apx!oyHYQ`Ow5(@ zv$MbLYC*6lXMXPEA*bn`oDMz-i5Oj59K4YwIIrK((z3-?hAgt^+I1Hw$#PJRa)Vun znOU;HbI~f}VK$1)sC@a)6?4>fALY*mWq7u~ZEgBWw6Qv!W7D4#9DDqNwvSnJLpc`3o$2Z=bkrK z+@0)}d3pq}SS^SqV8tsyPo7u+j=V$X&>-akhF`!KVS~f2lg`Y1<1;0`ZK$KYJ?=yI zI*L@USIN)YmfjdelEGLSJUcxfO_Mp_bO4Y;0by2> zVA^c8C~A!EFX>#6)1>%q<9mvqR&b8i*OIfDb1A5X2@$ZyV=5~c6lXjx4-WH*wl*(q z0o-i(2-YZ6f=j^L$)z^uYVBwkKQ96OcborZjut_jg2|_tVk5qVG3Q>(&3}-|XVDjT zH|K@0`YI4dexZMoA6(sGs&VsnG*`}<-=hI&QVCh%s@=>1t64HLh+RS6>aj%W#Ac7p z4WQqR^WaQfCp1Xb8pt2zzeQ?rdAK8R_&8ah6kqVl>S6mQwP4JnQqt0;Wo3XWLk`tJRzKh2{I>Y84_Mg?h||2t zbcHy#oP*T=2V$C7$;uXM)2a$+3RnJoi4U~1o&AgQB_YAV@6K07W`zg3I8EFCa?R*h zpYRO`P#B#ol=W%x5v^!QU~)N7p}|EboP%lgrg?wttyOWqS~^&x`gpm2orpsBF)?+z* zmj8NZ!s7RmkUV_+6^R1;UU*C;W}b{$(QYT!paZ!8ktSnqv4`(Y_}}yUa%CfS0~JS) z=I4KqMN7rJynfv6Ad#lTPm~b4$Hd1DiI{x#lHyu>fE3Er(j$POZT*?URH-0V=)o(7 z1SrNi+Y?q=R_v?94c^zFY~v73h}p z^fI&jSTdaPwJA8jdMD1PS`W~K1cVWvVr^iu2nczk^}ITjA(@9_ppnq1Eo-P+%U2Eu zupl(arbs544Y2n5?{Vl~r=~PzrJ0f7OAafzzQpV-%ZkCzZc%{)}oEsaW-C3_BDSE~8eSC!e2)4hmCZIi)KVv5aU=E}Odx=K@$LVvvtBEyOO zTkXx)Iq3bZ_U!j(l<4CtLUb$iy22#0qqeDiv91J{?d|QeUQr90ByBSSHt9#~ls|Es z$w?zFR3WO4F1VeQHeX1z_#c^-5T}?A#tdZ1>{Sj{n z-IK~!t@-C!wq<^3t=-&MQieF0yupFLbOJaB+77)c+gP z+ba7Bp1Vit<=%Xl00khwU(2QP86IhW=5!c7PQ_6CGG30D^bKsgztaNv=6!1ib8AK} zz@K4kf9z5~uq7}%*~-hOG5(DR4*_51{8l@jZGQ)YWcYG8^EQbnh1<)t{kJE4c4Bt~ z(J|vdgN23VcMaI4+-IvPCd{2x#!3KyiQ9nkI@wMg@l_(Z1|?QdULiH4C(c$`K`z$s zmXy zDKk-i{pwYY2(UvATrX`hB#1Ix1Lls&@POvxFa-wj-1uI5*Cti}E95hy7cZB`IKxwU zG!U+V@hWX}$rqKD3A>1*QsTofZ@@lD8V6cy5vh)Ky;0)+tH{n-~xgTbJ_(Vn5W1aoBiGhK~+0pdHKA+ToDmYW2+LQD3 zULN=TaDF@AA#Z)U)}Vxr#1P%Bb#){EJDyH$v`G_>dp62w;2~o=VxqE= zR>w@Q3k9_`-%d95VY;u+{p@#OSl9p%_kwFT2O18`bzvw-8Vy4Bc6LM~6FBdKe|>#i zq=#X}QBY8X5OONW$%X4q6q%S&+xiI_4mMd36DtLv6XFZN2nTxB7B zG&ns#JFlE4pJ==C?Xc3OZQ${oL{v_5piyvg(3RioVQ+sHc_v-3I4zdy6vc041HMRw z8BN(=49WJ7j_yquj)uc604NfFx|^{!v`fgT%d_7g3%h}FIU3bQw6)}Z!F_XNcvJbJ z@<)EYTA?x#y#@y?>g3W-bZc@X!$n;|KnsEgTwLq|z?GHygt@G9?;6S)ocGP1LA?cl z1kT157J6ptBVAqU&Z;8=0(P62A2ZK_?>pLs6{*DfJ9frR%^X*@6+%6moR6iQ#mmNM zflysm!A~MiX6FeQdN{tS0 z@95w=J@wsVgM#?ni{xRqXS@DRRAJ9%WUwx z?`dsi3TRX?l#F-8Ku6DtOJNK^X^a^9rk6=eZwrG)nVTG2rF$H>yQ=Km#pZ_i^WKD9GE+VUw`E;by`mf7w8 zYMD>vaY;Buce~i~+CI4kd=Z5xlQuwJh5%M`Q2ga2?WWf8M*q99tgKS_gKK`Ri|bxv zBZ-17Dq3i3Tid~Wy-aX{5?pNtPP@N308{rCcuJ7T&=`Ji&$!uUJX49Yud{y>JJv0H zzPZ}vHAYLVnDhSrZhcaZHnZDfZ>lAn!#QsFa<*Kg-s9G3tZ*`6X0YfxpkliIKt);; zU%lT$DPTt#Xarx3AT0ZAw6oK3yhrBk+hzM7Vff>R;ru24z=5_4IzBfth67hW99fOU z!>JU-a`QmOOYOgYE#0%;o)N4qtA+X-b%qcb8ybFb=$QlV55PUz>KPA~Nv_PmOvb%; zJ;8TSrqjNF2N%vZyii0!-K(>kobbH&KigVh*lf#FXuQaa#G=>aVz;$_B*8c&;xz?8 zE#MOfy$sLsH>gKPYld8R@YK|Mwo#j|a&p%*{eC+R1Q(~hmX?aseY#2oy@C63 zbz9A%v+~6)#=%_0C6ej(@b85qomJr(>r{v-0mw-D-ykK8ICwDEa!uhQC8+*84hk4> zP_+sXGc;6Gfj4dyKoJSFGyZH#Rx%EWfu^xy6C@0L{jXsfLW7V-0hEuH+W6d1Cs*I) znunP0s(4+PmQ#X=D6a3j)$wq_)=&LJCXB;OCP0%1|Mz#RW+K#r(Fq>86NHRup2EFpgF=17?n6QE#k zj52CVjew9vV%zeo=z^leKVd3fCW(K%?={}jON@zVtRdM24X4Sfzs8ax=>6!c$ZbAb zwGYH=7d>z3UW_a*E{={e_l|?cX<0r{$-vLOMs?c!;p)}06uqaf?x{8gV7EKtG_Hz6 zqodKi>p+MlXWW!khE}!o`#RB!`4MIMNRPE-RDaObIS?4eqLc;1;CO56kDW5T&Ma-B zOkw{$wzpCV2qBxR&P;U?DRsO?jD_t_UZKz-Ga$@My1cyCJek()!mLuQ(BoumXS+F^ zDF%=vKsj`k*+n3}pCEwzLZaiff)j##IvvYC?2?-y7 zwD#DZoVa*e96u|&>arlBN*>1VmBOW&E1h_9b8be>s9tHDUYk#Rv^oIe2HTI4NHGVv zKHca`TwPukSXC`5OsY4ILoJVk7``j_EsZSRp_R;c#nHkQgy)s->lcN3XGT zB$zNfJk0W5GIWHY=_(`bHd?`UgLzqYZ?@XXYO#s;p47y(D~u=@mrjuBGz)na%E`>e z_HeUXl7E*a5TELK6NvLE270{#LsugUMHfy*l-gI$39V8pm|yqB zljXZl5)u+X+#H9mNvIK-HnX;MDH>;-!$@ns!6lk22#Dc-`S$Bc+@d`E9-oho&+Q^> z5qo}eGCqnbH*y~e%QaeJ{A06BHZ5AmT9*+z@nKcil$#KZmg1g>H&u!ZdSwj zfu+x?+x~NCNd7{>z78UF*x&s4;MVARz7<~sTqPhZ527Xb`fv>_Zj+*HAh$yDWg;V( zoYLVa4@|w|lwB8aM1E;HUf^*)t|CsspVzPEn+oq217CBwoah63`to4@lxreGh@A2T zFe3ocy9Xu|0KpQc|LqsKCBORZa0?SeJa~9v^UK#t0wXEu8QX&7L&*Uv;LJ)A$jpaXVmSwCc+umGVAuqOb17UUz4GrM)8`lA;ckvuYDmIIO%VE{t z>P1hf`3QU4hr823&LXvqW{ z)XvjacYH&m()g{9u7J}Fl=Evcma{J#rBE`~)&Kqn&C6vdi^&LZ%1s16Nj4Kl9Yqr_ z)HwuuPh_xBj=Dg!;Y2LP5wWqc)+U(!avI*sv+4caK>{2!`oG=L1QZoV`8;kIhYXGF z%2$R-&zc|a2S-Lgr$Y-1O(vr`sFegW&?0Bw=o@cp<)Y8h@9^={rf6R>4s-|g%lG{9 ze(pExU0YYjX0-tIj;pud#+-q6e1d{)0ZKp}+q2N<#ysQ+z&f$y)92NC;u4a#yLYp1 zn%k$0Sy$C1B~O4Y1zuD{uqaJupc|N{Pt_RY5K3^TlFVkI&qM%=e*5WP=cFak=p`Pj)4wyM(G;`2l`9AK2`)eB+BjS5O2@b! zs(A8JaLLOP-1&@b9Ud}BBfWSrEQf^^?RkIm1r}q$ai2=L!0~p$$dKygb$`30D8JMc z%|(g(yjj6VA20dSPmGL=r|;R>tNqd5F~MRSl9`qIi{GPJ%yfkbc$Ybj6fPNfUK`{4 zcmb0eKGbD@r@?^<3!^&fUF#-KLWap`@vJ->9NK!&jod?s;SmN3-!&kbk~kc#OPRG?!EYdM_6=@Hn43wm6&#Cv2)3 zKz?@xk4iudbaHaqDW%h_vj+f90{ZAVhR&~CNxkDQJ2l2if<=(nD1Ijit4U|;b~CkG z3SO-zJ-G>oG_ze6o^&SEUhM`&QF;e zYMp9`As&4hSL`L%?oY{6i{*7G84;MBC14~~5u!uK2jmTrn(y%+&KyIOsO;S2p69?& z>CU!DWP}6SNwn~mG-R7i1~EgVIvxiWA{fRBDlJ}XH-^T<74Lr2&4hRN^-W1OgDq|o zoYyC&o4}k#cLE&CZJ4Vdb{RJvm4(i+fe0LioT{6F@%<_~cLKbQ`R};Ea0W1)!gq!6 zx;7lJ^;wxlj-t*wK!c%|V1%Ho?z%AodE;MU9Sl;gQ{^iIEu)s3D=HzBzz18)?H8aQ z-?v{YWFCX^HL!iRdA{sx&Rh4Eh=dYE*qvx8k1wt`Hp1O3!o>Fh8UY7#c#<_q%$mCE zhMxP*9IMY;U#ZnQarTUK3zJR4nT0>$PRFn{yTk>zR{ZihpLeZ%IJiBh!f}{v>R|(9qVy1d{Zb z>~kUxD*$tkPINSmukeSuzEJCI-F`^HLAbwDmX(m0uJRb&W~Kx*=-gZnItf>mZb!3~ zDj9BY_2HE5Uan7No@6ZHXzlzfxVE(693+2ZLG=>wi;njTG>#WeyQ<3!ckl0fDK z$<+4F3Y*CaZBp9vhx2wE9YjRL5^>`Uy;@}*KoZW5wks&rtBcP)Z&b4-^C8(AKxWt6 ze5C7UgCT(eGw?kT4CDPAtHVhHg9`1|sGIyEpN}srZ+vI44zV{@Hv9b%&1i=9H-kh0 z?JwQai^kDr&3UZ%JB9LFD*0m>4i%BMwNV>`+7ksPZQhXzEtP_{whh72M%7`=p`oMA zZbUdlu18zCB#Y{j**Y*nO;v%Y-QH)~I366Q@U^*8n{yyn7)Ho>ygRNg8E2osrCN5IFxlP6Or8Xo7d|xXmv9!qOW(H>;LQty68b&=Dq+)*{03-K*PX+&Dsf{IGj>>V7NvW{Lfoa}s{fUrf3}27f{>kScQ{ z?Gf*uzBsy>{ptEp-1#QE(aq~oAd9CA2W8r>Q%6(uJC-`3yna2-L$t3med2=EIhd!p z`y4N!)^pWX+8mX)K3P4{_5deG21Y`3zg&X+V1M@pC;Uu#WoKtYtLhHO&JDe5w~8Mq zJ1fCucAZRvx;cYczkIQn&52H3?4?`?_eEpSYW7R6+_q=V9!^nj6~2 zYfY0kGHL1F_rxBX&g!0NJIR4esAv&Yw#90QMqx5m)-rnax&gDtE*54c>h{f!{?7B; zct^PG@cx`-IY{9_lMtr=Q1e{!|M$%wM(gAYpmK?_dd2UyOhVY@@$oSLe&c%Au~BtAO{&XJH|Zw9WGj&(2ql6%t{`V-<_o%2RZ;59h@e{Nolgwdq;>}MW z;#*QT+s4{j33662^hasDzXGL;jO6hbPqXlVGo3U)a_8a{5-9PAMvdJ=8xIV&81NA; zM}IpecnkZA=<+IlN2=k*w_?GuFO%PQLDR5Uq$c__N0h49@5=vwHwE(KKCu zs&!IAQkmCDoK!0npVG6Kq!}s1US2J{NEvv6fRD?`vfVm_sH~xJ3E8>_=eG;Su*ppJ{yR2+1wCLIe zOpK8QQ7CJBG2Jm>1Gq}P7~GVIX^@@e_jabZt;sSQToBGtFa$DU7OQRA=*yreYk))UTNnKUd@EY5`&!LeJ(DOlr*>u4ou(+5~#jJwUO;gRowBp;S zsspQ!&*73BuOIvRB|-cVO`ft&VN^Pi3&5PXD+Ld@P-)QPQTK%?T(W{T|C$$bWcrc7YaEd#9r@p<vF83U2XJ_|cXz!2=q?rx#MbQ0wohDQ z$aNGFLo64xJ$XAvl5-efsk8YQI@&v=?&+`KQElJ2& zZv+TjELQG(8!2AZBGpnG<#ylB@*l%_TG~5iyj~`5;#)M2PY!tlHsG^dv|qmDn#R{A z!lQ-AXWC~soo3dShRH!DPpe*SBW7!{|CEhAVm|Ztp}gjEcWAH)dU{JKJTJwOgXh&a zgsi&H9O}#$%KcHk+S$D>;X-?fLDweCBHPGOPCy~+7@shUfZg*a0#(0haXz4?(aGOCq_5Vy_hlRUxJwt~gnlnL$Q+|~UKv^M(UfG;Jv zc**I#`eniXH+5#S1HR8rt}5c7f+mGm`!zLMd_lqD`hjH@NO+x%pX{1meBf)kln@jW zD%Pw&8xQi+>cs_vsU$#Z6Bbn|nj1>A@mB0=Y06vI zz1-y*Szvq$3WIs`gLwy?>vAp;vTvzntcf7;GBSgwr2^!c5fPkoiDUO%2)%$y-=KNPhND5~kL2#pSd~IfTEa7k^E;gR2wW@HiOsGou zvz;tokXljFMb`AD`d1V5XHDMHU+i+3hP=S&cWj6rpu-bmeKOP-Xl^cVOax1{ zbydHDG-@QtvBdna?{Rj^^-bwi$a4u3#Od}7l+XL1J+b;TK*%b56L<*5!!ZQ9w8;Y`883gL{ZIEU8!VuCs{(YjG3ySL)wAS8Q;~x|j z>`_?mFdY5ce&wZGgo;|g=!^nsbg=sY_L2eQJCMU@uXuY%(jSl!WzkkX{%F47+~xYH z2Ia3*svJ0cRkUTWqCuQG6Hv51ratSLuK_jEP=R$>~t+8OfP=?R_9<^Yl6sQFHq^v9+Ui^DydjDnY z2A5NR&lhLGTQdlndt4wThW~Z=8h~J1=I%FVCWEM;?SOi>APWvw^!FTJo3XjMxyKyR z#qX|G!|h)}AdnG)sZyP`IV;t>HmbCZ&-Xv_>cyQGF$1leA)i%&M`PSF*>4Sb%W|ry zsKklYVah%ocko*TrUd7=FW0xWem^;xP4#+^*i5Ldb~-RCRU3g@nIpUgU9nu)!8e)Tc7sv1N0G-OmaDE(H4kS5PZGJdnq+e&&*um zp5J2lYS|rc+<_{?)6+9=xApdikB=YwG4N;&1*P8p{!kozUuH8Pa*xZ`?OjKY>`S

dB z@eWr8KSpdes{L1S@t;Q%b2&2aZtC%j(f&^<=N`}W{>Sm;v}}~~iygUNDrpyLGbais z(F#XdLrt#bwvjr~v9KLcxhBP&SB!9|;;_GX(kYo63TA9I(OSET5w~{VhjGkT=9s(gD zO-+dr&qKg!AM|Hb&i+`2PPAO zYPg3CiaP^r7Sc#u$S`AWtEfF7t=hPD8wl?+up zURzeyw%AQ%+A~qDSp{ngZ@j+XMLbCQo;cnn5Yod!drC@5!p! z?tY`=AotFxzYcoVYw)F_jh}&1vhnzNV3mR z0*Jxuw0Tei^dW5#p$>11HB`nwiJl9ZZ(D>L4-}^}7`arV6#KW8l%GL(nzsE~N?34gy@TCRB;K-6Rn1^Uxtyq_&DPQ_ zhFyaT!;5OqEic;L!Y(!vf(pZNgD5cgv)g55miV5$Fbhi9+X`;>vjGji#(`+aIW9{@aU|mg9hPFd%z-|Dw|82#eOIFC5Ii zxR(NXdgW3|=puCc&HN_b<^*y`_vE{$^D9`+r~*H%>->Gn6Jx1J?nDzVqpDRIzvE#) zYZ$A zL?2lFB#PEFqm2~fXRc~%^pHg&AKj?LuCDtVyiM?Ie`VxjfbN72RX-7~S9h&~cWGef zm(x6dAuTg-LJ)Rg?CqXcAHGiZKXFN~&UvX+6+Mx^f4!w!K5VC3sqC0_(0KVj@s2DD zi}~IT)*Ykz-)1HG_-B(sd*_X#ePvDl!(REzc0>x5YcNmXG-t`y2Zg zp7R-Dpf`lu=i%x)fTKiE0}zYqvLV-<;^_5}Mp z{*F8o^ssl`7^$g)3p{Y}`zv|qp)wyVAd5lu5~k@{f7u+3E_Usx{gxDr+lgl~q_vlH%60l9rGZfK?v=|0-Oo#N@(6uPOD*WHbHC9F-jUacM=@P0jdB{+vB zE~92fZ`Ra&3xgv*4zFp?CK^-+FCXqOKq56&R8EtP!9|cdn2Hn9PK>k566~!JO2FU% zrc}iZS%2^*oVII@t_+^s%8O+BcaY-a<2|2VEBAZ#RS9#X^2wR0t~z91;A&j9@2y<_ zI~GT8-acD)$>L5(**zTP!$UZ-4lr#yTwD)TthaY{O}-v+H{~EodLN|~ z_}8=0115!G^QQjKr2ZYh!6uZ2+TP21F`q*|)@kQEvECH;V3~NgyFb*p_L;bkB*5`T z=GiT_cK9tz^`14fyyRpGfHQWkstF2vCBk~_m9I-;rev7fJ_ZJ2M-GNhFENWLmI${@ z4Ar>$`e-~Ejfd5f9ORR_yPb#7d5x`$@s3s3$!Jw~469urNRs>Oe^LYJXJ~a}lXk!0 zs*jOuitL3|gY4%^6$kJr2ZXNyVdoeL6jB7Pjfwl>l6U!WH6YTLz0hVoHTGzt@l^h! zP-1YWPh7Ie$V>BcmKs{>N$q-gEB^V->}K3-P*b8wl;7<`bKTP%J|w}`fU?)JJZ>g5 z7;aTgRMlo@WTbNYRQQtt9f`QOUn literal 0 HcmV?d00001 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..020c6e28a 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -269,19 +269,18 @@ nav: - Examples: - 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 From 4de1bd6e666ba9305d259f8f043608c4f9c6aac9 Mon Sep 17 00:00:00 2001 From: Lauren Hirata Singh Date: Tue, 8 Jul 2025 12:33:14 -0400 Subject: [PATCH 28/31] docs: cleanup (#5401) * docs: cleanup * fix nav * fix * fix nits --- docs/_scripts/extract_images.py | 70 -- docs/docs/additional-resources/index.md | 11 + docs/docs/agents/agents.md | 2 +- docs/docs/cloud/concepts/threads.md | 12 - docs/docs/examples/index.md | 23 + docs/docs/guides/index.md | 41 + .../tutorials/multi_agent/agent_supervisor.md | 2 +- docs/docs/tutorials/overview.md | 21 - docs/docs/tutorials/sql-agent.ipynb | 759 ------------------ docs/mkdocs.yml | 3 + 10 files changed, 80 insertions(+), 864 deletions(-) delete mode 100644 docs/_scripts/extract_images.py create mode 100644 docs/docs/additional-resources/index.md delete mode 100644 docs/docs/cloud/concepts/threads.md create mode 100644 docs/docs/examples/index.md create mode 100644 docs/docs/guides/index.md delete mode 100644 docs/docs/tutorials/overview.md delete mode 100644 docs/docs/tutorials/sql-agent.ipynb diff --git a/docs/_scripts/extract_images.py b/docs/_scripts/extract_images.py deleted file mode 100644 index 781ba0a22..000000000 --- a/docs/_scripts/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/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/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/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/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/tutorials/multi_agent/agent_supervisor.md b/docs/docs/tutorials/multi_agent/agent_supervisor.md index ba8f84ff6..71335c8db 100644 --- a/docs/docs/tutorials/multi_agent/agent_supervisor.md +++ b/docs/docs/tutorials/multi_agent/agent_supervisor.md @@ -206,7 +206,7 @@ Name: tavily_search ### Math agent -For math agent tools we will use [vanilla Python functions](../../agents/tools.md#define-simple-tools): +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): diff --git a/docs/docs/tutorials/overview.md b/docs/docs/tutorials/overview.md deleted file mode 100644 index 6eacbd4e4..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.md) -- [SQL agent](./sql/sql-agent.md) -- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md) - -## 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-integration.md) -- [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/sql-agent.ipynb b/docs/docs/tutorials/sql-agent.ipynb deleted file mode 100644 index a06626f40..000000000 --- a/docs/docs/tutorials/sql-agent.ipynb +++ /dev/null @@ -1,759 +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 genre on average has the longest tracks?\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_list_tables (call_d8lCgywSroCgpVl558nmXKwA)\n", - " Call ID: call_d8lCgywSroCgpVl558nmXKwA\n", - " Args:\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_nNf6IIUcwMYLIkE0l6uWkZHe)\n", - " Call ID: call_nNf6IIUcwMYLIkE0l6uWkZHe\n", - " Args:\n", - " table_names: Genre, Track\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_schema\n", - "\n", - "\n", - "CREATE TABLE \"Genre\" (\n", - "\t\"GenreId\" INTEGER NOT NULL, \n", - "\t\"Name\" NVARCHAR(120), \n", - "\tPRIMARY KEY (\"GenreId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Genre table:\n", - "GenreId\tName\n", - "1\tRock\n", - "2\tJazz\n", - "3\tMetal\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"Track\" (\n", - "\t\"TrackId\" INTEGER NOT NULL, \n", - "\t\"Name\" NVARCHAR(200) NOT NULL, \n", - "\t\"AlbumId\" INTEGER, \n", - "\t\"MediaTypeId\" INTEGER NOT NULL, \n", - "\t\"GenreId\" INTEGER, \n", - "\t\"Composer\" NVARCHAR(220), \n", - "\t\"Milliseconds\" INTEGER NOT NULL, \n", - "\t\"Bytes\" INTEGER, \n", - "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", - "\tPRIMARY KEY (\"TrackId\"), \n", - "\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \n", - "\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \n", - "\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Track table:\n", - "TrackId\tName\tAlbumId\tMediaTypeId\tGenreId\tComposer\tMilliseconds\tBytes\tUnitPrice\n", - "1\tFor Those About To Rock (We Salute You)\t1\t1\t1\tAngus Young, Malcolm Young, Brian Johnson\t343719\t11170334\t0.99\n", - "2\tBalls to the Wall\t2\t2\t1\tNone\t342562\t5510424\t0.99\n", - "3\tFast As a Shark\t3\t2\t1\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\t230619\t3990994\t0.99\n", - "*/\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query_checker (call_urTRmtiGtTxkwHtscec7Fd2K)\n", - " Call ID: call_urTRmtiGtTxkwHtscec7Fd2K\n", - " Args:\n", - " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", - "FROM Track\n", - "JOIN Genre ON Track.GenreId = Genre.GenreId\n", - "GROUP BY Genre.Name\n", - "ORDER BY AvgMilliseconds DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query_checker\n", - "\n", - "```sql\n", - "SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", - "FROM Track\n", - "JOIN Genre ON Track.GenreId = Genre.GenreId\n", - "GROUP BY Genre.Name\n", - "ORDER BY AvgMilliseconds DESC\n", - "LIMIT 1;\n", - "```\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_RNMqyUEMv0rvy0UxSwrXY2AV)\n", - " Call ID: call_RNMqyUEMv0rvy0UxSwrXY2AV\n", - " Args:\n", - " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgMilliseconds\n", - "FROM Track\n", - "JOIN Genre ON Track.GenreId = Genre.GenreId\n", - "GROUP BY Genre.Name\n", - "ORDER BY AvgMilliseconds DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query\n", - "\n", - "[('Sci Fi & Fantasy', 2911783.0384615385)]\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "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.\n" - ] - } - ], - "source": [ - "question = \"Which genre on average has the longest tracks?\"\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": 6, - "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": 7, - "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": 8, - "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": 9, - "id": "6c800a77-2359-4011-ab0c-dad22ed333b1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "================================\u001b[1m Human Message \u001b[0m=================================\n", - "\n", - "Which genre on average has the longest tracks?\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_qxKtYiHgf93AiTDin9ez5wFp)\n", - " Call ID: call_qxKtYiHgf93AiTDin9ez5wFp\n", - " Args:\n", - " table_names: Genre,Track\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_schema\n", - "\n", - "\n", - "CREATE TABLE \"Genre\" (\n", - "\t\"GenreId\" INTEGER NOT NULL, \n", - "\t\"Name\" NVARCHAR(120), \n", - "\tPRIMARY KEY (\"GenreId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Genre table:\n", - "GenreId\tName\n", - "1\tRock\n", - "2\tJazz\n", - "3\tMetal\n", - "*/\n", - "\n", - "\n", - "CREATE TABLE \"Track\" (\n", - "\t\"TrackId\" INTEGER NOT NULL, \n", - "\t\"Name\" NVARCHAR(200) NOT NULL, \n", - "\t\"AlbumId\" INTEGER, \n", - "\t\"MediaTypeId\" INTEGER NOT NULL, \n", - "\t\"GenreId\" INTEGER, \n", - "\t\"Composer\" NVARCHAR(220), \n", - "\t\"Milliseconds\" INTEGER NOT NULL, \n", - "\t\"Bytes\" INTEGER, \n", - "\t\"UnitPrice\" NUMERIC(10, 2) NOT NULL, \n", - "\tPRIMARY KEY (\"TrackId\"), \n", - "\tFOREIGN KEY(\"MediaTypeId\") REFERENCES \"MediaType\" (\"MediaTypeId\"), \n", - "\tFOREIGN KEY(\"GenreId\") REFERENCES \"Genre\" (\"GenreId\"), \n", - "\tFOREIGN KEY(\"AlbumId\") REFERENCES \"Album\" (\"AlbumId\")\n", - ")\n", - "\n", - "/*\n", - "3 rows from Track table:\n", - "TrackId\tName\tAlbumId\tMediaTypeId\tGenreId\tComposer\tMilliseconds\tBytes\tUnitPrice\n", - "1\tFor Those About To Rock (We Salute You)\t1\t1\t1\tAngus Young, Malcolm Young, Brian Johnson\t343719\t11170334\t0.99\n", - "2\tBalls to the Wall\t2\t2\t1\tNone\t342562\t5510424\t0.99\n", - "3\tFast As a Shark\t3\t2\t1\tF. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman\t230619\t3990994\t0.99\n", - "*/\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_RPN3GABMfb6DTaFTLlwnZxVN)\n", - " Call ID: call_RPN3GABMfb6DTaFTLlwnZxVN\n", - " Args:\n", - " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength\n", - "FROM Track\n", - "JOIN Genre ON Track.GenreId = Genre.GenreId\n", - "GROUP BY Genre.GenreId\n", - "ORDER BY AvgTrackLength DESC\n", - "LIMIT 1;\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "Tool Calls:\n", - " sql_db_query (call_PR4s8ymiF3ZQLaoZADXtdqcl)\n", - " Call ID: call_PR4s8ymiF3ZQLaoZADXtdqcl\n", - " Args:\n", - " query: SELECT Genre.Name, AVG(Track.Milliseconds) AS AvgTrackLength\n", - "FROM Track\n", - "JOIN Genre ON Track.GenreId = Genre.GenreId\n", - "GROUP BY Genre.GenreId\n", - "ORDER BY AvgTrackLength DESC\n", - "LIMIT 1;\n", - "=================================\u001b[1m Tool Message \u001b[0m=================================\n", - "Name: sql_db_query\n", - "\n", - "[('Sci Fi & Fantasy', 2911783.0384615385)]\n", - "==================================\u001b[1m Ai Message \u001b[0m==================================\n", - "\n", - "The genre with the longest tracks on average is \"Sci Fi & Fantasy,\" with an average track length of approximately 2,911,783 milliseconds.\n" - ] - } - ], - "source": [ - "question = \"Which genre on average has the longest tracks?\"\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/94b8c9ac-12f7-4692-8706-836a1f30f1ea/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/mkdocs.yml b/docs/mkdocs.yml index 020c6e28a..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,6 +269,7 @@ 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.md - Agent Supervisor: tutorials/multi_agent/agent_supervisor.md @@ -286,6 +288,7 @@ nav: - 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 From fb1c0ae9f9072363e1c934d259549ed131f1bcd1 Mon Sep 17 00:00:00 2001 From: Jake Broekhuizen Date: Tue, 8 Jul 2025 09:55:15 -0700 Subject: [PATCH 29/31] docs: Updating mcp_tools_node fn & referencing runtime graph rebuild docs (#5328) Fix: Updating mcp_tools_node fn & referencing runtime graph rebuild docs --- docs/docs/concepts/server-mcp.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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. From 9cb6365914d11ca33909d1d3c5f56565c91fc16b Mon Sep 17 00:00:00 2001 From: Michael Li Date: Wed, 9 Jul 2025 04:58:04 +1000 Subject: [PATCH 30/31] docs: update file paths to make the examples more robust (#5382) * cli: update file paths to make the examples more robust * fix: fix the prompt path --- libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py | 2 +- libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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() From 0d8a8c5847703e78b88b3b2e3fb224a4d3adff63 Mon Sep 17 00:00:00 2001 From: William FH <13333726+hinthornw@users.noreply.github.com> Date: Tue, 8 Jul 2025 12:41:47 -0700 Subject: [PATCH 31/31] feat: [CLI] Add arg to retain build deps (setuptools, pip, wheel) (#5404) --- docs/docs/cloud/reference/cli.md | 1 + libs/cli/examples/langgraph.json | 1 + libs/cli/langgraph_cli/config.py | 124 ++++++++++++++++++---- libs/cli/pyproject.toml | 2 +- libs/cli/schemas/schema.json | 36 ++++++- libs/cli/schemas/schema.v0.json | 36 ++++++- libs/cli/schemas/version.schema.json | 46 ++++++++ libs/cli/tests/unit_tests/cli/test_cli.py | 7 +- libs/cli/tests/unit_tests/test_config.py | 57 +++++++++- libs/cli/uv.lock | 2 +- 10 files changed, 280 insertions(+), 32 deletions(-) create mode 100644 libs/cli/schemas/version.schema.json 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/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 cd0356350..ce1c6e8b9 100644 --- a/libs/cli/langgraph_cli/config.py +++ b/libs/cli/langgraph_cli/config.py @@ -338,7 +338,7 @@ class HttpConfig(TypedDict, total=False): Default is False. """ disable_meta: bool - """Optional. If True, all meta endpoints (/ok, /info, /metrics, /docs) are disabled. + """Optional. If True, all meta endpoints (/openapi.json, /info, /metrics, /docs) are disabled. Default is False. """ @@ -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"): @@ -635,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 @@ -1128,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, @@ -1135,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" @@ -1297,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/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 268f44e00..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), 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 a6a0d0270..b312f2e06 100644 --- a/libs/cli/uv.lock +++ b/libs/cli/uv.lock @@ -522,7 +522,7 @@ wheels = [ [[package]] name = "langgraph-cli" -version = "0.3.3" +version = "0.3.4" source = { editable = "." } dependencies = [ { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
\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", - "