mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-09 11:17:53 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b5e81e086 |
@@ -1,29 +1,29 @@
|
||||
name: "\U0001F41B Bug Report"
|
||||
description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the LangChain Forum at forum.langchain.com.
|
||||
description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the GitHub Discussions.
|
||||
labels: [pending,bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
value: >
|
||||
Thank you for taking the time to file a bug report.
|
||||
|
||||
Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
|
||||
Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use [GitHub Discussions](https://github.com/langchain-ai/langgraph/discussions).
|
||||
|
||||
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
|
||||
if there's another way to solve your problem:
|
||||
|
||||
* [LangChain Forum](https://forum.langchain.com/),
|
||||
* [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||
* [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
||||
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
||||
* [GitHub search](https://github.com/langchain-ai/langgraph),
|
||||
[LangGraph Github Discussions](https://github.com/langchain-ai/langgraph/discussions),
|
||||
[LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||
[LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
||||
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
||||
[GitHub search](https://github.com/langchain-ai/langgraph),
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Checked other resources
|
||||
description: Before submitting this issue, please confirm that you have completed all the steps below by checking each option. These steps help ensure your issue is well-defined, relevant, and actionable.
|
||||
options:
|
||||
- label: This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
|
||||
- label: This is a bug, not a usage question. For questions, please use GitHub Discussions.
|
||||
required: true
|
||||
- label: I added a clear and detailed title that summarizes the issue.
|
||||
required: true
|
||||
@@ -38,7 +38,7 @@ body:
|
||||
attributes:
|
||||
label: Example Code
|
||||
description: |
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case. Replace this code with your own!
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
|
||||
placeholder: |
|
||||
from langgraph.graph import StateGraph
|
||||
|
||||
@@ -78,7 +78,7 @@ body:
|
||||
attributes:
|
||||
label: System Info
|
||||
description: |
|
||||
Run on your machine: `python -m langchain_core.sys_info`
|
||||
python -m langchain_core.sys_info
|
||||
placeholder: |
|
||||
python -m langchain_core.sys_info
|
||||
validations:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
version: 2.1
|
||||
contact_links:
|
||||
- name: Feature Request
|
||||
url: https://github.com/langchain-ai/langgraph/discussions/categories/ideas
|
||||
about: Suggest a feature or an idea
|
||||
- name: LangChain Forum
|
||||
url: https://forum.langchain.com/
|
||||
about: General community discussions, support, and feature requests
|
||||
about: General community discussions and support
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
name: 🔒 Privileged
|
||||
description: You are a LangGraph maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
|
||||
description: You are a LangChain maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in LangGraph! 🚀
|
||||
|
||||
If you are not a LangGraph maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation on the [LangChain Forum](https://forum.langchain.com/) instead.
|
||||
|
||||
You are a LangGraph maintainer if you maintain any of the packages inside of the LangGraph repository
|
||||
or are a regular contributor to LangGraph with previous merged merged pull requests.
|
||||
Thanks for your interest in LangChain! 🚀
|
||||
|
||||
If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation in a [Question in GitHub Discussions](https://github.com/langchain-ai/langchain/discussions/categories/q-a) instead.
|
||||
|
||||
You are a LangChain maintainer if you maintain any of the packages inside of the LangChain repository
|
||||
or are a regular contributor to LangChain with previous merged merged pull requests.
|
||||
- type: checkboxes
|
||||
id: privileged
|
||||
attributes:
|
||||
label: Privileged issue
|
||||
description: Confirm that you are allowed to create an issue here.
|
||||
options:
|
||||
- label: I am a LangGraph maintainer, or was asked directly by a LangGraph maintainer to create an issue here.
|
||||
- label: I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create an issue here.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: Issue Content
|
||||
description: Add the content of the issue here.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Community members should **NOT** work on Privileged issues unless these issues have been explicitly marked with a "help-wanted" tag.
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
Thank you for contributing to LangGraph! Follow these steps to mark your pull request as ready for review. **If any of these steps are not completed, your PR will not be considered for review.**
|
||||
|
||||
- [ ] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
|
||||
- Examples:
|
||||
- feat(core): add multi-tenant support
|
||||
- fix(cli): resolve flag parsing error
|
||||
- docs(openai): update API usage examples
|
||||
- Allowed `{TYPE}` values:
|
||||
- feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release
|
||||
- Allowed `{SCOPE}` values (optional):
|
||||
- langgraph, docs, cli, checkpoint, checkpoint-postgres, checkpoint-sqlite, prebuilt, scheduler-kafka, sdk-py
|
||||
- Once you've written the title, please delete this checklist item; do not include it in the PR.
|
||||
|
||||
- [ ] **PR message**: ***Delete this entire checklist*** and replace with
|
||||
- **Description:** a description of the change. Include a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if applicable.
|
||||
- **Issue:** the issue # it fixes, if applicable
|
||||
- **Dependencies:** any dependencies required for this change
|
||||
- **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out!
|
||||
|
||||
- [ ] **Add tests and docs**: If you're adding a new integration, you must include:
|
||||
1. A test for the integration, preferably unit tests that do not rely on network access,
|
||||
2. An example notebook showing its use. It lives in `docs/docs/integrations` directory.
|
||||
|
||||
- [ ] **Lint and test**: Run `make format`, `make lint` and `make test` from the root of the package(s) you've modified. We will not consider a PR unless these three are passing in CI. See [contribution guidelines](https://github.com/langchain-ai/langgraph/blob/main/CONTRIBUTING.md) for more.
|
||||
|
||||
Additional guidelines:
|
||||
|
||||
- Make sure optional dependencies are imported within a function.
|
||||
- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests.
|
||||
- Most PRs should not touch more than one package.
|
||||
- Changes should be backwards compatible.
|
||||
@@ -1,11 +0,0 @@
|
||||
LangChain
|
||||
LangGraph
|
||||
LangSmith
|
||||
thead
|
||||
stdio
|
||||
nd
|
||||
jupyter
|
||||
lets
|
||||
lite
|
||||
uis
|
||||
deque
|
||||
@@ -34,16 +34,10 @@
|
||||
id: extract_ignore_words
|
||||
|
||||
- name: Codespell
|
||||
uses: codespell-project/actions-codespell@v2.1
|
||||
uses: codespell-project/actions-codespell@v2
|
||||
with:
|
||||
skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map'
|
||||
skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.md'
|
||||
ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
|
||||
# We do this to avoid spellchecking cell outputs
|
||||
- name: Codespell Notebooks
|
||||
run: make codespell
|
||||
|
||||
- name: Codespell LangGraph Library
|
||||
run: |
|
||||
# Change to root directory to check the main LangGraph library
|
||||
cd ..
|
||||
codespell --skip="*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map,*.pyc,__pycache__/*" --ignore-words-list="${{ steps.extract_ignore_words.outputs.ignore_words_list }}" libs/langgraph/langgraph/
|
||||
run: make codespell
|
||||
+9
-8
@@ -9,7 +9,7 @@ Here are some things to keep in mind for all types of contributions:
|
||||
- Follow the ["fork and pull request"](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) workflow.
|
||||
- Fill out the checked-in pull request template when opening pull requests. Note related issues and tag relevant maintainers.
|
||||
- Ensure your PR passes formatting, linting, and testing checks before requesting a review.
|
||||
- If you would like comments or feedback, please tag a maintainer.
|
||||
- If you would like comments or feedback, please open an issue or discussion and tag a maintainer.
|
||||
- Backwards compatibility is key. Your changes must not be breaking, except in case of critical bug and security fixes.
|
||||
- Look for duplicate PRs or issues that have already been opened before opening a new one.
|
||||
- Keep scope as isolated as possible. As a general rule, your changes should not affect more than one package at a time.
|
||||
@@ -20,7 +20,7 @@ For bug fixes, please open up an issue before proposing a fix to ensure the prop
|
||||
|
||||
### New features
|
||||
|
||||
For new features, please start a new [discussion](https://forum.langchain.com/), where the maintainers will help with scoping out the necessary changes.
|
||||
For new features, please start a new [discussion](https://github.com/langchain-ai/langgraph/discussions), where the maintainers will help with scoping out the necessary changes.
|
||||
|
||||
## Contribute Documentation
|
||||
|
||||
@@ -111,6 +111,7 @@ in a more abstract way than how-to guides or tutorials, and should be geared tow
|
||||
gaining a deeper understanding of the framework. Try to avoid excessively large code examples. The goal here is to
|
||||
impart perspective to the user rather than to finish a practical project. These guides should cover **why** things work the way they do.
|
||||
|
||||
|
||||
To quote the Diataxis website:
|
||||
|
||||
> The perspective of explanation is higher and wider than that of the other types. It does not take the user’s eye-level view, as in a how-to guide, or a close-up view of the machinery, like reference material. Its scope in each case is a topic - “an area of knowledge”, that somehow has to be bounded in a reasonable, meaningful way.
|
||||
@@ -186,9 +187,9 @@ Be concise, including in code samples.
|
||||
|
||||
## Setup
|
||||
|
||||
LangGraph documentation consists of two components:
|
||||
LangChain documentation consists of two components:
|
||||
|
||||
1. Main Documentation: Hosted at [https://langchain-ai.github.io/langgraph/](https://langchain-ai.github.io/langgraph/),
|
||||
1. Main Documentation: Hosted at [https://langchain-ai.github.io](https://langchain-ai.github.io/langgraph/),
|
||||
this comprehensive resource serves as the primary user-facing documentation.
|
||||
It covers a wide array of topics, including tutorials, use cases, integrations,
|
||||
and more, offering extensive guidance on building with LangGraph.
|
||||
@@ -249,17 +250,17 @@ make serve-docs
|
||||
|
||||
#### Linting
|
||||
|
||||
To spell check the docs, run the following from the `docs` directory:
|
||||
The documentation is linted from the **monorepo root**. To lint it, run the following from there:
|
||||
|
||||
```bash
|
||||
codespell --skip="*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map" --ignore-words-list="infor,thead,stdio,nd,jupyter,lets,lite,uis,deque" .
|
||||
make spellcheck
|
||||
```
|
||||
|
||||
### ️In-code Documentation
|
||||
|
||||
The in-code documentation is autogenerated from docstrings.
|
||||
|
||||
For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangGraph because the API reference is the primary resource for developers to understand how to use the codebase.
|
||||
For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangChain because the API reference is the primary resource for developers to understand how to use the codebase.
|
||||
|
||||
We generally follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) for docstrings.
|
||||
|
||||
@@ -290,4 +291,4 @@ def my_function(arg1: int, arg2: str) -> float:
|
||||
This is a description of the return value.
|
||||
"""
|
||||
return 3.14
|
||||
```
|
||||
```
|
||||
@@ -73,7 +73,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
||||
|
||||
- [Guides](https://langchain-ai.github.io/langgraph/how-tos/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.).
|
||||
- [Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components.
|
||||
- [Examples](https://langchain-ai.github.io/langgraph/examples/): Guided examples on getting started with LangGraph.
|
||||
- [Examples](https://langchain-ai.github.io/langgraph/tutorials/overview/): Guided examples on getting started with LangGraph.
|
||||
- [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback.
|
||||
- [LangChain Academy](https://academy.langchain.com/courses/intro-to-langgraph): Learn the basics of LangGraph in our free, structured course.
|
||||
- [Templates](https://langchain-ai.github.io/langgraph/concepts/template_applications/): Pre-built reference apps for common agentic workflows (e.g. ReAct agent, memory, retrieval etc.) that can be cloned and adapted.
|
||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||
|
||||
+14
-41
@@ -55,16 +55,14 @@ The `langchain-mcp-adapters` package enables agents to use tools defined across
|
||||
|
||||
=== "In a workflow"
|
||||
|
||||
```python title="Workflow using MCP tools with ToolNode"
|
||||
```python
|
||||
from langchain_mcp_adapters.client import MultiServerMCPClient
|
||||
from langgraph.graph import StateGraph, MessagesState, START
|
||||
from langgraph.prebuilt import ToolNode, tools_condition
|
||||
|
||||
from langchain.chat_models import init_chat_model
|
||||
from langgraph.graph import StateGraph, MessagesState, START, END
|
||||
from langgraph.prebuilt import ToolNode
|
||||
model = init_chat_model("openai:gpt-4.1")
|
||||
|
||||
# Initialize the model
|
||||
model = init_chat_model("anthropic:claude-3-5-sonnet-latest")
|
||||
|
||||
# Set up MCP client
|
||||
client = MultiServerMCPClient(
|
||||
{
|
||||
"math": {
|
||||
@@ -82,47 +80,22 @@ The `langchain-mcp-adapters` package enables agents to use tools defined across
|
||||
)
|
||||
tools = await client.get_tools()
|
||||
|
||||
# Bind tools to model
|
||||
model_with_tools = model.bind_tools(tools)
|
||||
def call_model(state: MessagesState):
|
||||
response = model.bind_tools(tools).invoke(state["messages"])
|
||||
return {"messages": response}
|
||||
|
||||
# Create ToolNode
|
||||
tool_node = ToolNode(tools)
|
||||
|
||||
def should_continue(state: MessagesState):
|
||||
messages = state["messages"]
|
||||
last_message = messages[-1]
|
||||
if last_message.tool_calls:
|
||||
return "tools"
|
||||
return END
|
||||
|
||||
# Define call_model function
|
||||
async def call_model(state: MessagesState):
|
||||
messages = state["messages"]
|
||||
response = await model_with_tools.ainvoke(messages)
|
||||
return {"messages": [response]}
|
||||
|
||||
# Build the graph
|
||||
builder = StateGraph(MessagesState)
|
||||
builder.add_node("call_model", call_model)
|
||||
builder.add_node("tools", tool_node)
|
||||
|
||||
builder.add_node(call_model)
|
||||
builder.add_node(ToolNode(tools))
|
||||
builder.add_edge(START, "call_model")
|
||||
builder.add_conditional_edges(
|
||||
"call_model",
|
||||
should_continue,
|
||||
tools_condition,
|
||||
)
|
||||
builder.add_edge("tools", "call_model")
|
||||
|
||||
# Compile the graph
|
||||
graph = builder.compile()
|
||||
|
||||
# Test the graph
|
||||
math_response = await graph.ainvoke(
|
||||
{"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
|
||||
)
|
||||
weather_response = await graph.ainvoke(
|
||||
{"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
|
||||
)
|
||||
math_response = await graph.ainvoke({"messages": "what's (3 + 5) x 12?"})
|
||||
weather_response = await graph.ainvoke({"messages": "what is the weather in nyc?"})
|
||||
```
|
||||
|
||||
|
||||
@@ -175,4 +148,4 @@ if __name__ == "__main__":
|
||||
|
||||
- [MCP documentation](https://modelcontextprotocol.io/introduction)
|
||||
- [MCP Transport documentation](https://modelcontextprotocol.io/docs/concepts/transports)
|
||||
- [langchain_mcp_adapters](https://github.com/langchain-ai/langchain-mcp-adapters)
|
||||
- [langchain_mcp_adapters](https://github.com/langchain-ai/langchain-mcp-adapters)
|
||||
@@ -1,119 +0,0 @@
|
||||
# Egress for Subscription Metrics and Operational Metadata
|
||||
|
||||
> **Important: Self Hosted Only**
|
||||
> This section only applies to customers who are not running in offline mode and assumes you are using a self-hosted LangGraph Platform instance.
|
||||
> This does not apply to SaaS or Hybrid deployments.
|
||||
|
||||
Self-Hosted LangGraph Platform instances store all information locally and will never send sensitive information outside of your network. We currently only track platform usage for billing purposes according to the entitlements in your order. In order to better remotely support our customers, we do require egress to `https://beacon.langchain.com`.
|
||||
|
||||
In the future, we will be introducing support diagnostics to help us ensure that the LangGraph Platform is running at an optimal level within your environment.
|
||||
|
||||
> **Warning**
|
||||
> **This will require egress to `https://beacon.langchain.com` from your network.**
|
||||
> **If using an API key, you will also need to allow egress to `https://api.smith.langchain.com` or `https://eu.api.smith.langchain.com` for API key verification.**
|
||||
|
||||
Generally, data that we send to Beacon can be categorized as follows:
|
||||
|
||||
- **Subscription Metrics**
|
||||
- Subscription metrics are used to determine level of access and utilization of LangSmith. This includes, but are not limited to:
|
||||
- Nodes Executed
|
||||
- Runs Executed
|
||||
- License Key Verification
|
||||
- **Operational Metadata**
|
||||
- This metadata will contain and collect the above subscription metrics to assist with remote support, allowing the LangChain team to diagnose and troubleshoot performance issues more effectively and proactively.
|
||||
|
||||
## Example Payloads
|
||||
|
||||
In an effort to maximize transparency, we provide sample payloads here:
|
||||
|
||||
### License Verification (If using an Enterprise License)
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
`POST beacon.langchain.com/v1/beacon/verify`
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{
|
||||
"license": "<YOUR_LICENSE_KEY>"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "Valid JWT" // Short-lived JWT token to avoid repeated license checks
|
||||
}
|
||||
```
|
||||
|
||||
### Api Key Verification (If using a LangSmith API Key)
|
||||
|
||||
**Endpoint:**
|
||||
`POST api.smith.langchain.com/auth`
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
"Headers": {
|
||||
X-Api-Key: <YOUR_API_KEY>
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"org_config": {
|
||||
"org_id": "3a1c2b6f-4430-4b92-8a5b-79b8b567bbc1",
|
||||
... // Additional organization details
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage Reporting
|
||||
|
||||
**Endpoint:**
|
||||
|
||||
`POST beacon.langchain.com/v1/metadata/submit`
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{
|
||||
"license": "<YOUR_LICENSE_KEY>",
|
||||
"from_timestamp": "2025-01-06T09:00:00Z",
|
||||
"to_timestamp": "2025-01-06T10:00:00Z",
|
||||
"tags": {
|
||||
"langgraph.python.version": "0.1.0",
|
||||
"langgraph_api.version": "0.2.0",
|
||||
"langgraph.platform.revision": "abc123",
|
||||
"langgraph.platform.variant": "standard",
|
||||
"langgraph.platform.host": "host-1",
|
||||
"langgraph.platform.tenant_id": "3a1c2b6f-4430-4b92-8a5b-79b8b567bbc1",
|
||||
"langgraph.platform.project_id": "c5b5f53a-4716-4326-8967-d4f7f7799735",
|
||||
"langgraph.platform.plan": "enterprise",
|
||||
"user_app.uses_indexing": "true",
|
||||
"user_app.uses_custom_app": "false",
|
||||
"user_app.uses_custom_auth": "true",
|
||||
"user_app.uses_thread_ttl": "true",
|
||||
"user_app.uses_store_ttl": "false"
|
||||
},
|
||||
"measures": {
|
||||
"langgraph.platform.runs": 150,
|
||||
"langgraph.platform.nodes": 450
|
||||
},
|
||||
"logs": []
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
"204 No Content"
|
||||
```
|
||||
|
||||
## Our Commitment
|
||||
|
||||
LangChain will not store any sensitive information in the Subscription Metrics or Operational Metadata. Any data collected will not be shared with a third party. If you have any concerns about the data being sent, please reach out to your account team.
|
||||
@@ -23,8 +23,6 @@ Before deploying, review the [conceptual guide for the Self-Hosted Control Plane
|
||||
|
||||
kubectl get storageclass
|
||||
|
||||
1. Egress to `https://beacon.langchain.com` from your network. This is required for license verification and usage reporting if not running in air-gapped mode. See the [Egress documentation](../../cloud/deployment/egress.md) for more details.
|
||||
|
||||
## Setup
|
||||
|
||||
1. As part of configuring your Self-Hosted LangSmith instance, you enable the `langgraphPlatform` option. This will provision a few key resources.
|
||||
|
||||
@@ -24,7 +24,6 @@ Before deploying, review the [conceptual guide for the Standalone Container](../
|
||||
1. `LANGSMITH_API_KEY`: (if using [Lite](../../concepts/langgraph_server.md#server-versions)) LangSmith API key. This will be used to authenticate ONCE at server start up.
|
||||
1. `LANGGRAPH_CLOUD_LICENSE_KEY`: (if using [Enterprise](../../concepts/langgraph_data_plane.md#licensing)) LangGraph Platform license key. This will be used to authenticate ONCE at server start up.
|
||||
1. `LANGSMITH_ENDPOINT`: To send traces to a [self-hosted LangSmith](https://docs.smith.langchain.com/self_hosting) instance, set `LANGSMITH_ENDPOINT` to the hostname of the self-hosted LangSmith instance.
|
||||
1. Egress to `https://beacon.langchain.com` from your network. This is required for license verification and usage reporting if not running in air-gapped mode. See the [Egress documentation](../../cloud/deployment/egress.md) for more details.
|
||||
|
||||
## Kubernetes (Helm)
|
||||
|
||||
|
||||
@@ -30,33 +30,17 @@ export default {
|
||||
|
||||
Next, define your UI components in your `langgraph.json` configuration:
|
||||
|
||||
=== "Python agent"
|
||||
|
||||
```json title="langgraph.json"
|
||||
{
|
||||
"node_version": "20",
|
||||
"graphs": {
|
||||
"agent": "./src/agent.py:graph"
|
||||
},
|
||||
"ui": {
|
||||
"agent": "./src/agent/ui.tsx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
=== "JS agent"
|
||||
|
||||
```json title="langgraph.json"
|
||||
{
|
||||
"node_version": "20",
|
||||
"graphs": {
|
||||
"agent": "./src/agent/index.ts:graph"
|
||||
},
|
||||
"ui": {
|
||||
"agent": "./src/agent/ui.tsx"
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"node_version": "20",
|
||||
"graphs": {
|
||||
"agent": "./src/agent/index.ts:graph"
|
||||
},
|
||||
"ui": {
|
||||
"agent": "./src/agent/ui.tsx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `ui` section points to the UI components that will be used by graphs. By default, we recommend using the same key as the graph name, but you can split out the components however you like, see [Customise the namespace of UI components](#customise-the-namespace-of-ui-components) for more details.
|
||||
|
||||
|
||||
@@ -140,22 +140,6 @@ https://my-server.app/my-webhook-endpoint?token=YOUR_SECRET_TOKEN
|
||||
|
||||
Your server should extract and validate this token before processing requests.
|
||||
|
||||
## Disable webhooks
|
||||
|
||||
As of `langgraph-api>=0.2.78`, developers can disable webhooks in the `langgraph.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"http": {
|
||||
"disable_webhooks": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This feature is primarily intended for self-hosted deployments, where platform administrators or developers may prefer to disable webhooks to simplify their security posture—especially if they are not configuring firewall rules or other network controls. Disabling webhooks helps prevent untrusted payloads from being sent to internal endpoints.
|
||||
|
||||
For full configuration details, refer to the [configuration file reference](https://langchain-ai.github.io/langgraph/cloud/reference/cli/?h=disable_webhooks#configuration-file).
|
||||
|
||||
## Test webhooks
|
||||
|
||||
You can test your webhook using online services like:
|
||||
|
||||
@@ -409,8 +409,8 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema](
|
||||
| Option | Default | Description |
|
||||
| ---------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--wait` | | Wait for services to start before returning. Implies --detach |
|
||||
| `--base-image TEXT` | `langchain/langgraph-api` | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
|
||||
| `--image TEXT` | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
|
||||
| `--base-image TEXT` | `langchain/langgraph-api` | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
|
||||
| `--image TEXT` | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
|
||||
| `--postgres-uri TEXT` | Local database | Postgres URI to use for the database. |
|
||||
| `--watch` | | Restart on file changes |
|
||||
| `--debugger-base-url TEXT` | `http://127.0.0.1:[PORT]` | URL used by the debugger to access LangGraph API. |
|
||||
@@ -438,8 +438,8 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema](
|
||||
| Option | Default | Description |
|
||||
| ---------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| <span style="white-space: nowrap;">`--wait`</span> | | Wait for services to start before returning. Implies --detach |
|
||||
| <span style="white-space: nowrap;">`--base-image TEXT`</span> | <span style="white-space: nowrap;">`langchain/langgraph-api`</span> | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
|
||||
| <span style="white-space: nowrap;">`--image TEXT`</span> | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
|
||||
| <span style="white-space: nowrap;">`--base-image TEXT`</span> | <span style="white-space: nowrap;">`langchain/langgraph-api`</span> | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
|
||||
| <span style="white-space: nowrap;">`--image TEXT`</span> | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
|
||||
| <span style="white-space: nowrap;">`--postgres-uri TEXT`</span> | Local database | Postgres URI to use for the database. |
|
||||
| <span style="white-space: nowrap;">`--watch`</span> | | Restart on file changes |
|
||||
| <span style="white-space: nowrap;">`-c, --config FILE`</span> | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
|
||||
|
||||
@@ -28,9 +28,6 @@ Specify `DD_API_KEY` (your [Datadog API Key](https://docs.datadoghq.com/account_
|
||||
|
||||
If `DD_API_KEY` is specified, the application process is wrapped in the [`ddtrace-run` command](https://ddtrace.readthedocs.io/en/stable/installation_quickstart.html). Other `DD_*` environment variables (e.g. `DD_SITE`, `DD_ENV`, `DD_SERVICE`, `DD_TRACE_ENABLED`) are typically needed to properly configure the tracing instrumentation. See [`DD_*` environment variables](https://ddtrace.readthedocs.io/en/stable/configuration.html) for more details.
|
||||
|
||||
!!! note
|
||||
Enabling `DD_API_KEY` (and thus `ddtrace-run`) can override or interfere with other auto-instrumentation solutions (such as OpenTelemetry) that you may have instrumented into your application code.
|
||||
|
||||
## `LANGCHAIN_TRACING_SAMPLING_RATE`
|
||||
|
||||
Sampling rate for traces sent to LangSmith. Valid values: Any float between `0` and `1`.
|
||||
|
||||
@@ -4,38 +4,8 @@
|
||||
|
||||
---
|
||||
|
||||
## v0.2.96 (2025-07-17)
|
||||
- Added a fallback mechanism for configurable header patterns to handle exclude/include settings more effectively.
|
||||
|
||||
## v0.2.95 (2025-07-17)
|
||||
- Avoided setting the future if it is already done to prevent redundant operations.
|
||||
- Resolved compatibility errors in CI by switching from `typing.TypedDict` to `typing_extensions.TypedDict` for Python versions below 3.12.
|
||||
|
||||
## v0.2.94 (2025-07-16)
|
||||
- Improved performance by omitting pending sends for langgraph versions 0.5 and above.
|
||||
- Improved server startup logs to provide clearer warnings when the DD_API_KEY environment variable is set.
|
||||
|
||||
## v0.2.93 (2025-07-16)
|
||||
- Removed the GIN index for run metadata to improve performance.
|
||||
|
||||
## v0.2.92 (2025-07-16)
|
||||
- Enabled copying functionality for blobs and checkpoints, improving data management flexibility.
|
||||
|
||||
## v0.2.91 (2025-07-16)
|
||||
- Reduced writes to the `checkpoint_blobs` table by inlining small values (null, numeric, str, etc.). This means we don't need to store extra values for channels that haven't been updated.
|
||||
|
||||
## v0.2.90 (2025-07-16)
|
||||
- Improve checkpoint writes via node-local background queueing.
|
||||
|
||||
|
||||
## v0.2.89 (2025-07-15)
|
||||
- Decoupled checkpoint writing from thread/run state by removing foreign keys and updated logger to prevent timeout-related failures.
|
||||
|
||||
## v0.2.88 (2025-07-14)
|
||||
- Removed the foreign key constraint for `thread` in the `run` table to simplify database schema.
|
||||
|
||||
## v0.2.87 (2025-07-14)
|
||||
- Added more detailed logs for Redis worker signaling to improve debugging.
|
||||
- Enhanced logging for Redis worker signaling to provide more helpful insights into worker activities.
|
||||
|
||||
## v0.2.86 (2025-07-11)
|
||||
- Honored tool descriptions in the `/mcp` endpoint to align with expected functionality.
|
||||
|
||||
@@ -10,7 +10,7 @@ search:
|
||||
There are two free options for deploying LangGraph applications via the LangGraph Server:
|
||||
|
||||
1. [Local](../tutorials/langgraph-platform/local-server.md): Deploy for local testing and development.
|
||||
1. [Standalone Container (Lite)](../concepts/langgraph_standalone_container.md): A limited version of Standalone Container for deployments unlikely to see more than 1 million node executions per year and that do not need crons and other enterprise features. Standalone Container (Lite) deployment option is free with a LangSmith API key.
|
||||
1. [Standalone Container (Lite)](../concepts/langgraph_standalone_container.md): A limited version of Standalone Container for deployments unlikely to see more that 1 million node executions per year and that do not need crons and other enterprise features. Standalone Container (Lite) deployment option is free with a LangSmith API key.
|
||||
|
||||
## Production deployment
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ The first thing you do when you define a graph is define the `State` of the grap
|
||||
|
||||
### Schema
|
||||
|
||||
The main documented way to specify the schema of a graph is by using a [`TypedDict`](https://docs.python.org/3/library/typing.html#typing.TypedDict). If you want to provide default values in your state, use a [`dataclass`](https://docs.python.org/3/library/dataclasses.html). We also support using a Pydantic [BaseModel](../how-tos/graph-api.md#use-pydantic-models-for-graph-state) as your graph state if you want recursive data validation (though note that pydantic is less performant than a `TypedDict` or `dataclass`).
|
||||
The main documented way to specify the schema of a graph is by using `TypedDict`. However, we also support [using a Pydantic BaseModel](../how-tos/graph-api.md#use-pydantic-models-for-graph-state) as your graph state to add **default values** and additional data validation.
|
||||
|
||||
By default, the graph will have the same input and output schemas. If you want to change this, you can also specify explicit input and output schemas directly. This is useful when you have a lot of keys, and some are explicitly for input and others for output. See the [guide here](../how-tos/graph-api.md#define-input-and-output-schemas) for how to use.
|
||||
|
||||
@@ -298,7 +298,7 @@ print(graph.invoke({"x": 5}, stream_mode='updates')) # (2)!
|
||||
[{'expensive_node': {'result': 10}, '__metadata__': {'cached': True}}]
|
||||
```
|
||||
|
||||
1. First run takes two seconds to run (due to mocked expensive computation).
|
||||
1. First run takes the full second to run (due to mocked expensive computation).
|
||||
2. Second run utilizes cache and returns quickly.
|
||||
|
||||
## Edges
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# Tracing
|
||||
|
||||
Traces are a series of steps that your application takes to go from input to output. Each of these individual steps is represented by a run. You can use [LangSmith](https://smith.langchain.com/) to visualize these execution steps. To use it, [enable tracing for your application](../how-tos/enable-tracing.md). This enables you to do the following:
|
||||
|
||||
- [Debug a locally running application](../cloud/how-tos/clone_traces_studio.md).
|
||||
- [Evaluate the application performance](../agents/evals.md).
|
||||
- [Monitor the application](https://docs.smith.langchain.com/observability/how_to_guides/dashboards).
|
||||
|
||||
To get started, sign up for a free account at [LangSmith](https://smith.langchain.com/).
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md)
|
||||
- [LangSmith Observability quickstart](https://docs.smith.langchain.com/observability)
|
||||
- [Trace with LangGraph](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_langgraph)
|
||||
- [Tracing conceptual guide](https://docs.smith.langchain.com/observability/concepts#traces)
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
The pages in this section provide a conceptual overview and how-tos for the following topics:
|
||||
|
||||
## Agent development
|
||||
|
||||
- [Overview](../agents/overview.md): Use prebuilt components to build an agent.
|
||||
- [Run an agent](../agents/run_agents.md): Run an agent by providing input, interpreting output, enabling streaming, and controlling execution limits.
|
||||
|
||||
## LangGraph APIs
|
||||
|
||||
- [Graph API](../concepts/low_level.md): Use the Graph API to define workflows using a graph paradigm.
|
||||
|
||||
@@ -31,12 +31,12 @@ To leverage custom authentication and access user-level metadata in your deploym
|
||||
api_key = headers.get("x-api-key")
|
||||
if not api_key or not is_valid_key(api_key):
|
||||
raise Auth.exceptions.HTTPException(status_code=401, detail="Invalid API key")
|
||||
|
||||
# Fetch user-specific tokens from your secret store
|
||||
|
||||
# Fetch user-specific tokens from your secret store
|
||||
user_tokens = await fetch_user_tokens(api_key)
|
||||
|
||||
return { # (2)!
|
||||
"identity": api_key, # fetch user ID from LangSmith
|
||||
"identity": api_key, # fetch user ID from LangSmith
|
||||
"github_token" : user_tokens.github_token
|
||||
"jira_token" : user_tokens.jira_token
|
||||
# ... custom fields/secrets here
|
||||
@@ -50,14 +50,14 @@ To leverage custom authentication and access user-level metadata in your deploym
|
||||
|
||||
```json hl_lines="7-9"
|
||||
{
|
||||
"dependencies": ["."],
|
||||
"graphs": {
|
||||
"dependencies": ["."],
|
||||
"graphs": {
|
||||
"agent": "./agent.py:graph"
|
||||
},
|
||||
"env": ".env",
|
||||
"auth": {
|
||||
},
|
||||
"env": ".env",
|
||||
"auth": {
|
||||
"path": "./auth.py:my_auth"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -80,7 +80,7 @@ To leverage custom authentication and access user-level metadata in your deploym
|
||||
|
||||
```python
|
||||
from langgraph.pregel.remote import RemoteGraph
|
||||
|
||||
|
||||
my_token = "your-token" # In practice, you would generate a signed token with your auth provider
|
||||
remote_graph = RemoteGraph(
|
||||
"agent",
|
||||
@@ -133,44 +133,15 @@ To allow an agent to perform authenticated actions on behalf of the user, access
|
||||
def my_node(state, config):
|
||||
user_config = config["configurable"].get("langgraph_auth_user")
|
||||
# token was resolved during the @auth.authenticate function
|
||||
token = user_config.get("github_token","")
|
||||
token = user_config.get("github_token","")
|
||||
...
|
||||
```
|
||||
|
||||
!!! note
|
||||
Fetch user credentials from a secure secret store. Storing secrets in graph state is not recommended.
|
||||
|
||||
### Authorizing a Studio user
|
||||
|
||||
By default, if you add custom authorization on your resources, this will also apply to interactions made from the Studio. If you want, you can handle logged-in Studio users differently by checking [is_studio_user()](../../reference/functions/sdk_auth.isStudioUser.html).
|
||||
|
||||
!!! note
|
||||
`is_studio_user` was added in version 0.1.73 of the langgraph-sdk. If you're on an older version, you can still check whether `isinstance(ctx.user, StudioUser)`.
|
||||
|
||||
```python
|
||||
from langgraph_sdk.auth import is_studio_user, Auth
|
||||
auth = Auth()
|
||||
|
||||
# ... Setup authenticate, etc.
|
||||
|
||||
@auth.on
|
||||
async def add_owner(
|
||||
ctx: Auth.types.AuthContext,
|
||||
value: dict # The payload being sent to this access method
|
||||
) -> dict: # Returns a filter dict that restricts access to resources
|
||||
if is_studio_user(ctx.user):
|
||||
return {}
|
||||
|
||||
filters = {"owner": ctx.user.identity}
|
||||
metadata = value.setdefault("metadata", {})
|
||||
metadata.update(filters)
|
||||
return filters
|
||||
```
|
||||
|
||||
Only use this if you want to permit developer access to a graph deployed on the managed LangGraph Platform SaaS.
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Authentication & Access Control](../../concepts/auth.md)
|
||||
- [LangGraph Platform](../../concepts/langgraph_platform.md)
|
||||
- [Setting up custom authentication tutorial](../../tutorials/auth/getting_started.md)
|
||||
* [Authentication & Access Control](../../concepts/auth.md)
|
||||
* [LangGraph Platform](../../concepts/langgraph_platform.md)
|
||||
* [Setting up custom authentication tutorial](../../tutorials/auth/getting_started.md)
|
||||
|
||||
@@ -290,7 +290,7 @@ my-autogen-agent/
|
||||
|
||||
```
|
||||
langgraph>=0.1.0
|
||||
ag2>=0.2.0
|
||||
pyautogen>=0.2.0
|
||||
langchain-core>=0.1.0
|
||||
langchain-openai>=0.0.5
|
||||
```
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Enable tracing for your application
|
||||
|
||||
To enable [tracing](../concepts/tracing.md) for your application, set the following environment variables:
|
||||
|
||||
```python
|
||||
export LANGSMITH_TRACING=true
|
||||
export LANGSMITH_API_KEY=<your-api-key>
|
||||
```
|
||||
|
||||
For more information, see [Trace with LangGraph](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_langgraph).
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md)
|
||||
- [LangSmith Observability quickstart](https://docs.smith.langchain.com/observability)
|
||||
- [Tracing conceptual guide](https://docs.smith.langchain.com/observability/concepts#traces)
|
||||
@@ -328,15 +328,14 @@ Output of graph invocation: {'a': 'set by node_3'}
|
||||
|
||||
A [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.StateGraph) accepts a `state_schema` argument on initialization that specifies the "shape" of the state that the nodes in the graph can access and update.
|
||||
|
||||
In our examples, we typically use a python-native `TypedDict` or [`dataclass`](https://docs.python.org/3/library/dataclasses.html) for `state_schema`, but `state_schema` can be any [type](https://docs.python.org/3/library/stdtypes.html#type-objects).
|
||||
In our examples, we typically use a python-native `TypedDict` for `state_schema`, but `state_schema` can be any [type](https://docs.python.org/3/library/stdtypes.html#type-objects).
|
||||
|
||||
Here, we'll see how a [Pydantic BaseModel](https://docs.pydantic.dev/latest/api/base_model/) can be used for `state_schema` to add run-time validation on **inputs**.
|
||||
Here, we'll see how a [Pydantic BaseModel](https://docs.pydantic.dev/latest/api/base_model/). can be used for `state_schema` to add run time validation on **inputs**.
|
||||
|
||||
!!! note "Known Limitations"
|
||||
- Currently, the output of the graph will **NOT** be an instance of a pydantic model.
|
||||
- Run-time validation only occurs on inputs into nodes, not on the outputs.
|
||||
- The validation error trace from pydantic does not show which node the error arises in.
|
||||
- Pydantic's recursive validation can be slow. For performance-sensitive applications, you may want to consider using a `dataclass` instead.
|
||||
|
||||
```python
|
||||
from langgraph.graph import StateGraph, START, END
|
||||
@@ -1152,13 +1151,12 @@ LangGraph supports map-reduce and other advanced branching patterns using the Se
|
||||
```python
|
||||
from langgraph.graph import StateGraph, START, END
|
||||
from langgraph.types import Send
|
||||
from typing_extensions import TypedDict, Annotated
|
||||
import operator
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
class OverallState(TypedDict):
|
||||
topic: str
|
||||
subjects: list[str]
|
||||
jokes: Annotated[list[str], operator.add]
|
||||
jokes: list[str]
|
||||
best_selected_joke: str
|
||||
|
||||
def generate_topics(state: OverallState):
|
||||
@@ -1196,7 +1194,7 @@ from IPython.display import Image, display
|
||||
display(Image(graph.get_graph().draw_mermaid_png()))
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
```python
|
||||
# Call the graph: here we call it to generate a list of jokes
|
||||
@@ -1448,7 +1446,7 @@ Recursion Error
|
||||
display(Image(graph.get_graph().draw_mermaid_png()))
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
This graph looks complex, but can be conceptualized as loop of [supersteps](../concepts/low_level.md#graphs):
|
||||
|
||||
@@ -1567,9 +1565,9 @@ class State(TypedDict):
|
||||
|
||||
def node_a(state: State) -> Command[Literal["node_b", "node_c"]]:
|
||||
print("Called A")
|
||||
value = random.choice(["b", "c"])
|
||||
value = random.choice(["a", "b"])
|
||||
# this is a replacement for a conditional edge function
|
||||
if value == "b":
|
||||
if value == "a":
|
||||
goto = "node_b"
|
||||
else:
|
||||
goto = "node_c"
|
||||
|
||||
+5
-8
@@ -103,15 +103,14 @@ nav:
|
||||
- 5. Customize state: tutorials/get-started/5-customize-state.md
|
||||
- 6. Time travel: tutorials/get-started/6-time-travel.md
|
||||
- Run a local server: tutorials/langgraph-platform/local-server.md
|
||||
- General concepts:
|
||||
- Agent development:
|
||||
- Workflows & agents: tutorials/workflows.md
|
||||
- Prebuilt components: agents/overview.md
|
||||
- Run an agent: agents/run_agents.md
|
||||
- Agent architectures: concepts/agentic_concepts.md
|
||||
|
||||
- Guides:
|
||||
- guides/index.md
|
||||
- Agent development:
|
||||
- Overview: agents/overview.md
|
||||
- Run an agent: agents/run_agents.md
|
||||
- LangGraph APIs:
|
||||
- Graph API:
|
||||
- Overview: concepts/low_level.md
|
||||
@@ -158,10 +157,8 @@ nav:
|
||||
- Overview: concepts/mcp.md
|
||||
- Use MCP: agents/mcp.md
|
||||
- Server API: concepts/server-mcp.md
|
||||
- Tracing:
|
||||
- Overview: concepts/tracing.md
|
||||
- Enable tracing: how-tos/enable-tracing.md
|
||||
- Evaluate performance: agents/evals.md
|
||||
- Evaluation:
|
||||
- Basic implementation: agents/evals.md
|
||||
- Platform-only capabilities:
|
||||
- LangGraph Platform:
|
||||
- Overview: concepts/langgraph_platform.md
|
||||
|
||||
+1
-3
@@ -112,6 +112,4 @@ extend-include = ["*.ipynb"]
|
||||
[tool.codespell]
|
||||
# https://mypy.readthedocs.io/en/stable/config_file.html
|
||||
# comma-separated list
|
||||
ignore-words-list = "infor,thead,stdio,nd,jupyter,lets,lite,uis,deque"
|
||||
# Exclude generated files and directories
|
||||
skip = "*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map"
|
||||
ignore-words-list = "infor"
|
||||
|
||||
@@ -289,7 +289,6 @@ class PostgresSaver(BasePostgresSaver):
|
||||
)
|
||||
|
||||
copy = checkpoint.copy()
|
||||
copy["channel_values"] = copy["channel_values"].copy()
|
||||
next_config = {
|
||||
"configurable": {
|
||||
"thread_id": thread_id,
|
||||
@@ -298,28 +297,16 @@ class PostgresSaver(BasePostgresSaver):
|
||||
}
|
||||
}
|
||||
|
||||
# inline primitive values in checkpoint table
|
||||
# others are stored in blobs table
|
||||
blob_values = {}
|
||||
for k, v in checkpoint["channel_values"].items():
|
||||
if v is None or isinstance(v, (str, int, float, bool)):
|
||||
pass
|
||||
else:
|
||||
blob_values[k] = copy["channel_values"].pop(k)
|
||||
|
||||
with self._cursor(pipeline=True) as cur:
|
||||
if blob_versions := {
|
||||
k: v for k, v in new_versions.items() if k in blob_values
|
||||
}:
|
||||
cur.executemany(
|
||||
self.UPSERT_CHECKPOINT_BLOBS_SQL,
|
||||
self._dump_blobs(
|
||||
thread_id,
|
||||
checkpoint_ns,
|
||||
blob_values,
|
||||
blob_versions,
|
||||
),
|
||||
)
|
||||
cur.executemany(
|
||||
self.UPSERT_CHECKPOINT_BLOBS_SQL,
|
||||
self._dump_blobs(
|
||||
thread_id,
|
||||
checkpoint_ns,
|
||||
copy.pop("channel_values"), # type: ignore[misc]
|
||||
new_versions,
|
||||
),
|
||||
)
|
||||
cur.execute(
|
||||
self.UPSERT_CHECKPOINTS_SQL,
|
||||
(
|
||||
@@ -452,10 +439,7 @@ class PostgresSaver(BasePostgresSaver):
|
||||
},
|
||||
{
|
||||
**value["checkpoint"],
|
||||
"channel_values": {
|
||||
**value["checkpoint"].get("channel_values"),
|
||||
**self._load_blobs(value["channel_values"]),
|
||||
},
|
||||
"channel_values": self._load_blobs(value["channel_values"]),
|
||||
},
|
||||
value["metadata"],
|
||||
(
|
||||
|
||||
@@ -245,7 +245,6 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
||||
)
|
||||
|
||||
copy = checkpoint.copy()
|
||||
copy["channel_values"] = copy["channel_values"].copy()
|
||||
next_config = {
|
||||
"configurable": {
|
||||
"thread_id": thread_id,
|
||||
@@ -254,29 +253,17 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
||||
}
|
||||
}
|
||||
|
||||
# inline primitive values in checkpoint table
|
||||
# others are stored in blobs table
|
||||
blob_values = {}
|
||||
for k, v in checkpoint["channel_values"].items():
|
||||
if v is None or isinstance(v, (str, int, float, bool)):
|
||||
pass
|
||||
else:
|
||||
blob_values[k] = copy["channel_values"].pop(k)
|
||||
|
||||
async with self._cursor(pipeline=True) as cur:
|
||||
if blob_versions := {
|
||||
k: v for k, v in new_versions.items() if k in blob_values
|
||||
}:
|
||||
await cur.executemany(
|
||||
self.UPSERT_CHECKPOINT_BLOBS_SQL,
|
||||
await asyncio.to_thread(
|
||||
self._dump_blobs,
|
||||
thread_id,
|
||||
checkpoint_ns,
|
||||
blob_values,
|
||||
blob_versions,
|
||||
),
|
||||
)
|
||||
await cur.executemany(
|
||||
self.UPSERT_CHECKPOINT_BLOBS_SQL,
|
||||
await asyncio.to_thread(
|
||||
self._dump_blobs,
|
||||
thread_id,
|
||||
checkpoint_ns,
|
||||
copy.pop("channel_values"), # type: ignore[misc]
|
||||
new_versions,
|
||||
),
|
||||
)
|
||||
await cur.execute(
|
||||
self.UPSERT_CHECKPOINTS_SQL,
|
||||
(
|
||||
@@ -410,10 +397,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
||||
},
|
||||
{
|
||||
**value["checkpoint"],
|
||||
"channel_values": {
|
||||
**value["checkpoint"].get("channel_values"),
|
||||
**self._load_blobs(value["channel_values"]),
|
||||
},
|
||||
"channel_values": self._load_blobs(value["channel_values"]),
|
||||
},
|
||||
value["metadata"],
|
||||
(
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "langgraph-checkpoint-postgres"
|
||||
version = "2.0.23"
|
||||
version = "2.0.22"
|
||||
description = "Library with a Postgres implementation of LangGraph checkpoint saver."
|
||||
authors = []
|
||||
requires-python = ">=3.9"
|
||||
|
||||
Generated
+2
-2
@@ -304,7 +304,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
source = { editable = "../checkpoint" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
@@ -334,7 +334,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint-postgres"
|
||||
version = "2.0.23"
|
||||
version = "2.0.22"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "langgraph-checkpoint" },
|
||||
|
||||
@@ -29,7 +29,7 @@ _AIO_ERROR_MSG = (
|
||||
"from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver\n"
|
||||
"Note: AsyncSqliteSaver requires the aiosqlite package to use.\n"
|
||||
"Install with:\n`pip install aiosqlite`\n"
|
||||
"See https://langchain-ai.github.io/langgraph/reference/checkpoints/#langgraph.checkpoint.sqlite.aio.AsyncSqliteSaver"
|
||||
"See https://langchain-ai.github.io/langgraph/reference/checkpoints/asyncsqlitesaver"
|
||||
"for more information."
|
||||
)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -316,7 +316,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
source = { editable = "../checkpoint" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
|
||||
@@ -343,14 +343,10 @@ async def _run(
|
||||
|
||||
# set the results of each operation
|
||||
for fut, result in zip(futs, results):
|
||||
# guard against future being done (e.g. cancelled)
|
||||
if not fut.done():
|
||||
fut.set_result(result)
|
||||
fut.set_result(result)
|
||||
except Exception as e:
|
||||
for fut in futs:
|
||||
# guard against future being done (e.g. cancelled)
|
||||
if not fut.done():
|
||||
fut.set_exception(e)
|
||||
fut.set_exception(e)
|
||||
finally:
|
||||
# remove strong ref to store
|
||||
del s
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
description = "Library with base interfaces for LangGraph checkpoint savers."
|
||||
authors = []
|
||||
requires-python = ">=3.9"
|
||||
|
||||
@@ -155,43 +155,6 @@ async def test_async_batch_store(mocker: MockerFixture) -> None:
|
||||
]
|
||||
|
||||
|
||||
async def test_async_batch_store_handles_cancellation() -> None:
|
||||
class MockStore(AsyncBatchedBaseStore):
|
||||
def batch(self, ops: Iterable[Op]) -> list[Result]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def abatch(self, ops: Iterable[Op]) -> list[Result]:
|
||||
assert all(isinstance(op, GetOp) for op in ops)
|
||||
return [
|
||||
Item(
|
||||
value={},
|
||||
key=getattr(op, "key", ""),
|
||||
namespace=getattr(op, "namespace", ()),
|
||||
created_at=datetime(2024, 9, 24, 17, 29, 10, 128397),
|
||||
updated_at=datetime(2024, 9, 24, 17, 29, 10, 128397),
|
||||
)
|
||||
for op in ops
|
||||
]
|
||||
|
||||
store = MockStore()
|
||||
|
||||
# Simulate cancellation
|
||||
task = asyncio.create_task(store.aget(namespace=("a",), key="b"))
|
||||
await asyncio.sleep(0)
|
||||
task.cancel()
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Cancelling individual queries against the store should not break the store
|
||||
result = await store.aget(namespace=("c",), key="d")
|
||||
assert result == Item(
|
||||
value={},
|
||||
key="d",
|
||||
namespace=("c",),
|
||||
created_at=datetime(2024, 9, 24, 17, 29, 10, 128397),
|
||||
updated_at=datetime(2024, 9, 24, 17, 29, 10, 128397),
|
||||
)
|
||||
|
||||
|
||||
def test_list_namespaces_basic() -> None:
|
||||
store = InMemoryStore()
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -323,7 +323,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "langgraph-cli"
|
||||
version = "0.3.5"
|
||||
version = "0.3.4"
|
||||
description = "CLI for interacting with LangGraph API"
|
||||
authors = []
|
||||
requires-python = ">=3.9"
|
||||
@@ -19,7 +19,7 @@ dependencies = [
|
||||
[project.optional-dependencies]
|
||||
inmem = [
|
||||
"langgraph-api>=0.2.67,<0.3.0 ; python_version >= '3.11'",
|
||||
"langgraph-runtime-inmem>=0.6.0 ; python_version >= '3.11'",
|
||||
"langgraph-runtime-inmem>=0.3.0,<0.4.0 ; python_version >= '3.11'",
|
||||
"python-dotenv>=0.8.0",
|
||||
]
|
||||
|
||||
|
||||
Generated
+160
-170
@@ -30,34 +30,25 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backports-asyncio-runner"
|
||||
version = "1.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blockbuster"
|
||||
version = "1.5.25"
|
||||
version = "1.5.24"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "forbiddenfruit", marker = "python_full_version >= '3.11' and implementation_name == 'cpython'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7f/bc/57c49465decaeeedd58ce2d970b4cdfd93a74ba9993abff2dc498a31c283/blockbuster-1.5.25.tar.gz", hash = "sha256:b72f1d2aefdeecd2a820ddf1e1c8593bf00b96e9fdc4cd2199ebafd06f7cb8f0", size = 36058, upload-time = "2025-07-14T16:00:20.766Z" }
|
||||
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 = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/01/dccc277c014f171f61a6047bb22c684e16c7f2db6bb5c8cce1feaf41ec55/blockbuster-1.5.25-py3-none-any.whl", hash = "sha256:cb06229762273e0f5f3accdaed3d2c5a3b61b055e38843de202311ede21bb0f5", size = 13196, upload-time = "2025-07-14T16:00:19.396Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/c8/57a4c80e5abec29fa9406307a5277527f21210bfc6c2c61c3d8ded36c09b/blockbuster-1.5.24-py3-none-any.whl", hash = "sha256:e703497b55bc72af09d60d1cd746c2f3ba7ce0c446fa256be6ccda5e7d403520", size = 13214, upload-time = "2025-03-18T10:12:04.802Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.7.14"
|
||||
version = "2025.7.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995", size = 163981, upload-time = "2025-07-14T03:29:28.449Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/de/8a/c729b6b60c66a38f590c4e774decc4b2ec7b0576be8f1aa984a53ffa812a/certifi-2025.7.9.tar.gz", hash = "sha256:c1d2ec05395148ee10cf672ffc28cd37ea0ab0d99f9cc74c43e588cbd111b079", size = 160386, upload-time = "2025-07-09T02:13:58.874Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/f3/80a3f974c8b535d394ff960a11ac20368e06b736da395b551a49ce950cce/certifi-2025.7.9-py3-none-any.whl", hash = "sha256:d842783a14f8fdd646895ac26f719a061408834473cfc10203f6a575beb15d39", size = 159230, upload-time = "2025-07-09T02:13:57.007Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -453,7 +444,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langchain-core"
|
||||
version = "0.3.69"
|
||||
version = "0.3.68"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "jsonpatch", marker = "python_full_version >= '3.11'" },
|
||||
@@ -464,14 +455,14 @@ 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/82/26/c4770d3933237cde2918d502e3b0a8b6ce100b296840b632658f3e59b341/langchain_core-0.3.69.tar.gz", hash = "sha256:c132961117cc7f0227a4c58dd3e209674a6dd5b7e74abc61a0df93b0d736e283", size = 563824, upload-time = "2025-07-15T21:19:56.626Z" }
|
||||
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/51/7b/bb7b088440ff9cc55e9e6eba94162cbdcd3b1693c194e1ad4764acba29b9/langchain_core-0.3.69-py3-none-any.whl", hash = "sha256:383e9cb4919f7ef4b24bf8552ef42e4323c064924fea88b28dd5d7ddb740d3b8", size = 441556, upload-time = "2025-07-15T21:19:55.342Z" },
|
||||
{ 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.5.3"
|
||||
version = "0.5.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core", marker = "python_full_version >= '3.11'" },
|
||||
@@ -481,14 +472,14 @@ dependencies = [
|
||||
{ name = "pydantic", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "xxhash", marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/99/f4/f4ebb83dff589b31d4a11c0d3c9c39a55d41f2a722dfb78761f7ed95e96d/langgraph-0.5.3.tar.gz", hash = "sha256:36d4b67f984ff2649d447826fc99b1a2af3e97599a590058f20750048e4f548f", size = 442591, upload-time = "2025-07-14T20:10:02.907Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c0/18/1e255fc8c36ff5056d797d83c9ca9fd926683ace294a9ba38c4b40599237/langgraph-0.5.2.tar.gz", hash = "sha256:393b767e9d6a129636a9df36edc492499336c71e4ee268e64b9d1299d30e636c", size = 442564, upload-time = "2025-07-09T19:15:20.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/2f/11be9302d3a213debcfe44355453a1e8fd7ee5e3138edeb8bd82b56bc8f6/langgraph-0.5.3-py3-none-any.whl", hash = "sha256:9819b88a6ef6134a0fa6d6121a81b202dc3d17b25cf7ea3fe4d7669b9b252b5d", size = 143774, upload-time = "2025-07-14T20:10:01.497Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/44/6e6c41a3cc00d533dc91cc5f086862b1fccf34aa0ec9605a2cbd116c6ba0/langgraph-0.5.2-py3-none-any.whl", hash = "sha256:db6b8053bf99887957fe45ec27918f8819c4bba269afde88b538e00e9301a581", size = 143735, upload-time = "2025-07-09T19:15:18.733Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-api"
|
||||
version = "0.2.96"
|
||||
version = "0.2.86"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cloudpickle", marker = "python_full_version >= '3.11'" },
|
||||
@@ -511,27 +502,27 @@ dependencies = [
|
||||
{ name = "uvicorn", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "watchfiles", marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/4c/837c5ce4aab704b6b13f27c5dd6330dabaf2f25d198032cb18e5d5dcaa53/langgraph_api-0.2.96.tar.gz", hash = "sha256:c498b5542a952d194121cdbe5a4b04e2f48fbc37480141ea2b87ba39a132ddb1", size = 238776, upload-time = "2025-07-17T17:57:47.274Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/06/f8d6c1310772a8507dfa2c586bab8d0ab8b8cbe1f896106ee315af08fb1d/langgraph_api-0.2.86.tar.gz", hash = "sha256:220532a5a2232d32efef7e3b98be74ee6328d18f785e83949fa815ef2ac77f2f", size = 237417, upload-time = "2025-07-11T17:02:39.535Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/7f/dfae9bc0f85a98bbd96d00df2a39e8b8386977e8ce4a6199d1065bb3709d/langgraph_api-0.2.96-py3-none-any.whl", hash = "sha256:304d424d7a85735489fab1764b439e8219739619ad708b9465b8b8f421f17b37", size = 194393, upload-time = "2025-07-17T17:57:45.89Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/48/e6b774e8cfe254694b768629c72004689d94d002a54e949c23e05b776eae/langgraph_api-0.2.86-py3-none-any.whl", hash = "sha256:b20ac26ef9c5323732012eed602290ca9ca268473341dcb3282b02ed6622ec8c", size = 192498, upload-time = "2025-07-11T17:02:38.199Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
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/73/3e/d00eb2b56c3846a0cabd2e5aa71c17a95f882d4f799a6ffe96a19b55eba9/langgraph_checkpoint-2.1.1.tar.gz", hash = "sha256:72038c0f9e22260cb9bff1f3ebe5eb06d940b7ee5c1e4765019269d4f21cf92d", size = 136256, upload-time = "2025-07-17T13:07:52.411Z" }
|
||||
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/4c/dd/64686797b0927fb18b290044be12ae9d4df01670dce6bb2498d5ab65cb24/langgraph_checkpoint-2.1.1-py3-none-any.whl", hash = "sha256:5a779134fd28134a9a83d078be4450bbf0e0c79fdf5e992549658899e6fc5ea7", size = 43925, upload-time = "2025-07-17T13:07:51.023Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/41/390a97d9d0abe5b71eea2f6fb618d8adadefa674e97f837bae6cda670bc7/langgraph_checkpoint-2.1.0-py3-none-any.whl", hash = "sha256:4cea3e512081da1241396a519cbfe4c5d92836545e2c64e85b6f5c34a1b8bc61", size = 43844, upload-time = "2025-06-16T22:05:00.758Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-cli"
|
||||
version = "0.3.5"
|
||||
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'" },
|
||||
@@ -562,7 +553,7 @@ dev = [
|
||||
requires-dist = [
|
||||
{ name = "click", specifier = ">=8.1.7" },
|
||||
{ name = "langgraph-api", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.2.67,<0.3.0" },
|
||||
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.6.0" },
|
||||
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.3.0,<0.4.0" },
|
||||
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11'", specifier = ">=0.1.0" },
|
||||
{ name = "python-dotenv", marker = "extra == 'inmem'", specifier = ">=0.8.0" },
|
||||
]
|
||||
@@ -595,7 +586,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-runtime-inmem"
|
||||
version = "0.6.0"
|
||||
version = "0.3.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "blockbuster", marker = "python_full_version >= '3.11'" },
|
||||
@@ -605,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/04/0c/d145c6d83d36efda17b10812760711b77ec05f5bbe962c961d75b32e3c17/langgraph_runtime_inmem-0.6.0.tar.gz", hash = "sha256:b09675789a331be4a2b387c9c46de8772c4c8418e74c057b4ca24e85c25acae3", size = 77618, upload-time = "2025-07-17T16:51:01.504Z" }
|
||||
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/12/6a/9dc5769b5d2f97d1feacbbf93b180c359dff7462454b37dfef8aed4ebcf7/langgraph_runtime_inmem-0.6.0-py3-none-any.whl", hash = "sha256:312dab25bec6557f1edf95cb8bd7c8bb52f7f4bfeecaf66e7001662f095c9079", size = 29317, upload-time = "2025-07-17T16:51:00.622Z" },
|
||||
{ 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.73"
|
||||
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/ba/e8/daf0271f91e93b10566533955c00ee16e471066755c2efd1ba9a887a7eab/langgraph_sdk-0.1.73.tar.gz", hash = "sha256:6e6dcdf66bcf8710739899616856527a72a605ce15beb76fbac7f4ce0e2ad080", size = 72157, upload-time = "2025-07-14T23:57:22.765Z" }
|
||||
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/77/86/56e01e715e5b0028cdaff1492a89e54fa12e18c21e03b805a10ea36ecd5a/langgraph_sdk-0.1.73-py3-none-any.whl", hash = "sha256:a60ac33f70688ad07051edff1d5ed8089c8f0de1f69dc900be46e095ca20eed8", size = 50222, upload-time = "2025-07-14T23:57:21.42Z" },
|
||||
{ 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.6"
|
||||
version = "0.4.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "httpx", marker = "python_full_version >= '3.11'" },
|
||||
@@ -636,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/fc/9e/11536528c6e351820ad3fca0d2807f0e0f0619ff907529c78f68ba648497/langsmith-0.4.6.tar.gz", hash = "sha256:9189dbc9c60f2086ca3a1f0110cfe3aff6b0b7c2e0e3384f9572e70502e7933c", size = 352364, upload-time = "2025-07-15T19:43:18.541Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5c/92/7885823f3d13222f57773921f0da19b37d628c64607491233dc853a0f6ea/langsmith-0.4.5.tar.gz", hash = "sha256:49444bd8ccd4e46402f1b9ff1d686fa8e3a31b175e7085e72175ab8ec6164a34", size = 352235, upload-time = "2025-07-10T22:08:04.505Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/9b/f2be47db823e89448ea41bfd8fc5ce6a995556bd25be4c23e5b3bb5b6c9b/langsmith-0.4.6-py3-none-any.whl", hash = "sha256:900e83fe59ee672bcf2f75c8bb47cd012bf8154d92a99c0355fc38b6485cbd3e", size = 367901, upload-time = "2025-07-15T19:43:16.508Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/10/ad3107b666c3203b7938d10ea6b8746b9735c399cf737a51386d58e41d34/langsmith-0.4.5-py3-none-any.whl", hash = "sha256:4167717a2cccc4dff5809dbddc439628e836f6fd13d4fdb31ea013bc8d5cfaf5", size = 367795, upload-time = "2025-07-10T22:08:02.548Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -686,7 +677,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.17.0"
|
||||
version = "1.16.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mypy-extensions" },
|
||||
@@ -694,39 +685,39 @@ dependencies = [
|
||||
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hash = "sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03", size = 3352114, upload-time = "2025-07-14T20:34:30.181Z" }
|
||||
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/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6", size = 10998313, upload-time = "2025-07-14T20:33:24.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d", size = 10128922, upload-time = "2025-07-14T20:34:06.414Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b", size = 11913524, upload-time = "2025-07-14T20:33:19.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a", size = 12650527, upload-time = "2025-07-14T20:32:44.095Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f", size = 12897284, upload-time = "2025-07-14T20:33:38.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937", size = 9506493, upload-time = "2025-07-14T20:34:01.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be", size = 10914150, upload-time = "2025-07-14T20:31:51.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61", size = 10039845, upload-time = "2025-07-14T20:32:30.527Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f", size = 11837246, upload-time = "2025-07-14T20:32:01.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d", size = 12571106, upload-time = "2025-07-14T20:34:26.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3", size = 12759960, upload-time = "2025-07-14T20:33:42.882Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70", size = 9503888, upload-time = "2025-07-14T20:32:34.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb", size = 11086395, upload-time = "2025-07-14T20:34:11.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d", size = 10120052, upload-time = "2025-07-14T20:33:09.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8", size = 11861806, upload-time = "2025-07-14T20:32:16.028Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e", size = 12744371, upload-time = "2025-07-14T20:33:33.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8", size = 12914558, upload-time = "2025-07-14T20:33:56.961Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d", size = 9585447, upload-time = "2025-07-14T20:32:20.594Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06", size = 11070019, upload-time = "2025-07-14T20:32:07.99Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a", size = 10114457, upload-time = "2025-07-14T20:33:47.285Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889", size = 11857838, upload-time = "2025-07-14T20:33:14.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba", size = 12731358, upload-time = "2025-07-14T20:32:25.579Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658", size = 12917480, upload-time = "2025-07-14T20:34:21.868Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c", size = 9589666, upload-time = "2025-07-14T20:34:16.841Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab", size = 10988185, upload-time = "2025-07-14T20:33:04.797Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad", size = 10120169, upload-time = "2025-07-14T20:32:38.84Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c", size = 11918121, upload-time = "2025-07-14T20:33:52.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8", size = 12648821, upload-time = "2025-07-14T20:32:59.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97", size = 12896955, upload-time = "2025-07-14T20:32:49.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4", size = 9512957, upload-time = "2025-07-14T20:33:28.619Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl", hash = "sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496", size = 2283195, upload-time = "2025-07-14T20:31:54.753Z" },
|
||||
{ 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]]
|
||||
@@ -740,81 +731,81 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.11.0"
|
||||
version = "3.10.18"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/29/87/03ababa86d984952304ac8ce9fbd3a317afb4a225b9a81f9b606ac60c873/orjson-3.11.0.tar.gz", hash = "sha256:2e4c129da624f291bcc607016a99e7f04a353f6874f3bd8d9b47b88597d5f700", size = 5318246, upload-time = "2025-07-15T16:08:29.194Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53", size = 5422810, upload-time = "2025-04-29T23:30:08.423Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/07/aa/50818f480f0edcb33290c8f35eef6dd3a31e2ff7e1195f8b236ac7419811/orjson-3.11.0-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b8913baba9751f7400f8fa4ec18a8b618ff01177490842e39e47b66c1b04bc79", size = 240422, upload-time = "2025-07-15T16:06:23.029Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/50/5235aff455fa76337493d21e68618e7cf53aa9db011aaeb06cf378f1344c/orjson-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d4d86910554de5c9c87bc560b3bdd315cc3988adbdc2acf5dda3797079407ed", size = 132473, upload-time = "2025-07-15T16:06:25.598Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/93/bf1c4e77e7affc46cca13fb852842a86dca2dabbee1d91515ed17b1c21c4/orjson-3.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84ae3d329360cf18fb61b67c505c00dedb61b0ee23abfd50f377a58e7d7bed06", size = 127195, upload-time = "2025-07-15T16:06:27.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/2d/64b52c6827e43aa3d98def19e188e091a6c574ca13d9ecef5f3f3284fac6/orjson-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47a54e660414baacd71ebf41a69bb17ea25abb3c5b69ce9e13e43be7ac20e342", size = 128895, upload-time = "2025-07-15T16:06:28.641Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/5f/9d290bc7a88392f9f7dc2e92ceb2e3efbbebaaf56bbba655b5fe2e3d2ca3/orjson-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2560b740604751854be146169c1de7e7ee1e6120b00c1788ec3f3a012c6a243f", size = 132016, upload-time = "2025-07-15T16:06:32.576Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/8c/b2bdc34649bbb7b44827d487aef7ad4d6a96c53ebc490ddcc191d47bc3b9/orjson-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7f9cd995da9e46fbac0a371f0ff6e89a21d8ecb7a8a113c0acb147b0a32f73", size = 134251, upload-time = "2025-07-15T16:06:34.075Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/be/b763b602976aa27407e6f75331ac581258c719f8abb70f66f2de962f649f/orjson-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cf728cb3a013bdf9f4132575404bf885aa773d8bb4205656575e1890fc91990", size = 128078, upload-time = "2025-07-15T16:06:35.408Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/24/1b0fed70392bf179ac8b5abe800f1102ed94f89ac4f889d83916947a2b4e/orjson-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c27de273320294121200440cd5002b6aeb922d3cb9dab3357087c69f04ca6934", size = 130734, upload-time = "2025-07-15T16:06:36.832Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/d2/2d042bb4fe1da067692cb70d8c01a5ce2737e2f56444e6b2d716853ce8c3/orjson-3.11.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4430ec6ff1a1f4595dd7e0fad991bdb2fed65401ed294984c490ffa025926325", size = 404040, upload-time = "2025-07-15T16:06:38.259Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/c5/54938ab416c0d19c93f0d6977a47bb2b3d121e150305380b783f7d6da185/orjson-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:325be41a8d7c227d460a9795a181511ba0e731cf3fee088c63eb47e706ea7559", size = 144808, upload-time = "2025-07-15T16:06:39.796Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/be/5ead422f396ee7c8941659ceee3da001e26998971f7d5fe0a38519c48aa5/orjson-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9760217b84d1aee393b4436fbe9c639e963ec7bc0f2c074581ce5fb3777e466", size = 132570, upload-time = "2025-07-15T16:06:41.209Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/01/db8352f7d0374d7eec25144e294991800aa85738b2dc7f19cc152ba1b254/orjson-3.11.0-cp310-cp310-win32.whl", hash = "sha256:fe36e5012f886ff91c68b87a499c227fa220e9668cea96335219874c8be5fab5", size = 134763, upload-time = "2025-07-15T16:06:42.524Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/f5/1322b64d5836d92f0b0c119d959853b3c968b8aae23dd1e3c1bfa566823b/orjson-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:ebeecd5d5511b3ca9dc4e7db0ab95266afd41baf424cc2fad8c2d3a3cdae650a", size = 129506, upload-time = "2025-07-15T16:06:43.929Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/2c/0b71a763f0f5130aa2631ef79e2cd84d361294665acccbb12b7a9813194e/orjson-3.11.0-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1785df7ada75c18411ff7e20ac822af904a40161ea9dfe8c55b3f6b66939add6", size = 240007, upload-time = "2025-07-15T16:06:45.411Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/5a/f79ccd63d378b9c7c771d7a54c203d261b4c618fe3034ae95cd30f934f34/orjson-3.11.0-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:a57899bebbcea146616a2426d20b51b3562b4bc9f8039a3bd14fae361c23053d", size = 129320, upload-time = "2025-07-15T16:06:47.249Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/8a/63dafc147fa5ba945ad809c374b8f4ee692bb6b18aa6e161c3e6b69b594e/orjson-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fbc2fc825aff1456dd358c11a0ad7912a4cb4537d3db92e5334af7463a967", size = 132254, upload-time = "2025-07-15T16:06:48.597Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/11/4d1eb230483cc689a2f039c531bb2c980029c40ca5a9b5f64dce9786e955/orjson-3.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4305a638f4cf9bed3746ca3b7c242f14e05177d5baec2527026e0f9ee6c24fb7", size = 127003, upload-time = "2025-07-15T16:06:50.34Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/39/b6e96072946d908684e0f4b3de1639062fd5b32016b2929c035bd8e5c847/orjson-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1235fe7bbc37164f69302199d46f29cfb874018738714dccc5a5a44042c79c77", size = 128674, upload-time = "2025-07-15T16:06:51.659Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/dd/c77e3013f35b202ec2cc1f78a95fadf86b8c5a320d56eb1a0bbb965a87bb/orjson-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a640e3954e7b4fcb160097551e54cafbde9966be3991932155b71071077881aa", size = 131846, upload-time = "2025-07-15T16:06:53.359Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/7d/d83f0f96c2b142f9cdcf12df19052ea3767970989dc757598dc108db208f/orjson-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d750b97d22d5566955e50b02c622f3a1d32744d7a578c878b29a873190ccb7a", size = 134016, upload-time = "2025-07-15T16:06:54.691Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/4f/d22f79a3c56dde563c4fbc12eebf9224a1b87af5e4ec61beb11f9b3eb499/orjson-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfcfe498484161e011f8190a400591c52b026de96b3b3cbd3f21e8999b9dc0e", size = 127930, upload-time = "2025-07-15T16:06:56.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/1e/26aede257db2163d974139fd4571f1e80f565216ccbd2c44ee1d43a63dcc/orjson-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:feaed3ed43a1d2df75c039798eb5ec92c350c7d86be53369bafc4f3700ce7df2", size = 130569, upload-time = "2025-07-15T16:06:57.275Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/bf/2cb57eac8d6054b555cba27203490489a7d3f5dca8c34382f22f2f0f17ba/orjson-3.11.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1120607ec8fc98acf8c54aac6fb0b7b003ba883401fa2d261833111e2fa071", size = 403844, upload-time = "2025-07-15T16:06:59.107Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/34/36e859ccfc45464df7b35c438c0ecc7751c930b3ebbefb50db7e3a641eb7/orjson-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c4b48d9775b0cf1f0aca734f4c6b272cbfacfac38e6a455e6520662f9434afb7", size = 144613, upload-time = "2025-07-15T16:07:00.48Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/c5/5aeb84cdd0b44dc3972668944a1312f7983c2a45fb6b0e5e32b2f9408540/orjson-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f018ed1986d79434ac712ff19f951cd00b4dfcb767444410fbb834ebec160abf", size = 132419, upload-time = "2025-07-15T16:07:01.927Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/0c/95ee1e61a067ad24c4921609156b3beeca8b102f6f36dca62b08e1a7c7a8/orjson-3.11.0-cp311-cp311-win32.whl", hash = "sha256:08e191f8a55ac2c00be48e98a5d10dca004cbe8abe73392c55951bfda60fc123", size = 134620, upload-time = "2025-07-15T16:07:03.304Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/3e/afd5e284db9387023803553061ea05c785c36fe7845e4fe25912424b343f/orjson-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:b5a4214ea59c8a3b56f8d484b28114af74e9fba0956f9be5c3ce388ae143bf1f", size = 129333, upload-time = "2025-07-15T16:07:04.973Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/a4/d29e9995d73f23f2444b4db299a99477a4f7e6f5bf8923b775ef43a4e660/orjson-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:57e8e7198a679ab21241ab3f355a7990c7447559e35940595e628c107ef23736", size = 126656, upload-time = "2025-07-15T16:07:06.288Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/c9/241e304fb1e58ea70b720f1a9e5349c6bb7735ffac401ef1b94f422edd6d/orjson-3.11.0-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b4089f940c638bb1947d54e46c1cd58f4259072fcc97bc833ea9c78903150ac9", size = 240269, upload-time = "2025-07-15T16:07:08.173Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/7c/289457cdf40be992b43f1d90ae213ebc03a31a8e2850271ecd79e79a3135/orjson-3.11.0-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:8335a0ba1c26359fb5c82d643b4c1abbee2bc62875e0f2b5bde6c8e9e25eb68c", size = 129276, upload-time = "2025-07-15T16:07:10.128Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/de/5c0528d46ded965939b6b7f75b1fe93af42b9906b0039096fc92c9001c12/orjson-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63c1c9772dafc811d16d6a7efa3369a739da15d1720d6e58ebe7562f54d6f4a2", size = 131966, upload-time = "2025-07-15T16:07:11.509Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/74/39822f267b5935fb6fc961ccc443f4968a74d34fc9270b83caa44e37d907/orjson-3.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9457ccbd8b241fb4ba516417a4c5b95ba0059df4ac801309bcb4ec3870f45ad9", size = 127028, upload-time = "2025-07-15T16:07:13.023Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/e3/28f6ed7f03db69bddb3ef48621b2b05b394125188f5909ee0a43fcf4820e/orjson-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0846e13abe79daece94a00b92574f294acad1d362be766c04245b9b4dd0e47e1", size = 129105, upload-time = "2025-07-15T16:07:14.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/50/8867fd2fc92c0ab1c3e14673ec5d9d0191202e4ab8ba6256d7a1d6943ad3/orjson-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5587c85ae02f608a3f377b6af9eb04829606f518257cbffa8f5081c1aacf2e2f", size = 131902, upload-time = "2025-07-15T16:07:16.176Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/65/c189deea10342afee08006331082ff67d11b98c2394989998b3ea060354a/orjson-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7a1964a71c1567b4570c932a0084ac24ad52c8cf6253d1881400936565ed438", size = 134042, upload-time = "2025-07-15T16:07:17.937Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/e4/cf23c3f4231d2a9a043940ab045f799f84a6df1b4fb6c9b4412cdc3ebf8c/orjson-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5a8243e73690cc6e9151c9e1dd046a8f21778d775f7d478fa1eb4daa4897c61", size = 128260, upload-time = "2025-07-15T16:07:19.651Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/b9/2cb94d3a67edb918d19bad4a831af99cd96c3657a23daa239611bcf335d7/orjson-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51646f6d995df37b6e1b628f092f41c0feccf1d47e3452c6e95e2474b547d842", size = 130282, upload-time = "2025-07-15T16:07:21.022Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/96/df963cc973e689d4c56398647917b4ee95f47e5b6d2779338c09c015b23b/orjson-3.11.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:2fb8ca8f0b4e31b8aaec674c7540649b64ef02809410506a44dc68d31bd5647b", size = 403765, upload-time = "2025-07-15T16:07:25.469Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/92/71429ee1badb69f53281602dbb270fa84fc2e51c83193a814d0208bb63b0/orjson-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:64a6a3e94a44856c3f6557e6aa56a6686544fed9816ae0afa8df9077f5759791", size = 144779, upload-time = "2025-07-15T16:07:27.339Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/ab/3678b2e5ff0c622a974cb8664ed7cdda5ed26ae2b9d71ba66ec36f32d6cf/orjson-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d69f95d484938d8fab5963e09131bcf9fbbb81fa4ec132e316eb2fb9adb8ce78", size = 132797, upload-time = "2025-07-15T16:07:28.717Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/8c/74509f715ff189d2aca90ebb0bd5af6658e0f9aa2512abbe6feca4c78208/orjson-3.11.0-cp312-cp312-win32.whl", hash = "sha256:8514f9f9c667ce7d7ef709ab1a73e7fcab78c297270e90b1963df7126d2b0e23", size = 134695, upload-time = "2025-07-15T16:07:30.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/ba/ef25e3e223f452a01eac6a5b38d05c152d037508dcbf87ad2858cbb7d82e/orjson-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:41b38a894520b8cb5344a35ffafdf6ae8042f56d16771b2c5eb107798cee85ee", size = 129446, upload-time = "2025-07-15T16:07:31.412Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/cd/6f4d93867c5d81bb4ab2d4ac870d3d6e9ba34fa580a03b8d04bf1ce1d8ad/orjson-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:5579acd235dd134467340b2f8a670c1c36023b5a69c6a3174c4792af7502bd92", size = 126400, upload-time = "2025-07-15T16:07:34.143Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/63/82d9b6b48624009d230bc6038e54778af8f84dfd54402f9504f477c5cfd5/orjson-3.11.0-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a8ba9698655e16746fdf5266939427da0f9553305152aeb1a1cc14974a19cfb", size = 240125, upload-time = "2025-07-15T16:07:35.976Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/3a/d557ed87c63237d4c97a7bac7ac054c347ab8c4b6da09748d162ca287175/orjson-3.11.0-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:67133847f9a35a5ef5acfa3325d4a2f7fe05c11f1505c4117bb086fc06f2a58f", size = 129189, upload-time = "2025-07-15T16:07:37.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/5e/b2c9e22e2cd10aa7d76a629cee65d661e06a61fbaf4dc226386f5636dd44/orjson-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f797d57814975b78f5f5423acb003db6f9be5186b72d48bd97a1000e89d331d", size = 131953, upload-time = "2025-07-15T16:07:39.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/60/760fcd9b50eb44d1206f2b30c8d310b79714553b9d94a02f9ea3252ebe63/orjson-3.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:28acd19822987c5163b9e03a6e60853a52acfee384af2b394d11cb413b889246", size = 126922, upload-time = "2025-07-15T16:07:41.282Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/7a/8c46daa867ccc92da6de9567608be62052774b924a77c78382e30d50b579/orjson-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8d38d9e1e2cf9729658e35956cf01e13e89148beb4cb9e794c9c10c5cb252f8", size = 128787, upload-time = "2025-07-15T16:07:42.681Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/14/a2f1b123d85f11a19e8749f7d3f9ed6c9b331c61f7b47cfd3e9a1fedb9bc/orjson-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05f094edd2b782650b0761fd78858d9254de1c1286f5af43145b3d08cdacfd51", size = 131895, upload-time = "2025-07-15T16:07:44.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/10/362e8192df7528e8086ea712c5cb01355c8d4e52c59a804417ba01e2eb2d/orjson-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d09176a4a9e04a5394a4a0edd758f645d53d903b306d02f2691b97d5c736a9e", size = 133868, upload-time = "2025-07-15T16:07:46.227Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/4e/ef43582ef3e3dfd2a39bc3106fa543364fde1ba58489841120219da6e22f/orjson-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a585042104e90a61eda2564d11317b6a304eb4e71cd33e839f5af6be56c34d3", size = 128234, upload-time = "2025-07-15T16:07:48.123Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/fa/02dabb2f1d605bee8c4bb1160cfc7467976b1ed359a62cc92e0681b53c45/orjson-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d2218629dbfdeeb5c9e0573d59f809d42f9d49ae6464d2f479e667aee14c3ef4", size = 130232, upload-time = "2025-07-15T16:07:50.197Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/76/951b5619605c8d2ede80cc989f32a66abc954530d86e84030db2250c63a1/orjson-3.11.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:613e54a2b10b51b656305c11235a9c4a5c5491ef5c283f86483d4e9e123ed5e4", size = 403648, upload-time = "2025-07-15T16:07:52.136Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/e2/5fa53bb411455a63b3713db90b588e6ca5ed2db59ad49b3fb8a0e94e0dda/orjson-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9dac7fbf3b8b05965986c5cfae051eb9a30fced7f15f1d13a5adc608436eb486", size = 144572, upload-time = "2025-07-15T16:07:54.004Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/d0/7d6f91e1e0f034258c3a3358f20b0c9490070e8a7ab8880085547274c7f9/orjson-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b64b254414e2be55ac5257124b5602c5f0b4d06b80bd27d1165efe8f36e836", size = 132766, upload-time = "2025-07-15T16:07:55.936Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/f8/4d46481f1b3fb40dc826d62179f96c808eb470cdcc74b6593fb114d74af3/orjson-3.11.0-cp313-cp313-win32.whl", hash = "sha256:359cbe11bc940c64cb3848cf22000d2aef36aff7bfd09ca2c0b9cb309c387132", size = 134638, upload-time = "2025-07-15T16:07:57.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/3f/544938dcfb7337d85ee1e43d7685cf8f3bfd452e0b15a32fe70cb4ca5094/orjson-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:0759b36428067dc777b202dd286fbdd33d7f261c6455c4238ea4e8474358b1e6", size = 129411, upload-time = "2025-07-15T16:07:58.852Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/0c/f75015669d7817d222df1bb207f402277b77d22c4833950c8c8c7cf2d325/orjson-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:51cdca2f36e923126d0734efaf72ddbb5d6da01dbd20eab898bdc50de80d7b5a", size = 126349, upload-time = "2025-07-15T16:08:00.322Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/41/eac31c44ce001b3da8a6b5ebbb8a4fc2c3eaf479e2d068e36b2ea6ab7095/orjson-3.11.0-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d79c180cfb3ae68f13245d0ff551dca03d96258aa560830bf8a223bd68d8272c", size = 241023, upload-time = "2025-07-15T16:08:02.233Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/d6/1edc258f3eff573af7416b2b8536032e6f4ed3759fa5773c5db95a28d2f2/orjson-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:105bca887532dc71ce4b05a5de95dea447a310409d7a8cf0cb1c4a120469e9ad", size = 132245, upload-time = "2025-07-15T16:08:04.734Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/89/49236838cdc8d88b93f1c80f44531103f589307e4e783c855a6a63f28b45/orjson-3.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acf5a63ae9cdb88274126af85913ceae554d8fd71122effa24a53227abbeee16", size = 126981, upload-time = "2025-07-15T16:08:06.114Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/78/8744b86efae7693344edcf255addc2a9f9e4f5552ccf71d9581d03c3e1aa/orjson-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:894635df36c0be32f1c8c8607e853b8865edb58e7618e57892e85d06418723eb", size = 128686, upload-time = "2025-07-15T16:08:07.843Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/8c/4c45feee9fa52488e67be2e887eb966337d4ddb6675129471f0dab98587d/orjson-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02dd4f0a1a2be943a104ce5f3ec092631ee3e9f0b4bb9eeee3400430bd94ddef", size = 131830, upload-time = "2025-07-15T16:08:14.423Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/15/9462308306650de38d042af226e186d2fe28ee8e44c5462e011e767e6e44/orjson-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:720b4bb5e1b971960a62c2fa254c2d2a14e7eb791e350d05df8583025aa59d15", size = 134004, upload-time = "2025-07-15T16:08:16.024Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/1d/bfa55d7681cf704d73e9c6de8138535b2f41e06a49d88bf9bdf27c8d4d7b/orjson-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf058105a8aed144e0d1cfe7ac4174748c3fc7203f225abaeac7f4121abccb0", size = 127893, upload-time = "2025-07-15T16:08:17.558Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/bb/e91aa9e63077d8754d1578787e8917078e5c6743579290bc454bbc609241/orjson-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a2788f741e5a0e885e5eaf1d91d0c9106e03cb9575b0c55ba36fd3d48b0b1e9b", size = 130546, upload-time = "2025-07-15T16:08:19.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/67/4c53a325ac9abf883e922da214707f63efcb8b4d54529984df0e6aff1d0b/orjson-3.11.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:c60c99fe1e15894367b0340b2ff16c7c69f9c3f3a54aa3961a58c102b292ad94", size = 403849, upload-time = "2025-07-15T16:08:21.025Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/64/a779341bd2231e28eb09cf6e6260d9f713a39ae5163b0f1228ab5175bfee/orjson-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:99d17aab984f4d029b8f3c307e6be3c63d9ee5ef55e30d761caf05e883009949", size = 144600, upload-time = "2025-07-15T16:08:22.701Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/c1/fc36a6e3b40df3388ecf57b18a940f6584362652e6ee57464ccc5715b2e3/orjson-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e98f02e23611763c9e5dfcb83bd33219231091589f0d1691e721aea9c52bf329", size = 132416, upload-time = "2025-07-15T16:08:24.258Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/29/eb5ed777d7ea5d0fdee5981751e3a4e9de73f47e32bb20f1ea748b04b1d2/orjson-3.11.0-cp39-cp39-win32.whl", hash = "sha256:923301f33ea866b18f8836cf41d9c6d33e3b5cab8577d20fed34ec29f0e13a0d", size = 134617, upload-time = "2025-07-15T16:08:26.052Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/40/feba627d9349bb1a91500e0047ae526d83bb1918545ff4dfee3e1bd7195e/orjson-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:475491bb78af2a0170f49e90013f1a0f1286527f3617491f8940d7e5da862da7", size = 129320, upload-time = "2025-07-15T16:08:27.484Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/16/2ceb9fb7bc2b11b1e4a3ea27794256e93dee2309ebe297fd131a778cd150/orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402", size = 248927, upload-time = "2025-04-29T23:28:08.643Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/e1/d3c0a2bba5b9906badd121da449295062b289236c39c3a7801f92c4682b0/orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c", size = 136995, upload-time = "2025-04-29T23:28:11.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/51/698dd65e94f153ee5ecb2586c89702c9e9d12f165a63e74eb9ea1299f4e1/orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92", size = 132893, upload-time = "2025-04-29T23:28:12.751Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/e5/155ce5a2c43a85e790fcf8b985400138ce5369f24ee6770378ee6b691036/orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13", size = 137017, upload-time = "2025-04-29T23:28:14.498Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/bb/6141ec3beac3125c0b07375aee01b5124989907d61c72c7636136e4bd03e/orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469", size = 138290, upload-time = "2025-04-29T23:28:16.211Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/36/6961eca0b66b7809d33c4ca58c6bd4c23a1b914fb23aba2fa2883f791434/orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f", size = 142828, upload-time = "2025-04-29T23:28:18.065Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/2f/0c646d5fd689d3be94f4d83fa9435a6c4322c9b8533edbb3cd4bc8c5f69a/orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68", size = 132806, upload-time = "2025-04-29T23:28:19.782Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/af/65907b40c74ef4c3674ef2bcfa311c695eb934710459841b3c2da212215c/orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056", size = 135005, upload-time = "2025-04-29T23:28:21.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/d1/68bd20ac6a32cd1f1b10d23e7cc58ee1e730e80624e3031d77067d7150fc/orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d", size = 413418, upload-time = "2025-04-29T23:28:23.097Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/31/c701ec0bcc3e80e5cb6e319c628ef7b768aaa24b0f3b4c599df2eaacfa24/orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8", size = 153288, upload-time = "2025-04-29T23:28:25.02Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/31/5e1aa99a10893a43cfc58009f9da840990cc8a9ebb75aa452210ba18587e/orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f", size = 137181, upload-time = "2025-04-29T23:28:26.318Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06", size = 142694, upload-time = "2025-04-29T23:28:28.092Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92", size = 134600, upload-time = "2025-04-29T23:28:29.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/c7/c54a948ce9a4278794f669a353551ce7db4ffb656c69a6e1f2264d563e50/orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8", size = 248929, upload-time = "2025-04-29T23:28:30.716Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/60/a9c674ef1dd8ab22b5b10f9300e7e70444d4e3cda4b8258d6c2488c32143/orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d", size = 133364, upload-time = "2025-04-29T23:28:32.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/4e/f7d1bdd983082216e414e6d7ef897b0c2957f99c545826c06f371d52337e/orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7", size = 136995, upload-time = "2025-04-29T23:28:34.024Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/89/46b9181ba0ea251c9243b0c8ce29ff7c9796fa943806a9c8b02592fce8ea/orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a", size = 132894, upload-time = "2025-04-29T23:28:35.318Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/dd/7bce6fcc5b8c21aef59ba3c67f2166f0a1a9b0317dcca4a9d5bd7934ecfd/orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679", size = 137016, upload-time = "2025-04-29T23:28:36.674Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/4a/b8aea1c83af805dcd31c1f03c95aabb3e19a016b2a4645dd822c5686e94d/orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947", size = 138290, upload-time = "2025-04-29T23:28:38.3Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/d6/7eb05c85d987b688707f45dcf83c91abc2251e0dd9fb4f7be96514f838b1/orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4", size = 142829, upload-time = "2025-04-29T23:28:39.657Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/78/ddd3ee7873f2b5f90f016bc04062713d567435c53ecc8783aab3a4d34915/orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334", size = 132805, upload-time = "2025-04-29T23:28:40.969Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/09/c8e047f73d2c5d21ead9c180203e111cddeffc0848d5f0f974e346e21c8e/orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17", size = 135008, upload-time = "2025-04-29T23:28:42.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/4b/dccbf5055ef8fb6eda542ab271955fc1f9bf0b941a058490293f8811122b/orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e", size = 413419, upload-time = "2025-04-29T23:28:43.673Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/f3/1eac0c5e2d6d6790bd2025ebfbefcbd37f0d097103d76f9b3f9302af5a17/orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b", size = 153292, upload-time = "2025-04-29T23:28:45.573Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/b4/ef0abf64c8f1fabf98791819ab502c2c8c1dc48b786646533a93637d8999/orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7", size = 137182, upload-time = "2025-04-29T23:28:47.229Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1", size = 142695, upload-time = "2025-04-29T23:28:48.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a", size = 134603, upload-time = "2025-04-29T23:28:50.442Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5", size = 131400, upload-time = "2025-04-29T23:28:51.838Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/1a/67236da0916c1a192d5f4ccbe10ec495367a726996ceb7614eaa687112f2/orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753", size = 249184, upload-time = "2025-04-29T23:28:53.612Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/bc/c7f1db3b1d094dc0c6c83ed16b161a16c214aaa77f311118a93f647b32dc/orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17", size = 133279, upload-time = "2025-04-29T23:28:55.055Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/84/664657cd14cc11f0d81e80e64766c7ba5c9b7fc1ec304117878cc1b4659c/orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d", size = 136799, upload-time = "2025-04-29T23:28:56.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/bb/f50039c5bb05a7ab024ed43ba25d0319e8722a0ac3babb0807e543349978/orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae", size = 132791, upload-time = "2025-04-29T23:28:58.751Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/8c/ee74709fc072c3ee219784173ddfe46f699598a1723d9d49cbc78d66df65/orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f", size = 137059, upload-time = "2025-04-29T23:29:00.129Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/37/e6d3109ee004296c80426b5a62b47bcadd96a3deab7443e56507823588c5/orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c", size = 138359, upload-time = "2025-04-29T23:29:01.704Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/5d/387dafae0e4691857c62bd02839a3bf3fa648eebd26185adfac58d09f207/orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad", size = 142853, upload-time = "2025-04-29T23:29:03.576Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/6f/875e8e282105350b9a5341c0222a13419758545ae32ad6e0fcf5f64d76aa/orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c", size = 133131, upload-time = "2025-04-29T23:29:05.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/b2/73a1f0b4790dcb1e5a45f058f4f5dcadc8a85d90137b50d6bbc6afd0ae50/orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406", size = 134834, upload-time = "2025-04-29T23:29:07.35Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/f5/7ed133a5525add9c14dbdf17d011dd82206ca6840811d32ac52a35935d19/orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6", size = 413368, upload-time = "2025-04-29T23:29:09.301Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/7c/439654221ed9c3324bbac7bdf94cf06a971206b7b62327f11a52544e4982/orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06", size = 153359, upload-time = "2025-04-29T23:29:10.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/e7/d58074fa0cc9dd29a8fa2a6c8d5deebdfd82c6cfef72b0e4277c4017563a/orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5", size = 137466, upload-time = "2025-04-29T23:29:12.26Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e", size = 142683, upload-time = "2025-04-29T23:29:13.865Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc", size = 134754, upload-time = "2025-04-29T23:29:15.338Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a", size = 131218, upload-time = "2025-04-29T23:29:17.324Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/f0/8aedb6574b68096f3be8f74c0b56d36fd94bcf47e6c7ed47a7bd1474aaa8/orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147", size = 249087, upload-time = "2025-04-29T23:29:19.083Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/f7/7118f965541aeac6844fcb18d6988e111ac0d349c9b80cda53583e758908/orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c", size = 133273, upload-time = "2025-04-29T23:29:20.602Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/d9/839637cc06eaf528dd8127b36004247bf56e064501f68df9ee6fd56a88ee/orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103", size = 136779, upload-time = "2025-04-29T23:29:22.062Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/6d/f226ecfef31a1f0e7d6bf9a31a0bbaf384c7cbe3fce49cc9c2acc51f902a/orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595", size = 132811, upload-time = "2025-04-29T23:29:23.602Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/2d/371513d04143c85b681cf8f3bce743656eb5b640cb1f461dad750ac4b4d4/orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc", size = 137018, upload-time = "2025-04-29T23:29:25.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/cb/a4d37a30507b7a59bdc484e4a3253c8141bf756d4e13fcc1da760a0b00cb/orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc", size = 138368, upload-time = "2025-04-29T23:29:26.609Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/ae/cd10883c48d912d216d541eb3db8b2433415fde67f620afe6f311f5cd2ca/orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049", size = 142840, upload-time = "2025-04-29T23:29:28.153Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/4c/2bda09855c6b5f2c055034c9eda1529967b042ff8d81a05005115c4e6772/orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58", size = 133135, upload-time = "2025-04-29T23:29:29.726Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/4a/35971fd809a8896731930a80dfff0b8ff48eeb5d8b57bb4d0d525160017f/orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034", size = 134810, upload-time = "2025-04-29T23:29:31.269Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/70/0fa9e6310cda98365629182486ff37a1c6578e34c33992df271a476ea1cd/orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1", size = 413491, upload-time = "2025-04-29T23:29:33.315Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/cb/990a0e88498babddb74fb97855ae4fbd22a82960e9b06eab5775cac435da/orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012", size = 153277, upload-time = "2025-04-29T23:29:34.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/44/473248c3305bf782a384ed50dd8bc2d3cde1543d107138fd99b707480ca1/orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f", size = 137367, upload-time = "2025-04-29T23:29:36.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687, upload-time = "2025-04-29T23:29:38.292Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794, upload-time = "2025-04-29T23:29:40.349Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186, upload-time = "2025-04-29T23:29:41.922Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/db/69488acaa2316788b7e171f024912c6fe8193aa2e24e9cfc7bc41c3669ba/orjson-3.10.18-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95fae14225edfd699454e84f61c3dd938df6629a00c6ce15e704f57b58433bb", size = 249301, upload-time = "2025-04-29T23:29:44.719Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/21/d816c44ec5d1482c654e1d23517d935bb2716e1453ff9380e861dc6efdd3/orjson-3.10.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5232d85f177f98e0cefabb48b5e7f60cff6f3f0365f9c60631fecd73849b2a82", size = 136786, upload-time = "2025-04-29T23:29:46.517Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/9f/f68d8a9985b717e39ba7bf95b57ba173fcd86aeca843229ec60d38f1faa7/orjson-3.10.18-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2783e121cafedf0d85c148c248a20470018b4ffd34494a68e125e7d5857655d1", size = 132711, upload-time = "2025-04-29T23:29:48.605Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/63/447f5955439bf7b99bdd67c38a3f689d140d998ac58e3b7d57340520343c/orjson-3.10.18-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e54ee3722caf3db09c91f442441e78f916046aa58d16b93af8a91500b7bbf273", size = 136841, upload-time = "2025-04-29T23:29:50.31Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/9e/4855972f2be74097242e4681ab6766d36638a079e09d66f3d6a5d1188ce7/orjson-3.10.18-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2daf7e5379b61380808c24f6fc182b7719301739e4271c3ec88f2984a2d61f89", size = 138082, upload-time = "2025-04-29T23:29:51.992Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/0f/e68431e53a39698d2355faf1f018c60a3019b4b54b4ea6be9dc6b8208a3d/orjson-3.10.18-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f39b371af3add20b25338f4b29a8d6e79a8c7ed0e9dd49e008228a065d07781", size = 142618, upload-time = "2025-04-29T23:29:53.642Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/da/bdcfff239ddba1b6ef465efe49d7e43cc8c30041522feba9fd4241d47c32/orjson-3.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b819ed34c01d88c6bec290e6842966f8e9ff84b7694632e88341363440d4cc0", size = 132627, upload-time = "2025-04-29T23:29:55.318Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/28/bc634da09bbe972328f615b0961f1e7d91acb3cc68bddbca9e8dd64e8e24/orjson-3.10.18-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2f6c57debaef0b1aa13092822cbd3698a1fb0209a9ea013a969f4efa36bdea57", size = 134832, upload-time = "2025-04-29T23:29:56.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/d2/e8ac0c2d0ec782ed8925b4eb33f040cee1f1fbd1d8b268aeb84b94153e49/orjson-3.10.18-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:755b6d61ffdb1ffa1e768330190132e21343757c9aa2308c67257cc81a1a6f5a", size = 413161, upload-time = "2025-04-29T23:29:59.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/f0/397e98c352a27594566e865999dc6b88d6f37d5bbb87b23c982af24114c4/orjson-3.10.18-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce8d0a875a85b4c8579eab5ac535fb4b2a50937267482be402627ca7e7570ee3", size = 153012, upload-time = "2025-04-29T23:30:01.066Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/bf/2c7334caeb48bdaa4cae0bde17ea417297ee136598653b1da7ae1f98c785/orjson-3.10.18-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57b5d0673cbd26781bebc2bf86f99dd19bd5a9cb55f71cc4f66419f6b50f3d77", size = 136999, upload-time = "2025-04-29T23:30:02.93Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/72/4827b1c0c31621c2aa1e661a899cdd2cfac0565c6cd7131890daa4ef7535/orjson-3.10.18-cp39-cp39-win32.whl", hash = "sha256:951775d8b49d1d16ca8818b1f20c4965cae9157e7b562a2ae34d3967b8f21c8e", size = 142560, upload-time = "2025-04-29T23:30:04.805Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/91/ef8e76868e7eed478887c82f60607a8abf58dadd24e95817229a4b2e2639/orjson-3.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:fdd9d68f83f0bc4406610b1ac68bdcded8c5ee58605cc69e643a06f4d075f429", size = 134455, upload-time = "2025-04-29T23:30:06.588Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -867,11 +858,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
version = "24.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" }
|
||||
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" },
|
||||
{ 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]]
|
||||
@@ -1063,16 +1054,15 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "1.1.0"
|
||||
version = "1.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" },
|
||||
{ name = "pytest" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" }
|
||||
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/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" },
|
||||
{ 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]]
|
||||
@@ -1190,27 +1180,27 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.12.4"
|
||||
version = "0.12.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9b/ce/8d7dbedede481245b489b769d27e2934730791a9a82765cb94566c6e6abd/ruff-0.12.4.tar.gz", hash = "sha256:13efa16df6c6eeb7d0f091abae50f58e9522f3843edb40d56ad52a5a4a4b6873", size = 5131435, upload-time = "2025-07-17T17:27:19.138Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/2a/43955b530c49684d3c38fcda18c43caf91e99204c2a065552528e0552d4f/ruff-0.12.3.tar.gz", hash = "sha256:f1b5a4b6668fd7b7ea3697d8d98857390b40c1320a63a178eee6be0899ea2d77", size = 4459341, upload-time = "2025-07-11T13:21:16.086Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/9f/517bc5f61bad205b7f36684ffa5415c013862dee02f55f38a217bdbe7aa4/ruff-0.12.4-py3-none-linux_armv6l.whl", hash = "sha256:cb0d261dac457ab939aeb247e804125a5d521b21adf27e721895b0d3f83a0d0a", size = 10188824, upload-time = "2025-07-17T17:26:31.412Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/83/691baae5a11fbbde91df01c565c650fd17b0eabed259e8b7563de17c6529/ruff-0.12.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:55c0f4ca9769408d9b9bac530c30d3e66490bd2beb2d3dae3e4128a1f05c7442", size = 10884521, upload-time = "2025-07-17T17:26:35.084Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/8d/756d780ff4076e6dd035d058fa220345f8c458391f7edfb1c10731eedc75/ruff-0.12.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a8224cc3722c9ad9044da7f89c4c1ec452aef2cfe3904365025dd2f51daeae0e", size = 10277653, upload-time = "2025-07-17T17:26:37.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/97/8eeee0f48ece153206dce730fc9e0e0ca54fd7f261bb3d99c0a4343a1892/ruff-0.12.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9949d01d64fa3672449a51ddb5d7548b33e130240ad418884ee6efa7a229586", size = 10485993, upload-time = "2025-07-17T17:26:40.68Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/b8/22a43d23a1f68df9b88f952616c8508ea6ce4ed4f15353b8168c48b2d7e7/ruff-0.12.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:be0593c69df9ad1465e8a2d10e3defd111fdb62dcd5be23ae2c06da77e8fcffb", size = 10022824, upload-time = "2025-07-17T17:26:43.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/70/37c234c220366993e8cffcbd6cadbf332bfc848cbd6f45b02bade17e0149/ruff-0.12.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7dea966bcb55d4ecc4cc3270bccb6f87a337326c9dcd3c07d5b97000dbff41c", size = 11524414, upload-time = "2025-07-17T17:26:46.219Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/77/c30f9964f481b5e0e29dd6a1fae1f769ac3fd468eb76fdd5661936edd262/ruff-0.12.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:afcfa3ab5ab5dd0e1c39bf286d829e042a15e966b3726eea79528e2e24d8371a", size = 12419216, upload-time = "2025-07-17T17:26:48.883Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/79/af7fe0a4202dce4ef62c5e33fecbed07f0178f5b4dd9c0d2fcff5ab4a47c/ruff-0.12.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c057ce464b1413c926cdb203a0f858cd52f3e73dcb3270a3318d1630f6395bb3", size = 11976756, upload-time = "2025-07-17T17:26:51.754Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/d1/33fb1fc00e20a939c305dbe2f80df7c28ba9193f7a85470b982815a2dc6a/ruff-0.12.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64b90d1122dc2713330350626b10d60818930819623abbb56535c6466cce045", size = 11020019, upload-time = "2025-07-17T17:26:54.265Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/f4/e3cd7f7bda646526f09693e2e02bd83d85fff8a8222c52cf9681c0d30843/ruff-0.12.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2abc48f3d9667fdc74022380b5c745873499ff827393a636f7a59da1515e7c57", size = 11277890, upload-time = "2025-07-17T17:26:56.914Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/d0/69a85fb8b94501ff1a4f95b7591505e8983f38823da6941eb5b6badb1e3a/ruff-0.12.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2b2449dc0c138d877d629bea151bee8c0ae3b8e9c43f5fcaafcd0c0d0726b184", size = 10348539, upload-time = "2025-07-17T17:26:59.381Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/a0/91372d1cb1678f7d42d4893b88c252b01ff1dffcad09ae0c51aa2542275f/ruff-0.12.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:56e45bb11f625db55f9b70477062e6a1a04d53628eda7784dce6e0f55fd549eb", size = 10009579, upload-time = "2025-07-17T17:27:02.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/1b/c4a833e3114d2cc0f677e58f1df6c3b20f62328dbfa710b87a1636a5e8eb/ruff-0.12.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:478fccdb82ca148a98a9ff43658944f7ab5ec41c3c49d77cd99d44da019371a1", size = 10942982, upload-time = "2025-07-17T17:27:05.343Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/ce/ce85e445cf0a5dd8842f2f0c6f0018eedb164a92bdf3eda51984ffd4d989/ruff-0.12.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0fc426bec2e4e5f4c4f182b9d2ce6a75c85ba9bcdbe5c6f2a74fcb8df437df4b", size = 11343331, upload-time = "2025-07-17T17:27:08.652Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/cf/441b7fc58368455233cfb5b77206c849b6dfb48b23de532adcc2e50ccc06/ruff-0.12.4-py3-none-win32.whl", hash = "sha256:4de27977827893cdfb1211d42d84bc180fceb7b72471104671c59be37041cf93", size = 10267904, upload-time = "2025-07-17T17:27:11.814Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/7e/20af4a0df5e1299e7368d5ea4350412226afb03d95507faae94c80f00afd/ruff-0.12.4-py3-none-win_amd64.whl", hash = "sha256:fe0b9e9eb23736b453143d72d2ceca5db323963330d5b7859d60d101147d461a", size = 11209038, upload-time = "2025-07-17T17:27:14.417Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/02/8857d0dfb8f44ef299a5dfd898f673edefb71e3b533b3b9d2db4c832dd13/ruff-0.12.4-py3-none-win_arm64.whl", hash = "sha256:0618ec4442a83ab545e5b71202a5c0ed7791e8471435b94e655b570a5031a98e", size = 10469336, upload-time = "2025-07-17T17:27:16.913Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/fd/b44c5115539de0d598d75232a1cc7201430b6891808df111b8b0506aae43/ruff-0.12.3-py3-none-linux_armv6l.whl", hash = "sha256:47552138f7206454eaf0c4fe827e546e9ddac62c2a3d2585ca54d29a890137a2", size = 10430499, upload-time = "2025-07-11T13:20:26.321Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/c5/9eba4f337970d7f639a37077be067e4ec80a2ad359e4cc6c5b56805cbc66/ruff-0.12.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0a9153b000c6fe169bb307f5bd1b691221c4286c133407b8827c406a55282041", size = 11213413, upload-time = "2025-07-11T13:20:30.017Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/2c/fac3016236cf1fe0bdc8e5de4f24c76ce53c6dd9b5f350d902549b7719b2/ruff-0.12.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fa6b24600cf3b750e48ddb6057e901dd5b9aa426e316addb2a1af185a7509882", size = 10586941, upload-time = "2025-07-11T13:20:33.046Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/0f/41fec224e9dfa49a139f0b402ad6f5d53696ba1800e0f77b279d55210ca9/ruff-0.12.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2506961bf6ead54887ba3562604d69cb430f59b42133d36976421bc8bd45901", size = 10783001, upload-time = "2025-07-11T13:20:35.534Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/ca/dd64a9ce56d9ed6cad109606ac014860b1c217c883e93bf61536400ba107/ruff-0.12.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c4faaff1f90cea9d3033cbbcdf1acf5d7fb11d8180758feb31337391691f3df0", size = 10269641, upload-time = "2025-07-11T13:20:38.459Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/5c/2be545034c6bd5ce5bb740ced3e7014d7916f4c445974be11d2a406d5088/ruff-0.12.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40dced4a79d7c264389de1c59467d5d5cefd79e7e06d1dfa2c75497b5269a5a6", size = 11875059, upload-time = "2025-07-11T13:20:41.517Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/d4/a74ef1e801ceb5855e9527dae105eaff136afcb9cc4d2056d44feb0e4792/ruff-0.12.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0262d50ba2767ed0fe212aa7e62112a1dcbfd46b858c5bf7bbd11f326998bafc", size = 12658890, upload-time = "2025-07-11T13:20:44.442Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/c8/1057916416de02e6d7c9bcd550868a49b72df94e3cca0aeb77457dcd9644/ruff-0.12.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12371aec33e1a3758597c5c631bae9a5286f3c963bdfb4d17acdd2d395406687", size = 12232008, upload-time = "2025-07-11T13:20:47.374Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/59/4f7c130cc25220392051fadfe15f63ed70001487eca21d1796db46cbcc04/ruff-0.12.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:560f13b6baa49785665276c963edc363f8ad4b4fc910a883e2625bdb14a83a9e", size = 11499096, upload-time = "2025-07-11T13:20:50.348Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/01/a0ad24a5d2ed6be03a312e30d32d4e3904bfdbc1cdbe63c47be9d0e82c79/ruff-0.12.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023040a3499f6f974ae9091bcdd0385dd9e9eb4942f231c23c57708147b06311", size = 11688307, upload-time = "2025-07-11T13:20:52.945Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/72/08f9e826085b1f57c9a0226e48acb27643ff19b61516a34c6cab9d6ff3fa/ruff-0.12.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:883d844967bffff5ab28bba1a4d246c1a1b2933f48cb9840f3fdc5111c603b07", size = 10661020, upload-time = "2025-07-11T13:20:55.799Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/a0/68da1250d12893466c78e54b4a0ff381370a33d848804bb51279367fc688/ruff-0.12.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2120d3aa855ff385e0e562fdee14d564c9675edbe41625c87eeab744a7830d12", size = 10246300, upload-time = "2025-07-11T13:20:58.222Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/22/5f0093d556403e04b6fd0984fc0fb32fbb6f6ce116828fd54306a946f444/ruff-0.12.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6b16647cbb470eaf4750d27dddc6ebf7758b918887b56d39e9c22cce2049082b", size = 11263119, upload-time = "2025-07-11T13:21:01.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/c9/f4c0b69bdaffb9968ba40dd5fa7df354ae0c73d01f988601d8fac0c639b1/ruff-0.12.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e1417051edb436230023575b149e8ff843a324557fe0a265863b7602df86722f", size = 11746990, upload-time = "2025-07-11T13:21:04.524Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/84/7cc7bd73924ee6be4724be0db5414a4a2ed82d06b30827342315a1be9e9c/ruff-0.12.3-py3-none-win32.whl", hash = "sha256:dfd45e6e926deb6409d0616078a666ebce93e55e07f0fb0228d4b2608b2c248d", size = 10589263, upload-time = "2025-07-11T13:21:07.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/87/c070f5f027bd81f3efee7d14cb4d84067ecf67a3a8efb43aadfc72aa79a6/ruff-0.12.3-py3-none-win_amd64.whl", hash = "sha256:a946cf1e7ba3209bdef039eb97647f1c77f6f540e5845ec9c114d3af8df873e7", size = 11695072, upload-time = "2025-07-11T13:21:11.004Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/30/f3eaf6563c637b6e66238ed6535f6775480db973c836336e4122161986fc/ruff-0.12.3-py3-none-win_arm64.whl", hash = "sha256:5f9c7c9c8f84c2d7f27e93674d27136fbf489720251544c4da7fb3d742e011b1", size = 10805855, upload-time = "2025-07-11T13:21:13.547Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -73,7 +73,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
||||
|
||||
- [Guides](https://langchain-ai.github.io/langgraph/how-tos/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.).
|
||||
- [Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components.
|
||||
- [Examples](https://langchain-ai.github.io/langgraph/examples/): Guided examples on getting started with LangGraph.
|
||||
- [Examples](https://langchain-ai.github.io/langgraph/tutorials/overview/): Guided examples on getting started with LangGraph.
|
||||
- [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback.
|
||||
- [LangChain Academy](https://academy.langchain.com/courses/intro-to-langgraph): Learn the basics of LangGraph in our free, structured course.
|
||||
- [Templates](https://langchain-ai.github.io/langgraph/concepts/template_applications/): Pre-built reference apps for common agentic workflows (e.g. ReAct agent, memory, retrieval etc.) that can be cloned and adapted.
|
||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||
LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
|
||||
|
||||
@@ -180,7 +180,6 @@ def task(
|
||||
warnings.warn(
|
||||
"`retry` is deprecated and will be removed. Please use `retry_policy` instead.",
|
||||
category=LangGraphDeprecatedSinceV05,
|
||||
stacklevel=2,
|
||||
)
|
||||
if retry_policy is None:
|
||||
retry_policy = retry # type: ignore[assignment]
|
||||
@@ -385,7 +384,6 @@ class entrypoint:
|
||||
warnings.warn(
|
||||
"`retry` is deprecated and will be removed. Please use `retry_policy` instead.",
|
||||
category=LangGraphDeprecatedSinceV05,
|
||||
stacklevel=2,
|
||||
)
|
||||
if retry_policy is None:
|
||||
retry_policy = retry # type: ignore[assignment]
|
||||
|
||||
@@ -1236,18 +1236,17 @@ def _control_branch(value: Any) -> Sequence[tuple[str, Any]]:
|
||||
for command in commands:
|
||||
if command.graph == Command.PARENT:
|
||||
raise ParentCommand(command)
|
||||
|
||||
goto_targets = (
|
||||
[command.goto] if isinstance(command.goto, (Send, str)) else command.goto
|
||||
)
|
||||
|
||||
for go in goto_targets:
|
||||
if isinstance(go, Send):
|
||||
rtn.append((TASKS, go))
|
||||
elif isinstance(go, str) and go != END:
|
||||
# END is a special case, it's not actually a node in a practical sense
|
||||
# but rather a special terminal node that we don't need to branch to
|
||||
rtn.append((CHANNEL_BRANCH_TO.format(go), None))
|
||||
if isinstance(command.goto, Send):
|
||||
rtn.append((TASKS, command.goto))
|
||||
elif isinstance(command.goto, str):
|
||||
rtn.append((CHANNEL_BRANCH_TO.format(command.goto), None))
|
||||
else:
|
||||
rtn.extend(
|
||||
(TASKS, go)
|
||||
if isinstance(go, Send)
|
||||
else (CHANNEL_BRANCH_TO.format(go), None)
|
||||
for go in command.goto
|
||||
)
|
||||
return rtn
|
||||
|
||||
|
||||
|
||||
@@ -106,7 +106,3 @@ packages = ["langgraph"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "--full-trace --strict-markers --strict-config --durations=5 --snapshot-warn-unused"
|
||||
|
||||
[tool.codespell]
|
||||
# Ignore words specific to the LangGraph library code
|
||||
ignore-words-list = "infor,thead,stdio,nd,jupyter,lets,lite,uis,deque,langgraph,langchain,pydantic,typing,async,await,coroutine,iterable,iterables,serializable,deserializable,checkpointer,checkpointing,stateful,statefulness,prebuilt,prebuilt,supervisor,supervisory,swarm,swarming,multiactor,multiactors,subgraph,subgraphs,workflow,workflows,streaming,streamable,streamed,streamer,streamers,streaming,streamable,streamed,streamer,streamers"
|
||||
|
||||
@@ -6955,30 +6955,3 @@ def test_weather_subgraph(
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def test_subgraph_to_end_does_not_warn() -> None:
|
||||
"""Regression test for https://github.com/langchain-ai/langgraph/issues/5572."""
|
||||
|
||||
class State(TypedDict):
|
||||
x: str
|
||||
|
||||
def update_x(state: State):
|
||||
return Command(goto=END, update={"x": state["x"] + "!"})
|
||||
|
||||
# Subgraph
|
||||
subgraph_builder = StateGraph(State)
|
||||
subgraph_builder.add_node("update_x", update_x)
|
||||
subgraph_builder.add_edge(START, "update_x")
|
||||
subgraph_builder.add_edge("update_x", END)
|
||||
subgraph = subgraph_builder.compile()
|
||||
|
||||
# Parent graph
|
||||
builder = StateGraph(State)
|
||||
builder.add_node("subgraph_node", subgraph)
|
||||
builder.add_edge(START, "subgraph_node")
|
||||
builder.add_edge("subgraph_node", END)
|
||||
graph = builder.compile()
|
||||
|
||||
response = graph.invoke({"x": "hello"})
|
||||
print(response)
|
||||
|
||||
Generated
+3
-3
@@ -1301,7 +1301,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
source = { editable = "../checkpoint" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
@@ -1331,7 +1331,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint-postgres"
|
||||
version = "2.0.23"
|
||||
version = "2.0.22"
|
||||
source = { editable = "../checkpoint-postgres" }
|
||||
dependencies = [
|
||||
{ name = "langgraph-checkpoint" },
|
||||
@@ -1463,7 +1463,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.1.74"
|
||||
version = "0.1.72"
|
||||
source = { editable = "../sdk-py" }
|
||||
dependencies = [
|
||||
{ name = "httpx" },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: all format lint test test-fast test_watch integration_tests spell_check spell_fix benchmark profile
|
||||
.PHONY: all format lint test test_watch integration_tests spell_check spell_fix benchmark profile
|
||||
|
||||
# Default target executed when no arguments are given to make.
|
||||
all: help
|
||||
@@ -15,17 +15,14 @@ stop-postgres:
|
||||
|
||||
TEST ?= .
|
||||
|
||||
test-fast:
|
||||
LANGGRAPH_TEST_FAST=1 uv run pytest $(TEST)
|
||||
|
||||
test:
|
||||
make start-postgres && LANGGRAPH_TEST_FAST=0 uv run pytest $(TEST); \
|
||||
make start-postgres && uv run pytest $(TEST); \
|
||||
EXIT_CODE=$$?; \
|
||||
make stop-postgres; \
|
||||
exit $$EXIT_CODE
|
||||
|
||||
test_watch:
|
||||
make start-postgres && LANGGRAPH_TEST_FAST=0 uv run ptw $(TEST); \
|
||||
make start-postgres && uv run ptw $(TEST); \
|
||||
EXIT_CODE=$$?; \
|
||||
make stop-postgres; \
|
||||
exit $$EXIT_CODE
|
||||
@@ -52,7 +49,7 @@ lint lint_diff lint_package lint_tests:
|
||||
|
||||
format format_diff:
|
||||
uv run ruff format $(PYTHON_FILES)
|
||||
uv run ruff check --fix $(PYTHON_FILES)
|
||||
uv run ruff check --select I --fix $(PYTHON_FILES)
|
||||
|
||||
spell_check:
|
||||
uv run codespell --toml pyproject.toml
|
||||
@@ -77,6 +74,5 @@ help:
|
||||
@echo '-- TESTS --'
|
||||
@echo 'coverage - run unit tests and generate coverage report'
|
||||
@echo 'test - run unit tests'
|
||||
@echo 'test-fast - run unit tests with in-memory checkpointer only'
|
||||
@echo 'test TEST_FILE=<test_file> - run all tests in file'
|
||||
@echo 'test_watch - run unit tests in watch mode'
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
from typing import Any, Literal, TypedDict
|
||||
|
||||
from langchain_core.messages import ToolCall
|
||||
|
||||
|
||||
class ToolCallWithContext(TypedDict):
|
||||
"""ToolCall with additional context for graph state.
|
||||
|
||||
This is an internal data-structure meant to help the ToolNode accept
|
||||
tools calls with additional context (e.g. state) when dispatched using the
|
||||
`Send` API.
|
||||
|
||||
The Send API is used in create_react_agent to be able to distribute the tool
|
||||
calls in parallel and support human-in-the-loop workflows where graph execution
|
||||
may be paused for an indefinite time.
|
||||
"""
|
||||
|
||||
tool_call: ToolCall
|
||||
__type: Literal["tool_call_with_context"]
|
||||
"""Type to parameterize the payload.
|
||||
|
||||
Using "__" as a prefix to be defensive against potential name collisions with
|
||||
regular user state.
|
||||
"""
|
||||
state: Any
|
||||
"""The state is provided as additional context."""
|
||||
@@ -39,7 +39,6 @@ from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.message import add_messages
|
||||
from langgraph.graph.state import CompiledStateGraph
|
||||
from langgraph.managed import IsLastStep, RemainingSteps
|
||||
from langgraph.prebuilt._internal import ToolCallWithContext
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import Checkpointer, Send
|
||||
@@ -651,17 +650,11 @@ def create_react_agent(
|
||||
elif version == "v2":
|
||||
if post_model_hook is not None:
|
||||
return "post_model_hook"
|
||||
return [
|
||||
Send(
|
||||
"tools",
|
||||
ToolCallWithContext(
|
||||
__type="tool_call_with_context",
|
||||
tool_call=tool_call,
|
||||
state=state,
|
||||
),
|
||||
)
|
||||
for tool_call in last_message.tool_calls
|
||||
tool_calls = [
|
||||
tool_node.inject_tool_args(call, state, store) # type: ignore[arg-type]
|
||||
for call in last_message.tool_calls
|
||||
]
|
||||
return [Send("tools", [tool_call]) for tool_call in tool_calls]
|
||||
|
||||
# Define a new graph
|
||||
workflow = StateGraph(state_schema or AgentState, config_schema=config_schema)
|
||||
@@ -740,17 +733,11 @@ def create_react_agent(
|
||||
]
|
||||
|
||||
if pending_tool_calls:
|
||||
return [
|
||||
Send(
|
||||
"tools",
|
||||
ToolCallWithContext(
|
||||
__type="tool_call_with_context",
|
||||
tool_call=tool_call,
|
||||
state=state,
|
||||
),
|
||||
)
|
||||
for tool_call in pending_tool_calls
|
||||
pending_tool_calls = [
|
||||
tool_node.inject_tool_args(call, state, store) # type: ignore[arg-type]
|
||||
for call in pending_tool_calls
|
||||
]
|
||||
return [Send("tools", [tool_call]) for tool_call in pending_tool_calls]
|
||||
elif isinstance(messages[-1], ToolMessage):
|
||||
return entrypoint
|
||||
elif response_format is not None:
|
||||
|
||||
@@ -1,36 +1,3 @@
|
||||
"""Tool execution node for LangGraph workflows.
|
||||
|
||||
This module provides prebuilt functionality for executing tools in LangGraph.
|
||||
|
||||
Tools are functions that models can call to interact with external systems,
|
||||
APIs, databases, or perform computations.
|
||||
|
||||
The module implements several key design patterns:
|
||||
- Parallel execution of multiple tool calls for efficiency
|
||||
- Robust error handling with customizable error messages
|
||||
- State injection for tools that need access to graph state
|
||||
- Store injection for tools that need persistent storage
|
||||
- Command-based state updates for advanced control flow
|
||||
|
||||
Key Components:
|
||||
ToolNode: Main class for executing tools in LangGraph workflows
|
||||
InjectedState: Annotation for injecting graph state into tools
|
||||
InjectedStore: Annotation for injecting persistent store into tools
|
||||
tools_condition: Utility function for conditional routing based on tool calls
|
||||
|
||||
Typical Usage:
|
||||
```python
|
||||
from langchain_core.tools import tool
|
||||
from langgraph.prebuilt import ToolNode
|
||||
|
||||
@tool
|
||||
def my_tool(x: int) -> str:
|
||||
return f"Result: {x}"
|
||||
|
||||
tool_node = ToolNode([my_tool])
|
||||
```
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import inspect
|
||||
import json
|
||||
@@ -71,7 +38,6 @@ from pydantic import BaseModel
|
||||
from typing_extensions import Annotated, get_args, get_origin
|
||||
|
||||
from langgraph.errors import GraphBubbleUp
|
||||
from langgraph.prebuilt._internal import ToolCallWithContext
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import Command, Send
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
@@ -83,24 +49,6 @@ TOOL_CALL_ERROR_TEMPLATE = "Error: {error}\n Please fix your mistakes."
|
||||
|
||||
|
||||
def msg_content_output(output: Any) -> Union[str, list[dict]]:
|
||||
"""Convert tool output to valid message content format.
|
||||
|
||||
LangChain ToolMessages accept either string content or a list of content blocks.
|
||||
This function ensures tool outputs are properly formatted for message consumption
|
||||
by attempting to preserve structured data when possible, falling back to JSON
|
||||
serialization or string conversion.
|
||||
|
||||
Args:
|
||||
output: The raw output from a tool execution. Can be any type.
|
||||
|
||||
Returns:
|
||||
Either a string representation of the output or a list of content blocks
|
||||
if the output is already in the correct format for structured content.
|
||||
|
||||
Note:
|
||||
This function prioritizes backward compatibility by defaulting to JSON
|
||||
serialization rather than supporting all possible message content formats.
|
||||
"""
|
||||
if isinstance(output, str):
|
||||
return output
|
||||
elif isinstance(output, list) and all(
|
||||
@@ -110,10 +58,9 @@ def msg_content_output(output: Any) -> Union[str, list[dict]]:
|
||||
]
|
||||
):
|
||||
return output
|
||||
# Technically a list of strings is also valid message content, but it's
|
||||
# not currently well tested that all chat models support this.
|
||||
# And for backwards compatibility we want to make sure we don't break
|
||||
# any existing ToolNode usage.
|
||||
# Technically a list of strings is also valid message content but it's not currently
|
||||
# well tested that all chat models support this. And for backwards compatibility
|
||||
# we want to make sure we don't break any existing ToolNode usage.
|
||||
else:
|
||||
try:
|
||||
return json.dumps(output, ensure_ascii=False)
|
||||
@@ -131,30 +78,6 @@ def _handle_tool_error(
|
||||
tuple[type[Exception], ...],
|
||||
],
|
||||
) -> str:
|
||||
"""Generate error message content based on exception handling configuration.
|
||||
|
||||
This function centralizes error message generation logic, supporting different
|
||||
error handling strategies configured via the ToolNode's handle_tool_errors
|
||||
parameter.
|
||||
|
||||
Args:
|
||||
e: The exception that occurred during tool execution.
|
||||
flag: Configuration for how to handle the error. Can be:
|
||||
- bool: If True, use default error template
|
||||
- str: Use this string as the error message
|
||||
- Callable: Call this function with the exception to get error message
|
||||
- tuple: Not used in this context (handled by caller)
|
||||
|
||||
Returns:
|
||||
A string containing the error message to include in the ToolMessage.
|
||||
|
||||
Raises:
|
||||
ValueError: If flag is not one of the supported types.
|
||||
|
||||
Note:
|
||||
The tuple case is handled by the caller through exception type checking,
|
||||
not by this function directly.
|
||||
"""
|
||||
if isinstance(flag, (bool, tuple)):
|
||||
content = TOOL_CALL_ERROR_TEMPLATE.format(error=repr(e))
|
||||
elif isinstance(flag, str):
|
||||
@@ -170,29 +93,6 @@ def _handle_tool_error(
|
||||
|
||||
|
||||
def _infer_handled_types(handler: Callable[..., str]) -> tuple[type[Exception], ...]:
|
||||
"""Infer exception types handled by a custom error handler function.
|
||||
|
||||
This function analyzes the type annotations of a custom error handler to determine
|
||||
which exception types it's designed to handle. This enables type-safe error handling
|
||||
where only specific exceptions are caught and processed by the handler.
|
||||
|
||||
Args:
|
||||
handler: A callable that takes an exception and returns an error message string.
|
||||
The first parameter (after self/cls if present) should be type-annotated
|
||||
with the exception type(s) to handle.
|
||||
|
||||
Returns:
|
||||
A tuple of exception types that the handler can process. Returns (Exception,)
|
||||
if no specific type information is available for backward compatibility.
|
||||
|
||||
Raises:
|
||||
ValueError: If the handler's annotation contains non-Exception types or
|
||||
if Union types contain non-Exception types.
|
||||
|
||||
Note:
|
||||
This function supports both single exception types and Union types for
|
||||
handlers that need to handle multiple exception types differently.
|
||||
"""
|
||||
sig = inspect.signature(handler)
|
||||
params = list(sig.parameters.values())
|
||||
if params:
|
||||
@@ -211,9 +111,8 @@ def _infer_handled_types(handler: Callable[..., str]) -> tuple[type[Exception],
|
||||
return tuple(args)
|
||||
else:
|
||||
raise ValueError(
|
||||
"All types in the error handler error annotation must be "
|
||||
"Exception types. For example, "
|
||||
"`def custom_handler(e: Union[ValueError, TypeError])`. "
|
||||
"All types in the error handler error annotation must be Exception types. "
|
||||
"For example, `def custom_handler(e: Union[ValueError, TypeError])`. "
|
||||
f"Got '{first_param.annotation}' instead."
|
||||
)
|
||||
|
||||
@@ -222,16 +121,13 @@ def _infer_handled_types(handler: Callable[..., str]) -> tuple[type[Exception],
|
||||
return (exception_type,)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Arbitrary types are not supported in the error handler "
|
||||
f"signature. Please annotate the error with either a "
|
||||
f"specific Exception type or a union of Exception types. "
|
||||
"For example, `def custom_handler(e: ValueError)` or "
|
||||
"`def custom_handler(e: Union[ValueError, TypeError])`. "
|
||||
f"Arbitrary types are not supported in the error handler signature. "
|
||||
"Please annotate the error with either a specific Exception type or a union of Exception types. "
|
||||
"For example, `def custom_handler(e: ValueError)` or `def custom_handler(e: Union[ValueError, TypeError])`. "
|
||||
f"Got '{exception_type}' instead."
|
||||
)
|
||||
|
||||
# If no type information is available, return (Exception,)
|
||||
# for backwards compatibility.
|
||||
# If no type information is available, return (Exception,) for backwards compatibility.
|
||||
return (Exception,)
|
||||
|
||||
|
||||
@@ -245,72 +141,60 @@ class ToolNode(RunnableCallable):
|
||||
Tool calls can also be passed directly as a list of `ToolCall` dicts.
|
||||
|
||||
Args:
|
||||
tools: A sequence of tools that can be invoked by this node. Tools can be
|
||||
BaseTool instances or plain functions that will be converted to tools.
|
||||
name: The name identifier for this node in the graph. Used for debugging
|
||||
and visualization. Defaults to "tools".
|
||||
tags: Optional metadata tags to associate with the node for filtering
|
||||
and organization. Defaults to None.
|
||||
handle_tool_errors: Configuration for error handling during tool execution.
|
||||
Defaults to True. Supports multiple strategies:
|
||||
tools: A sequence of tools that can be invoked by the ToolNode.
|
||||
name: The name of the ToolNode in the graph. Defaults to "tools".
|
||||
tags: Optional tags to associate with the node. Defaults to None.
|
||||
handle_tool_errors: How to handle tool errors raised by tools inside the node. Defaults to True.
|
||||
Must be one of the following:
|
||||
|
||||
- True: Catch all errors and return a ToolMessage with the default
|
||||
error template containing the exception details.
|
||||
- str: Catch all errors and return a ToolMessage with this custom
|
||||
error message string.
|
||||
- tuple[type[Exception], ...]: Only catch exceptions of the specified
|
||||
types and return default error messages for them.
|
||||
- Callable[..., str]: Catch exceptions matching the callable's signature
|
||||
and return the string result of calling it with the exception.
|
||||
- False: Disable error handling entirely, allowing exceptions to propagate.
|
||||
- True: all errors will be caught and
|
||||
a ToolMessage with a default error message (TOOL_CALL_ERROR_TEMPLATE) will be returned.
|
||||
- str: all errors will be caught and
|
||||
a ToolMessage with the string value of 'handle_tool_errors' will be returned.
|
||||
- tuple[type[Exception], ...]: exceptions in the tuple will be caught and
|
||||
a ToolMessage with a default error message (TOOL_CALL_ERROR_TEMPLATE) will be returned.
|
||||
- Callable[..., str]: exceptions from the signature of the callable will be caught and
|
||||
a ToolMessage with the string value of the result of the 'handle_tool_errors' callable will be returned.
|
||||
- False: none of the errors raised by the tools will be caught
|
||||
messages_key: The state key in the input that contains the list of messages.
|
||||
The same key will be used for the output from the ToolNode.
|
||||
Defaults to "messages".
|
||||
|
||||
messages_key: The key in the state dictionary that contains the message list.
|
||||
This same key will be used for the output ToolMessages. Defaults to "messages".
|
||||
The `ToolNode` is roughly analogous to:
|
||||
|
||||
Example:
|
||||
Basic usage with simple tools:
|
||||
```python
|
||||
tools_by_name = {tool.name: tool for tool in tools}
|
||||
def tool_node(state: dict):
|
||||
result = []
|
||||
for tool_call in state["messages"][-1].tool_calls:
|
||||
tool = tools_by_name[tool_call["name"]]
|
||||
observation = tool.invoke(tool_call["args"])
|
||||
result.append(ToolMessage(content=observation, tool_call_id=tool_call["id"]))
|
||||
return {"messages": result}
|
||||
```
|
||||
|
||||
```python
|
||||
from langgraph.prebuilt import ToolNode
|
||||
from langchain_core.tools import tool
|
||||
Tool calls can also be passed directly to a ToolNode. This can be useful when using
|
||||
the Send API, e.g., in a conditional edge:
|
||||
|
||||
@tool
|
||||
def calculator(a: int, b: int) -> int:
|
||||
\"\"\"Add two numbers.\"\"\"
|
||||
return a + b
|
||||
```python
|
||||
def example_conditional_edge(state: dict) -> List[Send]:
|
||||
tool_calls = state["messages"][-1].tool_calls
|
||||
# If tools rely on state or store variables (whose values are not generated
|
||||
# directly by a model), you can inject them into the tool calls.
|
||||
tool_calls = [
|
||||
tool_node.inject_tool_args(call, state, store)
|
||||
for call in last_message.tool_calls
|
||||
]
|
||||
return [Send("tools", [tool_call]) for tool_call in tool_calls]
|
||||
```
|
||||
|
||||
tool_node = ToolNode([calculator])
|
||||
```
|
||||
|
||||
Custom error handling:
|
||||
|
||||
```python
|
||||
def handle_math_errors(e: ZeroDivisionError) -> str:
|
||||
return "Cannot divide by zero!"
|
||||
|
||||
tool_node = ToolNode([calculator], handle_tool_errors=handle_math_errors)
|
||||
```
|
||||
|
||||
Direct tool call execution:
|
||||
|
||||
```python
|
||||
tool_calls = [{"name": "calculator", "args": {"a": 5, "b": 3}, "id": "1", "type": "tool_call"}]
|
||||
result = tool_node.invoke(tool_calls)
|
||||
```
|
||||
|
||||
Note:
|
||||
The ToolNode expects input in one of three formats:
|
||||
1. A dictionary with a messages key containing a list of messages
|
||||
2. A list of messages directly
|
||||
3. A list of tool call dictionaries
|
||||
|
||||
When using message formats, the last message must be an AIMessage with
|
||||
tool_calls populated. The node automatically extracts and processes these
|
||||
tool calls concurrently.
|
||||
|
||||
For advanced use cases involving state injection or store access, tools
|
||||
can be annotated with InjectedState or InjectedStore to receive graph
|
||||
context automatically.
|
||||
Important:
|
||||
- The input state can be one of the following:
|
||||
- A dict with a messages key containing a list of messages.
|
||||
- A list of messages.
|
||||
- A list of tool calls.
|
||||
- If operating on a message list, the last message must be an `AIMessage` with
|
||||
`tool_calls` populated.
|
||||
"""
|
||||
|
||||
name: str = "ToolNode"
|
||||
@@ -326,15 +210,6 @@ class ToolNode(RunnableCallable):
|
||||
] = True,
|
||||
messages_key: str = "messages",
|
||||
) -> None:
|
||||
"""Initialize the ToolNode with the provided tools and configuration.
|
||||
|
||||
Args:
|
||||
tools: Sequence of tools to make available for execution.
|
||||
name: Node name for graph identification.
|
||||
tags: Optional metadata tags.
|
||||
handle_tool_errors: Error handling configuration.
|
||||
messages_key: State key containing messages.
|
||||
"""
|
||||
super().__init__(self._func, self._afunc, name=name, tags=tags, trace=False)
|
||||
self.tools_by_name: dict[str, BaseTool] = {}
|
||||
self.tool_to_state_args: dict[str, dict[str, Optional[str]]] = {}
|
||||
@@ -359,8 +234,7 @@ class ToolNode(RunnableCallable):
|
||||
*,
|
||||
store: Optional[BaseStore],
|
||||
) -> Any:
|
||||
tool_calls, input_type = self._parse_input(input)
|
||||
tool_calls = [self.inject_tool_args(call, input, store) for call in tool_calls]
|
||||
tool_calls, input_type = self._parse_input(input, store)
|
||||
config_list = get_config_list(config, len(tool_calls))
|
||||
input_types = [input_type] * len(tool_calls)
|
||||
with get_executor_for_config(config) as executor:
|
||||
@@ -381,8 +255,7 @@ class ToolNode(RunnableCallable):
|
||||
*,
|
||||
store: Optional[BaseStore],
|
||||
) -> Any:
|
||||
tool_calls, input_type = self._parse_input(input)
|
||||
tool_calls = [self.inject_tool_args(call, input, store) for call in tool_calls]
|
||||
tool_calls, input_type = self._parse_input(input, store)
|
||||
outputs = await asyncio.gather(
|
||||
*(self._arun_one(call, input_type, config) for call in tool_calls)
|
||||
)
|
||||
@@ -439,19 +312,18 @@ class ToolNode(RunnableCallable):
|
||||
input_type: Literal["list", "dict", "tool_calls"],
|
||||
config: RunnableConfig,
|
||||
) -> ToolMessage:
|
||||
"""Run a single tool call synchronously."""
|
||||
if invalid_tool_message := self._validate_tool_call(call):
|
||||
return invalid_tool_message
|
||||
|
||||
try:
|
||||
call_args = {**call, **{"type": "tool_call"}}
|
||||
response = self.tools_by_name[call["name"]].invoke(call_args, config)
|
||||
input = {**call, **{"type": "tool_call"}}
|
||||
response = self.tools_by_name[call["name"]].invoke(input, config)
|
||||
|
||||
# GraphInterrupt is a special exception that will always be raised.
|
||||
# It can be triggered in the following scenarios:
|
||||
# (1) a NodeInterrupt is raised inside a tool
|
||||
# (2) a NodeInterrupt is raised inside a graph node for a graph called as a tool
|
||||
# (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph
|
||||
# called as a tool
|
||||
# (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph called as a tool
|
||||
# (2 and 3 can happen in a "supervisor w/ tools" multi-agent architecture)
|
||||
except GraphBubbleUp as e:
|
||||
raise e
|
||||
@@ -495,7 +367,6 @@ class ToolNode(RunnableCallable):
|
||||
input_type: Literal["list", "dict", "tool_calls"],
|
||||
config: RunnableConfig,
|
||||
) -> ToolMessage:
|
||||
"""Run a single tool call asynchronously."""
|
||||
if invalid_tool_message := self._validate_tool_call(call):
|
||||
return invalid_tool_message
|
||||
|
||||
@@ -553,25 +424,16 @@ class ToolNode(RunnableCallable):
|
||||
dict[str, Any],
|
||||
BaseModel,
|
||||
],
|
||||
store: Optional[BaseStore],
|
||||
) -> Tuple[list[ToolCall], Literal["list", "dict", "tool_calls"]]:
|
||||
input_type: Literal["list", "dict", "tool_calls"]
|
||||
if isinstance(input, list):
|
||||
if isinstance(input[-1], dict) and input[-1].get("type") == "tool_call":
|
||||
input_type = "tool_calls"
|
||||
tool_calls = cast(list[ToolCall], input)
|
||||
tool_calls = input
|
||||
return tool_calls, input_type
|
||||
else:
|
||||
input_type = "list"
|
||||
messages = input
|
||||
elif (
|
||||
isinstance(input, dict) and input.get("__type") == "tool_call_with_context"
|
||||
):
|
||||
# mypy will not be able to type narrow correctly since the signature
|
||||
# for input contains dict[str, Any]. We'd need to type dict[str, Any]
|
||||
# before we can apply correct typing.
|
||||
input = cast(ToolCallWithContext, input) # type: ignore[assignment]
|
||||
input_type = "tool_calls"
|
||||
return [input["tool_call"]], input_type
|
||||
elif isinstance(input, dict) and (messages := input.get(self.messages_key, [])):
|
||||
input_type = "dict"
|
||||
elif messages := getattr(input, self.messages_key, []):
|
||||
@@ -587,7 +449,10 @@ class ToolNode(RunnableCallable):
|
||||
except StopIteration:
|
||||
raise ValueError("No AIMessage found in input")
|
||||
|
||||
tool_calls = [call for call in latest_ai_message.tool_calls]
|
||||
tool_calls = [
|
||||
self.inject_tool_args(call, input, store)
|
||||
for call in latest_ai_message.tool_calls
|
||||
]
|
||||
return tool_calls, input_type
|
||||
|
||||
def _validate_tool_call(self, call: ToolCall) -> Optional[ToolMessage]:
|
||||
@@ -629,20 +494,15 @@ class ToolNode(RunnableCallable):
|
||||
required_fields_str = ", ".join(f for f in required_fields if f)
|
||||
err_msg += f" State should contain fields {required_fields_str}."
|
||||
raise ValueError(err_msg)
|
||||
|
||||
if isinstance(input, dict) and input.get("__type") == "tool_call_with_context":
|
||||
state = input["state"]
|
||||
else:
|
||||
state = input
|
||||
|
||||
if isinstance(state, dict):
|
||||
if isinstance(input, dict):
|
||||
tool_state_args = {
|
||||
tool_arg: state[state_field] if state_field else state
|
||||
tool_arg: input[state_field] if state_field else input
|
||||
for tool_arg, state_field in state_args.items()
|
||||
}
|
||||
|
||||
else:
|
||||
tool_state_args = {
|
||||
tool_arg: getattr(state, state_field) if state_field else state
|
||||
tool_arg: getattr(input, state_field) if state_field else input
|
||||
for tool_arg, state_field in state_args.items()
|
||||
}
|
||||
|
||||
@@ -681,38 +541,20 @@ class ToolNode(RunnableCallable):
|
||||
],
|
||||
store: Optional[BaseStore],
|
||||
) -> ToolCall:
|
||||
"""Inject graph state and store into tool call arguments.
|
||||
"""Injects the state and store into the tool call.
|
||||
|
||||
This method enables tools to access graph context that should not be controlled
|
||||
by the model. Tools can declare dependencies on graph state or persistent storage
|
||||
using InjectedState and InjectedStore annotations. This method automatically
|
||||
identifies these dependencies and injects the appropriate values.
|
||||
|
||||
The injection process preserves the original tool call structure while adding
|
||||
the necessary context arguments. This allows tools to be both model-callable
|
||||
and context-aware without exposing internal state management to the model.
|
||||
Tool arguments with types annotated as `InjectedState` and `InjectedStore` are
|
||||
ignored in tool schemas for generation purposes. This method injects them into
|
||||
tool calls for tool invocation.
|
||||
|
||||
Args:
|
||||
tool_call: The tool call dictionary to augment with injected arguments.
|
||||
Must contain 'name', 'args', 'id', and 'type' fields.
|
||||
input: The current graph state to inject into tools requiring state access.
|
||||
Can be a message list, state dictionary, or BaseModel instance.
|
||||
store: The persistent store instance to inject into tools requiring storage.
|
||||
Will be None if no store is configured for the graph.
|
||||
tool_call: The tool call to inject state and store into.
|
||||
input: The input state
|
||||
to inject.
|
||||
store: The store to inject.
|
||||
|
||||
Returns:
|
||||
A new ToolCall dictionary with the same structure as the input but with
|
||||
additional arguments injected based on the tool's annotation requirements.
|
||||
|
||||
Raises:
|
||||
ValueError: If a tool requires store injection but no store is provided,
|
||||
or if state injection requirements cannot be satisfied.
|
||||
|
||||
Note:
|
||||
This method is automatically called during tool execution but can also
|
||||
be used manually when working with the Send API or custom routing logic.
|
||||
The injection is performed on a copy of the tool call to avoid mutating
|
||||
the original.
|
||||
ToolCall: The tool call with injected state and store.
|
||||
"""
|
||||
if tool_call["name"] not in self.tools_by_name:
|
||||
return tool_call
|
||||
@@ -783,66 +625,55 @@ def tools_condition(
|
||||
state: Union[list[AnyMessage], dict[str, Any], BaseModel],
|
||||
messages_key: str = "messages",
|
||||
) -> Literal["tools", "__end__"]:
|
||||
"""Conditional routing function for tool-calling workflows.
|
||||
"""Use in the conditional_edge to route to the ToolNode if the last message
|
||||
|
||||
This utility function implements the standard conditional logic for ReAct-style
|
||||
agents: if the last AI message contains tool calls, route to the tool execution
|
||||
node; otherwise, end the workflow. This pattern is fundamental to most tool-calling
|
||||
agent architectures.
|
||||
|
||||
The function handles multiple state formats commonly used in LangGraph applications,
|
||||
making it flexible for different graph designs while maintaining consistent behavior.
|
||||
has tool calls. Otherwise, route to the end.
|
||||
|
||||
Args:
|
||||
state: The current graph state to examine for tool calls. Supported formats:
|
||||
- List of messages (for MessageGraph)
|
||||
- Dictionary containing a messages key (for StateGraph)
|
||||
- BaseModel instance with a messages attribute
|
||||
messages_key: The key or attribute name containing the message list in the state.
|
||||
This allows customization for graphs using different state schemas.
|
||||
Defaults to "messages".
|
||||
state: The state to check for
|
||||
tool calls. Must have a list of messages (MessageGraph) or have the
|
||||
"messages" key (StateGraph).
|
||||
|
||||
Returns:
|
||||
Either "tools" if tool calls are present in the last AI message, or "__end__"
|
||||
to terminate the workflow. These are the standard routing destinations for
|
||||
tool-calling conditional edges.
|
||||
The next node to route to.
|
||||
|
||||
Raises:
|
||||
ValueError: If no messages can be found in the provided state format.
|
||||
|
||||
Example:
|
||||
Basic usage in a ReAct agent:
|
||||
Examples:
|
||||
Create a custom ReAct-style agent with tools.
|
||||
|
||||
```python
|
||||
from langgraph.graph import StateGraph
|
||||
from langgraph.prebuilt import ToolNode, tools_condition
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
class State(TypedDict):
|
||||
messages: list
|
||||
|
||||
graph = StateGraph(State)
|
||||
graph.add_node("llm", call_model)
|
||||
graph.add_node("tools", ToolNode([my_tool]))
|
||||
graph.add_conditional_edges(
|
||||
"llm",
|
||||
tools_condition, # Routes to "tools" or "__end__"
|
||||
{"tools": "tools", "__end__": "__end__"}
|
||||
)
|
||||
```pycon
|
||||
>>> from langchain_anthropic import ChatAnthropic
|
||||
>>> from langchain_core.tools import tool
|
||||
...
|
||||
>>> from langgraph.graph import StateGraph
|
||||
>>> from langgraph.prebuilt import ToolNode, tools_condition
|
||||
>>> from langgraph.graph.message import add_messages
|
||||
...
|
||||
>>> from typing import Annotated
|
||||
>>> from typing_extensions import TypedDict
|
||||
...
|
||||
>>> @tool
|
||||
>>> def divide(a: float, b: float) -> int:
|
||||
... \"\"\"Return a / b.\"\"\"
|
||||
... return a / b
|
||||
...
|
||||
>>> llm = ChatAnthropic(model="claude-3-haiku-20240307")
|
||||
>>> tools = [divide]
|
||||
...
|
||||
>>> class State(TypedDict):
|
||||
... messages: Annotated[list, add_messages]
|
||||
>>>
|
||||
>>> graph_builder = StateGraph(State)
|
||||
>>> graph_builder.add_node("tools", ToolNode(tools))
|
||||
>>> graph_builder.add_node("chatbot", lambda state: {"messages":llm.bind_tools(tools).invoke(state['messages'])})
|
||||
>>> graph_builder.add_edge("tools", "chatbot")
|
||||
>>> graph_builder.add_conditional_edges(
|
||||
... "chatbot", tools_condition
|
||||
... )
|
||||
>>> graph_builder.set_entry_point("chatbot")
|
||||
>>> graph = graph_builder.compile()
|
||||
>>> graph.invoke({"messages": {"role": "user", "content": "What's 329993 divided by 13662?"}})
|
||||
```
|
||||
|
||||
Custom messages key:
|
||||
|
||||
```python
|
||||
def custom_condition(state):
|
||||
return tools_condition(state, messages_key="chat_history")
|
||||
```
|
||||
|
||||
Note:
|
||||
This function is designed to work seamlessly with ToolNode and standard
|
||||
LangGraph patterns. It expects the last message to be an AIMessage when
|
||||
tool calls are present, which is the standard output format for tool-calling
|
||||
language models.
|
||||
"""
|
||||
if isinstance(state, list):
|
||||
ai_message = state[-1]
|
||||
@@ -858,18 +689,16 @@ def tools_condition(
|
||||
|
||||
|
||||
class InjectedState(InjectedToolArg):
|
||||
"""Annotation for injecting graph state into tool arguments.
|
||||
"""Annotation for a Tool arg that is meant to be populated with the graph state.
|
||||
|
||||
This annotation enables tools to access graph state without exposing state
|
||||
management details to the language model. Tools annotated with InjectedState
|
||||
receive state data automatically during execution while remaining invisible
|
||||
to the model's tool-calling interface.
|
||||
Any Tool argument annotated with InjectedState will be hidden from a tool-calling
|
||||
model, so that the model doesn't attempt to generate the argument. If using
|
||||
ToolNode, the appropriate graph state field will be automatically injected into
|
||||
the model-generated tool args.
|
||||
|
||||
Args:
|
||||
field: Optional key to extract from the state dictionary. If None, the entire
|
||||
state is injected. If specified, only that field's value is injected.
|
||||
This allows tools to request specific state components rather than
|
||||
processing the full state structure.
|
||||
field: The key from state to insert. If None, the entire state is expected to
|
||||
be passed in.
|
||||
|
||||
Example:
|
||||
```python
|
||||
@@ -916,15 +745,6 @@ class InjectedState(InjectedToolArg):
|
||||
ToolMessage(content='bar2', name='foo_tool', tool_call_id='2')
|
||||
]
|
||||
```
|
||||
|
||||
Note:
|
||||
- InjectedState arguments are automatically excluded from tool schemas
|
||||
presented to language models
|
||||
- ToolNode handles the injection process during execution
|
||||
- Tools can mix regular arguments (controlled by the model) with injected
|
||||
arguments (controlled by the system)
|
||||
- State injection occurs after the model generates tool calls but before
|
||||
tool execution
|
||||
""" # noqa: E501
|
||||
|
||||
def __init__(self, field: Optional[str] = None) -> None:
|
||||
@@ -932,97 +752,61 @@ class InjectedState(InjectedToolArg):
|
||||
|
||||
|
||||
class InjectedStore(InjectedToolArg):
|
||||
"""Annotation for injecting persistent store into tool arguments.
|
||||
"""Annotation for a Tool arg that is meant to be populated with LangGraph store.
|
||||
|
||||
This annotation enables tools to access LangGraph's persistent storage system
|
||||
without exposing storage details to the language model. Tools annotated with
|
||||
InjectedStore receive the store instance automatically during execution while
|
||||
remaining invisible to the model's tool-calling interface.
|
||||
|
||||
The store provides persistent, cross-session data storage that tools can use
|
||||
for maintaining context, user preferences, or any other data that needs to
|
||||
persist beyond individual workflow executions.
|
||||
Any Tool argument annotated with InjectedStore will be hidden from a tool-calling
|
||||
model, so that the model doesn't attempt to generate the argument. If using
|
||||
ToolNode, the appropriate store field will be automatically injected into
|
||||
the model-generated tool args. Note: if a graph is compiled with a store object,
|
||||
the store will be automatically propagated to the tools with InjectedStore args
|
||||
when using ToolNode.
|
||||
|
||||
!!! Warning
|
||||
`InjectedStore` annotation requires `langchain-core >= 0.3.8`
|
||||
|
||||
Example:
|
||||
```python
|
||||
from typing import Any
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from langchain_core.messages import AIMessage
|
||||
from langchain_core.tools import tool
|
||||
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
from langgraph.prebuilt import InjectedStore, ToolNode
|
||||
|
||||
@tool
|
||||
def save_preference(
|
||||
key: str,
|
||||
value: str,
|
||||
store: Annotated[Any, InjectedStore()]
|
||||
) -> str:
|
||||
\"\"\"Save user preference to persistent storage.\"\"\"
|
||||
store.put(("preferences",), key, value)
|
||||
return f"Saved {key} = {value}"
|
||||
|
||||
@tool
|
||||
def get_preference(
|
||||
key: str,
|
||||
store: Annotated[Any, InjectedStore()]
|
||||
) -> str:
|
||||
\"\"\"Retrieve user preference from persistent storage.\"\"\"
|
||||
result = store.get(("preferences",), key)
|
||||
return result.value if result else "Not found"
|
||||
```
|
||||
|
||||
Usage with ToolNode and graph compilation:
|
||||
|
||||
```python
|
||||
from langgraph.graph import StateGraph
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
store = InMemoryStore()
|
||||
tool_node = ToolNode([save_preference, get_preference])
|
||||
store.put(("values",), "foo", {"bar": 2})
|
||||
|
||||
graph = StateGraph(State)
|
||||
graph.add_node("tools", tool_node)
|
||||
compiled_graph = graph.compile(store=store) # Store is injected automatically
|
||||
@tool
|
||||
def store_tool(x: int, my_store: Annotated[Any, InjectedStore()]) -> str:
|
||||
'''Do something with store.'''
|
||||
stored_value = my_store.get(("values",), "foo").value["bar"]
|
||||
return stored_value + x
|
||||
|
||||
node = ToolNode([store_tool])
|
||||
|
||||
tool_call = {"name": "store_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
|
||||
state = {
|
||||
"messages": [AIMessage("", tool_calls=[tool_call])],
|
||||
}
|
||||
|
||||
node.invoke(state, store=store)
|
||||
```
|
||||
|
||||
Cross-session persistence:
|
||||
|
||||
```python
|
||||
# First session
|
||||
result1 = graph.invoke({"messages": [HumanMessage("Save my favorite color as blue")]})
|
||||
|
||||
# Later session - data persists
|
||||
result2 = graph.invoke({"messages": [HumanMessage("What's my favorite color?")]})
|
||||
```pycon
|
||||
{
|
||||
"messages": [
|
||||
ToolMessage(content='3', name='store_tool', tool_call_id='1'),
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Note:
|
||||
- InjectedStore arguments are automatically excluded from tool schemas
|
||||
presented to language models
|
||||
- The store instance is automatically injected by ToolNode during execution
|
||||
- Tools can access namespaced storage using the store's get/put methods
|
||||
- Store injection requires the graph to be compiled with a store instance
|
||||
- Multiple tools can share the same store instance for data consistency
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
def _is_injection(
|
||||
type_arg: Any, injection_type: Union[Type[InjectedState], Type[InjectedStore]]
|
||||
) -> bool:
|
||||
"""Check if a type argument represents an injection annotation.
|
||||
|
||||
This utility function determines whether a type annotation indicates that
|
||||
an argument should be injected with state or store data. It handles both
|
||||
direct annotations and nested annotations within Union or Annotated types.
|
||||
|
||||
Args:
|
||||
type_arg: The type argument to check for injection annotations.
|
||||
injection_type: The injection type to look for (InjectedState or InjectedStore).
|
||||
|
||||
Returns:
|
||||
True if the type argument contains the specified injection annotation.
|
||||
"""
|
||||
if isinstance(type_arg, injection_type) or (
|
||||
isinstance(type_arg, type) and issubclass(type_arg, injection_type)
|
||||
):
|
||||
@@ -1034,19 +818,6 @@ def _is_injection(
|
||||
|
||||
|
||||
def _get_state_args(tool: BaseTool) -> dict[str, Optional[str]]:
|
||||
"""Extract state injection mappings from tool annotations.
|
||||
|
||||
This function analyzes a tool's input schema to identify arguments that should
|
||||
be injected with graph state. It processes InjectedState annotations to build
|
||||
a mapping of tool argument names to state field names.
|
||||
|
||||
Args:
|
||||
tool: The tool to analyze for state injection requirements.
|
||||
|
||||
Returns:
|
||||
A dictionary mapping tool argument names to state field names. If a field
|
||||
name is None, the entire state should be injected for that argument.
|
||||
"""
|
||||
full_schema = tool.get_input_schema()
|
||||
tool_args_to_state_fields: dict = {}
|
||||
|
||||
@@ -1073,22 +844,6 @@ def _get_state_args(tool: BaseTool) -> dict[str, Optional[str]]:
|
||||
|
||||
|
||||
def _get_store_arg(tool: BaseTool) -> Optional[str]:
|
||||
"""Extract store injection argument from tool annotations.
|
||||
|
||||
This function analyzes a tool's input schema to identify the argument that
|
||||
should be injected with the graph store. Only one store argument is supported
|
||||
per tool.
|
||||
|
||||
Args:
|
||||
tool: The tool to analyze for store injection requirements.
|
||||
|
||||
Returns:
|
||||
The name of the argument that should receive the store injection, or None
|
||||
if no store injection is required.
|
||||
|
||||
Raises:
|
||||
ValueError: If a tool argument has multiple InjectedStore annotations.
|
||||
"""
|
||||
full_schema = tool.get_input_schema()
|
||||
for name, type_ in get_all_basemodel_annotations(full_schema).items():
|
||||
injections = [
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
import re
|
||||
from typing import Union
|
||||
from typing import Any, Sequence, Union
|
||||
|
||||
from typing_extensions import Self
|
||||
|
||||
|
||||
class FloatBetween(float):
|
||||
def __new__(cls, min_value: float, max_value: float) -> Self:
|
||||
return super().__new__(cls, min_value)
|
||||
|
||||
def __init__(self, min_value: float, max_value: float) -> None:
|
||||
super().__init__()
|
||||
self.min_value = min_value
|
||||
self.max_value = max_value
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
return (
|
||||
isinstance(other, float)
|
||||
and other >= self.min_value
|
||||
and other <= self.max_value
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((float(self), self.min_value, self.max_value))
|
||||
|
||||
|
||||
class AnyStr(str):
|
||||
@@ -16,3 +38,49 @@ class AnyStr(str):
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((str(self), self.prefix))
|
||||
|
||||
|
||||
class AnyDict(dict):
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, dict) or len(self) != len(other):
|
||||
return False
|
||||
for k, v in self.items():
|
||||
if kk := next((kk for kk in other if kk == k), None):
|
||||
if v == other[kk]:
|
||||
continue
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class AnyVersion:
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
return isinstance(other, (str, int, float))
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(str(self))
|
||||
|
||||
|
||||
class UnsortedSequence:
|
||||
def __init__(self, *values: Any) -> None:
|
||||
self.seq = values
|
||||
|
||||
def __eq__(self, value: object) -> bool:
|
||||
return (
|
||||
isinstance(value, Sequence)
|
||||
and len(self.seq) == len(value)
|
||||
and all(a in value for a in self.seq)
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(frozenset(self.seq))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return repr(self.seq)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from collections.abc import AsyncIterator, Iterator
|
||||
from uuid import UUID
|
||||
|
||||
@@ -30,55 +29,6 @@ from tests.conftest_store import (
|
||||
|
||||
pytest.register_assert_rewrite("tests.memory_assert")
|
||||
|
||||
# Global variables for checkpointer and store configurations
|
||||
FAST_MODE = os.getenv("LANGGRAPH_TEST_FAST", "true").lower() in ("true", "1", "yes")
|
||||
|
||||
SYNC_CHECKPOINTER_PARAMS = (
|
||||
["memory"]
|
||||
if FAST_MODE
|
||||
else [
|
||||
"memory",
|
||||
"sqlite",
|
||||
"postgres",
|
||||
"postgres_pipe",
|
||||
"postgres_pool",
|
||||
]
|
||||
)
|
||||
|
||||
ASYNC_CHECKPOINTER_PARAMS = (
|
||||
["memory"]
|
||||
if FAST_MODE
|
||||
else [
|
||||
"memory",
|
||||
"sqlite_aio",
|
||||
"postgres_aio",
|
||||
"postgres_aio_pipe",
|
||||
"postgres_aio_pool",
|
||||
]
|
||||
)
|
||||
|
||||
SYNC_STORE_PARAMS = (
|
||||
["in_memory"]
|
||||
if FAST_MODE
|
||||
else [
|
||||
"in_memory",
|
||||
"postgres",
|
||||
"postgres_pipe",
|
||||
"postgres_pool",
|
||||
]
|
||||
)
|
||||
|
||||
ASYNC_STORE_PARAMS = (
|
||||
["in_memory"]
|
||||
if FAST_MODE
|
||||
else [
|
||||
"in_memory",
|
||||
"postgres_aio",
|
||||
"postgres_aio_pipe",
|
||||
"postgres_aio_pool",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def anyio_backend():
|
||||
@@ -98,7 +48,7 @@ def deterministic_uuids(mocker: MockerFixture) -> MockerFixture:
|
||||
|
||||
@pytest.fixture(
|
||||
scope="function",
|
||||
params=SYNC_STORE_PARAMS,
|
||||
params=["in_memory", "postgres", "postgres_pipe", "postgres_pool"],
|
||||
)
|
||||
def sync_store(request: pytest.FixtureRequest) -> Iterator[BaseStore]:
|
||||
store_name = request.param
|
||||
@@ -122,7 +72,7 @@ def sync_store(request: pytest.FixtureRequest) -> Iterator[BaseStore]:
|
||||
|
||||
@pytest.fixture(
|
||||
scope="function",
|
||||
params=ASYNC_STORE_PARAMS,
|
||||
params=["in_memory", "postgres_aio", "postgres_aio_pipe", "postgres_aio_pool"],
|
||||
)
|
||||
async def async_store(request: pytest.FixtureRequest) -> AsyncIterator[BaseStore]:
|
||||
store_name = request.param
|
||||
@@ -146,7 +96,13 @@ async def async_store(request: pytest.FixtureRequest) -> AsyncIterator[BaseStore
|
||||
|
||||
@pytest.fixture(
|
||||
scope="function",
|
||||
params=SYNC_CHECKPOINTER_PARAMS,
|
||||
params=[
|
||||
"memory",
|
||||
"sqlite",
|
||||
"postgres",
|
||||
"postgres_pipe",
|
||||
"postgres_pool",
|
||||
],
|
||||
)
|
||||
def sync_checkpointer(
|
||||
request: pytest.FixtureRequest,
|
||||
@@ -173,7 +129,13 @@ def sync_checkpointer(
|
||||
|
||||
@pytest.fixture(
|
||||
scope="function",
|
||||
params=ASYNC_CHECKPOINTER_PARAMS,
|
||||
params=[
|
||||
"memory",
|
||||
"sqlite_aio",
|
||||
"postgres_aio",
|
||||
"postgres_aio_pipe",
|
||||
"postgres_aio_pool",
|
||||
],
|
||||
)
|
||||
async def async_checkpointer(
|
||||
request: pytest.FixtureRequest,
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
from typing import Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
|
||||
from langgraph.checkpoint.base import (
|
||||
ChannelVersions,
|
||||
Checkpoint,
|
||||
CheckpointMetadata,
|
||||
CheckpointTuple,
|
||||
SerializerProtocol,
|
||||
)
|
||||
from langgraph.checkpoint.memory import InMemorySaver, PersistentDict
|
||||
from langgraph.pregel.checkpoint import copy_checkpoint
|
||||
|
||||
|
||||
class NoopSerializer(SerializerProtocol):
|
||||
def loads_typed(self, data: tuple[str, bytes]) -> Any:
|
||||
return data[1]
|
||||
|
||||
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
||||
return "type", obj
|
||||
|
||||
|
||||
class MemorySaverAssertImmutable(InMemorySaver):
|
||||
storage_for_copies: defaultdict[str, dict[str, dict[str, Checkpoint]]]
|
||||
|
||||
@@ -57,3 +69,66 @@ class MemorySaverAssertImmutable(InMemorySaver):
|
||||
)
|
||||
# call super to write checkpoint
|
||||
return super().put(config, checkpoint, metadata, new_versions)
|
||||
|
||||
|
||||
class MemorySaverAssertCheckpointMetadata(InMemorySaver):
|
||||
"""This custom checkpointer is for verifying that a run's configurable
|
||||
fields are merged with the previous checkpoint config for each step in
|
||||
the run. This is the desired behavior. Because the checkpointer's (a)put()
|
||||
method is called for each step, the implementation of this checkpointer
|
||||
should produce a side effect that can be asserted.
|
||||
"""
|
||||
|
||||
def put(
|
||||
self,
|
||||
config: RunnableConfig,
|
||||
checkpoint: Checkpoint,
|
||||
metadata: CheckpointMetadata,
|
||||
new_versions: ChannelVersions,
|
||||
) -> None:
|
||||
"""The implementation of put() merges config["configurable"] (a run's
|
||||
configurable fields) with the metadata field. The state of the
|
||||
checkpoint metadata can be asserted to confirm that the run's
|
||||
configurable fields were merged with the previous checkpoint config.
|
||||
"""
|
||||
configurable = config["configurable"].copy()
|
||||
|
||||
# remove checkpoint_id to make testing simpler
|
||||
checkpoint_id = configurable.pop("checkpoint_id", None)
|
||||
thread_id = config["configurable"]["thread_id"]
|
||||
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
||||
self.storage[thread_id][checkpoint_ns].update(
|
||||
{
|
||||
checkpoint["id"]: (
|
||||
self.serde.dumps_typed(checkpoint),
|
||||
# merge configurable fields and metadata
|
||||
self.serde.dumps_typed({**configurable, **metadata}),
|
||||
checkpoint_id,
|
||||
)
|
||||
}
|
||||
)
|
||||
return {
|
||||
"configurable": {
|
||||
"thread_id": config["configurable"]["thread_id"],
|
||||
"checkpoint_id": checkpoint["id"],
|
||||
}
|
||||
}
|
||||
|
||||
async def aput(
|
||||
self,
|
||||
config: RunnableConfig,
|
||||
checkpoint: Checkpoint,
|
||||
metadata: CheckpointMetadata,
|
||||
new_versions: ChannelVersions,
|
||||
) -> RunnableConfig:
|
||||
return await asyncio.get_running_loop().run_in_executor(
|
||||
None, self.put, config, checkpoint, metadata, new_versions
|
||||
)
|
||||
|
||||
|
||||
class MemorySaverNoPending(InMemorySaver):
|
||||
def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
|
||||
result = super().get_tuple(config)
|
||||
if result:
|
||||
return CheckpointTuple(result.config, result.checkpoint, result.metadata)
|
||||
return result
|
||||
|
||||
@@ -9,11 +9,33 @@ subclassed strings.
|
||||
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.messages import HumanMessage, ToolMessage
|
||||
from langchain_core.documents import Document
|
||||
from langchain_core.messages import AIMessage, AIMessageChunk, HumanMessage, ToolMessage
|
||||
|
||||
from tests.any_str import AnyStr
|
||||
|
||||
|
||||
def _AnyIdDocument(**kwargs: Any) -> Document:
|
||||
"""Create a document with an id field."""
|
||||
message = Document(**kwargs)
|
||||
message.id = AnyStr()
|
||||
return message
|
||||
|
||||
|
||||
def _AnyIdAIMessage(**kwargs: Any) -> AIMessage:
|
||||
"""Create ai message with an any id field."""
|
||||
message = AIMessage(**kwargs)
|
||||
message.id = AnyStr()
|
||||
return message
|
||||
|
||||
|
||||
def _AnyIdAIMessageChunk(**kwargs: Any) -> AIMessageChunk:
|
||||
"""Create ai message with an any id field."""
|
||||
message = AIMessageChunk(**kwargs)
|
||||
message.id = AnyStr()
|
||||
return message
|
||||
|
||||
|
||||
def _AnyIdHumanMessage(**kwargs: Any) -> HumanMessage:
|
||||
"""Create a human message with an any id field."""
|
||||
message = HumanMessage(**kwargs)
|
||||
|
||||
@@ -5,7 +5,6 @@ from functools import partial
|
||||
from typing import (
|
||||
Annotated,
|
||||
List,
|
||||
Literal,
|
||||
Optional,
|
||||
Type,
|
||||
TypeVar,
|
||||
@@ -510,7 +509,7 @@ class CustomStatePydantic(AgentStatePydantic):
|
||||
@pytest.mark.parametrize("state_schema", [CustomState, CustomStatePydantic])
|
||||
def test_react_agent_update_state(
|
||||
sync_checkpointer: BaseCheckpointSaver,
|
||||
version: Literal["v1", "v2"],
|
||||
version: str,
|
||||
state_schema: StateSchemaType,
|
||||
) -> None:
|
||||
@dec_tool
|
||||
@@ -558,7 +557,7 @@ def test_react_agent_update_state(
|
||||
version=version,
|
||||
)
|
||||
config = {"configurable": {"thread_id": "1"}}
|
||||
# Run until interrupted
|
||||
# run until interrpupted
|
||||
agent.invoke({"messages": [("user", "what's my name")]}, config)
|
||||
# supply the value for the interrupt
|
||||
response = agent.invoke(Command(resume="Archibald"), config)
|
||||
@@ -782,9 +781,8 @@ class AgentStateExtraKeyPydantic(AgentStatePydantic):
|
||||
"state_schema", [AgentStateExtraKey, AgentStateExtraKeyPydantic]
|
||||
)
|
||||
def test_create_react_agent_inject_vars(
|
||||
version: Literal["v1", "v2"], state_schema: StateSchemaType
|
||||
version: str, state_schema: StateSchemaType
|
||||
) -> None:
|
||||
"""Test that the agent can inject state and store into tool functions."""
|
||||
store = InMemoryStore()
|
||||
namespace = ("test",)
|
||||
store.put(namespace, "test_key", {"bar": 3})
|
||||
@@ -819,14 +817,15 @@ def test_create_react_agent_inject_vars(
|
||||
model = FakeToolCallingModel(tool_calls=[[tool_call], []])
|
||||
agent = create_react_agent(
|
||||
model,
|
||||
ToolNode([tool1], handle_tool_errors=False),
|
||||
[tool1],
|
||||
state_schema=state_schema,
|
||||
store=store,
|
||||
version=version,
|
||||
)
|
||||
result = agent.invoke({"messages": [{"role": "user", "content": "hi"}], "foo": 2})
|
||||
input_message = HumanMessage("hi")
|
||||
result = agent.invoke({"messages": [input_message], "foo": 2})
|
||||
assert result["messages"] == [
|
||||
_AnyIdHumanMessage(content="hi"),
|
||||
input_message,
|
||||
AIMessage(content="hi", tool_calls=[tool_call], id="0"),
|
||||
_AnyIdToolMessage(content="6", name="tool1", tool_call_id="some 0"),
|
||||
AIMessage("hi-hi-6", id="1"),
|
||||
@@ -1581,14 +1580,13 @@ def test_create_react_agent_inject_vars_with_post_model_hook(
|
||||
"type": "tool_call",
|
||||
}
|
||||
|
||||
def post_model_hook(state: dict) -> dict:
|
||||
"""Post model hook is injecting a new foo key."""
|
||||
return {"foo": 2}
|
||||
def post_model_hook(state: dict) -> None:
|
||||
return
|
||||
|
||||
model = FakeToolCallingModel(tool_calls=[[tool_call], []])
|
||||
agent = create_react_agent(
|
||||
model,
|
||||
ToolNode([tool1], handle_tool_errors=False),
|
||||
[tool1],
|
||||
state_schema=state_schema,
|
||||
store=store,
|
||||
post_model_hook=post_model_hook,
|
||||
|
||||
Generated
+3
-3
@@ -367,7 +367,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint"
|
||||
version = "2.1.1"
|
||||
version = "2.1.0"
|
||||
source = { editable = "../checkpoint" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
@@ -397,7 +397,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-checkpoint-postgres"
|
||||
version = "2.0.23"
|
||||
version = "2.0.22"
|
||||
source = { editable = "../checkpoint-postgres" }
|
||||
dependencies = [
|
||||
{ name = "langgraph-checkpoint" },
|
||||
@@ -507,7 +507,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.1.74"
|
||||
version = "0.1.72"
|
||||
source = { editable = "../sdk-py" }
|
||||
dependencies = [
|
||||
{ name = "httpx" },
|
||||
|
||||
@@ -335,10 +335,8 @@ class _ResourceOn(typing.Generic[VCreate, VRead, VUpdate, VDelete, VSearch]):
|
||||
@typing.overload
|
||||
def __call__(
|
||||
self,
|
||||
fn: (
|
||||
_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]
|
||||
| _ActionHandler[dict[str, typing.Any]]
|
||||
),
|
||||
fn: _ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]
|
||||
| _ActionHandler[dict[str, typing.Any]],
|
||||
) -> _ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]: ...
|
||||
|
||||
@typing.overload
|
||||
@@ -354,11 +352,9 @@ class _ResourceOn(typing.Generic[VCreate, VRead, VUpdate, VDelete, VSearch]):
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
fn: (
|
||||
_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]
|
||||
| _ActionHandler[dict[str, typing.Any]]
|
||||
| None
|
||||
) = None,
|
||||
fn: _ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]
|
||||
| _ActionHandler[dict[str, typing.Any]]
|
||||
| None = None,
|
||||
*,
|
||||
resources: str | Sequence[str] | None = None,
|
||||
actions: str | Sequence[str] | None = None,
|
||||
@@ -480,13 +476,9 @@ class _StoreOn:
|
||||
def __call__(
|
||||
self,
|
||||
*,
|
||||
actions: (
|
||||
typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
| Sequence[
|
||||
typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
]
|
||||
| None
|
||||
) = None,
|
||||
actions: typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
| Sequence[typing.Literal["put", "get", "search", "list_namespaces", "delete"]]
|
||||
| None = None,
|
||||
) -> Callable[[AHO], AHO]: ...
|
||||
|
||||
@typing.overload
|
||||
@@ -496,13 +488,9 @@ class _StoreOn:
|
||||
self,
|
||||
fn: AHO | None = None,
|
||||
*,
|
||||
actions: (
|
||||
typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
| Sequence[
|
||||
typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
]
|
||||
| None
|
||||
) = None,
|
||||
actions: typing.Literal["put", "get", "search", "list_namespaces", "delete"]
|
||||
| Sequence[typing.Literal["put", "get", "search", "list_namespaces", "delete"]]
|
||||
| None = None,
|
||||
) -> AHO | Callable[[AHO], AHO]:
|
||||
"""Register a handler for specific resources and actions.
|
||||
|
||||
@@ -720,12 +708,4 @@ def _validate_handler(fn: Callable[..., typing.Any]) -> None:
|
||||
)
|
||||
|
||||
|
||||
def is_studio_user(user: types.MinimalUser | types.User | types.UserDict) -> bool:
|
||||
return (
|
||||
isinstance(user, types.StudioUser)
|
||||
or isinstance(user, dict)
|
||||
and user.get("kind") == "StudioUser"
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["Auth", "types", "exceptions"]
|
||||
|
||||
@@ -251,7 +251,7 @@ class Thread(TypedDict):
|
||||
values: Json
|
||||
"""The current state of the thread."""
|
||||
interrupts: dict[str, list[Interrupt]]
|
||||
"""Mapping of task ids to interrupts that were raised in that task."""
|
||||
"""Interrupts which were thrown in this thread"""
|
||||
|
||||
|
||||
class ThreadTask(TypedDict):
|
||||
@@ -284,8 +284,6 @@ class ThreadState(TypedDict):
|
||||
"""The ID of the parent checkpoint. If missing, this is the root checkpoint."""
|
||||
tasks: Sequence[ThreadTask]
|
||||
"""Tasks to execute in this step. If already attempted, may contain an error."""
|
||||
interrupts: list[Interrupt]
|
||||
"""Interrupts which were thrown in this thread."""
|
||||
|
||||
|
||||
class ThreadUpdateStateResponse(TypedDict):
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.1.74"
|
||||
version = "0.1.72"
|
||||
description = "SDK for interacting with LangGraph API"
|
||||
authors = []
|
||||
requires-python = ">=3.9"
|
||||
|
||||
Generated
+37
-37
@@ -19,11 +19,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.7.14"
|
||||
version = "2025.7.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995", size = 163981, upload-time = "2025-07-14T03:29:28.449Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/de/8a/c729b6b60c66a38f590c4e774decc4b2ec7b0576be8f1aa984a53ffa812a/certifi-2025.7.9.tar.gz", hash = "sha256:c1d2ec05395148ee10cf672ffc28cd37ea0ab0d99f9cc74c43e588cbd111b079", size = 160386, upload-time = "2025-07-09T02:13:58.874Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/f3/80a3f974c8b535d394ff960a11ac20368e06b736da395b551a49ce950cce/certifi-2025.7.9-py3-none-any.whl", hash = "sha256:d842783a14f8fdd646895ac26f719a061408834473cfc10203f6a575beb15d39", size = 159230, upload-time = "2025-07-09T02:13:57.007Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -119,7 +119,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.1.74"
|
||||
version = "0.1.72"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "httpx" },
|
||||
@@ -156,7 +156,7 @@ dev = [
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.17.0"
|
||||
version = "1.16.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mypy-extensions" },
|
||||
@@ -164,39 +164,39 @@ dependencies = [
|
||||
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/e3/034322d5a779685218ed69286c32faa505247f1f096251ef66c8fd203b08/mypy-1.17.0.tar.gz", hash = "sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03", size = 3352114, upload-time = "2025-07-14T20:34:30.181Z" }
|
||||
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/6a/31/e762baa3b73905c856d45ab77b4af850e8159dffffd86a52879539a08c6b/mypy-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6", size = 10998313, upload-time = "2025-07-14T20:33:24.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/c1/25b2f0d46fb7e0b5e2bee61ec3a47fe13eff9e3c2f2234f144858bbe6485/mypy-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d", size = 10128922, upload-time = "2025-07-14T20:34:06.414Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/78/6d646603a57aa8a2886df1b8881fe777ea60f28098790c1089230cd9c61d/mypy-1.17.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b", size = 11913524, upload-time = "2025-07-14T20:33:19.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/19/dae6c55e87ee426fb76980f7e78484450cad1c01c55a1dc4e91c930bea01/mypy-1.17.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a", size = 12650527, upload-time = "2025-07-14T20:32:44.095Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/e1/f916845a235235a6c1e4d4d065a3930113767001d491b8b2e1b61ca56647/mypy-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f", size = 12897284, upload-time = "2025-07-14T20:33:38.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/dc/414760708a4ea1b096bd214d26a24e30ac5e917ef293bc33cdb6fe22d2da/mypy-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937", size = 9506493, upload-time = "2025-07-14T20:34:01.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/24/82efb502b0b0f661c49aa21cfe3e1999ddf64bf5500fc03b5a1536a39d39/mypy-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be", size = 10914150, upload-time = "2025-07-14T20:31:51.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/96/8ef9a6ff8cedadff4400e2254689ca1dc4b420b92c55255b44573de10c54/mypy-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61", size = 10039845, upload-time = "2025-07-14T20:32:30.527Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/32/7ce359a56be779d38021d07941cfbb099b41411d72d827230a36203dbb81/mypy-1.17.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f", size = 11837246, upload-time = "2025-07-14T20:32:01.28Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/16/b775047054de4d8dbd668df9137707e54b07fe18c7923839cd1e524bf756/mypy-1.17.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d", size = 12571106, upload-time = "2025-07-14T20:34:26.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/cf/fa33eaf29a606102c8d9ffa45a386a04c2203d9ad18bf4eef3e20c43ebc8/mypy-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3", size = 12759960, upload-time = "2025-07-14T20:33:42.882Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/75/3f5a29209f27e739ca57e6350bc6b783a38c7621bdf9cac3ab8a08665801/mypy-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70", size = 9503888, upload-time = "2025-07-14T20:32:34.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/e9/e6824ed620bbf51d3bf4d6cbbe4953e83eaf31a448d1b3cfb3620ccb641c/mypy-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb", size = 11086395, upload-time = "2025-07-14T20:34:11.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/51/a4afd1ae279707953be175d303f04a5a7bd7e28dc62463ad29c1c857927e/mypy-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d", size = 10120052, upload-time = "2025-07-14T20:33:09.897Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/71/19adfeac926ba8205f1d1466d0d360d07b46486bf64360c54cb5a2bd86a8/mypy-1.17.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8", size = 11861806, upload-time = "2025-07-14T20:32:16.028Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/64/d6120eca3835baf7179e6797a0b61d6c47e0bc2324b1f6819d8428d5b9ba/mypy-1.17.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e", size = 12744371, upload-time = "2025-07-14T20:33:33.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/dc/56f53b5255a166f5bd0f137eed960e5065f2744509dfe69474ff0ba772a5/mypy-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8", size = 12914558, upload-time = "2025-07-14T20:33:56.961Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/ac/070bad311171badc9add2910e7f89271695a25c136de24bbafc7eded56d5/mypy-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d", size = 9585447, upload-time = "2025-07-14T20:32:20.594Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/7b/5f8ab461369b9e62157072156935cec9d272196556bdc7c2ff5f4c7c0f9b/mypy-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06", size = 11070019, upload-time = "2025-07-14T20:32:07.99Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/f8/c49c9e5a2ac0badcc54beb24e774d2499748302c9568f7f09e8730e953fa/mypy-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a", size = 10114457, upload-time = "2025-07-14T20:33:47.285Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/0c/fb3f9c939ad9beed3e328008b3fb90b20fda2cddc0f7e4c20dbefefc3b33/mypy-1.17.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889", size = 11857838, upload-time = "2025-07-14T20:33:14.462Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/66/85607ab5137d65e4f54d9797b77d5a038ef34f714929cf8ad30b03f628df/mypy-1.17.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba", size = 12731358, upload-time = "2025-07-14T20:32:25.579Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/d0/341dbbfb35ce53d01f8f2969facbb66486cee9804048bf6c01b048127501/mypy-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658", size = 12917480, upload-time = "2025-07-14T20:34:21.868Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/63/70c8b7dbfc520089ac48d01367a97e8acd734f65bd07813081f508a8c94c/mypy-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c", size = 9589666, upload-time = "2025-07-14T20:34:16.841Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/a0/6263dd11941231f688f0a8f2faf90ceac1dc243d148d314a089d2fe25108/mypy-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab", size = 10988185, upload-time = "2025-07-14T20:33:04.797Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/13/b8f16d6b0dc80277129559c8e7dbc9011241a0da8f60d031edb0e6e9ac8f/mypy-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad", size = 10120169, upload-time = "2025-07-14T20:32:38.84Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/ef/978ba79df0d65af680e20d43121363cf643eb79b04bf3880d01fc8afeb6f/mypy-1.17.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c", size = 11918121, upload-time = "2025-07-14T20:33:52.328Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/10/55ef70b104151a0d8280474f05268ff0a2a79be8d788d5e647257d121309/mypy-1.17.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8", size = 12648821, upload-time = "2025-07-14T20:32:59.631Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/8c/7781fcd2e1eef48fbedd3a422c21fe300a8e03ed5be2eb4bd10246a77f4e/mypy-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97", size = 12896955, upload-time = "2025-07-14T20:32:49.543Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/13/03ac759dabe86e98ca7b6681f114f90ee03f3ff8365a57049d311bd4a4e3/mypy-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4", size = 9512957, upload-time = "2025-07-14T20:33:28.619Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/fc/ee058cc4316f219078464555873e99d170bde1d9569abd833300dbeb484a/mypy-1.17.0-py3-none-any.whl", hash = "sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496", size = 2283195, upload-time = "2025-07-14T20:31:54.753Z" },
|
||||
{ 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]]
|
||||
|
||||
Reference in New Issue
Block a user