mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-20 06:35:46 +02:00
Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fd3dfc542 | ||
|
|
ff38f75594 | ||
|
|
bbdd007341 | ||
|
|
3c75e414e5 | ||
|
|
575401c78c | ||
|
|
092c9ecde6 | ||
|
|
8336686e89 | ||
|
|
8b080a091e | ||
|
|
1157ec77b4 | ||
|
|
a10a66cbd1 | ||
|
|
ae525fb74f | ||
|
|
a6dde39be7 | ||
|
|
c1661dd07f | ||
|
|
2d848ffddd | ||
|
|
4c8d965710 | ||
|
|
4ac1c628ee | ||
|
|
41f8e61589 | ||
|
|
57a877279d | ||
|
|
d6dea53323 | ||
|
|
504e91ad5a | ||
|
|
10abf2deb1 | ||
|
|
5796ca9a0a | ||
|
|
fca3e4513c | ||
|
|
c5744f583b | ||
|
|
d298b489b4 | ||
|
|
c4144bb48f | ||
|
|
2c3e380a35 | ||
|
|
cf39fa5a91 | ||
|
|
7e666b58cd | ||
|
|
3f400b38d1 | ||
|
|
6527df688c | ||
|
|
aec841bd2a | ||
|
|
2d3121a17c | ||
|
|
06f9142419 | ||
|
|
a926450601 | ||
|
|
abb96c0e2f | ||
|
|
d9e3d83894 | ||
|
|
cedecd8ed6 | ||
|
|
6bf9a7a4bc | ||
|
|
bce1dcfcd2 | ||
|
|
9b46cba1fb | ||
|
|
a6dab889d1 | ||
|
|
7c6dbb3972 | ||
|
|
e08b8352a8 | ||
|
|
f7fe7c6698 | ||
|
|
c2bc6ab8e9 | ||
|
|
420550501f | ||
|
|
a0599139b8 | ||
|
|
c2f359f708 | ||
|
|
7f78a011fd | ||
|
|
7d166bfb9f | ||
|
|
6cc8899818 | ||
|
|
1ba96f49bf | ||
|
|
b0958115c1 | ||
|
|
04fb14d3ae | ||
|
|
efb0e8c176 | ||
|
|
0584eaa5c4 | ||
|
|
0c73af5624 |
@@ -1,21 +1,21 @@
|
|||||||
name: "\U0001F41B Bug Report"
|
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 LangChain Forum at forum.langchain.com.
|
||||||
labels: [pending,bug]
|
labels: [pending, bug]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Thank you for taking the time to file a bug report.
|
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 the [LangChain Forum](https://forum.langchain.com/).
|
||||||
|
|
||||||
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
|
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:
|
if there's another way to solve your problem:
|
||||||
|
|
||||||
* [LangChain Forum](https://forum.langchain.com/),
|
* [LangChain Forum](https://forum.langchain.com/),
|
||||||
* [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
* [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
|
||||||
* [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
|
* [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),
|
* [LangChain documentation with the integrated search](https://docs.langchain.com/),
|
||||||
* [GitHub search](https://github.com/langchain-ai/langgraph),
|
* [GitHub search](https://github.com/langchain-ai/langgraph),
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: checks
|
id: checks
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from urllib import request, error
|
from urllib import error, request
|
||||||
|
|
||||||
import langgraph_cli
|
import langgraph_cli
|
||||||
import langgraph_cli.config
|
import langgraph_cli.config
|
||||||
@@ -11,9 +12,13 @@ from langgraph_cli.constants import DEFAULT_PORT
|
|||||||
from langgraph_cli.exec import Runner, subp_exec
|
from langgraph_cli.exec import Runner, subp_exec
|
||||||
from langgraph_cli.progress import Progress
|
from langgraph_cli.progress import Progress
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
||||||
"""Spin up API with Postgres/Redis via docker compose and wait until ready."""
|
"""Spin up API with Postgres/Redis via docker compose and wait until ready."""
|
||||||
|
logger.info("Starting test...")
|
||||||
with Runner() as runner, Progress(message="Pulling...") as set:
|
with Runner() as runner, Progress(message="Pulling...") as set:
|
||||||
# Detect docker/compose capabilities
|
# Detect docker/compose capabilities
|
||||||
capabilities = langgraph_cli.docker.check_capabilities(runner)
|
capabilities = langgraph_cli.docker.check_capabilities(runner)
|
||||||
@@ -57,7 +62,9 @@ def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
|||||||
sys.stderr.write(f"docker compose up failed: {e}\n")
|
sys.stderr.write(f"docker compose up failed: {e}\n")
|
||||||
try:
|
try:
|
||||||
sys.stderr.write("\n== docker compose ps ==\n")
|
sys.stderr.write("\n== docker compose ps ==\n")
|
||||||
runner.run(subp_exec(*compose_cmd, *args, "ps", input=stdin, verbose=False))
|
runner.run(
|
||||||
|
subp_exec(*compose_cmd, *args, "ps", input=stdin, verbose=False)
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
@@ -93,7 +100,7 @@ def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
|||||||
set("")
|
set("")
|
||||||
base_url = f"http://localhost:{port}"
|
base_url = f"http://localhost:{port}"
|
||||||
ok_url = f"{base_url}/ok"
|
ok_url = f"{base_url}/ok"
|
||||||
print(f"Waiting for {ok_url} to respond with 200...")
|
logger.info(f"Waiting for {ok_url} to respond with 200...")
|
||||||
deadline = time.time() + 30
|
deadline = time.time() + 30
|
||||||
last_err: Exception | None = None
|
last_err: Exception | None = None
|
||||||
while time.time() < deadline:
|
while time.time() < deadline:
|
||||||
@@ -107,13 +114,16 @@ def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
last_err = RuntimeError(f"Unexpected status: {resp.status}")
|
last_err = RuntimeError(f"Unexpected status: {resp.status}")
|
||||||
print(f"Unexpected status: {resp.status}")
|
logger.error(f"Unexpected status: {resp.status}")
|
||||||
except error.URLError as e:
|
except error.URLError as e:
|
||||||
|
logger.error(f"URLError: {e}")
|
||||||
last_err = e
|
last_err = e
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001
|
||||||
|
logger.error(f"Exception: {e}")
|
||||||
last_err = e
|
last_err = e
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
else:
|
else:
|
||||||
|
logger.error("Timeout waiting for /ok to return 200")
|
||||||
# Bring stack down before raising
|
# Bring stack down before raising
|
||||||
args_down = [*args, "down", "-v", "--remove-orphans"]
|
args_down = [*args, "down", "-v", "--remove-orphans"]
|
||||||
try:
|
try:
|
||||||
@@ -131,15 +141,23 @@ def test(config: pathlib.Path, port: int, tag: str, verbose: bool):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Clean up: bring compose stack down to free ports for next test
|
# Clean up: bring compose stack down to free ports for next test
|
||||||
args_down = [*args, "down", "-v", "--remove-orphans"]
|
logger.info("Test succeeded. Bringing down compose stack...")
|
||||||
runner.run(
|
try:
|
||||||
subp_exec(
|
args_down = [*args, "down", "-v", "--remove-orphans"]
|
||||||
*compose_cmd,
|
runner.run(
|
||||||
*args_down,
|
subp_exec(
|
||||||
input=stdin,
|
*compose_cmd,
|
||||||
verbose=verbose,
|
*args_down,
|
||||||
|
input=stdin,
|
||||||
|
verbose=verbose,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
logger.info("Compose stack down. Finishing...")
|
||||||
|
except Exception:
|
||||||
|
logger.exception("Failed to bring down compose stack")
|
||||||
|
pass
|
||||||
|
|
||||||
|
logger.info("Test finished")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -150,4 +168,10 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("-c", "--config", type=str, default="./langgraph.json")
|
parser.add_argument("-c", "--config", type=str, default="./langgraph.json")
|
||||||
parser.add_argument("-p", "--port", type=int, default=DEFAULT_PORT)
|
parser.add_argument("-p", "--port", type=int, default=DEFAULT_PORT)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
test(pathlib.Path(args.config), args.port, args.tag, verbose=True)
|
try:
|
||||||
|
test(pathlib.Path(args.config), args.port, args.tag, verbose=True)
|
||||||
|
except BaseException:
|
||||||
|
logger.exception("Test failed")
|
||||||
|
raise
|
||||||
|
|
||||||
|
logger.info("Test execution finished")
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- "3.10"
|
- "3.10"
|
||||||
- "3.11"
|
- "3.14"
|
||||||
example:
|
example:
|
||||||
- name: A
|
- name: A
|
||||||
workdir: libs/cli/examples
|
workdir: libs/cli/examples
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
filter: "libs/cli/**"
|
filter: "libs/cli/**"
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -66,19 +66,19 @@ jobs:
|
|||||||
timeout 60 python "$REPO_ROOT/.github/scripts/run_langgraph_cli_test.py" -t ${{ matrix.example.tag }}
|
timeout 60 python "$REPO_ROOT/.github/scripts/run_langgraph_cli_test.py" -t ${{ matrix.example.tag }}
|
||||||
|
|
||||||
- name: Build JS service
|
- name: Build JS service
|
||||||
if: steps.changed-files.outputs.all
|
if: ${{ steps.changed-files.outputs.all && matrix.example.name == 'A' }}
|
||||||
working-directory: libs/cli/js-examples
|
working-directory: libs/cli/js-examples
|
||||||
run: |
|
run: |
|
||||||
langgraph build -t langgraph-test-e
|
langgraph build -t langgraph-test-e
|
||||||
|
|
||||||
- name: Build JS monorepo service
|
- name: Build JS monorepo service
|
||||||
if: steps.changed-files.outputs.all
|
if: ${{ steps.changed-files.outputs.all && matrix.example.name == 'A' }}
|
||||||
working-directory: libs/cli/js-monorepo-example
|
working-directory: libs/cli/js-monorepo-example
|
||||||
run: |
|
run: |
|
||||||
langgraph build -t langgraph-test-f -c apps/agent/langgraph.json --build-command "yarn run turbo build" --install-command "yarn install"
|
langgraph build -t langgraph-test-f -c apps/agent/langgraph.json --build-command "yarn run turbo build" --install-command "yarn install"
|
||||||
|
|
||||||
- name: Build Python monorepo service
|
- name: Build Python monorepo service
|
||||||
if: steps.changed-files.outputs.all
|
if: ${{ steps.changed-files.outputs.all && matrix.example.name == 'A' }}
|
||||||
working-directory: libs/cli/python-monorepo-example
|
working-directory: libs/cli/python-monorepo-example
|
||||||
run: |
|
run: |
|
||||||
langgraph build -t langgraph-test-g -c apps/agent/langgraph.json
|
langgraph build -t langgraph-test-g -c apps/agent/langgraph.json
|
||||||
@@ -87,24 +87,32 @@ jobs:
|
|||||||
timeout 60 python ../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-g -c apps/agent/langgraph.json
|
timeout 60 python ../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-g -c apps/agent/langgraph.json
|
||||||
|
|
||||||
- name: Build and test prerelease reqs service
|
- name: Build and test prerelease reqs service
|
||||||
if: steps.changed-files.outputs.all
|
if: ${{ steps.changed-files.outputs.all && matrix.example.name == 'A' }}
|
||||||
working-directory: libs/cli/examples/graph_prerelease_reqs
|
working-directory: libs/cli/examples/graph_prerelease_reqs
|
||||||
run: |
|
run: |
|
||||||
langgraph build -t langgraph-test-h
|
langgraph build -t langgraph-test-h
|
||||||
cp ../.env.example .env
|
cp ../.env.example .env
|
||||||
if [ -n "${{ secrets.LANGSMITH_API_KEY }}" ]; then echo "LANGSMITH_API_KEY=${{ secrets.LANGSMITH_API_KEY }}" >> .env; fi
|
if [ -n "${{ secrets.LANGSMITH_API_KEY }}" ]; then echo "LANGSMITH_API_KEY=${{ secrets.LANGSMITH_API_KEY }}" >> .env; fi
|
||||||
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-h
|
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-h
|
||||||
|
echo "Finished starting up langgraph-test-h"
|
||||||
LANGGRAPH_VERSION=$(docker run --rm --entrypoint "" langgraph-test-h python -c "import sys; from importlib.metadata import version; v = version('langgraph'); print(v);")
|
LANGGRAPH_VERSION=$(docker run --rm --entrypoint "" langgraph-test-h python -c "import sys; from importlib.metadata import version; v = version('langgraph'); print(v);")
|
||||||
if [ "$LANGGRAPH_VERSION" != "1.0.0a2" ]; then
|
if [ "$LANGGRAPH_VERSION" != "1.0.2" ]; then
|
||||||
|
echo "LANGGRAPH_VERSION != 1.0.2; $LANGGRAPH_VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
LANGCHAIN_OPENAI_VERSION=$(docker run --rm --entrypoint "" langgraph-test-h python -c "import sys; from importlib.metadata import version; v = version('langchain-openai'); print(v);")
|
LANGCHAIN_OPENAI_VERSION=$(docker run --rm --entrypoint "" langgraph-test-h python -c "import sys; from importlib.metadata import version; v = version('langchain-openai'); print(v);")
|
||||||
if [ "$LANGCHAIN_OPENAI_VERSION" != "0.3.0" ]; then
|
if [ "$LANGCHAIN_OPENAI_VERSION" != "1.0.1" ]; then
|
||||||
|
echo "LANGCHAIN_OPENAI_VERSION != 1.0.1; $LANGCHAIN_OPENAI_VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
LANGCHAIN_ANTHROPIC_VERSION=$(docker run --rm --entrypoint "" langgraph-test-h python -c "import sys; from importlib.metadata import version; v = version('langchain-anthropic'); print(v);")
|
||||||
|
if [ "$LANGCHAIN_ANTHROPIC_VERSION" != "1.0.0a5" ]; then
|
||||||
|
echo "LANGCHAIN_ANTHROPIC_VERSION != 1.0.0a5; $LANGCHAIN_ANTHROPIC_VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and test prerelease reqs fail service
|
- name: Build and test prerelease reqs fail service
|
||||||
if: steps.changed-files.outputs.all
|
if: ${{ steps.changed-files.outputs.all && matrix.example.name == 'A' }}
|
||||||
working-directory: libs/cli/examples/graph_prerelease_reqs_fail
|
working-directory: libs/cli/examples/graph_prerelease_reqs_fail
|
||||||
run: |
|
run: |
|
||||||
langgraph build -t langgraph-test-i || [ $? -eq 1 ]
|
langgraph build -t langgraph-test-i || [ $? -eq 1 ]
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
filter: "${{ inputs.working-directory }}/**"
|
filter: "${{ inputs.working-directory }}/**"
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
run: uv sync --frozen --group dev
|
run: uv sync --frozen --group lint
|
||||||
|
|
||||||
- name: Get .mypy_cache to speed up mypy
|
- name: Get .mypy_cache to speed up mypy
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
@@ -74,7 +74,7 @@ jobs:
|
|||||||
- name: Install test dependencies
|
- name: Install test dependencies
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
run: uv sync --group dev
|
run: uv sync --group lint
|
||||||
|
|
||||||
- name: Get .mypy_cache_test to speed up mypy
|
- name: Get .mypy_cache_test to speed up mypy
|
||||||
if: steps.changed-files.outputs.all
|
if: steps.changed-files.outputs.all
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- "3.9"
|
|
||||||
- "3.10"
|
- "3.10"
|
||||||
- "3.11"
|
- "3.11"
|
||||||
- "3.12"
|
- "3.12"
|
||||||
- "3.13"
|
- "3.13"
|
||||||
|
- "3.14"
|
||||||
|
|
||||||
name: "test #${{ matrix.python-version }}"
|
name: "test #${{ matrix.python-version }}"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
run: uv sync --frozen --group dev
|
run: uv sync --frozen --group test --no-dev
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- "3.9"
|
|
||||||
- "3.10"
|
- "3.10"
|
||||||
- "3.11"
|
- "3.11"
|
||||||
- "3.12"
|
- "3.12"
|
||||||
- "3.13"
|
- "3.13"
|
||||||
|
- "3.14"
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: uv sync --frozen --group dev
|
run: uv sync --frozen --group test --no-dev
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref == 'refs/heads/main'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@@ -27,7 +26,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up Python $${ env.PYTHON_VERSION }}
|
- name: Set up Python $${ env.PYTHON_VERSION }}
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -49,7 +48,7 @@ jobs:
|
|||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
|
|
||||||
- name: Upload build
|
- name: Upload build
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: test-dist
|
name: test-dist
|
||||||
path: ${{ inputs.working-directory }}/dist/
|
path: ${{ inputs.working-directory }}/dist/
|
||||||
@@ -77,7 +76,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- uses: actions/download-artifact@v5
|
- uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: test-dist
|
name: test-dist
|
||||||
path: ${{ inputs.working-directory }}/dist/
|
path: ${{ inputs.working-directory }}/dist/
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- run: SHA=$(git rev-parse HEAD) && echo "SHA=$SHA" >> $GITHUB_ENV
|
- run: SHA=$(git rev-parse HEAD) && echo "SHA=$SHA" >> $GITHUB_ENV
|
||||||
- name: Set up Python 3.11
|
- name: Set up Python 3.11
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
cache-suffix: "bench"
|
cache-suffix: "bench"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: uv sync --group dev
|
run: uv sync --group test
|
||||||
- name: Run benchmarks
|
- name: Run benchmarks
|
||||||
run: OUTPUT=out/benchmark-baseline.json make -s benchmark
|
run: OUTPUT=out/benchmark-baseline.json make -s benchmark
|
||||||
- name: Save outputs
|
- name: Save outputs
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
format: json
|
format: json
|
||||||
- name: Set up Python 3.11
|
- name: Set up Python 3.11
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
cache-suffix: "bench"
|
cache-suffix: "bench"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: uv sync --group dev
|
run: uv sync --group test
|
||||||
- name: Download baseline
|
- name: Download baseline
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
name: Deploy Docs
|
name: Deploy Docs Redirects
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -23,18 +20,6 @@ defaults:
|
|||||||
working-directory: docs
|
working-directory: docs
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-changed-files:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
changed-files: ${{ steps.changed-files.outputs.added_modified }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- name: Get changed files
|
|
||||||
id: changed-files
|
|
||||||
uses: Ana06/get-changed-files@v2.3.0
|
|
||||||
with:
|
|
||||||
filter: "docs/docs/**"
|
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10 # Job will be cancelled if it runs for more than 10 minutes
|
timeout-minutes: 10 # Job will be cancelled if it runs for more than 10 minutes
|
||||||
@@ -46,7 +31,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -62,84 +47,21 @@ jobs:
|
|||||||
uv run pip install "git+https://${GITHUB_TOKEN}@github.com/langchain-ai/mkdocs-material-insiders.git"
|
uv run pip install "git+https://${GITHUB_TOKEN}@github.com/langchain-ai/mkdocs-material-insiders.git"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Run unit tests
|
|
||||||
# Run unit tests on the docs build pipeline
|
|
||||||
run: make tests
|
|
||||||
- name: Lint Docs
|
|
||||||
# This step lints the docs using the existing linting set up.
|
|
||||||
# It should be very fast and should not require any external services.
|
|
||||||
run: make lint-docs
|
|
||||||
- name: Build llms-text
|
- name: Build llms-text
|
||||||
run: make llms-text
|
run: make llms-text
|
||||||
- name: Build site
|
|
||||||
run: |
|
- name: Build site (redirects only)
|
||||||
# If this is main branch, then we want to download stats. we do this
|
run: make build-docs
|
||||||
# with the env variable DOWNLOAD_STATS=true
|
|
||||||
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
|
|
||||||
DOWNLOAD_STATS=true make build-docs
|
|
||||||
else
|
|
||||||
make build-docs
|
|
||||||
fi
|
|
||||||
env:
|
env:
|
||||||
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.MKDOCS_GIT_COMMITTERS_APIKEY }}
|
|
||||||
OPENAI_API_KEY: sf-proj-1234567890 # fake placeholder, shouldn't actually be used
|
OPENAI_API_KEY: sf-proj-1234567890 # fake placeholder, shouldn't actually be used
|
||||||
ANTHROPIC_API_KEY: sk-ant-api03-1234567890 # fake placeholder, shouldn't actually be used
|
ANTHROPIC_API_KEY: sk-ant-api03-1234567890 # fake placeholder, shouldn't actually be used
|
||||||
- name: Check links in notebooks
|
|
||||||
env:
|
|
||||||
LANGCHAIN_API_KEY: test
|
|
||||||
if: github.event_name == 'schedule'
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.event_name }}" == "schedule" ]; then
|
|
||||||
echo "Running link check on all HTML files matching notebooks in docs directory..."
|
|
||||||
uv run pytest -v \
|
|
||||||
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
|
|
||||||
--check-links-ignore "https://academy\.langchain\.com/.*" \
|
|
||||||
--check-links-ignore "https://x.com/.*" \
|
|
||||||
--check-links-ignore "https://twitter.com/.*" \
|
|
||||||
--check-links-ignore "https://github\.com/.*" \
|
|
||||||
--check-links-ignore "http://localhost:8123/.*" \
|
|
||||||
--check-links-ignore "http://localhost:2024.*" \
|
|
||||||
--check-links-ignore "http://127.0.0.1:.*" \
|
|
||||||
--check-links-ignore "/.*\.(ipynb|html)$" \
|
|
||||||
--check-links-ignore "https://python\.langchain\.com/.*" \
|
|
||||||
--check-links-ignore "https://openai\.com/.*" \
|
|
||||||
--check-links-ignore "https://www\.uber\.com/.*" \
|
|
||||||
--check-links-ignore "https://pepy\.tech/.*" \
|
|
||||||
--check-links-ignore "docs/docs/static/wordmark_*" \
|
|
||||||
--check-links $(find site -name "index.html" | grep -v 'storm/index.html')
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "Fetching changes from origin/main..."
|
|
||||||
git fetch origin main
|
|
||||||
echo "Checking for changed notebook files..."
|
|
||||||
CHANGED_FILES=$(git diff --name-only --diff-filter=d origin/main | grep 'docs/docs/.*\.ipynb$' | grep -v 'storm.ipynb' | sed -E 's|^docs/docs/|site/|; s/\.ipynb$/\/index.html/' || true)
|
|
||||||
echo "Changed files: ${CHANGED_FILES}"
|
|
||||||
if [ -n "${CHANGED_FILES}" ]; then
|
|
||||||
echo "Running link check on HTML files matching changed notebook files..."
|
|
||||||
uv run pytest -v \
|
|
||||||
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
|
|
||||||
--check-links-ignore "https://academy\.langchain\.com/.*" \
|
|
||||||
--check-links-ignore "http://localhost:8123/.*" \
|
|
||||||
--check-links-ignore "http://localhost:2024.*" \
|
|
||||||
--check-links-ignore "http://127.0.0.1:.*" \
|
|
||||||
--check-links-ignore "https://x.com/.*" \
|
|
||||||
--check-links-ignore "https://twitter.com/.*" \
|
|
||||||
--check-links-ignore "https://github\.com/.*" \
|
|
||||||
--check-links-ignore "/.*\.(ipynb|html)$" \
|
|
||||||
--check-links-ignore "docs/docs/static/wordmark_*" \
|
|
||||||
--check-links ${CHANGED_FILES} \
|
|
||||||
|| ([ $? = 5 ] && exit 0 || exit $?)
|
|
||||||
else
|
|
||||||
echo "No notebook files changed."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Configure GitHub Pages
|
- name: Configure GitHub Pages
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
- name: Upload Pages Artifact
|
- name: Upload Pages Artifact
|
||||||
# if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
uses: actions/upload-pages-artifact@v4
|
uses: actions/upload-pages-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ./docs/site/
|
path: ./docs/site/
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref == 'refs/heads/main'
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@@ -29,7 +28,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -51,7 +50,7 @@ jobs:
|
|||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
|
|
||||||
- name: Upload build
|
- name: Upload build
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: ${{ inputs.working-directory }}/dist/
|
path: ${{ inputs.working-directory }}/dist/
|
||||||
@@ -174,7 +173,7 @@ jobs:
|
|||||||
# used in the real world.
|
# used in the real world.
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
@@ -222,7 +221,7 @@ jobs:
|
|||||||
uv run python -c "import $IMPORT_NAME; print(dir($IMPORT_NAME))"
|
uv run python -c "import $IMPORT_NAME; print(dir($IMPORT_NAME))"
|
||||||
|
|
||||||
- name: Import test dependencies
|
- name: Import test dependencies
|
||||||
run: uv sync --group dev
|
run: uv sync --group test
|
||||||
working-directory: ${{ inputs.working-directory }}
|
working-directory: ${{ inputs.working-directory }}
|
||||||
|
|
||||||
# Overwrite the local version of the package with the test PyPI version.
|
# Overwrite the local version of the package with the test PyPI version.
|
||||||
@@ -264,13 +263,13 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
cache-suffix: "release"
|
cache-suffix: "release"
|
||||||
|
|
||||||
- uses: actions/download-artifact@v5
|
- uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: ${{ inputs.working-directory }}/dist/
|
path: ${{ inputs.working-directory }}/dist/
|
||||||
@@ -305,13 +304,13 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ env.PYTHON_VERSION }}
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
cache-suffix: "release"
|
cache-suffix: "release"
|
||||||
|
|
||||||
- uses: actions/download-artifact@v5
|
- uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: ${{ inputs.working-directory }}/dist/
|
path: ${{ inputs.working-directory }}/dist/
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Python + Poetry
|
- name: Set up Python + Poetry
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Set up uv
|
- name: Set up uv
|
||||||
uses: astral-sh/setup-uv@v6
|
uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
# use minimum supported Python version
|
# use minimum supported Python version
|
||||||
python-version: "3.9"
|
python-version: "3.10"
|
||||||
enable-cache: true
|
enable-cache: true
|
||||||
cache-suffix: "uv-lock-upgrade"
|
cache-suffix: "uv-lock-upgrade"
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Below is a high-level overview:
|
|||||||
- **langgraph** – core framework for building stateful, multi-actor agents.
|
- **langgraph** – core framework for building stateful, multi-actor agents.
|
||||||
- **prebuilt** – high-level APIs for creating and running agents and tools.
|
- **prebuilt** – high-level APIs for creating and running agents and tools.
|
||||||
- **sdk-js** – JS/TS SDK for interacting with the LangGraph REST API.
|
- **sdk-js** – JS/TS SDK for interacting with the LangGraph REST API.
|
||||||
- **sdk-py** – Python SDK for the LangGraph Platform API.
|
- **sdk-py** – Python SDK for the LangGraph Server API.
|
||||||
|
|
||||||
### Dependency map
|
### Dependency map
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -277,9 +277,9 @@ def my_function(arg1: int, arg2: str) -> float:
|
|||||||
Examples:
|
Examples:
|
||||||
This is a section for examples of how to use the function.
|
This is a section for examples of how to use the function.
|
||||||
|
|
||||||
.. code-block:: python
|
```python
|
||||||
|
my_function(1, "hello")
|
||||||
my_function(1, "hello")
|
\```
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
arg1: This is a description of arg1. We do not need to specify the type since
|
arg1: This is a description of arg1. We do not need to specify the type since
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ LangGraph provides low-level supporting infrastructure for *any* long-running, s
|
|||||||
While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. To improve your LLM application development, pair LangGraph with:
|
While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. To improve your LLM application development, pair LangGraph with:
|
||||||
|
|
||||||
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
||||||
- [LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||||
- [LangChain](https://python.langchain.com/docs/introduction/) – Provides integrations and composable components to streamline LLM application development.
|
- [LangChain](https://docs.langchain.com/oss/python/langchain/overview) – Provides integrations and composable components to streamline LLM application development.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
||||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
## Acknowledgements
|
## 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.
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def _transform_link(
|
def _transform_link(
|
||||||
link_name: str, scope: str, file_path: str, line_number: int, custom_title: Optional[str] = None
|
link_name: str,
|
||||||
|
scope: str,
|
||||||
|
file_path: str,
|
||||||
|
line_number: int,
|
||||||
|
custom_title: Optional[str] = None,
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
"""Transform a cross-reference link based on the current scope.
|
"""Transform a cross-reference link based on the current scope.
|
||||||
|
|
||||||
@@ -38,7 +42,7 @@ def _transform_link(
|
|||||||
scope: The current scope context ("global", "python", "js", etc.).
|
scope: The current scope context ("global", "python", "js", etc.).
|
||||||
file_path: The file path for error reporting.
|
file_path: The file path for error reporting.
|
||||||
line_number: The line number for error reporting.
|
line_number: The line number for error reporting.
|
||||||
custom_title: Optional custom title for the link. If None, uses link_name.
|
custom_title: Optional custom title for the link. If `None`, uses link_name.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A formatted markdown link if the link is found in the scope mapping,
|
A formatted markdown link if the link is found in the scope mapping,
|
||||||
@@ -117,7 +121,9 @@ CROSS_REFERENCE_PATTERN = re.compile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _replace_autolinks(markdown: str, file_path: str, *, default_scope: str = "python") -> str:
|
def _replace_autolinks(
|
||||||
|
markdown: str, file_path: str, *, default_scope: str = "python"
|
||||||
|
) -> str:
|
||||||
"""Preprocess markdown lines to handle @[links] with conditional fence scopes.
|
"""Preprocess markdown lines to handle @[links] with conditional fence scopes.
|
||||||
|
|
||||||
This function processes markdown content to transform @[link_name] references
|
This function processes markdown content to transform @[link_name] references
|
||||||
@@ -169,7 +175,7 @@ def _replace_autolinks(markdown: str, file_path: str, *, default_scope: str = "p
|
|||||||
# This is @[ref] format
|
# This is @[ref] format
|
||||||
link_name = match.group("link_name")
|
link_name = match.group("link_name")
|
||||||
custom_title = None
|
custom_title = None
|
||||||
|
|
||||||
transformed = _transform_link(
|
transformed = _transform_link(
|
||||||
link_name, current_scope, file_path, line_number, custom_title
|
link_name, current_scope, file_path, line_number, custom_title
|
||||||
)
|
)
|
||||||
|
|||||||
Binary file not shown.
@@ -2108,9 +2108,9 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"hono@npm:^4.5.4":
|
"hono@npm:^4.5.4":
|
||||||
version: 4.9.7
|
version: 4.10.3
|
||||||
resolution: "hono@npm:4.9.7"
|
resolution: "hono@npm:4.10.3"
|
||||||
checksum: 10c0/089184660a9211ea216ab95bafa45260e371651cb019db49828064b7982b0ae61cc3c4715324bfeb9037aa2460c39ffa2c91d84ad0c8d500fa77cbcc7fc07a8f
|
checksum: 10c0/bdcc4c7066c74ba7cfa63ed6550768a0f43a420286c8f8f74b7012ea4901b8b06778fa8e98264b46f1a86920f056b7ede1f07814da4934912f9945def4977c29
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
+448
-170
@@ -27,185 +27,413 @@ DISABLED = os.getenv("DISABLE_NOTEBOOK_CONVERT") in ("1", "true", "True")
|
|||||||
|
|
||||||
REDIRECT_MAP = {
|
REDIRECT_MAP = {
|
||||||
# lib redirects
|
# lib redirects
|
||||||
"how-tos/stream-values.ipynb": "how-tos/streaming.md#stream-graph-state",
|
"how-tos/stream-values.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/stream-updates.ipynb": "how-tos/streaming.md#stream-graph-state",
|
"how-tos/stream-updates.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/streaming-content.ipynb": "how-tos/streaming.md",
|
"how-tos/streaming-content.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/stream-multiple.ipynb": "how-tos/streaming.md#stream-multiple-nodes",
|
"how-tos/stream-multiple.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/streaming-tokens-without-langchain.ipynb": "how-tos/streaming.md#use-with-any-llm",
|
"how-tos/streaming-tokens-without-langchain.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/streaming-from-final-node.ipynb": "how-tos/streaming-specific-nodes.ipynb",
|
"how-tos/streaming-from-final-node.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"how-tos/streaming-events-from-within-tools-without-langchain.ipynb": "how-tos/streaming-events-from-within-tools.ipynb#example-without-langchain",
|
"how-tos/streaming-events-from-within-tools-without-langchain.ipynb": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
# graph-api
|
# graph-api
|
||||||
"how-tos/state-reducers.ipynb": "how-tos/graph-api.md#define-and-update-state",
|
"how-tos/state-reducers.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#define-and-update-state",
|
||||||
"how-tos/sequence.ipynb": "how-tos/graph-api.md#create-a-sequence-of-steps",
|
"how-tos/sequence.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#create-a-sequence-of-steps",
|
||||||
"how-tos/branching.ipynb": "how-tos/graph-api.md#create-branches",
|
"how-tos/branching.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#create-branches",
|
||||||
"how-tos/recursion-limit.ipynb": "how-tos/graph-api.md#create-and-control-loops",
|
"how-tos/recursion-limit.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#create-and-control-loops",
|
||||||
"how-tos/visualization.ipynb": "how-tos/graph-api.md#visualize-your-graph",
|
"how-tos/visualization.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#visualize-your-graph",
|
||||||
"how-tos/input_output_schema.ipynb": "how-tos/graph-api.md#define-input-and-output-schemas",
|
"how-tos/input_output_schema.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#define-input-and-output-schemas",
|
||||||
"how-tos/pass_private_state.ipynb": "how-tos/graph-api.md#pass-private-state-between-nodes",
|
"how-tos/pass_private_state.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#pass-private-state-between-nodes",
|
||||||
"how-tos/state-model.ipynb": "how-tos/graph-api.md#use-pydantic-models-for-graph-state",
|
"how-tos/state-model.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#use-pydantic-models-for-graph-state",
|
||||||
"how-tos/map-reduce.ipynb": "how-tos/graph-api.md#map-reduce-and-the-send-api",
|
"how-tos/map-reduce.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#map-reduce-and-the-send-api",
|
||||||
"how-tos/command.ipynb": "how-tos/graph-api.md#combine-control-flow-and-state-updates-with-command",
|
"how-tos/command.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#combine-control-flow-and-state-updates-with-command",
|
||||||
"how-tos/configuration.ipynb": "how-tos/graph-api.md#add-runtime-configuration",
|
"how-tos/configuration.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#add-runtime-configuration",
|
||||||
"how-tos/node-retries.ipynb": "how-tos/graph-api.md#add-retry-policies",
|
"how-tos/node-retries.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#add-retry-policies",
|
||||||
"how-tos/return-when-recursion-limit-hits.ipynb": "how-tos/graph-api.md#impose-a-recursion-limit",
|
"how-tos/return-when-recursion-limit-hits.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#impose-a-recursion-limit",
|
||||||
"how-tos/async.ipynb": "how-tos/graph-api.md#async",
|
"how-tos/async.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api#async",
|
||||||
# memory how-tos
|
# memory how-tos
|
||||||
"how-tos/memory/manage-conversation-history.ipynb": "how-tos/memory/add-memory.md",
|
"how-tos/memory/manage-conversation-history.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
"how-tos/memory/delete-messages.ipynb": "how-tos/memory/add-memory.md#delete-messages",
|
"how-tos/memory/delete-messages.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#delete-messages",
|
||||||
"how-tos/memory/add-summary-conversation-history.ipynb": "how-tos/memory/add-memory.md#summarize-messages",
|
"how-tos/memory/add-summary-conversation-history.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#summarize-messages",
|
||||||
"how-tos/memory.ipynb": "how-tos/memory/add-memory.md",
|
"how-tos/memory.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
"agents/memory.ipynb": "how-tos/memory/add-memory.md",
|
"agents/memory.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
# subgraph how-tos
|
# subgraph how-tos
|
||||||
"how-tos/subgraph-transform-state.ipynb": "how-tos/subgraph.md#different-state-schemas",
|
"how-tos/subgraph-transform-state.ipynb": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs#different-state-schemas",
|
||||||
"how-tos/subgraphs-manage-state.ipynb": "how-tos/subgraph.md#add-persistence",
|
"how-tos/subgraphs-manage-state.ipynb": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs#add-persistence",
|
||||||
# persistence how-tos
|
# persistence how-tos
|
||||||
"how-tos/persistence_postgres.ipynb": "how-tos/memory/add-memory.md#use-in-production",
|
"how-tos/persistence_postgres.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#use-in-production",
|
||||||
"how-tos/persistence_mongodb.ipynb": "how-tos/memory/add-memory.md#use-in-production",
|
"how-tos/persistence_mongodb.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#use-in-production",
|
||||||
"how-tos/persistence_redis.ipynb": "how-tos/memory/add-memory.md#use-in-production",
|
"how-tos/persistence_redis.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#use-in-production",
|
||||||
"how-tos/subgraph-persistence.ipynb": "how-tos/memory/add-memory.md#use-with-subgraphs",
|
"how-tos/subgraph-persistence.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#use-with-subgraphs",
|
||||||
"how-tos/cross-thread-persistence.ipynb": "how-tos/memory/add-memory.md#add-long-term-memory",
|
"how-tos/cross-thread-persistence.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory#add-long-term-memory",
|
||||||
"cloud/how-tos/copy_threads": "cloud/how-tos/use_threads",
|
"cloud/how-tos/copy_threads": "https://docs.langchain.com/langsmith/use-threads",
|
||||||
"cloud/how-tos/check-thread-status": "cloud/how-tos/use_threads",
|
"cloud/how-tos/check-thread-status": "https://docs.langchain.com/langsmith/use-threads",
|
||||||
"cloud/concepts/threads.md": "concepts/persistence.md#threads",
|
"cloud/concepts/threads.md": "https://docs.langchain.com/oss/python/langgraph/persistence#threads",
|
||||||
"how-tos/persistence.ipynb": "how-tos/memory/add-memory.md",
|
"how-tos/persistence.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
# tool calling how-tos
|
# tool calling how-tos
|
||||||
"how-tos/tool-calling-errors.ipynb": "how-tos/tool-calling.ipynb#handle-errors",
|
"how-tos/tool-calling-errors.ipynb": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
"how-tos/pass-config-to-tools.ipynb": "how-tos/tool-calling.ipynb#access-config",
|
"how-tos/pass-config-to-tools.ipynb": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
"how-tos/pass-run-time-values-to-tools.ipynb": "how-tos/tool-calling.ipynb#read-state",
|
"how-tos/pass-run-time-values-to-tools.ipynb": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
"how-tos/update-state-from-tools.ipynb": "how-tos/tool-calling.ipynb#update-state",
|
"how-tos/update-state-from-tools.ipynb": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
"agents/tools.md": "how-tos/tool-calling.md",
|
"agents/tools.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
# multi-agent how-tos
|
# multi-agent how-tos
|
||||||
"how-tos/agent-handoffs.ipynb": "how-tos/multi_agent.md#handoffs",
|
"how-tos/agent-handoffs.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
"how-tos/multi-agent-network.ipynb": "how-tos/multi_agent.md#use-in-a-multi-agent-system",
|
"how-tos/multi-agent-network.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
"how-tos/multi-agent-multi-turn-convo.ipynb": "how-tos/multi_agent.md#multi-turn-conversation",
|
"how-tos/multi-agent-multi-turn-convo.ipynb": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
# cloud redirects
|
# cloud redirects
|
||||||
"cloud/index.md": "index.md",
|
"cloud/index.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
"cloud/how-tos/index.md": "concepts/langgraph_platform",
|
"cloud/how-tos/index.md": "https://docs.langchain.com/langsmith/home",
|
||||||
"cloud/concepts/api.md": "concepts/langgraph_server.md",
|
"cloud/concepts/api.md": "https://docs.langchain.com/langsmith/agent-server",
|
||||||
"cloud/concepts/cloud.md": "concepts/langgraph_cloud.md",
|
"cloud/concepts/cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
"cloud/faq/studio.md": "concepts/langgraph_studio.md#studio-faqs",
|
"cloud/faq/studio.md": "https://docs.langchain.com/langsmith/studio",
|
||||||
"cloud/how-tos/human_in_the_loop_edit_state.md": "cloud/how-tos/add-human-in-the-loop.md",
|
"cloud/how-tos/human_in_the_loop_edit_state.md": "https://docs.langchain.com/langsmith/add-human-in-the-loop",
|
||||||
"cloud/how-tos/human_in_the_loop_user_input.md": "cloud/how-tos/add-human-in-the-loop.md",
|
"cloud/how-tos/human_in_the_loop_user_input.md": "https://docs.langchain.com/langsmith/add-human-in-the-loop",
|
||||||
"concepts/platform_architecture.md": "concepts/langgraph_cloud#architecture",
|
"concepts/platform_architecture.md": "https://docs.langchain.com/langsmith/cloud#architecture",
|
||||||
# cloud streaming redirects
|
# cloud streaming redirects
|
||||||
"cloud/how-tos/stream_values.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_values.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/how-tos/stream_updates.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_updates.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/how-tos/stream_messages.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_messages.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/how-tos/stream_events.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_events.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/how-tos/stream_debug.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_debug.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/how-tos/stream_multiple.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/stream_multiple.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/concepts/streaming.md": "concepts/streaming.md",
|
"cloud/concepts/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
"agents/streaming.md": "how-tos/streaming.md",
|
"agents/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
# prebuilt redirects
|
# prebuilt redirects
|
||||||
"how-tos/create-react-agent.ipynb": "agents/agents.md#basic-configuration",
|
"how-tos/create-react-agent.ipynb": "https://docs.langchain.com/oss/python/langchain/agents#basic-configuration",
|
||||||
"how-tos/create-react-agent-memory.ipynb": "agents/memory.md",
|
"how-tos/create-react-agent-memory.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
"how-tos/create-react-agent-system-prompt.ipynb": "agents/context.md#prompts",
|
"how-tos/create-react-agent-system-prompt.ipynb": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
"how-tos/create-react-agent-structured-output.ipynb": "agents/agents.md#structured-output",
|
"how-tos/create-react-agent-structured-output.ipynb": "https://docs.langchain.com/oss/python/langchain/agents#structured-output",
|
||||||
# misc
|
# misc
|
||||||
"prebuilt.md": "agents/prebuilt.md",
|
"prebuilt.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
"reference/prebuilt.md": "reference/agents.md",
|
"reference/prebuilt.md": "https://reference.langchain.com/python/langgraph/agents/",
|
||||||
"concepts/high_level.md": "index.md",
|
"concepts/high_level.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
"concepts/index.md": "index.md",
|
"concepts/index.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
"concepts/v0-human-in-the-loop.md": "concepts/human-in-the-loop.md",
|
"concepts/v0-human-in-the-loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"how-tos/index.md": "index.md",
|
"how-tos/index.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
"tutorials/introduction.ipynb": "concepts/why-langgraph.md",
|
"tutorials/introduction.ipynb": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
"agents/deployment.md": "tutorials/langgraph-platform/local-server.md",
|
"agents/deployment.md": "https://docs.langchain.com/oss/python/langgraph/local-server",
|
||||||
# deployment redirects
|
# deployment redirects
|
||||||
"how-tos/deploy-self-hosted.md": "cloud/deployment/self_hosted_data_plane.md",
|
"how-tos/deploy-self-hosted.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
"concepts/self_hosted.md": "concepts/langgraph_self_hosted_data_plane.md",
|
"concepts/self_hosted.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
"tutorials/deployment.md": "concepts/deployment_options.md",
|
"tutorials/deployment.md": "https://docs.langchain.com/langsmith/deployments",
|
||||||
# assistant redirects
|
# assistant redirects
|
||||||
"cloud/how-tos/assistant_versioning.md": "cloud/how-tos/configuration_cloud.md",
|
"cloud/how-tos/assistant_versioning.md": "https://docs.langchain.com/langsmith/configuration-cloud",
|
||||||
"cloud/concepts/runs.md": "concepts/assistants.md#execution",
|
"cloud/concepts/runs.md": "https://docs.langchain.com/langsmith/assistants#execution",
|
||||||
# hitl redirects
|
# hitl redirects
|
||||||
"how-tos/wait-user-input-functional.ipynb": "how-tos/use-functional-api.md",
|
"how-tos/wait-user-input-functional.ipynb": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
"how-tos/review-tool-calls-functional.ipynb": "how-tos/use-functional-api.md",
|
"how-tos/review-tool-calls-functional.ipynb": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
"how-tos/create-react-agent-hitl.ipynb": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
|
"how-tos/create-react-agent-hitl.ipynb": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"agents/human-in-the-loop.md": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
|
"agents/human-in-the-loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"how-tos/human_in_the_loop/dynamic_breakpoints.ipynb": "how-tos/human_in_the_loop/breakpoints.md",
|
"how-tos/human_in_the_loop/dynamic_breakpoints.ipynb": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"concepts/breakpoints.md": "concepts/human_in_the_loop.md",
|
"concepts/breakpoints.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"how-tos/human_in_the_loop/breakpoints.md": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
|
"how-tos/human_in_the_loop/breakpoints.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
"cloud/how-tos/human_in_the_loop_breakpoint.md": "cloud/how-tos/add-human-in-the-loop.md",
|
"cloud/how-tos/human_in_the_loop_breakpoint.md": "https://docs.langchain.com/langsmith/add-human-in-the-loop",
|
||||||
"how-tos/human_in_the_loop/edit-graph-state.ipynb": "how-tos/human_in_the_loop/time-travel.md",
|
"how-tos/human_in_the_loop/edit-graph-state.ipynb": "https://docs.langchain.com/oss/python/langgraph/use-time-travel",
|
||||||
|
|
||||||
# LGP mintlify migration redirects
|
# LGP mintlify migration redirects
|
||||||
"tutorials/auth/getting_started.md": "https://docs.langchain.com/langgraph-platform/auth",
|
"tutorials/auth/getting_started.md": "https://docs.langchain.com/langsmith/auth",
|
||||||
"tutorials/auth/resource_auth.md": "https://docs.langchain.com/langgraph-platform/resource-auth",
|
"tutorials/auth/resource_auth.md": "https://docs.langchain.com/langsmith/resource-auth",
|
||||||
"tutorials/auth/add_auth_server.md": "https://docs.langchain.com/langgraph-platform/add-auth-server",
|
"tutorials/auth/add_auth_server.md": "https://docs.langchain.com/langsmith/add-auth-server",
|
||||||
"how-tos/use-remote-graph.md": "https://docs.langchain.com/langgraph-platform/use-remote-graph",
|
"how-tos/use-remote-graph.md": "https://docs.langchain.com/langsmith/use-remote-graph",
|
||||||
"how-tos/autogen-integration.md": "https://docs.langchain.com/langgraph-platform/autogen-integration",
|
"how-tos/autogen-integration.md": "https://docs.langchain.com/langsmith/autogen-integration",
|
||||||
"cloud/how-tos/use_stream_react.md": "https://docs.langchain.com/langgraph-platform/use-stream-react",
|
"cloud/how-tos/use_stream_react.md": "https://docs.langchain.com/langsmith/use-stream-react",
|
||||||
"cloud/how-tos/generative_ui_react.md": "https://docs.langchain.com/langgraph-platform/generative-ui-react",
|
"cloud/how-tos/generative_ui_react.md": "https://docs.langchain.com/langsmith/generative-ui-react",
|
||||||
"concepts/langgraph_platform.md": "https://docs.langchain.com/langgraph-platform/index",
|
"concepts/langgraph_platform.md": "https://docs.langchain.com/langsmith/deployments",
|
||||||
"concepts/langgraph_components.md": "https://docs.langchain.com/langgraph-platform/components",
|
"concepts/langgraph_components.md": "https://docs.langchain.com/langsmith/components",
|
||||||
"concepts/langgraph_server.md": "https://docs.langchain.com/langgraph-platform/langgraph-server",
|
"concepts/langgraph_server.md": "https://docs.langchain.com/langsmith/agent-server",
|
||||||
"concepts/langgraph_data_plane.md": "https://docs.langchain.com/langgraph-platform/data-plane",
|
"concepts/langgraph_data_plane.md": "https://docs.langchain.com/langsmith/data-plane",
|
||||||
"concepts/langgraph_control_plane.md": "https://docs.langchain.com/langgraph-platform/control-plane",
|
"concepts/langgraph_control_plane.md": "https://docs.langchain.com/langsmith/control-plane",
|
||||||
"concepts/langgraph_cli.md": "https://docs.langchain.com/langgraph-platform/langgraph-cli",
|
"concepts/langgraph_cli.md": "https://docs.langchain.com/langsmith/cli",
|
||||||
"concepts/langgraph_studio.md": "https://docs.langchain.com/langgraph-platform/langgraph-studio",
|
"concepts/langgraph_studio.md": "https://docs.langchain.com/langsmith/studio",
|
||||||
"cloud/how-tos/studio/quick_start.md": "https://docs.langchain.com/langgraph-platform/quick-start-studio",
|
"cloud/how-tos/studio/quick_start.md": "https://docs.langchain.com/langsmith/quick-start-studio",
|
||||||
"cloud/how-tos/invoke_studio.md": "https://docs.langchain.com/langgraph-platform/use-studio#run-application",
|
"cloud/how-tos/invoke_studio.md": "https://docs.langchain.com/langsmith/use-studio#run-application",
|
||||||
"cloud/how-tos/studio/manage_assistants.md": "https://docs.langchain.com/langgraph-platform/use-studio#manage-assistants",
|
"cloud/how-tos/studio/manage_assistants.md": "https://docs.langchain.com/langsmith/use-studio#manage-assistants",
|
||||||
"cloud/how-tos/threads_studio.md": "https://docs.langchain.com/langgraph-platform/use-studio#manage-threads",
|
"cloud/how-tos/threads_studio.md": "https://docs.langchain.com/langsmith/use-studio#manage-threads",
|
||||||
"cloud/how-tos/iterate_graph_studio.md": "https://docs.langchain.com/langgraph-platform/observability-studio#iterate-on-prompts",
|
"cloud/how-tos/iterate_graph_studio.md": "https://docs.langchain.com/langsmith/observability-studio#iterate-on-prompts",
|
||||||
"cloud/how-tos/studio/run_evals.md": "https://docs.langchain.com/langgraph-platform/observability-studio#run-experiments-over-a-dataset",
|
"cloud/how-tos/studio/run_evals.md": "https://docs.langchain.com/langsmith/observability-studio#run-experiments-over-a-dataset",
|
||||||
"cloud/how-tos/clone_traces_studio.md": "https://docs.langchain.com/langgraph-platform/observability-studio#debug-langsmith-traces",
|
"cloud/how-tos/clone_traces_studio.md": "https://docs.langchain.com/langsmith/observability-studio#debug-langsmith-traces",
|
||||||
"cloud/how-tos/datasets_studio.md": "https://docs.langchain.com/langgraph-platform/observability-studio#add-node-to-dataset",
|
"cloud/how-tos/datasets_studio.md": "https://docs.langchain.com/langsmith/observability-studio#add-node-to-dataset",
|
||||||
"concepts/sdk.md": "https://docs.langchain.com/langgraph-platform/sdk",
|
"concepts/sdk.md": "https://docs.langchain.com/langsmith/sdk",
|
||||||
"concepts/plans.md": "https://docs.langchain.com/langgraph-platform/plans",
|
"concepts/plans.md": "https://langchain.com/pricing",
|
||||||
"concepts/application_structure.md": "https://docs.langchain.com/langgraph-platform/application-structure",
|
"concepts/application_structure.md": "https://docs.langchain.com/langsmith/application-structure",
|
||||||
"concepts/scalability_and_resilience.md": "https://docs.langchain.com/langgraph-platform/scalability-and-resilience",
|
"concepts/scalability_and_resilience.md": "https://docs.langchain.com/langsmith/scalability-and-resilience",
|
||||||
"concepts/auth.md": "https://docs.langchain.com/langgraph-platform/auth",
|
"concepts/auth.md": "https://docs.langchain.com/langsmith/authentication-methods",
|
||||||
"how-tos/auth/custom_auth.md": "https://docs.langchain.com/langgraph-platform/custom-auth",
|
"how-tos/auth/custom_auth.md": "https://docs.langchain.com/langsmith/custom-auth",
|
||||||
"how-tos/auth/openapi_security.md": "https://docs.langchain.com/langgraph-platform/openapi-security",
|
"how-tos/auth/openapi_security.md": "https://docs.langchain.com/langsmith/openapi-security",
|
||||||
"concepts/assistants.md": "https://docs.langchain.com/langgraph-platform/assistants",
|
"concepts/assistants.md": "https://docs.langchain.com/langsmith/assistants",
|
||||||
"cloud/how-tos/configuration_cloud.md": "https://docs.langchain.com/langgraph-platform/configuration-cloud",
|
"cloud/how-tos/configuration_cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
"cloud/how-tos/use_threads.md": "https://docs.langchain.com/langgraph-platform/use-threads",
|
"cloud/how-tos/use_threads.md": "https://docs.langchain.com/langsmith/use-threads",
|
||||||
"cloud/how-tos/background_run.md": "https://docs.langchain.com/langgraph-platform/background-run",
|
"cloud/how-tos/background_run.md": "https://docs.langchain.com/langsmith/background-run",
|
||||||
"cloud/how-tos/same-thread.md": "https://docs.langchain.com/langgraph-platform/same-thread",
|
"cloud/how-tos/same-thread.md": "https://docs.langchain.com/langsmith/same-thread",
|
||||||
"cloud/how-tos/stateless_runs.md": "https://docs.langchain.com/langgraph-platform/stateless-runs",
|
"cloud/how-tos/stateless_runs.md": "https://docs.langchain.com/langsmith/stateless-runs",
|
||||||
"cloud/how-tos/configurable_headers.md": "https://docs.langchain.com/langgraph-platform/configurable-headers",
|
"cloud/how-tos/configurable_headers.md": "https://docs.langchain.com/langsmith/configurable-headers",
|
||||||
"concepts/double_texting.md": "https://docs.langchain.com/langgraph-platform/double-texting",
|
"concepts/double_texting.md": "https://docs.langchain.com/langsmith/double-texting",
|
||||||
"cloud/how-tos/interrupt_concurrent.md": "https://docs.langchain.com/langgraph-platform/interrupt-concurrent",
|
"cloud/how-tos/interrupt_concurrent.md": "https://docs.langchain.com/langsmith/interrupt-concurrent",
|
||||||
"cloud/how-tos/rollback_concurrent.md": "https://docs.langchain.com/langgraph-platform/rollback-concurrent",
|
"cloud/how-tos/rollback_concurrent.md": "https://docs.langchain.com/langsmith/rollback-concurrent",
|
||||||
"cloud/how-tos/reject_concurrent.md": "https://docs.langchain.com/langgraph-platform/reject-concurrent",
|
"cloud/how-tos/reject_concurrent.md": "https://docs.langchain.com/langsmith/reject-concurrent",
|
||||||
"cloud/how-tos/enqueue_concurrent.md": "https://docs.langchain.com/langgraph-platform/enqueue-concurrent",
|
"cloud/how-tos/enqueue_concurrent.md": "https://docs.langchain.com/langsmith/enqueue-concurrent",
|
||||||
"cloud/concepts/webhooks.md": "https://docs.langchain.com/langgraph-platform/use-webhooks",
|
"cloud/concepts/webhooks.md": "https://docs.langchain.com/langsmith/use-webhooks",
|
||||||
"cloud/how-tos/webhooks.md": "https://docs.langchain.com/langgraph-platform/use-webhooks",
|
"cloud/how-tos/webhooks.md": "https://docs.langchain.com/langsmith/use-webhooks",
|
||||||
"cloud/concepts/cron_jobs.md": "https://docs.langchain.com/langgraph-platform/cron-jobs",
|
"cloud/concepts/cron_jobs.md": "https://docs.langchain.com/langsmith/cron-jobs",
|
||||||
"cloud/how-tos/cron_jobs.md": "https://docs.langchain.com/langgraph-platform/cron-jobs",
|
"cloud/how-tos/cron_jobs.md": "https://docs.langchain.com/langsmith/cron-jobs",
|
||||||
"how-tos/http/custom_lifespan.md": "https://docs.langchain.com/langgraph-platform/custom-lifespan",
|
"how-tos/http/custom_lifespan.md": "https://docs.langchain.com/langsmith/custom-lifespan",
|
||||||
"how-tos/http/custom_middleware.md": "https://docs.langchain.com/langgraph-platform/custom-middleware",
|
"how-tos/http/custom_middleware.md": "https://docs.langchain.com/langsmith/custom-middleware",
|
||||||
"how-tos/http/custom_routes.md": "https://docs.langchain.com/langgraph-platform/custom-routes",
|
"how-tos/http/custom_routes.md": "https://docs.langchain.com/langsmith/custom-routes",
|
||||||
"cloud/concepts/data_storage_and_privacy.md": "https://docs.langchain.com/langgraph-platform/data-storage-and-privacy",
|
"cloud/concepts/data_storage_and_privacy.md": "https://docs.langchain.com/langsmith/data-storage-and-privacy",
|
||||||
"cloud/deployment/semantic_search.md": "https://docs.langchain.com/langgraph-platform/semantic-search",
|
"cloud/deployment/semantic_search.md": "https://docs.langchain.com/langsmith/semantic-search",
|
||||||
"how-tos/ttl/configure_ttl.md": "https://docs.langchain.com/langgraph-platform/configure-ttl",
|
"how-tos/ttl/configure_ttl.md": "https://docs.langchain.com/langsmith/configure-ttl",
|
||||||
"concepts/deployment_options.md": "https://docs.langchain.com/langgraph-platform/deployment-options",
|
"concepts/deployment_options.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
"cloud/quick_start.md": "https://docs.langchain.com/langgraph-platform/deployment-quickstart",
|
"cloud/quick_start.md": "https://docs.langchain.com/langsmith/deployment-quickstart",
|
||||||
"cloud/deployment/setup.md": "https://docs.langchain.com/langgraph-platform/setup-app-requirements-txt",
|
"cloud/deployment/setup.md": "https://docs.langchain.com/langsmith/setup-app-requirements-txt",
|
||||||
"cloud/deployment/setup_pyproject.md": "https://docs.langchain.com/langgraph-platform/setup-pyproject",
|
"cloud/deployment/setup_pyproject.md": "https://docs.langchain.com/langsmith/setup-pyproject",
|
||||||
"cloud/deployment/setup_javascript.md": "https://docs.langchain.com/langgraph-platform/setup-javascript",
|
"cloud/deployment/setup_javascript.md": "https://docs.langchain.com/langsmith/setup-javascript",
|
||||||
"cloud/deployment/custom_docker.md": "https://docs.langchain.com/langgraph-platform/custom-docker",
|
"cloud/deployment/custom_docker.md": "https://docs.langchain.com/langsmith/custom-docker",
|
||||||
"cloud/deployment/graph_rebuild.md": "https://docs.langchain.com/langgraph-platform/graph-rebuild",
|
"cloud/deployment/graph_rebuild.md": "https://docs.langchain.com/langsmith/graph-rebuild",
|
||||||
"concepts/langgraph_cloud.md": "https://docs.langchain.com/langgraph-platform/cloud",
|
"concepts/langgraph_cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
"concepts/langgraph_self_hosted_data_plane.md": "https://docs.langchain.com/langgraph-platform/hybrid",
|
"concepts/langgraph_self_hosted_data_plane.md": "https://docs.langchain.com/langsmith/hybrid",
|
||||||
"concepts/langgraph_self_hosted_control_plane.md": "https://docs.langchain.com/langgraph-platform/self-hosted",
|
"concepts/langgraph_self_hosted_control_plane.md": "https://docs.langchain.com/langsmith/self-hosted",
|
||||||
"concepts/langgraph_standalone_container.md": "https://docs.langchain.com/langgraph-platform/self-hosted#standalone-server",
|
"concepts/langgraph_standalone_container.md": "https://docs.langchain.com/langsmith/self-hosted#standalone-server",
|
||||||
"cloud/deployment/cloud.md": "https://docs.langchain.com/langgraph-platform/cloud",
|
"cloud/deployment/cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
"cloud/deployment/self_hosted_data_plane.md": "https://docs.langchain.com/langgraph-platform/deploy-hybrid",
|
"cloud/deployment/self_hosted_data_plane.md": "https://docs.langchain.com/langsmith/deploy-hybrid",
|
||||||
"cloud/deployment/self_hosted_control_plane.md": "https://docs.langchain.com/langgraph-platform/deploy-self-hosted-full-platform",
|
"cloud/deployment/self_hosted_control_plane.md": "https://docs.langchain.com/langsmith/deploy-self-hosted-full-platform",
|
||||||
"cloud/deployment/standalone_container.md": "https://docs.langchain.com/langgraph-platform/deploy-standalone-server",
|
"cloud/deployment/standalone_container.md": "https://docs.langchain.com/langsmith/deploy-standalone-server",
|
||||||
"concepts/server-mcp.md": "https://docs.langchain.com/langgraph-platform/server-mcp",
|
"concepts/server-mcp.md": "https://docs.langchain.com/langsmith/server-mcp",
|
||||||
"cloud/how-tos/human_in_the_loop_time_travel.md": "https://docs.langchain.com/langgraph-platform/human-in-the-loop-time-travel",
|
"cloud/how-tos/human_in_the_loop_time_travel.md": "https://docs.langchain.com/langsmith/human-in-the-loop-time-travel",
|
||||||
"cloud/how-tos/add-human-in-the-loop.md": "https://docs.langchain.com/langgraph-platform/add-human-in-the-loop",
|
"cloud/how-tos/add-human-in-the-loop.md": "https://docs.langchain.com/langsmith/add-human-in-the-loop",
|
||||||
"cloud/deployment/egress.md": "https://docs.langchain.com/langgraph-platform/env-var",
|
"cloud/deployment/egress.md": "https://docs.langchain.com/langsmith/env-var",
|
||||||
"cloud/how-tos/streaming.md": "https://docs.langchain.com/langgraph-platform/streaming",
|
"cloud/how-tos/streaming.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
"cloud/reference/api/api_ref.md": "https://docs.langchain.com/langgraph-platform/server-api-ref",
|
"cloud/reference/api/api_ref.md": "https://docs.langchain.com/langsmith/server-api-ref",
|
||||||
"cloud/reference/langgraph_server_changelog.md": "https://docs.langchain.com/langgraph-platform/langgraph-server-changelog",
|
"cloud/reference/langgraph_server_changelog.md": "https://docs.langchain.com/langsmith/agent-server-changelog",
|
||||||
"cloud/reference/api/api_ref_control_plane.md": "https://docs.langchain.com/langgraph-platform/api-ref-control-plane",
|
"cloud/reference/api/api_ref_control_plane.md": "https://docs.langchain.com/langsmith/api-ref-control-plane",
|
||||||
"cloud/reference/cli.md": "https://docs.langchain.com/langgraph-platform/cli",
|
"cloud/reference/cli.md": "https://docs.langchain.com/langsmith/cli",
|
||||||
"cloud/reference/env_var.md": "https://docs.langchain.com/langgraph-platform/env-var",
|
"cloud/reference/env_var.md": "https://docs.langchain.com/langsmith/env-var",
|
||||||
"troubleshooting/studio.md": "https://docs.langchain.com/langgraph-platform/troubleshooting-studio",
|
"troubleshooting/studio.md": "https://docs.langchain.com/langsmith/troubleshooting-studio",
|
||||||
|
|
||||||
|
# LangGraph mintlify migration redirects
|
||||||
|
"index.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"agents/agents.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
|
"concepts/why-langgraph.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"tutorials/get-started/1-build-basic-chatbot.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/get-started/2-add-tools.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/get-started/3-add-memory.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/get-started/4-human-in-the-loop.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/get-started/5-customize-state.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/get-started/6-time-travel.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"tutorials/langsmith/local-server.md": "https://docs.langchain.com/oss/python/langgraph/local-server",
|
||||||
|
"tutorials/workflows.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"concepts/agentic_concepts.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"guides/index.md": "https://docs.langchain.com/oss/python/langchain/overview",
|
||||||
|
"agents/overview.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
|
"agents/run_agents.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"concepts/low_level.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"how-tos/graph-api.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"concepts/functional_api.md": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
|
"how-tos/use-functional-api.md": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
|
"concepts/pregel.md": "https://docs.langchain.com/oss/python/langgraph/pregel",
|
||||||
|
"concepts/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
|
"how-tos/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
|
"concepts/persistence.md": "https://docs.langchain.com/oss/python/langgraph/persistence",
|
||||||
|
"concepts/durable_execution.md": "https://docs.langchain.com/oss/python/langgraph/durable-execution",
|
||||||
|
"concepts/memory.md": "https://docs.langchain.com/oss/python/langgraph/memory",
|
||||||
|
"how-tos/memory/add-memory.md": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
|
"agents/context.md": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
|
"agents/models.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"concepts/tools.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"how-tos/tool-calling.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"concepts/human_in_the_loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
|
"how-tos/human_in_the_loop/add-human-in-the-loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
|
"concepts/time-travel.md": "https://docs.langchain.com/oss/python/langgraph/persistence",
|
||||||
|
"how-tos/human_in_the_loop/time-travel.md": "https://docs.langchain.com/oss/python/langgraph/use-time-travel",
|
||||||
|
"concepts/subgraphs.md": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs",
|
||||||
|
"how-tos/subgraph.md": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs",
|
||||||
|
"concepts/multi_agent.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"agents/multi-agent.md": "https://docs.langchain.com/oss/python/langchain/multi-agent",
|
||||||
|
"how-tos/multi_agent.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"concepts/mcp.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"agents/mcp.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"concepts/tracing.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"how-tos/enable-tracing.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"agents/evals.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"examples/index.md": "https://docs.langchain.com/oss/python/langgraph/case-studies",
|
||||||
|
"concepts/template_applications.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"tutorials/rag/langgraph_agentic_rag.md": "https://docs.langchain.com/oss/python/langgraph/agentic-rag",
|
||||||
|
"tutorials/multi_agent/agent_supervisor.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"tutorials/sql/sql-agent.md": "https://docs.langchain.com/oss/python/langgraph/sql-agent",
|
||||||
|
"agents/ui.md": "https://docs.langchain.com/oss/python/langgraph/ui",
|
||||||
|
"how-tos/run-id-langsmith.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"troubleshooting/errors/index.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"troubleshooting/errors/INVALID_CHAT_HISTORY.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_CHAT_HISTORY",
|
||||||
|
"troubleshooting/errors/INVALID_LICENSE.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"adopters.md": "https://docs.langchain.com/oss/python/langgraph/case-studies",
|
||||||
|
"concepts/faq.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"agents/prebuilt.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
|
"reference/index.md": "https://reference.langchain.com/python/langgraph/",
|
||||||
|
"reference/graphs.md": "https://reference.langchain.com/python/langgraph/graphs/",
|
||||||
|
"reference/func.md": "https://reference.langchain.com/python/langgraph/func/",
|
||||||
|
"reference/pregel.md": "https://reference.langchain.com/python/langgraph/pregel/",
|
||||||
|
"reference/checkpoints.md": "https://reference.langchain.com/python/langgraph/checkpoints/",
|
||||||
|
"reference/store.md": "https://reference.langchain.com/python/langgraph/store/",
|
||||||
|
"reference/cache.md": "https://reference.langchain.com/python/langgraph/cache/",
|
||||||
|
"reference/types.md": "https://reference.langchain.com/python/langgraph/types/",
|
||||||
|
"reference/runtime.md": "https://reference.langchain.com/python/langgraph/runtime/",
|
||||||
|
"reference/config.md": "https://reference.langchain.com/python/langgraph/config/",
|
||||||
|
"reference/errors.md": "https://reference.langchain.com/python/langgraph/errors/",
|
||||||
|
"reference/constants.md": "https://reference.langchain.com/python/langgraph/constants/",
|
||||||
|
"reference/channels.md": "https://reference.langchain.com/python/langgraph/channels/",
|
||||||
|
"reference/agents.md": "https://reference.langchain.com/python/langgraph/agents/",
|
||||||
|
"reference/supervisor.md": "https://reference.langchain.com/python/langgraph/supervisor/",
|
||||||
|
"reference/swarm.md": "https://reference.langchain.com/python/langgraph/swarm/",
|
||||||
|
"reference/mcp.md": "https://reference.langchain.com/python/langgraph/mcp/",
|
||||||
|
"cloud/reference/sdk/python_sdk_ref.md": "https://reference.langchain.com/python/platform/python_sdk/",
|
||||||
|
"reference/remote_graph.md": "https://reference.langchain.com/python/platform/remote_graph/",
|
||||||
|
|
||||||
|
# additional exclude-search entries from mkdocs.yml
|
||||||
|
"additional-resources/index.md": "https://docs.langchain.com/oss/python/langchain/overview",
|
||||||
|
"cloud/concepts/cron_jobs.md": "https://docs.langchain.com/langsmith/cron-jobs",
|
||||||
|
"cloud/concepts/data_storage_and_privacy.md": "https://docs.langchain.com/langsmith/data-storage-and-privacy",
|
||||||
|
"cloud/concepts/webhooks.md": "https://docs.langchain.com/langsmith/use-webhooks",
|
||||||
|
"cloud/deployment/cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
|
"cloud/deployment/custom_docker.md": "https://docs.langchain.com/langsmith/custom-docker",
|
||||||
|
"cloud/deployment/egress.md": "https://docs.langchain.com/langsmith/env-var",
|
||||||
|
"cloud/deployment/graph_rebuild.md": "https://docs.langchain.com/langsmith/graph-rebuild",
|
||||||
|
"cloud/deployment/self_hosted_control_plane.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
|
"cloud/deployment/self_hosted_data_plane.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
|
"cloud/deployment/semantic_search.md": "https://docs.langchain.com/langsmith/semantic-search",
|
||||||
|
"cloud/deployment/setup_javascript.md": "https://docs.langchain.com/langsmith/setup-javascript",
|
||||||
|
"cloud/deployment/setup_pyproject.md": "https://docs.langchain.com/langsmith/setup-pyproject",
|
||||||
|
"cloud/deployment/setup.md": "https://docs.langchain.com/langsmith/setup-app-requirements-txt",
|
||||||
|
"cloud/deployment/standalone_container.md": "https://docs.langchain.com/langsmith/docker",
|
||||||
|
"cloud/how-tos/add-human-in-the-loop.md": "https://docs.langchain.com/langsmith/add-human-in-the-loop",
|
||||||
|
"cloud/how-tos/background_run.md": "https://docs.langchain.com/langsmith/background-run",
|
||||||
|
"cloud/how-tos/clone_traces_studio.md": "https://docs.langchain.com/langsmith/observability",
|
||||||
|
"cloud/how-tos/configurable_headers.md": "https://docs.langchain.com/langsmith/configurable-headers",
|
||||||
|
"cloud/how-tos/configuration_cloud.md": "https://docs.langchain.com/langsmith/configuration-cloud",
|
||||||
|
"cloud/how-tos/cron_jobs.md": "https://docs.langchain.com/langsmith/cron-jobs",
|
||||||
|
"cloud/how-tos/datasets_studio.md": "https://docs.langchain.com/langsmith/use-studio",
|
||||||
|
"cloud/how-tos/enqueue_concurrent.md": "https://docs.langchain.com/langsmith/enqueue-concurrent",
|
||||||
|
"cloud/how-tos/generative_ui_react.md": "https://docs.langchain.com/langsmith/generative-ui-react",
|
||||||
|
"cloud/how-tos/human_in_the_loop_time_travel.md": "https://docs.langchain.com/langsmith/human-in-the-loop-time-travel",
|
||||||
|
"cloud/how-tos/interrupt_concurrent.md": "https://docs.langchain.com/langsmith/interrupt-concurrent",
|
||||||
|
"cloud/how-tos/invoke_studio.md": "https://docs.langchain.com/langsmith/use-studio",
|
||||||
|
"cloud/how-tos/iterate_graph_studio.md": "https://docs.langchain.com/langsmith/use-studio",
|
||||||
|
"cloud/how-tos/reject_concurrent.md": "https://docs.langchain.com/langsmith/reject-concurrent",
|
||||||
|
"cloud/how-tos/rollback_concurrent.md": "https://docs.langchain.com/langsmith/rollback-concurrent",
|
||||||
|
"cloud/how-tos/same-thread.md": "https://docs.langchain.com/langsmith/same-thread",
|
||||||
|
"cloud/how-tos/stateless_runs.md": "https://docs.langchain.com/langsmith/stateless-runs",
|
||||||
|
"cloud/how-tos/streaming.md": "https://docs.langchain.com/langsmith/streaming",
|
||||||
|
"cloud/how-tos/studio/manage_assistants.md": "https://docs.langchain.com/langsmith/use-studio",
|
||||||
|
"cloud/how-tos/studio/quick_start.md": "https://docs.langchain.com/langsmith/quick-start-studio",
|
||||||
|
"cloud/how-tos/studio/run_evals.md": "https://docs.langchain.com/langsmith/observability",
|
||||||
|
"cloud/how-tos/threads_studio.md": "https://docs.langchain.com/langsmith/use-threads",
|
||||||
|
"cloud/how-tos/use_stream_react.md": "https://docs.langchain.com/langsmith/use-stream-react",
|
||||||
|
"cloud/how-tos/use_threads.md": "https://docs.langchain.com/langsmith/use-threads",
|
||||||
|
"cloud/how-tos/webhooks.md": "https://docs.langchain.com/langsmith/use-webhooks",
|
||||||
|
"cloud/quick_start.md": "https://docs.langchain.com/langsmith/deployment-quickstart",
|
||||||
|
"cloud/reference/api/api_ref_control_plane.md": "https://docs.langchain.com/langsmith/api-ref-control-plane",
|
||||||
|
"cloud/reference/api/api_ref.md": "https://docs.langchain.com/langsmith/server-api-ref",
|
||||||
|
"cloud/reference/cli.md": "https://docs.langchain.com/langsmith/cli",
|
||||||
|
"cloud/reference/env_var.md": "https://docs.langchain.com/langsmith/env-var",
|
||||||
|
"cloud/reference/langgraph_server_changelog.md": "https://docs.langchain.com/langsmith/agent-server-changelog",
|
||||||
|
"cloud/reference/sdk/js_ts_sdk_ref.md": "https://reference.langchain.com/javascript/modules/langsmith.html",
|
||||||
|
"concepts/application_structure.md": "https://docs.langchain.com/langsmith/application-structure",
|
||||||
|
"concepts/assistants.md": "https://docs.langchain.com/langsmith/assistants",
|
||||||
|
"concepts/auth.md": "https://docs.langchain.com/langsmith/auth",
|
||||||
|
"concepts/deployment_options.md": "https://docs.langchain.com/langsmith/deployments",
|
||||||
|
"concepts/double_texting.md": "https://docs.langchain.com/langsmith/double-texting",
|
||||||
|
"concepts/faq.md": "https://docs.langchain.com/langsmith/faq",
|
||||||
|
"concepts/langgraph_cli.md": "https://docs.langchain.com/langsmith/cli",
|
||||||
|
"concepts/langgraph_cloud.md": "https://docs.langchain.com/langsmith/cloud",
|
||||||
|
"concepts/langgraph_components.md": "https://docs.langchain.com/langsmith/components",
|
||||||
|
"concepts/langgraph_control_plane.md": "https://docs.langchain.com/langsmith/control-plane",
|
||||||
|
"concepts/langgraph_data_plane.md": "https://docs.langchain.com/langsmith/data-plane",
|
||||||
|
"concepts/langgraph_platform.md": "https://docs.langchain.com/langsmith/home",
|
||||||
|
"concepts/langgraph_self_hosted_control_plane.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
|
"concepts/langgraph_self_hosted_data_plane.md": "https://docs.langchain.com/langsmith/platform-setup",
|
||||||
|
"concepts/langgraph_server.md": "https://docs.langchain.com/langsmith/agent-server",
|
||||||
|
"concepts/langgraph_standalone_container.md": "https://docs.langchain.com/langsmith/docker",
|
||||||
|
"concepts/langgraph_studio.md": "https://docs.langchain.com/langsmith/studio",
|
||||||
|
"concepts/plans.md": "https://docs.langchain.com/langsmith/home",
|
||||||
|
"concepts/scalability_and_resilience.md": "https://docs.langchain.com/langsmith/scalability-and-resilience",
|
||||||
|
"concepts/sdk.md": "https://docs.langchain.com/langsmith/sdk",
|
||||||
|
"concepts/server-mcp.md": "https://docs.langchain.com/langsmith/server-mcp",
|
||||||
|
"concepts/template_applications.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"concepts/why-langgraph.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"examples/index.md": "https://docs.langchain.com/oss/python/langgraph/case-studies",
|
||||||
|
"guides/index.md": "https://docs.langchain.com/oss/python/langchain/overview",
|
||||||
|
"how-tos/auth/custom_auth.md": "https://docs.langchain.com/langsmith/custom-auth",
|
||||||
|
"how-tos/auth/openapi_security.md": "https://docs.langchain.com/langsmith/openapi-security",
|
||||||
|
"how-tos/autogen-integration.md": "https://docs.langchain.com/langsmith/autogen-integration",
|
||||||
|
"how-tos/http/custom_lifespan.md": "https://docs.langchain.com/langsmith/custom-lifespan",
|
||||||
|
"how-tos/http/custom_middleware.md": "https://docs.langchain.com/langsmith/custom-middleware",
|
||||||
|
"how-tos/http/custom_routes.md": "https://docs.langchain.com/langsmith/custom-routes",
|
||||||
|
"how-tos/ttl/configure_ttl.md": "https://docs.langchain.com/langsmith/configure-ttl",
|
||||||
|
"how-tos/use-remote-graph.md": "https://docs.langchain.com/langsmith/use-remote-graph",
|
||||||
|
"index.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"snippets/chat_model_tabs.md": "https://docs.langchain.com/oss/python/langchain/overview",
|
||||||
|
"troubleshooting/errors/GRAPH_RECURSION_LIMIT.md": "https://docs.langchain.com/oss/python/langgraph/GRAPH_RECURSION_LIMIT",
|
||||||
|
"troubleshooting/errors/index.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"troubleshooting/errors/INVALID_CHAT_HISTORY.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_CHAT_HISTORY",
|
||||||
|
"troubleshooting/errors/INVALID_CONCURRENT_GRAPH_UPDATE.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_CONCURRENT_GRAPH_UPDATE",
|
||||||
|
"troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_GRAPH_NODE_RETURN_VALUE",
|
||||||
|
"troubleshooting/errors/INVALID_LICENSE.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"troubleshooting/errors/MULTIPLE_SUBGRAPHS.md": "https://docs.langchain.com/oss/python/langgraph/MULTIPLE_SUBGRAPHS",
|
||||||
|
"troubleshooting/studio.md": "https://docs.langchain.com/langsmith/troubleshooting-studio",
|
||||||
|
"tutorials/auth/add_auth_server.md": "https://docs.langchain.com/langsmith/add-auth-server",
|
||||||
|
"tutorials/auth/getting_started.md": "https://docs.langchain.com/langsmith/auth",
|
||||||
|
"tutorials/auth/resource_auth.md": "https://docs.langchain.com/langsmith/resource-auth",
|
||||||
|
"agents/agents.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
|
"concepts/why-langgraph.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"tutorials/langsmith/local-server.md": "https://docs.langchain.com/oss/python/langgraph/local-server",
|
||||||
|
"tutorials/workflows.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"concepts/agentic_concepts.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"guides/index.md": "https://docs.langchain.com/oss/python/langchain/overview",
|
||||||
|
"agents/overview.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
|
"concepts/agentic_concepts.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"agents/run_agents.md": "https://docs.langchain.com/oss/python/langgraph/quickstart",
|
||||||
|
"concepts/low_level.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"how-tos/graph-api.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"concepts/functional_api.md": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
|
"how-tos/use-functional-api.md": "https://docs.langchain.com/oss/python/langgraph/functional-api",
|
||||||
|
"concepts/pregel.md": "https://docs.langchain.com/oss/python/langgraph/pregel",
|
||||||
|
"concepts/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
|
"how-tos/streaming.md": "https://docs.langchain.com/oss/python/langgraph/streaming",
|
||||||
|
"concepts/persistence.md": "https://docs.langchain.com/oss/python/langgraph/persistence",
|
||||||
|
"concepts/durable_execution.md": "https://docs.langchain.com/oss/python/langgraph/durable-execution",
|
||||||
|
"concepts/memory.md": "https://docs.langchain.com/oss/python/langgraph/memory",
|
||||||
|
"how-tos/memory/add-memory.md": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
|
"agents/context.md": "https://docs.langchain.com/oss/python/langgraph/add-memory",
|
||||||
|
"agents/models.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"concepts/tools.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"how-tos/tool-calling.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"concepts/human_in_the_loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
|
"how-tos/human_in_the_loop/add-human-in-the-loop.md": "https://docs.langchain.com/oss/python/langgraph/interrupts",
|
||||||
|
"concepts/time-travel.md": "https://docs.langchain.com/oss/python/langgraph/persistence",
|
||||||
|
"how-tos/human_in_the_loop/time-travel.md": "https://docs.langchain.com/oss/python/langgraph/use-time-travel",
|
||||||
|
"concepts/subgraphs.md": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs",
|
||||||
|
"how-tos/subgraph.md": "https://docs.langchain.com/oss/python/langgraph/use-subgraphs",
|
||||||
|
"concepts/multi_agent.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"agents/multi-agent.md": "https://docs.langchain.com/oss/python/langchain/multi-agent",
|
||||||
|
"how-tos/multi_agent.md": "https://docs.langchain.com/oss/python/langgraph/graph-api",
|
||||||
|
"concepts/mcp.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"agents/mcp.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"concepts/tracing.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"how-tos/enable-tracing.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"agents/evals.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"examples/index.md": "https://docs.langchain.com/oss/python/langgraph/case-studies",
|
||||||
|
"concepts/template_applications.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"tutorials/rag/langgraph_agentic_rag.md": "https://docs.langchain.com/oss/python/langgraph/agentic-rag",
|
||||||
|
"tutorials/multi_agent/agent_supervisor.md": "https://docs.langchain.com/oss/python/langgraph/workflows-agents",
|
||||||
|
"tutorials/sql/sql-agent.md": "https://docs.langchain.com/oss/python/langgraph/sql-agent",
|
||||||
|
"agents/ui.md": "https://docs.langchain.com/oss/python/langgraph/ui",
|
||||||
|
"how-tos/run-id-langsmith.md": "https://docs.langchain.com/oss/python/langgraph/observability",
|
||||||
|
"troubleshooting/errors/index.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"troubleshooting/errors/GRAPH_RECURSION_LIMIT.md": "https://docs.langchain.com/oss/python/langgraph/GRAPH_RECURSION_LIMIT",
|
||||||
|
"troubleshooting/errors/INVALID_CONCURRENT_GRAPH_UPDATE.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_CONCURRENT_GRAPH_UPDATE",
|
||||||
|
"troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_GRAPH_NODE_RETURN_VALUE",
|
||||||
|
"troubleshooting/errors/MULTIPLE_SUBGRAPHS.md": "https://docs.langchain.com/oss/python/langgraph/MULTIPLE_SUBGRAPHS",
|
||||||
|
"troubleshooting/errors/INVALID_CHAT_HISTORY.md": "https://docs.langchain.com/oss/python/langgraph/INVALID_CHAT_HISTORY",
|
||||||
|
"troubleshooting/errors/INVALID_LICENSE.md": "https://docs.langchain.com/oss/python/langgraph/common-errors",
|
||||||
|
"adopters.md": "https://docs.langchain.com/oss/python/langgraph/case-studies",
|
||||||
|
"concepts/faq.md": "https://docs.langchain.com/oss/python/langgraph/overview",
|
||||||
|
"agents/prebuilt.md": "https://docs.langchain.com/oss/python/langchain/agents",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -560,10 +788,16 @@ def on_post_page(html: str, page: Page, config: MkDocsConfig) -> str:
|
|||||||
# Create HTML files for redirects after site dir has been built
|
# Create HTML files for redirects after site dir has been built
|
||||||
def on_post_build(config):
|
def on_post_build(config):
|
||||||
use_directory_urls = config.get("use_directory_urls")
|
use_directory_urls = config.get("use_directory_urls")
|
||||||
|
site_dir = config["site_dir"]
|
||||||
|
|
||||||
|
# Track which paths have explicit redirects
|
||||||
|
redirected_paths = set()
|
||||||
|
|
||||||
|
# Process explicit redirects from REDIRECT_MAP
|
||||||
for page_old, page_new in REDIRECT_MAP.items():
|
for page_old, page_new in REDIRECT_MAP.items():
|
||||||
# Convert .ipynb to .md for path calculation
|
# Convert .ipynb to .md for path calculation
|
||||||
page_old = page_old.replace(".ipynb", ".md")
|
page_old = page_old.replace(".ipynb", ".md")
|
||||||
|
|
||||||
# Calculate the HTML path for the old page (whether it exists or not)
|
# Calculate the HTML path for the old page (whether it exists or not)
|
||||||
if use_directory_urls:
|
if use_directory_urls:
|
||||||
# With directory URLs: /path/to/page/ becomes /path/to/page/index.html
|
# With directory URLs: /path/to/page/ becomes /path/to/page/index.html
|
||||||
@@ -577,15 +811,18 @@ def on_post_build(config):
|
|||||||
old_html_path = page_old[:-3] + ".html"
|
old_html_path = page_old[:-3] + ".html"
|
||||||
else:
|
else:
|
||||||
old_html_path = page_old + ".html"
|
old_html_path = page_old + ".html"
|
||||||
|
|
||||||
|
# Track this path as redirected
|
||||||
|
redirected_paths.add(old_html_path)
|
||||||
|
|
||||||
if isinstance(page_new, str) and page_new.startswith("http"):
|
if isinstance(page_new, str) and page_new.startswith("http"):
|
||||||
# Handle external redirects
|
# Handle external redirects
|
||||||
_write_html(config["site_dir"], old_html_path, page_new)
|
_write_html(site_dir, old_html_path, page_new)
|
||||||
else:
|
else:
|
||||||
# Handle internal redirects
|
# Handle internal redirects
|
||||||
page_new = page_new.replace(".ipynb", ".md")
|
page_new = page_new.replace(".ipynb", ".md")
|
||||||
page_new_before_hash, hash, suffix = page_new.partition("#")
|
page_new_before_hash, hash, suffix = page_new.partition("#")
|
||||||
|
|
||||||
# Try to get the new path using File class, but fallback to manual calculation
|
# Try to get the new path using File class, but fallback to manual calculation
|
||||||
try:
|
try:
|
||||||
new_html_path = File(page_new_before_hash, "", "", True).url
|
new_html_path = File(page_new_before_hash, "", "", True).url
|
||||||
@@ -607,5 +844,46 @@ def on_post_build(config):
|
|||||||
else:
|
else:
|
||||||
new_html_path = page_new_before_hash + ".html"
|
new_html_path = page_new_before_hash + ".html"
|
||||||
new_html_path += hash + suffix
|
new_html_path += hash + suffix
|
||||||
|
|
||||||
_write_html(config["site_dir"], old_html_path, new_html_path)
|
_write_html(site_dir, old_html_path, new_html_path)
|
||||||
|
|
||||||
|
# Create root index.html redirect
|
||||||
|
root_redirect_html = """<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Redirecting to LangGraph Documentation</title>
|
||||||
|
<link rel="canonical" href="https://docs.langchain.com/oss/python/langgraph/overview">
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
|
<script>var anchor=window.location.hash.substr(1);location.href="https://docs.langchain.com/oss/python/langgraph/overview"+(anchor?"#"+anchor:"")</script>
|
||||||
|
<meta http-equiv="refresh" content="0; url=https://docs.langchain.com/oss/python/langgraph/overview">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Documentation has moved</h1>
|
||||||
|
<p>The LangGraph documentation has moved to <a href="https://docs.langchain.com/oss/python/langgraph/overview">docs.langchain.com</a>.</p>
|
||||||
|
<p>Redirecting you now...</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
root_index_path = os.path.join(site_dir, "index.html")
|
||||||
|
with open(root_index_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(root_redirect_html)
|
||||||
|
|
||||||
|
# Create server-side catch-all redirect file for Netlify/Cloudflare Pages
|
||||||
|
# This handles any pages not explicitly mapped in REDIRECT_MAP
|
||||||
|
# Note: This won't work on GitHub Pages, but kept for potential future use
|
||||||
|
redirects_content = """# Netlify/Cloudflare Pages redirect rules
|
||||||
|
# Specific redirects are handled by individual HTML redirect pages
|
||||||
|
# This is the catch-all for any unmapped pages
|
||||||
|
|
||||||
|
# Exclude reference docs from catch-all
|
||||||
|
/reference/* 200
|
||||||
|
|
||||||
|
# Catch-all: redirect any page not explicitly mapped
|
||||||
|
/* https://docs.langchain.com/oss/python/langgraph/overview 301
|
||||||
|
"""
|
||||||
|
|
||||||
|
redirects_path = os.path.join(site_dir, "_redirects")
|
||||||
|
with open(redirects_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(redirects_content)
|
||||||
|
|||||||
@@ -20,16 +20,19 @@ class Package(TypedDict):
|
|||||||
description: str
|
description: str
|
||||||
"""A brief description of what the package does."""
|
"""A brief description of what the package does."""
|
||||||
|
|
||||||
|
|
||||||
class ResolvedPackage(Package):
|
class ResolvedPackage(Package):
|
||||||
weekly_downloads: int | None
|
weekly_downloads: int | None
|
||||||
"""The weekly download count of the package."""
|
"""The weekly download count of the package."""
|
||||||
language: str
|
language: str
|
||||||
"""The language of the package. (either 'python' or 'js')"""
|
"""The language of the package. (either 'python' or 'js')"""
|
||||||
|
|
||||||
|
|
||||||
HERE = pathlib.Path(__file__).parent
|
HERE = pathlib.Path(__file__).parent
|
||||||
PACKAGES_FILE = HERE / "packages.yml"
|
PACKAGES_FILE = HERE / "packages.yml"
|
||||||
PACKAGES = yaml.safe_load(PACKAGES_FILE.read_text())["packages"]
|
PACKAGES = yaml.safe_load(PACKAGES_FILE.read_text())["packages"]
|
||||||
|
|
||||||
|
|
||||||
def _get_pypi_downloads(package: Package) -> int:
|
def _get_pypi_downloads(package: Package) -> int:
|
||||||
"""Retrieve the weekly download count for a package from PyPIStats."""
|
"""Retrieve the weekly download count for a package from PyPIStats."""
|
||||||
|
|
||||||
@@ -72,7 +75,8 @@ def _get_pypi_downloads(package: Package) -> int:
|
|||||||
return sum(entry["downloads"] for entry in sorted_data[:7])
|
return sum(entry["downloads"] for entry in sorted_data[:7])
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _get_npm_downloads(package: Package) -> int:
|
def _get_npm_downloads(package: Package) -> int:
|
||||||
"""Retrieve the weekly download count for a package on the npm registry."""
|
"""Retrieve the weekly download count for a package on the npm registry."""
|
||||||
|
|
||||||
@@ -82,14 +86,18 @@ def _get_npm_downloads(package: Package) -> int:
|
|||||||
npm_response = requests.get(npm_url)
|
npm_response = requests.get(npm_url)
|
||||||
npm_response.raise_for_status()
|
npm_response.raise_for_status()
|
||||||
except requests.exceptions.HTTPError:
|
except requests.exceptions.HTTPError:
|
||||||
raise AssertionError(f"Package {package['name']} does not exist on npm registry")
|
raise AssertionError(
|
||||||
|
f"Package {package['name']} does not exist on npm registry"
|
||||||
|
)
|
||||||
|
|
||||||
npm_data = npm_response.json()
|
npm_data = npm_response.json()
|
||||||
|
|
||||||
# Retrieve the first publish date using the 'created' timestamp from the 'time' field.
|
# Retrieve the first publish date using the 'created' timestamp from the 'time' field.
|
||||||
created_str = npm_data.get("time", {}).get("created")
|
created_str = npm_data.get("time", {}).get("created")
|
||||||
if created_str is None:
|
if created_str is None:
|
||||||
raise AssertionError(f"Package {package['name']} has no creation time in registry data")
|
raise AssertionError(
|
||||||
|
f"Package {package['name']} has no creation time in registry data"
|
||||||
|
)
|
||||||
# Remove the trailing 'Z' if present and parse the ISO format timestamp
|
# Remove the trailing 'Z' if present and parse the ISO format timestamp
|
||||||
first_publish_date = datetime.fromisoformat(created_str.rstrip("Z"))
|
first_publish_date = datetime.fromisoformat(created_str.rstrip("Z"))
|
||||||
|
|
||||||
@@ -103,7 +111,10 @@ def _get_npm_downloads(package: Package) -> int:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_weekly_downloads(packages: dict[str, list[Package]], fake: bool) -> list[ResolvedPackage]:
|
|
||||||
|
def _get_weekly_downloads(
|
||||||
|
packages: dict[str, list[Package]], fake: bool
|
||||||
|
) -> list[ResolvedPackage]:
|
||||||
"""Retrieve the weekly download count for a dictionary of python or js packages."""
|
"""Retrieve the weekly download count for a dictionary of python or js packages."""
|
||||||
resolved_packages: list[ResolvedPackage] = []
|
resolved_packages: list[ResolvedPackage] = []
|
||||||
|
|
||||||
@@ -131,7 +142,7 @@ def _get_weekly_downloads(packages: dict[str, list[Package]], fake: bool) -> lis
|
|||||||
num_downloads = _get_npm_downloads(package)
|
num_downloads = _get_npm_downloads(package)
|
||||||
else:
|
else:
|
||||||
num_downloads = None
|
num_downloads = None
|
||||||
|
|
||||||
resolved_packages.append(
|
resolved_packages.append(
|
||||||
{
|
{
|
||||||
"name": package["name"],
|
"name": package["name"],
|
||||||
@@ -145,12 +156,13 @@ def _get_weekly_downloads(packages: dict[str, list[Package]], fake: bool) -> lis
|
|||||||
|
|
||||||
return resolved_packages
|
return resolved_packages
|
||||||
|
|
||||||
|
|
||||||
def main(output_file: str, fake: bool) -> None:
|
def main(output_file: str, fake: bool) -> None:
|
||||||
"""Main function to generate package download information.
|
"""Main function to generate package download information.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
output_file: Path to the output YAML file.
|
output_file: Path to the output YAML file.
|
||||||
fake: If True, use fake download counts for testing purposes.
|
fake: If `True`, use fake download counts for testing purposes.
|
||||||
"""
|
"""
|
||||||
resolved_packages: list[ResolvedPackage] = _get_weekly_downloads(PACKAGES, fake)
|
resolved_packages: list[ResolvedPackage] = _get_weekly_downloads(PACKAGES, fake)
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ LangGraph provides three ways to manage context, which combines the mutability a
|
|||||||
|
|
||||||
**Static runtime context** represents immutable data like user metadata, tools, and database connections that are passed to an application at the start of a run via the `context` argument to `invoke`/`stream`. This data does not change during execution.
|
**Static runtime context** represents immutable data like user metadata, tools, and database connections that are passed to an application at the start of a run via the `context` argument to `invoke`/`stream`. This data does not change during execution.
|
||||||
|
|
||||||
!!! version-added "New in LangGraph v0.6: `context` replaces `config['configurable']`"
|
!!! version-added "Added in version 0.6.0: `context` replaces `config['configurable']`"
|
||||||
|
|
||||||
Runtime context is now passed to the `context` argument of `invoke`/`stream`,
|
Runtime context is now passed to the `context` argument of `invoke`/`stream`,
|
||||||
which replaces the previous pattern of passing application configuration to `config['configurable']`.
|
which replaces the previous pattern of passing application configuration to `config['configurable']`.
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ output = agent.invoke(
|
|||||||
print(output["messages"][-1].text())
|
print(output["messages"][-1].text())
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! version-added "New in LangGraph v0.6"
|
!!! version-added "Added in version 0.6.0"
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -351,11 +351,13 @@ If your desired LLM isn't officially supported by LangChain, consider these opti
|
|||||||
:::python
|
:::python
|
||||||
|
|
||||||
1. **Implement a custom LangChain chat model**: Create a model conforming to the [LangChain chat model interface](https://python.langchain.com/docs/how_to/custom_chat_model/). This enables full compatibility with LangGraph's agents and workflows but requires understanding of the LangChain framework.
|
1. **Implement a custom LangChain chat model**: Create a model conforming to the [LangChain chat model interface](https://python.langchain.com/docs/how_to/custom_chat_model/). This enables full compatibility with LangGraph's agents and workflows but requires understanding of the LangChain framework.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
|
|
||||||
1. **Implement a custom LangChain chat model**: Create a model conforming to the [LangChain chat model interface](https://js.langchain.com/docs/how_to/custom_chat/). This enables full compatibility with LangGraph's agents and workflows but requires understanding of the LangChain framework.
|
1. **Implement a custom LangChain chat model**: Create a model conforming to the [LangChain chat model interface](https://js.langchain.com/docs/how_to/custom_chat/). This enables full compatibility with LangGraph's agents and workflows but requires understanding of the LangChain framework.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
2. **Direct invocation with custom streaming**: Use your model directly by [adding custom streaming logic](../how-tos/streaming.md#use-with-any-llm) with `StreamWriter`.
|
2. **Direct invocation with custom streaming**: Use your model directly by [adding custom streaming logic](../how-tos/streaming.md#use-with-any-llm) with `StreamWriter`.
|
||||||
@@ -371,6 +373,7 @@ If your desired LLM isn't officially supported by LangChain, consider these opti
|
|||||||
- [Force model to call a specific tool](https://python.langchain.com/docs/how_to/tool_choice/)
|
- [Force model to call a specific tool](https://python.langchain.com/docs/how_to/tool_choice/)
|
||||||
- [All chat model how-to guides](https://python.langchain.com/docs/how_to/#chat-models)
|
- [All chat model how-to guides](https://python.langchain.com/docs/how_to/#chat-models)
|
||||||
- [Chat model integrations](https://python.langchain.com/docs/integrations/chat/)
|
- [Chat model integrations](https://python.langchain.com/docs/integrations/chat/)
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
@@ -381,4 +384,5 @@ If your desired LLM isn't officially supported by LangChain, consider these opti
|
|||||||
- [Force model to call a specific tool](https://js.langchain.com/docs/how_to/tool_choice/)
|
- [Force model to call a specific tool](https://js.langchain.com/docs/how_to/tool_choice/)
|
||||||
- [All chat model how-to guides](https://js.langchain.com/docs/how_to/#chat-models)
|
- [All chat model how-to guides](https://js.langchain.com/docs/how_to/#chat-models)
|
||||||
- [Chat model integrations](https://js.langchain.com/docs/integrations/chat/)
|
- [Chat model integrations](https://js.langchain.com/docs/integrations/chat/)
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"openapi": "3.1.0",
|
"openapi": "3.1.0",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "LangGraph Platform",
|
"title": "LangSmith Deployment",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|||||||
@@ -21,12 +21,16 @@ To leverage durable execution in LangGraph, you need to:
|
|||||||
1. Enable [persistence](./persistence.md) in your workflow by specifying a [checkpointer](./persistence.md#checkpointer-libraries) that will save workflow progress.
|
1. Enable [persistence](./persistence.md) in your workflow by specifying a [checkpointer](./persistence.md#checkpointer-libraries) that will save workflow progress.
|
||||||
2. Specify a [thread identifier](./persistence.md#threads) when executing a workflow. This will track the execution history for a particular instance of the workflow.
|
2. Specify a [thread identifier](./persistence.md#threads) when executing a workflow. This will track the execution history for a particular instance of the workflow.
|
||||||
|
|
||||||
:::python
|
:::python
|
||||||
|
|
||||||
3. Wrap any non-deterministic operations (e.g., random number generation) or operations with side effects (e.g., file writes, API calls) inside @[tasks][task] to ensure that when a workflow is resumed, these operations are not repeated for the particular run, and instead their results are retrieved from the persistence layer. For more information, see [Determinism and Consistent Replay](#determinism-and-consistent-replay).
|
3. Wrap any non-deterministic operations (e.g., random number generation) or operations with side effects (e.g., file writes, API calls) inside @[tasks][task] to ensure that when a workflow is resumed, these operations are not repeated for the particular run, and instead their results are retrieved from the persistence layer. For more information, see [Determinism and Consistent Replay](#determinism-and-consistent-replay).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
|
|
||||||
3. Wrap any non-deterministic operations (e.g., random number generation) or operations with side effects (e.g., file writes, API calls) inside @[tasks][task] to ensure that when a workflow is resumed, these operations are not repeated for the particular run, and instead their results are retrieved from the persistence layer. For more information, see [Determinism and Consistent Replay](#determinism-and-consistent-replay).
|
3. Wrap any non-deterministic operations (e.g., random number generation) or operations with side effects (e.g., file writes, API calls) inside @[tasks][task] to ensure that when a workflow is resumed, these operations are not repeated for the particular run, and instead their results are retrieved from the persistence layer. For more information, see [Determinism and Consistent Replay](#determinism-and-consistent-replay).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Determinism and Consistent Replay
|
## Determinism and Consistent Replay
|
||||||
@@ -61,7 +65,7 @@ LangGraph supports three durability modes that allow you to balance performance
|
|||||||
|
|
||||||
A higher durability mode add more overhead to the workflow execution.
|
A higher durability mode add more overhead to the workflow execution.
|
||||||
|
|
||||||
!!! version-added "Added in v0.6.0"
|
!!! version-added "Added in version 0.6.0"
|
||||||
|
|
||||||
Use the `durability` parameter instead of `checkpoint_during` (deprecated in v0.6.0) for persistence policy management:
|
Use the `durability` parameter instead of `checkpoint_during` (deprecated in v0.6.0) for persistence policy management:
|
||||||
|
|
||||||
@@ -73,14 +77,16 @@ A higher durability mode add more overhead to the workflow execution.
|
|||||||
* `checkpoint_during=True` -> `durability="async"`
|
* `checkpoint_during=True` -> `durability="async"`
|
||||||
* `checkpoint_during=False` -> `durability="exit"`
|
* `checkpoint_during=False` -> `durability="exit"`
|
||||||
|
|
||||||
|
|
||||||
### `"exit"`
|
### `"exit"`
|
||||||
|
|
||||||
Changes are persisted only when graph execution completes (either successfully or with an error). This provides the best performance for long-running graphs but means intermediate state is not saved, so you cannot recover from mid-execution failures or interrupt the graph execution.
|
Changes are persisted only when graph execution completes (either successfully or with an error). This provides the best performance for long-running graphs but means intermediate state is not saved, so you cannot recover from mid-execution failures or interrupt the graph execution.
|
||||||
|
|
||||||
### `"async"`
|
### `"async"`
|
||||||
|
|
||||||
Changes are persisted asynchronously while the next step executes. This provides good performance and durability, but there's a small risk that checkpoints might not be written if the process crashes during execution.
|
Changes are persisted asynchronously while the next step executes. This provides good performance and durability, but there's a small risk that checkpoints might not be written if the process crashes during execution.
|
||||||
|
|
||||||
### `"sync"`
|
### `"sync"`
|
||||||
|
|
||||||
Changes are persisted synchronously before the next step starts. This ensures that every checkpoint is written before continuing execution, providing high durability at the cost of some performance overhead.
|
Changes are persisted synchronously before the next step starts. This ensures that every checkpoint is written before continuing execution, providing high durability at the cost of some performance overhead.
|
||||||
|
|
||||||
You can specify the durability mode when calling any graph execution method:
|
You can specify the durability mode when calling any graph execution method:
|
||||||
@@ -310,12 +316,14 @@ Once you have enabled durable execution in your workflow, you can resume executi
|
|||||||
|
|
||||||
- **Pausing and Resuming Workflows:** Use the @[interrupt][interrupt] function to pause a workflow at specific points and the @[Command] primitive to resume it with updated state. See [**Human-in-the-Loop**](./human_in_the_loop.md) for more details.
|
- **Pausing and Resuming Workflows:** Use the @[interrupt][interrupt] function to pause a workflow at specific points and the @[Command] primitive to resume it with updated state. See [**Human-in-the-Loop**](./human_in_the_loop.md) for more details.
|
||||||
- **Recovering from Failures:** Automatically resume workflows from the last successful checkpoint after an exception (e.g., LLM provider outage). This involves executing the workflow with the same thread identifier by providing it with a `None` as the input value (see this [example](../how-tos/use-functional-api.md#resuming-after-an-error) with the functional API).
|
- **Recovering from Failures:** Automatically resume workflows from the last successful checkpoint after an exception (e.g., LLM provider outage). This involves executing the workflow with the same thread identifier by providing it with a `None` as the input value (see this [example](../how-tos/use-functional-api.md#resuming-after-an-error) with the functional API).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
|
|
||||||
- **Pausing and Resuming Workflows:** Use the @[interrupt][interrupt] function to pause a workflow at specific points and the @[Command] primitive to resume it with updated state. See [**Human-in-the-Loop**](./human_in_the_loop.md) for more details.
|
- **Pausing and Resuming Workflows:** Use the @[interrupt][interrupt] function to pause a workflow at specific points and the @[Command] primitive to resume it with updated state. See [**Human-in-the-Loop**](./human_in_the_loop.md) for more details.
|
||||||
- **Recovering from Failures:** Automatically resume workflows from the last successful checkpoint after an exception (e.g., LLM provider outage). This involves executing the workflow with the same thread identifier by providing it with a `null` as the input value (see this [example](../how-tos/use-functional-api.md#resuming-after-an-error) with the functional API).
|
- **Recovering from Failures:** Automatically resume workflows from the last successful checkpoint after an exception (e.g., LLM provider outage). This involves executing the workflow with the same thread identifier by providing it with a `null` as the input value (see this [example](../how-tos/use-functional-api.md#resuming-after-an-error) with the functional API).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Starting Points for Resuming Workflows
|
## Starting Points for Resuming Workflows
|
||||||
@@ -326,6 +334,7 @@ Once you have enabled durable execution in your workflow, you can resume executi
|
|||||||
- If you're making a subgraph call inside a node, the starting point will be the **parent** node that called the subgraph that was halted.
|
- If you're making a subgraph call inside a node, the starting point will be the **parent** node that called the subgraph that was halted.
|
||||||
Inside the subgraph, the starting point will be the specific [**node**](./low_level.md#nodes) where execution stopped.
|
Inside the subgraph, the starting point will be the specific [**node**](./low_level.md#nodes) where execution stopped.
|
||||||
- If you're using the Functional API, the starting point is the beginning of the [**entrypoint**](./functional_api.md#entrypoint) where execution stopped.
|
- If you're using the Functional API, the starting point is the beginning of the [**entrypoint**](./functional_api.md#entrypoint) where execution stopped.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
@@ -334,4 +343,5 @@ Once you have enabled durable execution in your workflow, you can resume executi
|
|||||||
- If you're making a subgraph call inside a node, the starting point will be the **parent** node that called the subgraph that was halted.
|
- If you're making a subgraph call inside a node, the starting point will be the **parent** node that called the subgraph that was halted.
|
||||||
Inside the subgraph, the starting point will be the specific [**node**](./low_level.md#nodes) where execution stopped.
|
Inside the subgraph, the starting point will be the specific [**node**](./low_level.md#nodes) where execution stopped.
|
||||||
- If you're using the Functional API, the starting point is the beginning of the [**entrypoint**](./functional_api.md#entrypoint) where execution stopped.
|
- If you're using the Functional API, the starting point is the beginning of the [**entrypoint**](./functional_api.md#entrypoint) where execution stopped.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ output = agent.invoke(
|
|||||||
print(output["messages"][-1].text())
|
print(output["messages"][-1].text())
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! version-added "New in langgraph>=0.6"
|
!!! version-added "Added in version 0.6.0"
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
::: langgraph.cache.base
|
::: langgraph.cache.base
|
||||||
::: langgraph.cache.memory
|
::: langgraph.cache.memory
|
||||||
::: langgraph.cache.sqlite
|
::: langgraph.cache.sqlite
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ The server will start and open the studio in your browser:
|
|||||||
> - 📚 API Docs: http://127.0.0.1:2024/docs
|
> - 📚 API Docs: http://127.0.0.1:2024/docs
|
||||||
>
|
>
|
||||||
> This in-memory server is designed for development and testing.
|
> This in-memory server is designed for development and testing.
|
||||||
> For production use, please use LangGraph Platform.
|
> For production use, please use LangSmith Deployment.
|
||||||
```
|
```
|
||||||
|
|
||||||
If you were to self-host this on the public internet, anyone could access it!
|
If you were to self-host this on the public internet, anyone could access it!
|
||||||
|
|||||||
@@ -294,9 +294,9 @@ Now that you have a LangGraph app running locally, take your journey further by
|
|||||||
:::python
|
:::python
|
||||||
|
|
||||||
- [Python SDK Reference](../../cloud/reference/sdk/python_sdk_ref.md): Explore the Python SDK API Reference.
|
- [Python SDK Reference](../../cloud/reference/sdk/python_sdk_ref.md): Explore the Python SDK API Reference.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::js
|
:::js
|
||||||
|
|
||||||
- [JS/TS SDK Reference](../../cloud/reference/sdk/js_ts_sdk_ref.md): Explore the JS/TS SDK API Reference.
|
- [JS/TS SDK Reference](../../cloud/reference/sdk/js_ts_sdk_ref.md): Explore the JS/TS SDK API Reference.
|
||||||
:::
|
:::
|
||||||
|
|||||||
+62
-98
@@ -149,6 +149,67 @@ plugins:
|
|||||||
- tutorials/auth/add_auth_server.md
|
- tutorials/auth/add_auth_server.md
|
||||||
- tutorials/auth/getting_started.md
|
- tutorials/auth/getting_started.md
|
||||||
- tutorials/auth/resource_auth.md
|
- tutorials/auth/resource_auth.md
|
||||||
|
- agents/agents.md
|
||||||
|
- concepts/why-langgraph.md
|
||||||
|
- tutorials/get-started/1-build-basic-chatbot.md
|
||||||
|
- tutorials/get-started/2-add-tools.md
|
||||||
|
- tutorials/get-started/3-add-memory.md
|
||||||
|
- tutorials/get-started/4-human-in-the-loop.md
|
||||||
|
- tutorials/get-started/5-customize-state.md
|
||||||
|
- tutorials/get-started/6-time-travel.md
|
||||||
|
- tutorials/langgraph-platform/local-server.md
|
||||||
|
- tutorials/workflows.md
|
||||||
|
- concepts/agentic_concepts.md
|
||||||
|
- guides/index.md
|
||||||
|
- agents/overview.md
|
||||||
|
- agents/run_agents.md
|
||||||
|
- concepts/low_level.md
|
||||||
|
- how-tos/graph-api.md
|
||||||
|
- concepts/functional_api.md
|
||||||
|
- how-tos/use-functional-api.md
|
||||||
|
- concepts/pregel.md
|
||||||
|
- concepts/streaming.md
|
||||||
|
- how-tos/streaming.md
|
||||||
|
- concepts/persistence.md
|
||||||
|
- concepts/durable_execution.md
|
||||||
|
- concepts/memory.md
|
||||||
|
- how-tos/memory/add-memory.md
|
||||||
|
- agents/context.md
|
||||||
|
- agents/models.md
|
||||||
|
- concepts/tools.md
|
||||||
|
- how-tos/tool-calling.md
|
||||||
|
- concepts/human_in_the_loop.md
|
||||||
|
- how-tos/human_in_the_loop/add-human-in-the-loop.md
|
||||||
|
- concepts/time-travel.md
|
||||||
|
- how-tos/human_in_the_loop/time-travel.md
|
||||||
|
- concepts/subgraphs.md
|
||||||
|
- how-tos/subgraph.md
|
||||||
|
- concepts/multi_agent.md
|
||||||
|
- agents/multi-agent.md
|
||||||
|
- how-tos/multi_agent.md
|
||||||
|
- concepts/mcp.md
|
||||||
|
- agents/mcp.md
|
||||||
|
- concepts/tracing.md
|
||||||
|
- how-tos/enable-tracing.md
|
||||||
|
- agents/evals.md
|
||||||
|
- examples/index.md
|
||||||
|
- concepts/template_applications.md # TODO: make tutorial
|
||||||
|
- tutorials/rag/langgraph_agentic_rag.md
|
||||||
|
- tutorials/multi_agent/agent_supervisor.md
|
||||||
|
- tutorials/sql/sql-agent.md
|
||||||
|
- agents/ui.md
|
||||||
|
- how-tos/run-id-langsmith.md
|
||||||
|
- troubleshooting/errors/index.md
|
||||||
|
- troubleshooting/errors/GRAPH_RECURSION_LIMIT.md
|
||||||
|
- troubleshooting/errors/INVALID_CONCURRENT_GRAPH_UPDATE.md
|
||||||
|
- troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE.md
|
||||||
|
- troubleshooting/errors/MULTIPLE_SUBGRAPHS.md
|
||||||
|
- troubleshooting/errors/INVALID_CHAT_HISTORY.md
|
||||||
|
- troubleshooting/errors/INVALID_LICENSE.md
|
||||||
|
- adopters.md
|
||||||
|
- concepts/faq.md
|
||||||
|
- agents/prebuilt.md # NOTE: prebuilt.md is auto-generated by `make build-prebuilt`
|
||||||
|
|
||||||
- tags
|
- tags
|
||||||
- include-markdown
|
- include-markdown
|
||||||
- mkdocstrings:
|
- mkdocstrings:
|
||||||
@@ -186,75 +247,6 @@ plugins:
|
|||||||
- "!^_"
|
- "!^_"
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Get started:
|
|
||||||
- index.md
|
|
||||||
- Quickstarts:
|
|
||||||
- Start with a prebuilt agent: agents/agents.md
|
|
||||||
- Build a custom workflow:
|
|
||||||
- concepts/why-langgraph.md
|
|
||||||
- 1. Build a basic chatbot: tutorials/get-started/1-build-basic-chatbot.md
|
|
||||||
- 2. Add tools: tutorials/get-started/2-add-tools.md
|
|
||||||
- 3. Add memory: tutorials/get-started/3-add-memory.md
|
|
||||||
- 4. Add human-in-the-loop: tutorials/get-started/4-human-in-the-loop.md
|
|
||||||
- 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:
|
|
||||||
- Workflows & agents: tutorials/workflows.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
|
|
||||||
- Use the Graph API: how-tos/graph-api.md
|
|
||||||
- Functional API:
|
|
||||||
- Overview: concepts/functional_api.md
|
|
||||||
- Use the Functional API: how-tos/use-functional-api.md
|
|
||||||
- Runtime: concepts/pregel.md
|
|
||||||
- Core capabilities:
|
|
||||||
- Streaming:
|
|
||||||
- Overview: concepts/streaming.md
|
|
||||||
- Stream outputs: how-tos/streaming.md
|
|
||||||
- Persistence:
|
|
||||||
- Overview: concepts/persistence.md
|
|
||||||
- Durable execution:
|
|
||||||
- Overview: concepts/durable_execution.md
|
|
||||||
- Memory:
|
|
||||||
- Overview: concepts/memory.md
|
|
||||||
- Add memory: how-tos/memory/add-memory.md
|
|
||||||
- Context:
|
|
||||||
- Add context: agents/context.md
|
|
||||||
- Models:
|
|
||||||
- Configure model: agents/models.md
|
|
||||||
- Tools:
|
|
||||||
- Overview: concepts/tools.md
|
|
||||||
- Call tools: how-tos/tool-calling.md
|
|
||||||
- Human-in-the-loop:
|
|
||||||
- Overview: concepts/human_in_the_loop.md
|
|
||||||
- Add human intervention: how-tos/human_in_the_loop/add-human-in-the-loop.md
|
|
||||||
- Time travel:
|
|
||||||
- Overview: concepts/time-travel.md
|
|
||||||
- Use time travel: how-tos/human_in_the_loop/time-travel.md
|
|
||||||
- Subgraphs:
|
|
||||||
- Overview: concepts/subgraphs.md
|
|
||||||
- Use subgraphs: how-tos/subgraph.md
|
|
||||||
- Multi-agent:
|
|
||||||
- Overview: concepts/multi_agent.md
|
|
||||||
- Prebuilt implementation: agents/multi-agent.md
|
|
||||||
- Custom implementation: how-tos/multi_agent.md
|
|
||||||
- MCP:
|
|
||||||
- Overview: concepts/mcp.md
|
|
||||||
- Use MCP: agents/mcp.md
|
|
||||||
- Tracing:
|
|
||||||
- Overview: concepts/tracing.md
|
|
||||||
- Enable tracing: how-tos/enable-tracing.md
|
|
||||||
- Evaluate performance: agents/evals.md
|
|
||||||
|
|
||||||
- Reference:
|
- Reference:
|
||||||
- reference/index.md
|
- reference/index.md
|
||||||
- LangGraph:
|
- LangGraph:
|
||||||
@@ -278,35 +270,7 @@ nav:
|
|||||||
- LangGraph Platform:
|
- LangGraph Platform:
|
||||||
- SDK (Python): cloud/reference/sdk/python_sdk_ref.md
|
- SDK (Python): cloud/reference/sdk/python_sdk_ref.md
|
||||||
- SDK (JS/TS): https://langchain-ai.github.io/langgraphjs/reference/modules/sdk.html
|
- SDK (JS/TS): https://langchain-ai.github.io/langgraphjs/reference/modules/sdk.html
|
||||||
- RemoteGraph: reference/remote_graph.md
|
- RemoteGraph: reference/remote_graph.md
|
||||||
|
|
||||||
- Examples:
|
|
||||||
- examples/index.md
|
|
||||||
- Template applications: concepts/template_applications.md # TODO: make tutorial
|
|
||||||
- Agentic RAG: tutorials/rag/langgraph_agentic_rag.md
|
|
||||||
- Agent Supervisor: tutorials/multi_agent/agent_supervisor.md
|
|
||||||
- SQL agent: tutorials/sql/sql-agent.md
|
|
||||||
- Prebuilt chat UI: agents/ui.md
|
|
||||||
- Graph runs in LangSmith: how-tos/run-id-langsmith.md
|
|
||||||
|
|
||||||
- Additional resources:
|
|
||||||
- additional-resources/index.md
|
|
||||||
- agents/prebuilt.md # NOTE: prebuilt.md is auto-generated by `make build-prebuilt`
|
|
||||||
- LangGraph Academy course: https://academy.langchain.com/courses/intro-to-langgraph
|
|
||||||
- Case studies: adopters.md
|
|
||||||
- concepts/faq.md
|
|
||||||
- llms.txt: llms-txt-overview.md
|
|
||||||
- LangChain Forum: https://forum.langchain.com/
|
|
||||||
- Troubleshooting:
|
|
||||||
- Errors:
|
|
||||||
- troubleshooting/errors/index.md
|
|
||||||
- troubleshooting/errors/GRAPH_RECURSION_LIMIT.md
|
|
||||||
- troubleshooting/errors/INVALID_CONCURRENT_GRAPH_UPDATE.md
|
|
||||||
- troubleshooting/errors/INVALID_GRAPH_NODE_RETURN_VALUE.md
|
|
||||||
- troubleshooting/errors/MULTIPLE_SUBGRAPHS.md
|
|
||||||
- troubleshooting/errors/INVALID_CHAT_HISTORY.md
|
|
||||||
- troubleshooting/errors/INVALID_LICENSE.md
|
|
||||||
|
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- abbr
|
- abbr
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from langgraph.checkpoint.base import (
|
|||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
CheckpointTuple,
|
CheckpointTuple,
|
||||||
get_checkpoint_id,
|
get_checkpoint_id,
|
||||||
get_checkpoint_metadata,
|
get_serializable_checkpoint_metadata,
|
||||||
)
|
)
|
||||||
from langgraph.checkpoint.serde.base import SerializerProtocol
|
from langgraph.checkpoint.serde.base import SerializerProtocol
|
||||||
from psycopg import Capabilities, Connection, Cursor, Pipeline
|
from psycopg import Capabilities, Connection, Cursor, Pipeline
|
||||||
@@ -94,6 +94,7 @@ class PostgresSaver(BasePostgresSaver):
|
|||||||
for v, migration in zip(
|
for v, migration in zip(
|
||||||
range(version + 1, len(self.MIGRATIONS)),
|
range(version + 1, len(self.MIGRATIONS)),
|
||||||
self.MIGRATIONS[version + 1 :],
|
self.MIGRATIONS[version + 1 :],
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
cur.execute(migration)
|
cur.execute(migration)
|
||||||
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
||||||
@@ -115,12 +116,12 @@ class PostgresSaver(BasePostgresSaver):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The config to use for listing the checkpoints.
|
config: The config to use for listing the checkpoints.
|
||||||
filter: Additional filtering criteria for metadata. Defaults to None.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: The maximum number of checkpoints to return. Defaults to None.
|
limit: The maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Iterator[CheckpointTuple]: An iterator of checkpoint tuples.
|
An iterator of checkpoint tuples.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> from langgraph.checkpoint.postgres import PostgresSaver
|
>>> from langgraph.checkpoint.postgres import PostgresSaver
|
||||||
@@ -182,7 +183,7 @@ class PostgresSaver(BasePostgresSaver):
|
|||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and timestamp is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and timestamp is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ class PostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -325,7 +326,7 @@ class PostgresSaver(BasePostgresSaver):
|
|||||||
checkpoint["id"],
|
checkpoint["id"],
|
||||||
checkpoint_id,
|
checkpoint_id,
|
||||||
Jsonb(copy),
|
Jsonb(copy),
|
||||||
Jsonb(get_checkpoint_metadata(config, metadata)),
|
Jsonb(get_serializable_checkpoint_metadata(config, metadata)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return next_config
|
return next_config
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from psycopg import AsyncConnection
|
from psycopg import AsyncConnection
|
||||||
from psycopg.rows import DictRow
|
from psycopg.rows import DictRow
|
||||||
from psycopg_pool import AsyncConnectionPool
|
from psycopg_pool import AsyncConnectionPool
|
||||||
|
|
||||||
Conn = Union[AsyncConnection[DictRow], AsyncConnectionPool[AsyncConnection[DictRow]]]
|
Conn = AsyncConnection[DictRow] | AsyncConnectionPool[AsyncConnection[DictRow]]
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from psycopg import Connection
|
from psycopg import Connection
|
||||||
from psycopg.rows import DictRow
|
from psycopg.rows import DictRow
|
||||||
from psycopg_pool import ConnectionPool
|
from psycopg_pool import ConnectionPool
|
||||||
|
|
||||||
Conn = Union[Connection[DictRow], ConnectionPool[Connection[DictRow]]]
|
Conn = Connection[DictRow] | ConnectionPool[Connection[DictRow]]
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from langgraph.checkpoint.base import (
|
|||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
CheckpointTuple,
|
CheckpointTuple,
|
||||||
get_checkpoint_id,
|
get_checkpoint_id,
|
||||||
get_checkpoint_metadata,
|
get_serializable_checkpoint_metadata,
|
||||||
)
|
)
|
||||||
from langgraph.checkpoint.serde.base import SerializerProtocol
|
from langgraph.checkpoint.serde.base import SerializerProtocol
|
||||||
from psycopg import AsyncConnection, AsyncCursor, AsyncPipeline, Capabilities
|
from psycopg import AsyncConnection, AsyncCursor, AsyncPipeline, Capabilities
|
||||||
@@ -99,6 +99,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
for v, migration in zip(
|
for v, migration in zip(
|
||||||
range(version + 1, len(self.MIGRATIONS)),
|
range(version + 1, len(self.MIGRATIONS)),
|
||||||
self.MIGRATIONS[version + 1 :],
|
self.MIGRATIONS[version + 1 :],
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
await cur.execute(migration)
|
await cur.execute(migration)
|
||||||
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
||||||
@@ -121,11 +122,11 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
Args:
|
Args:
|
||||||
config: Base configuration for filtering checkpoints.
|
config: Base configuration for filtering checkpoints.
|
||||||
filter: Additional filtering criteria for metadata.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
AsyncIterator[CheckpointTuple]: An asynchronous iterator of matching checkpoint tuples.
|
An asynchronous iterator of matching checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
where, args = self._search_where(config, filter, before)
|
where, args = self._search_where(config, filter, before)
|
||||||
query = self.SELECT_SQL + where + " ORDER BY checkpoint_id DESC"
|
query = self.SELECT_SQL + where + " ORDER BY checkpoint_id DESC"
|
||||||
@@ -169,7 +170,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
"""Get a checkpoint tuple from the database asynchronously.
|
"""Get a checkpoint tuple from the database asynchronously.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and "checkpoint_id" is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and "checkpoint_id" is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -177,7 +178,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
thread_id = config["configurable"]["thread_id"]
|
thread_id = config["configurable"]["thread_id"]
|
||||||
checkpoint_id = get_checkpoint_id(config)
|
checkpoint_id = get_checkpoint_id(config)
|
||||||
@@ -283,7 +284,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
checkpoint["id"],
|
checkpoint["id"],
|
||||||
checkpoint_id,
|
checkpoint_id,
|
||||||
Jsonb(copy),
|
Jsonb(copy),
|
||||||
Jsonb(get_checkpoint_metadata(config, metadata)),
|
Jsonb(get_serializable_checkpoint_metadata(config, metadata)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return next_config
|
return next_config
|
||||||
@@ -444,11 +445,11 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
Args:
|
Args:
|
||||||
config: Base configuration for filtering checkpoints.
|
config: Base configuration for filtering checkpoints.
|
||||||
filter: Additional filtering criteria for metadata.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Iterator[CheckpointTuple]: An iterator of matching checkpoint tuples.
|
An iterator of matching checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# check if we are in the main thread, only bg threads can block
|
# check if we are in the main thread, only bg threads can block
|
||||||
@@ -476,7 +477,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and "checkpoint_id" is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and "checkpoint_id" is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -484,7 +485,7 @@ class AsyncPostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# check if we are in the main thread, only bg threads can block
|
# check if we are in the main thread, only bg threads can block
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
import warnings
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Any, Optional, cast
|
from importlib.metadata import version as get_version
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
from langgraph.checkpoint.base import (
|
from langgraph.checkpoint.base import (
|
||||||
@@ -14,7 +16,19 @@ from langgraph.checkpoint.base import (
|
|||||||
from langgraph.checkpoint.serde.types import TASKS
|
from langgraph.checkpoint.serde.types import TASKS
|
||||||
from psycopg.types.json import Jsonb
|
from psycopg.types.json import Jsonb
|
||||||
|
|
||||||
MetadataInput = Optional[dict[str, Any]]
|
MetadataInput = dict[str, Any] | None
|
||||||
|
|
||||||
|
try:
|
||||||
|
major, minor = get_version("langgraph").split(".")[:2]
|
||||||
|
if int(major) == 0 and int(minor) < 5:
|
||||||
|
warnings.warn(
|
||||||
|
"You're using incompatible versions of langgraph and checkpoint-postgres. Please upgrade langgraph to avoid unexpected behavior.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
# skip version check if running from source
|
||||||
|
pass
|
||||||
|
|
||||||
"""
|
"""
|
||||||
To add a new migration, add a new string to the MIGRATIONS list.
|
To add a new migration, add a new string to the MIGRATIONS list.
|
||||||
@@ -67,7 +81,7 @@ MIGRATIONS = [
|
|||||||
"""
|
"""
|
||||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS checkpoint_writes_thread_id_idx ON checkpoint_writes(thread_id);
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS checkpoint_writes_thread_id_idx ON checkpoint_writes(thread_id);
|
||||||
""",
|
""",
|
||||||
"""ALTER TABLE checkpoint_writes ADD COLUMN task_path TEXT NOT NULL DEFAULT '';""",
|
"""ALTER TABLE checkpoint_writes ADD COLUMN IF NOT EXISTS task_path TEXT NOT NULL DEFAULT '';""",
|
||||||
]
|
]
|
||||||
|
|
||||||
SELECT_SQL = """
|
SELECT_SQL = """
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import threading
|
|||||||
import warnings
|
import warnings
|
||||||
from collections.abc import AsyncIterator, Iterator, Sequence
|
from collections.abc import AsyncIterator, Iterator, Sequence
|
||||||
from contextlib import asynccontextmanager, contextmanager
|
from contextlib import asynccontextmanager, contextmanager
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
from langgraph.checkpoint.base import (
|
from langgraph.checkpoint.base import (
|
||||||
@@ -12,7 +12,7 @@ from langgraph.checkpoint.base import (
|
|||||||
Checkpoint,
|
Checkpoint,
|
||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
CheckpointTuple,
|
CheckpointTuple,
|
||||||
get_checkpoint_metadata,
|
get_serializable_checkpoint_metadata,
|
||||||
)
|
)
|
||||||
from langgraph.checkpoint.serde.base import SerializerProtocol
|
from langgraph.checkpoint.serde.base import SerializerProtocol
|
||||||
from langgraph.checkpoint.serde.types import TASKS
|
from langgraph.checkpoint.serde.types import TASKS
|
||||||
@@ -77,7 +77,7 @@ MIGRATIONS = [
|
|||||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS checkpoint_writes_thread_id_idx ON checkpoint_writes(thread_id);
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS checkpoint_writes_thread_id_idx ON checkpoint_writes(thread_id);
|
||||||
""",
|
""",
|
||||||
"""
|
"""
|
||||||
ALTER TABLE checkpoint_writes ADD COLUMN task_path TEXT NOT NULL DEFAULT '';
|
ALTER TABLE checkpoint_writes ADD COLUMN IF NOT EXISTS task_path TEXT NOT NULL DEFAULT '';
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ def _dump_blobs(
|
|||||||
checkpoint_ns: str,
|
checkpoint_ns: str,
|
||||||
values: dict[str, Any],
|
values: dict[str, Any],
|
||||||
versions: ChannelVersions,
|
versions: ChannelVersions,
|
||||||
) -> list[tuple[str, str, str, str, Optional[bytes]]]:
|
) -> list[tuple[str, str, str, str, bytes | None]]:
|
||||||
if not versions:
|
if not versions:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -186,8 +186,8 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
conn: _internal.Conn,
|
conn: _internal.Conn,
|
||||||
pipe: Optional[Pipeline] = None,
|
pipe: Pipeline | None = None,
|
||||||
serde: Optional[SerializerProtocol] = None,
|
serde: SerializerProtocol | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"ShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
|
"ShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
|
||||||
@@ -249,6 +249,7 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
for v, migration in zip(
|
for v, migration in zip(
|
||||||
range(version + 1, len(self.MIGRATIONS)),
|
range(version + 1, len(self.MIGRATIONS)),
|
||||||
self.MIGRATIONS[version + 1 :],
|
self.MIGRATIONS[version + 1 :],
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
cur.execute(migration)
|
cur.execute(migration)
|
||||||
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
||||||
@@ -257,11 +258,11 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
|
|
||||||
def list(
|
def list(
|
||||||
self,
|
self,
|
||||||
config: Optional[RunnableConfig],
|
config: RunnableConfig | None,
|
||||||
*,
|
*,
|
||||||
filter: Optional[dict[str, Any]] = None,
|
filter: dict[str, Any] | None = None,
|
||||||
before: Optional[RunnableConfig] = None,
|
before: RunnableConfig | None = None,
|
||||||
limit: Optional[int] = None,
|
limit: int | None = None,
|
||||||
) -> Iterator[CheckpointTuple]:
|
) -> Iterator[CheckpointTuple]:
|
||||||
"""List checkpoints from the database.
|
"""List checkpoints from the database.
|
||||||
|
|
||||||
@@ -299,7 +300,7 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
pending_writes=self._load_writes(value["pending_writes"]),
|
pending_writes=self._load_writes(value["pending_writes"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
|
def get_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
@@ -309,7 +310,7 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -441,7 +442,7 @@ class ShallowPostgresSaver(BasePostgresSaver):
|
|||||||
thread_id,
|
thread_id,
|
||||||
checkpoint_ns,
|
checkpoint_ns,
|
||||||
Jsonb(copy),
|
Jsonb(copy),
|
||||||
Jsonb(get_checkpoint_metadata(config, metadata)),
|
Jsonb(get_serializable_checkpoint_metadata(config, metadata)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return next_config
|
return next_config
|
||||||
@@ -542,8 +543,8 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
conn: _ainternal.Conn,
|
conn: _ainternal.Conn,
|
||||||
pipe: Optional[AsyncPipeline] = None,
|
pipe: AsyncPipeline | None = None,
|
||||||
serde: Optional[SerializerProtocol] = None,
|
serde: SerializerProtocol | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"AsyncShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
|
"AsyncShallowPostgresSaver is deprecated as of version 2.0.20 and will be removed in 3.0.0. "
|
||||||
@@ -570,7 +571,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
conn_string: str,
|
conn_string: str,
|
||||||
*,
|
*,
|
||||||
pipeline: bool = False,
|
pipeline: bool = False,
|
||||||
serde: Optional[SerializerProtocol] = None,
|
serde: SerializerProtocol | None = None,
|
||||||
) -> AsyncIterator["AsyncShallowPostgresSaver"]:
|
) -> AsyncIterator["AsyncShallowPostgresSaver"]:
|
||||||
"""Create a new AsyncShallowPostgresSaver instance from a connection string.
|
"""Create a new AsyncShallowPostgresSaver instance from a connection string.
|
||||||
|
|
||||||
@@ -610,6 +611,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
for v, migration in zip(
|
for v, migration in zip(
|
||||||
range(version + 1, len(self.MIGRATIONS)),
|
range(version + 1, len(self.MIGRATIONS)),
|
||||||
self.MIGRATIONS[version + 1 :],
|
self.MIGRATIONS[version + 1 :],
|
||||||
|
strict=False,
|
||||||
):
|
):
|
||||||
await cur.execute(migration)
|
await cur.execute(migration)
|
||||||
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
|
||||||
@@ -618,11 +620,11 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
|
|
||||||
async def alist(
|
async def alist(
|
||||||
self,
|
self,
|
||||||
config: Optional[RunnableConfig],
|
config: RunnableConfig | None,
|
||||||
*,
|
*,
|
||||||
filter: Optional[dict[str, Any]] = None,
|
filter: dict[str, Any] | None = None,
|
||||||
before: Optional[RunnableConfig] = None,
|
before: RunnableConfig | None = None,
|
||||||
limit: Optional[int] = None,
|
limit: int | None = None,
|
||||||
) -> AsyncIterator[CheckpointTuple]:
|
) -> AsyncIterator[CheckpointTuple]:
|
||||||
"""List checkpoints from the database asynchronously.
|
"""List checkpoints from the database asynchronously.
|
||||||
|
|
||||||
@@ -662,7 +664,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def aget_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
|
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
||||||
"""Get a checkpoint tuple from the database asynchronously.
|
"""Get a checkpoint tuple from the database asynchronously.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
@@ -672,7 +674,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
thread_id = config["configurable"]["thread_id"]
|
thread_id = config["configurable"]["thread_id"]
|
||||||
checkpoint_ns = config["configurable"].get("checkpoint_ns", "")
|
checkpoint_ns = config["configurable"].get("checkpoint_ns", "")
|
||||||
@@ -774,7 +776,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
thread_id,
|
thread_id,
|
||||||
checkpoint_ns,
|
checkpoint_ns,
|
||||||
Jsonb(copy),
|
Jsonb(copy),
|
||||||
Jsonb(get_checkpoint_metadata(config, metadata)),
|
Jsonb(get_serializable_checkpoint_metadata(config, metadata)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return next_config
|
return next_config
|
||||||
@@ -861,11 +863,11 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
|
|
||||||
def list(
|
def list(
|
||||||
self,
|
self,
|
||||||
config: Optional[RunnableConfig],
|
config: RunnableConfig | None,
|
||||||
*,
|
*,
|
||||||
filter: Optional[dict[str, Any]] = None,
|
filter: dict[str, Any] | None = None,
|
||||||
before: Optional[RunnableConfig] = None,
|
before: RunnableConfig | None = None,
|
||||||
limit: Optional[int] = None,
|
limit: int | None = None,
|
||||||
) -> Iterator[CheckpointTuple]:
|
) -> Iterator[CheckpointTuple]:
|
||||||
"""List checkpoints from the database.
|
"""List checkpoints from the database.
|
||||||
|
|
||||||
@@ -883,7 +885,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
except StopAsyncIteration:
|
except StopAsyncIteration:
|
||||||
break
|
break
|
||||||
|
|
||||||
def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
|
def get_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the Postgres database based on the
|
This method retrieves a checkpoint tuple from the Postgres database based on the
|
||||||
@@ -893,7 +895,7 @@ class AsyncShallowPostgresSaver(BasePostgresSaver):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# check if we are in the main thread, only bg threads can block
|
# check if we are in the main thread, only bg threads can block
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from collections.abc import AsyncIterator, Iterable, Sequence
|
from collections.abc import AsyncIterator, Callable, Iterable, Sequence
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
from typing import Any, Callable, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
from langgraph.store.base import (
|
from langgraph.store.base import (
|
||||||
@@ -339,7 +339,7 @@ class AsyncPostgresStore(AsyncBatchedBaseStore, BasePostgresStore[_ainternal.Con
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
timeout: Maximum time to wait for the task to stop, in seconds.
|
timeout: Maximum time to wait for the task to stop, in seconds.
|
||||||
If None, wait indefinitely.
|
If `None`, wait indefinitely.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if the task was successfully stopped or wasn't running,
|
bool: True if the task was successfully stopped or wasn't running,
|
||||||
@@ -465,7 +465,9 @@ class AsyncPostgresStore(AsyncBatchedBaseStore, BasePostgresStore[_ainternal.Con
|
|||||||
query,
|
query,
|
||||||
[
|
[
|
||||||
p
|
p
|
||||||
for (ns, k, pathname, _), vector in zip(txt_params, vectors)
|
for (ns, k, pathname, _), vector in zip(
|
||||||
|
txt_params, vectors, strict=False
|
||||||
|
)
|
||||||
for p in (ns, k, pathname, vector)
|
for p in (ns, k, pathname, vector)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -486,13 +488,13 @@ class AsyncPostgresStore(AsyncBatchedBaseStore, BasePostgresStore[_ainternal.Con
|
|||||||
vectors = await self.embeddings.aembed_documents(
|
vectors = await self.embeddings.aembed_documents(
|
||||||
[query for _, query in embedding_requests]
|
[query for _, query in embedding_requests]
|
||||||
)
|
)
|
||||||
for (idx, _), vector in zip(embedding_requests, vectors):
|
for (idx, _), vector in zip(embedding_requests, vectors, strict=False):
|
||||||
_paramslist = queries[idx][1]
|
_paramslist = queries[idx][1]
|
||||||
for i in range(len(_paramslist)):
|
for i in range(len(_paramslist)):
|
||||||
if _paramslist[i] is PLACEHOLDER:
|
if _paramslist[i] is PLACEHOLDER:
|
||||||
_paramslist[i] = vector
|
_paramslist[i] = vector
|
||||||
|
|
||||||
for (idx, _), (query, params) in zip(search_ops, queries):
|
for (idx, _), (query, params) in zip(search_ops, queries, strict=False):
|
||||||
await cur.execute(query, params)
|
await cur.execute(query, params)
|
||||||
rows = cast(list[Row], await cur.fetchall())
|
rows = cast(list[Row], await cur.fetchall())
|
||||||
items = [
|
items = [
|
||||||
@@ -510,7 +512,7 @@ class AsyncPostgresStore(AsyncBatchedBaseStore, BasePostgresStore[_ainternal.Con
|
|||||||
cur: AsyncCursor[DictRow],
|
cur: AsyncCursor[DictRow],
|
||||||
) -> None:
|
) -> None:
|
||||||
queries = self._get_batch_list_namespaces_queries(list_ops)
|
queries = self._get_batch_list_namespaces_queries(list_ops)
|
||||||
for (query, params), (idx, _) in zip(queries, list_ops):
|
for (query, params), (idx, _) in zip(queries, list_ops, strict=False):
|
||||||
await cur.execute(query, params)
|
await cur.execute(query, params)
|
||||||
rows = cast(list[dict], await cur.fetchall())
|
rows = cast(list[dict], await cur.fetchall())
|
||||||
namespaces = [_decode_ns_bytes(row["truncated_prefix"]) for row in rows]
|
namespaces = [_decode_ns_bytes(row["truncated_prefix"]) for row in rows]
|
||||||
|
|||||||
@@ -6,18 +6,16 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import Iterable, Iterator, Sequence
|
from collections.abc import Callable, Iterable, Iterator, Sequence
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
|
||||||
Generic,
|
Generic,
|
||||||
Literal,
|
Literal,
|
||||||
NamedTuple,
|
NamedTuple,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
|
||||||
cast,
|
cast,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -141,7 +139,7 @@ CREATE INDEX CONCURRENTLY IF NOT EXISTS store_vectors_embedding_idx ON store_vec
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
C = TypeVar("C", bound=Union[_pg_internal.Conn, _ainternal.Conn])
|
C = TypeVar("C", bound=_pg_internal.Conn | _ainternal.Conn)
|
||||||
|
|
||||||
|
|
||||||
class PoolConfig(TypedDict, total=False):
|
class PoolConfig(TypedDict, total=False):
|
||||||
@@ -255,7 +253,7 @@ class BasePostgresStore(Generic[C]):
|
|||||||
|
|
||||||
results = []
|
results = []
|
||||||
for namespace, items in namespace_groups.items():
|
for namespace, items in namespace_groups.items():
|
||||||
_, keys = zip(*items)
|
_, keys = zip(*items, strict=False)
|
||||||
this_refresh_ttls = refresh_ttls[namespace]
|
this_refresh_ttls = refresh_ttls[namespace]
|
||||||
|
|
||||||
query = """
|
query = """
|
||||||
@@ -868,7 +866,7 @@ class PostgresStore(BaseStore, BasePostgresStore[_pg_internal.Conn]):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
timeout: Maximum time to wait for the thread to stop, in seconds.
|
timeout: Maximum time to wait for the thread to stop, in seconds.
|
||||||
If None, wait indefinitely.
|
If `None`, wait indefinitely.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if the thread was successfully stopped or wasn't running,
|
bool: True if the thread was successfully stopped or wasn't running,
|
||||||
@@ -1014,7 +1012,9 @@ class PostgresStore(BaseStore, BasePostgresStore[_pg_internal.Conn]):
|
|||||||
query,
|
query,
|
||||||
[
|
[
|
||||||
p
|
p
|
||||||
for (ns, k, pathname, _), vector in zip(txt_params, vectors)
|
for (ns, k, pathname, _), vector in zip(
|
||||||
|
txt_params, vectors, strict=False
|
||||||
|
)
|
||||||
for p in (ns, k, pathname, vector)
|
for p in (ns, k, pathname, vector)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -1035,13 +1035,15 @@ class PostgresStore(BaseStore, BasePostgresStore[_pg_internal.Conn]):
|
|||||||
embeddings = self.embeddings.embed_documents(
|
embeddings = self.embeddings.embed_documents(
|
||||||
[query for _, query in embedding_requests]
|
[query for _, query in embedding_requests]
|
||||||
)
|
)
|
||||||
for (idx, _), embedding in zip(embedding_requests, embeddings):
|
for (idx, _), embedding in zip(
|
||||||
|
embedding_requests, embeddings, strict=False
|
||||||
|
):
|
||||||
_paramslist = queries[idx][1]
|
_paramslist = queries[idx][1]
|
||||||
for i in range(len(_paramslist)):
|
for i in range(len(_paramslist)):
|
||||||
if _paramslist[i] is PLACEHOLDER:
|
if _paramslist[i] is PLACEHOLDER:
|
||||||
_paramslist[i] = embedding
|
_paramslist[i] = embedding
|
||||||
|
|
||||||
for (idx, _), (query, params) in zip(search_ops, queries):
|
for (idx, _), (query, params) in zip(search_ops, queries, strict=False):
|
||||||
cur.execute(query, params)
|
cur.execute(query, params)
|
||||||
rows = cast(list[Row], cur.fetchall())
|
rows = cast(list[Row], cur.fetchall())
|
||||||
results[idx] = [
|
results[idx] = [
|
||||||
@@ -1058,7 +1060,7 @@ class PostgresStore(BaseStore, BasePostgresStore[_pg_internal.Conn]):
|
|||||||
cur: Cursor[DictRow],
|
cur: Cursor[DictRow],
|
||||||
) -> None:
|
) -> None:
|
||||||
for (query, params), (idx, _) in zip(
|
for (query, params), (idx, _) in zip(
|
||||||
self._get_batch_list_namespaces_queries(list_ops), list_ops
|
self._get_batch_list_namespaces_queries(list_ops), list_ops, strict=False
|
||||||
):
|
):
|
||||||
cur.execute(query, params)
|
cur.execute(query, params)
|
||||||
results[idx] = [_decode_ns_bytes(row["truncated_prefix"]) for row in cur]
|
results[idx] = [_decode_ns_bytes(row["truncated_prefix"]) for row in cur]
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "langgraph-checkpoint-postgres"
|
name = "langgraph-checkpoint-postgres"
|
||||||
version = "2.0.24"
|
version = "3.0.1"
|
||||||
description = "Library with a Postgres implementation of LangGraph checkpoint saver."
|
description = "Library with a Postgres implementation of LangGraph checkpoint saver."
|
||||||
authors = []
|
authors = []
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
license-files = ['LICENSE']
|
license-files = ['LICENSE']
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langgraph-checkpoint>=2.0.21,<3.0.0",
|
"langgraph-checkpoint>=2.1.2,<4.0.0",
|
||||||
"orjson>=3.10.1",
|
"orjson>=3.10.1",
|
||||||
"psycopg>=3.2.0",
|
"psycopg>=3.2.0",
|
||||||
"psycopg-pool>=3.2.0",
|
"psycopg-pool>=3.2.0",
|
||||||
@@ -22,18 +22,24 @@ dependencies = [
|
|||||||
Repository = "https://www.github.com/langchain-ai/langgraph"
|
Repository = "https://www.github.com/langchain-ai/langgraph"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
test = [
|
||||||
"ruff",
|
|
||||||
"codespell",
|
|
||||||
"pytest",
|
"pytest",
|
||||||
"anyio",
|
"anyio",
|
||||||
"pytest-asyncio",
|
"pytest-asyncio",
|
||||||
"pytest-mock",
|
"pytest-mock",
|
||||||
"mypy",
|
|
||||||
"psycopg[binary]",
|
"psycopg[binary]",
|
||||||
"langgraph-checkpoint",
|
"langgraph-checkpoint",
|
||||||
"pytest-watcher",
|
"pytest-watcher",
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
"ruff",
|
||||||
|
"codespell",
|
||||||
|
"mypy",
|
||||||
|
]
|
||||||
|
dev = [
|
||||||
|
{include-group = "test"},
|
||||||
|
{include-group = "lint"},
|
||||||
|
]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
default-groups = ['dev']
|
default-groups = ['dev']
|
||||||
@@ -55,8 +61,10 @@ lint.select = [
|
|||||||
"UP", # pyupgrade
|
"UP", # pyupgrade
|
||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"I", # isort
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
]
|
]
|
||||||
lint.ignore = ["E501", "B008"]
|
lint.ignore = ["E501", "B008"]
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
# https://mypy.readthedocs.io/en/stable/config_file.html
|
# https://mypy.readthedocs.io/en/stable/config_file.html
|
||||||
|
|||||||
@@ -187,13 +187,11 @@ def test_data():
|
|||||||
metadata_1: CheckpointMetadata = {
|
metadata_1: CheckpointMetadata = {
|
||||||
"source": "input",
|
"source": "input",
|
||||||
"step": 2,
|
"step": 2,
|
||||||
"writes": {},
|
|
||||||
"score": 1,
|
"score": 1,
|
||||||
}
|
}
|
||||||
metadata_2: CheckpointMetadata = {
|
metadata_2: CheckpointMetadata = {
|
||||||
"source": "loop",
|
"source": "loop",
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
"score": None,
|
"score": None,
|
||||||
}
|
}
|
||||||
metadata_3: CheckpointMetadata = {}
|
metadata_3: CheckpointMetadata = {}
|
||||||
@@ -220,7 +218,6 @@ async def test_combined_metadata(saver_name: str, test_data) -> None:
|
|||||||
metadata: CheckpointMetadata = {
|
metadata: CheckpointMetadata = {
|
||||||
"source": "loop",
|
"source": "loop",
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
"score": None,
|
"score": None,
|
||||||
}
|
}
|
||||||
await saver.aput(config, chkpnt, metadata, {})
|
await saver.aput(config, chkpnt, metadata, {})
|
||||||
@@ -246,7 +243,6 @@ async def test_asearch(saver_name: str, test_data) -> None:
|
|||||||
query_1 = {"source": "input"} # search by 1 key
|
query_1 = {"source": "input"} # search by 1 key
|
||||||
query_2 = {
|
query_2 = {
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
} # search by multiple keys
|
} # search by multiple keys
|
||||||
query_3: dict[str, Any] = {} # search by no keys, return all checkpoints
|
query_3: dict[str, Any] = {} # search by no keys, return all checkpoints
|
||||||
query_4 = {"source": "update", "step": 1} # no match
|
query_4 = {"source": "update", "step": 1} # no match
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import itertools
|
import itertools
|
||||||
import sys
|
|
||||||
import uuid
|
import uuid
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
@@ -34,9 +33,6 @@ TTL_MINUTES = TTL_SECONDS / 60
|
|||||||
|
|
||||||
@pytest.fixture(scope="function", params=["default", "pipe", "pool"])
|
@pytest.fixture(scope="function", params=["default", "pipe", "pool"])
|
||||||
async def store(request) -> AsyncIterator[AsyncPostgresStore]:
|
async def store(request) -> AsyncIterator[AsyncPostgresStore]:
|
||||||
if sys.version_info < (3, 10):
|
|
||||||
pytest.skip("Async Postgres tests require Python 3.10+")
|
|
||||||
|
|
||||||
database = f"test_{uuid.uuid4().hex[:16]}"
|
database = f"test_{uuid.uuid4().hex[:16]}"
|
||||||
uri_parts = DEFAULT_URI.split("/")
|
uri_parts = DEFAULT_URI.split("/")
|
||||||
uri_base = "/".join(uri_parts[:-1])
|
uri_base = "/".join(uri_parts[:-1])
|
||||||
@@ -358,8 +354,6 @@ async def _create_vector_store(
|
|||||||
text_fields: list[str] | None = None,
|
text_fields: list[str] | None = None,
|
||||||
) -> AsyncIterator[AsyncPostgresStore]:
|
) -> AsyncIterator[AsyncPostgresStore]:
|
||||||
"""Create a store with vector search enabled."""
|
"""Create a store with vector search enabled."""
|
||||||
if sys.version_info < (3, 10):
|
|
||||||
pytest.skip("Async Postgres tests require Python 3.10+")
|
|
||||||
|
|
||||||
database = f"test_{uuid.uuid4().hex[:16]}"
|
database = f"test_{uuid.uuid4().hex[:16]}"
|
||||||
uri_parts = DEFAULT_URI.split("/")
|
uri_parts = DEFAULT_URI.split("/")
|
||||||
|
|||||||
@@ -754,7 +754,7 @@ def _cosine_similarity(X: list[float], Y: list[list[float]]) -> list[float]:
|
|||||||
|
|
||||||
similarities = []
|
similarities = []
|
||||||
for y in Y:
|
for y in Y:
|
||||||
dot_product = sum(a * b for a, b in zip(X, y))
|
dot_product = sum(a * b for a, b in zip(X, y, strict=False))
|
||||||
norm1 = sum(a * a for a in X) ** 0.5
|
norm1 = sum(a * a for a in X) ** 0.5
|
||||||
norm2 = sum(a * a for a in y) ** 0.5
|
norm2 = sum(a * a for a in y) ** 0.5
|
||||||
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
||||||
@@ -771,7 +771,7 @@ def _inner_product(X: list[float], Y: list[list[float]]) -> list[float]:
|
|||||||
|
|
||||||
similarities = []
|
similarities = []
|
||||||
for y in Y:
|
for y in Y:
|
||||||
similarity = sum(a * b for a, b in zip(X, y))
|
similarity = sum(a * b for a, b in zip(X, y, strict=False))
|
||||||
similarities.append(similarity)
|
similarities.append(similarity)
|
||||||
|
|
||||||
return similarities
|
return similarities
|
||||||
@@ -785,7 +785,7 @@ def _neg_l2_distance(X: list[float], Y: list[list[float]]) -> list[float]:
|
|||||||
|
|
||||||
similarities = []
|
similarities = []
|
||||||
for y in Y:
|
for y in Y:
|
||||||
similarity = sum((a - b) ** 2 for a, b in zip(X, y)) ** 0.5
|
similarity = sum((a - b) ** 2 for a, b in zip(X, y, strict=False)) ** 0.5
|
||||||
similarities.append(-similarity)
|
similarities.append(-similarity)
|
||||||
|
|
||||||
return similarities
|
return similarities
|
||||||
|
|||||||
@@ -169,13 +169,11 @@ def test_data():
|
|||||||
metadata_1: CheckpointMetadata = {
|
metadata_1: CheckpointMetadata = {
|
||||||
"source": "input",
|
"source": "input",
|
||||||
"step": 2,
|
"step": 2,
|
||||||
"writes": {},
|
|
||||||
"score": 1,
|
"score": 1,
|
||||||
}
|
}
|
||||||
metadata_2: CheckpointMetadata = {
|
metadata_2: CheckpointMetadata = {
|
||||||
"source": "loop",
|
"source": "loop",
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
"score": None,
|
"score": None,
|
||||||
}
|
}
|
||||||
metadata_3: CheckpointMetadata = {}
|
metadata_3: CheckpointMetadata = {}
|
||||||
@@ -202,7 +200,6 @@ def test_combined_metadata(saver_name: str, test_data) -> None:
|
|||||||
metadata: CheckpointMetadata = {
|
metadata: CheckpointMetadata = {
|
||||||
"source": "loop",
|
"source": "loop",
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
"score": None,
|
"score": None,
|
||||||
}
|
}
|
||||||
saver.put(config, chkpnt, metadata, {})
|
saver.put(config, chkpnt, metadata, {})
|
||||||
@@ -228,7 +225,6 @@ def test_search(saver_name: str, test_data) -> None:
|
|||||||
query_1 = {"source": "input"} # search by 1 key
|
query_1 = {"source": "input"} # search by 1 key
|
||||||
query_2 = {
|
query_2 = {
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"writes": {"foo": "bar"},
|
|
||||||
} # search by multiple keys
|
} # search by multiple keys
|
||||||
query_3: dict[str, Any] = {} # search by no keys, return all checkpoints
|
query_3: dict[str, Any] = {} # search by no keys, return all checkpoints
|
||||||
query_4 = {"source": "update", "step": 1} # no match
|
query_4 = {"source": "update", "step": 1} # no match
|
||||||
|
|||||||
Generated
+208
-221
@@ -1,6 +1,6 @@
|
|||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 3
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
@@ -105,17 +105,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" },
|
{ url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" },
|
{ url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" },
|
{ url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/ca/9a0983dd5c8e9733565cf3db4df2b0a2e9a82659fd8aa2a868ac6e4a991f/charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", size = 207520, upload-time = "2025-08-09T07:57:11.026Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/c6/99271dc37243a4f925b09090493fb96c9333d7992c6187f5cfe5312008d2/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", size = 147307, upload-time = "2025-08-09T07:57:12.4Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/69/132eab043356bba06eb333cc2cc60c6340857d0a2e4ca6dc2b51312886b3/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", size = 160448, upload-time = "2025-08-09T07:57:13.712Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/04/9a/914d294daa4809c57667b77470533e65def9c0be1ef8b4c1183a99170e9d/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", size = 157758, upload-time = "2025-08-09T07:57:14.979Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/a8/6f5bcf1bcf63cb45625f7c5cadca026121ff8a6c8a3256d8d8cd59302663/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", size = 152487, upload-time = "2025-08-09T07:57:16.332Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/72/d3d0e9592f4e504f9dea08b8db270821c909558c353dc3b457ed2509f2fb/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", size = 150054, upload-time = "2025-08-09T07:57:17.576Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/20/30/5f64fe3981677fe63fa987b80e6c01042eb5ff653ff7cec1b7bd9268e54e/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", size = 161703, upload-time = "2025-08-09T07:57:20.012Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e1/ef/dd08b2cac9284fd59e70f7d97382c33a3d0a926e45b15fc21b3308324ffd/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", size = 159096, upload-time = "2025-08-09T07:57:21.329Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/8c/dcef87cfc2b3f002a6478f38906f9040302c68aebe21468090e39cde1445/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", size = 153852, upload-time = "2025-08-09T07:57:22.608Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/63/86/9cbd533bd37883d467fcd1bd491b3547a3532d0fbb46de2b99feeebf185e/charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", size = 99840, upload-time = "2025-08-09T07:57:23.883Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/d6/7e805c8e5c46ff9729c49950acc4ee0aeb55efb8b3a56687658ad10c3216/charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", size = 107438, upload-time = "2025-08-09T07:57:25.287Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -245,7 +234,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langgraph-checkpoint"
|
name = "langgraph-checkpoint"
|
||||||
version = "2.1.1"
|
version = "3.0.1"
|
||||||
source = { editable = "../checkpoint" }
|
source = { editable = "../checkpoint" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "langchain-core" },
|
{ name = "langchain-core" },
|
||||||
@@ -255,7 +244,7 @@ dependencies = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "langchain-core", specifier = ">=0.2.38" },
|
{ name = "langchain-core", specifier = ">=0.2.38" },
|
||||||
{ name = "ormsgpack", specifier = ">=1.10.0" },
|
{ name = "ormsgpack", specifier = ">=1.12.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
@@ -273,10 +262,26 @@ dev = [
|
|||||||
{ name = "redis" },
|
{ name = "redis" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "dataclasses-json" },
|
||||||
|
{ name = "numpy" },
|
||||||
|
{ name = "pandas" },
|
||||||
|
{ name = "pandas-stubs", specifier = ">=2.2.2.240807" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
{ name = "redis" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langgraph-checkpoint-postgres"
|
name = "langgraph-checkpoint-postgres"
|
||||||
version = "2.0.24"
|
version = "3.0.1"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "langgraph-checkpoint" },
|
{ name = "langgraph-checkpoint" },
|
||||||
@@ -298,6 +303,20 @@ dev = [
|
|||||||
{ name = "pytest-watcher" },
|
{ name = "pytest-watcher" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
{ name = "langgraph-checkpoint" },
|
||||||
|
{ name = "psycopg", extra = ["binary"] },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
@@ -320,6 +339,20 @@ dev = [
|
|||||||
{ name = "pytest-watcher" },
|
{ name = "pytest-watcher" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
{ name = "langgraph-checkpoint", editable = "../checkpoint" },
|
||||||
|
{ name = "psycopg", extras = ["binary"] },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langsmith"
|
name = "langsmith"
|
||||||
@@ -381,12 +414,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" },
|
{ url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/a6/490ff491d8ecddf8ab91762d4f67635040202f76a44171420bcbe38ceee5/mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b", size = 12807230, upload-time = "2025-09-19T00:09:49.471Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/2e/60076fc829645d167ece9e80db9e8375648d210dab44cc98beb5b322a826/mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133", size = 11895666, upload-time = "2025-09-19T00:10:53.678Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/4a/1e2880a2a5dda4dc8d9ecd1a7e7606bc0b0e14813637eeda40c38624e037/mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6", size = 12499608, upload-time = "2025-09-19T00:09:36.204Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/00/81/a117f1b73a3015b076b20246b1f341c34a578ebd9662848c6b80ad5c4138/mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac", size = 13244551, upload-time = "2025-09-19T00:10:17.531Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9b/61/b9f48e1714ce87c7bf0358eb93f60663740ebb08f9ea886ffc670cea7933/mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b", size = 13491552, upload-time = "2025-09-19T00:10:13.753Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/66/b2c0af3b684fa80d1b27501a8bdd3d2daa467ea3992a8aa612f5ca17c2db/mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0", size = 9765635, upload-time = "2025-09-19T00:10:30.993Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" },
|
{ url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -474,67 +501,61 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl", hash = "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", size = 136266, upload-time = "2025-08-26T17:46:13.853Z" },
|
{ url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl", hash = "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", size = 136266, upload-time = "2025-08-26T17:46:13.853Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", size = 131351, upload-time = "2025-08-26T17:46:15.27Z" },
|
{ url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", size = 131351, upload-time = "2025-08-26T17:46:15.27Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", size = 125985, upload-time = "2025-08-26T17:46:16.67Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", size = 125985, upload-time = "2025-08-26T17:46:16.67Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/a6/18d88ccf8e5d8f711310eba9b4f6562f4aa9d594258efdc4dcf8c1550090/orjson-3.11.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:56afaf1e9b02302ba636151cfc49929c1bb66b98794291afd0e5f20fecaf757c", size = 238221, upload-time = "2025-08-26T17:46:18.113Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/18/e210365a17bf984c89db40c8be65da164b4ce6a866a2a0ae1d6407c2630b/orjson-3.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:913f629adef31d2d350d41c051ce7e33cf0fd06a5d1cb28d49b1899b23b903aa", size = 123209, upload-time = "2025-08-26T17:46:19.688Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/43/6b3f8ec15fa910726ed94bd2e618f86313ad1cae7c3c8c6b9b8a3a161814/orjson-3.11.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0a23b41f8f98b4e61150a03f83e4f0d566880fe53519d445a962929a4d21045", size = 127881, upload-time = "2025-08-26T17:46:21.502Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4a/ed/f41d2406355ce67efdd4ab504732b27bea37b7dbdab3eb86314fe764f1b9/orjson-3.11.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d721fee37380a44f9d9ce6c701b3960239f4fb3d5ceea7f31cbd43882edaa2f", size = 130306, upload-time = "2025-08-26T17:46:22.914Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/a1/1be02950f92c82e64602d3d284bd76d9fc82a6b92c9ce2a387e57a825a11/orjson-3.11.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73b92a5b69f31b1a58c0c7e31080aeaec49c6e01b9522e71ff38d08f15aa56de", size = 132383, upload-time = "2025-08-26T17:46:24.33Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/49/46766ac00c68192b516a15ffc44c2a9789ca3468b8dc8a500422d99bf0dd/orjson-3.11.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2489b241c19582b3f1430cc5d732caefc1aaf378d97e7fb95b9e56bed11725f", size = 135159, upload-time = "2025-08-26T17:46:25.741Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/e1/27fd5e7600fdd82996329d48ee56f6e9e9ae4d31eadbc7f93fd2ff0d8214/orjson-3.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5189a5dab8b0312eadaf9d58d3049b6a52c454256493a557405e77a3d67ab7f", size = 132690, upload-time = "2025-08-26T17:46:27.271Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/21/f57ef08799a68c36ef96fe561101afeef735caa80814636b2e18c234e405/orjson-3.11.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9d8787bdfbb65a85ea76d0e96a3b1bed7bf0fbcb16d40408dc1172ad784a49d2", size = 131086, upload-time = "2025-08-26T17:46:33.067Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/84/a3a24306a9dc482e929232c65f5b8c69188136edd6005441d8cc4754f7ea/orjson-3.11.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:8e531abd745f51f8035e207e75e049553a86823d189a51809c078412cefb399a", size = 403884, upload-time = "2025-08-26T17:46:34.55Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/11/98/fdae5b2c28bc358e6868e54c8eca7398c93d6a511f0436b61436ad1b04dc/orjson-3.11.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8ab962931015f170b97a3dd7bd933399c1bae8ed8ad0fb2a7151a5654b6941c7", size = 145837, upload-time = "2025-08-26T17:46:36.46Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7d/a9/2fe5cd69ed231f3ed88b1ad36a6957e3d2c876eb4b2c6b17b8ae0a6681fc/orjson-3.11.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:124d5ba71fee9c9902c4a7baa9425e663f7f0aecf73d31d54fe3dd357d62c1a7", size = 135325, upload-time = "2025-08-26T17:46:38.03Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ac/a4/7d4c8aefb45f6c8d7d527d84559a3a7e394b9fd1d424a2b5bcaf75fa68e7/orjson-3.11.3-cp39-cp39-win32.whl", hash = "sha256:22724d80ee5a815a44fc76274bb7ba2e7464f5564aacb6ecddaa9970a83e3225", size = 136184, upload-time = "2025-08-26T17:46:39.542Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/1f/1d6a24d22001e96c0afcf1806b6eabee1109aebd2ef20ec6698f6a6012d7/orjson-3.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:215c595c792a87d4407cb72dd5e0f6ee8e694ceeb7f9102b533c5a9bf2a916bb", size = 131373, upload-time = "2025-08-26T17:46:41.227Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ormsgpack"
|
name = "ormsgpack"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/92/36/44eed5ef8ce93cded76a576780bab16425ce7876f10d3e2e6265e46c21ea/ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16", size = 58629, upload-time = "2025-05-24T19:07:53.944Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/6c/67/d5ef41c3b4a94400be801984ef7c7fc9623e1a82b643e74eeec367e7462b/ormsgpack-1.12.0.tar.gz", hash = "sha256:94be818fdbb0285945839b88763b269987787cb2f7ef280cad5d6ec815b7e608", size = 49959, upload-time = "2025-11-04T18:30:10.083Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/fc/74/c2dd5daf069e3798d09d5746000f9b210de04df83834e5cb47f0ace51892/ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216", size = 376280, upload-time = "2025-05-24T19:06:51.3Z" },
|
{ url = "https://files.pythonhosted.org/packages/4d/0c/8f45fcd22c95190b05d4fba71375d8f783a9e3b0b6aaf476812b693e3868/ormsgpack-1.12.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e08904c232358b94a682ccfbb680bc47d3fd5c424bb7dccb65974dd20c95e8e1", size = 369156, upload-time = "2025-11-04T18:29:17.629Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/78/7b/30ff4bffb709e8a242005a8c4d65714fd96308ad640d31cff1b85c0d8cc4/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373", size = 204335, upload-time = "2025-05-24T19:06:53.442Z" },
|
{ url = "https://files.pythonhosted.org/packages/d2/f8/c7adc093d4ceb05e38786906815f868210f808326c27f8124b4d9466a26b/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9ed7a4b0037d69c8ba7e670e03ee65ae8d5c5114a409e73c5770d7fb5e4b895", size = 195743, upload-time = "2025-11-04T18:29:18.964Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8f/3f/c95b7d142819f801a0acdbd04280e8132e43b6e5a8920173e8eb92ea0e6a/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5", size = 215373, upload-time = "2025-05-24T19:06:55.153Z" },
|
{ url = "https://files.pythonhosted.org/packages/fe/b8/bf002648fa6c150ed6157837b00303edafb35f65c352429463f83214de18/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:db2928525b684f3f2af0367aef7ae8d20cde37fc5349c700017129d493a755aa", size = 206472, upload-time = "2025-11-04T18:29:19.951Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/1a/e30f4bcf386db2015d1686d1da6110c95110294d8ea04f86091dd5eb3361/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a", size = 216469, upload-time = "2025-05-24T19:06:56.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/23/d6/1f445947c95a931bb189b7864a3f9dcbeebe7dcbc1b3c7387427b3779228/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45f911d9c5b23d11e49ff03fc8f9566745a2b1a7d9033733a1c0a2fa9301cd60", size = 207959, upload-time = "2025-11-04T18:29:21.282Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/96/fc/7e44aeade22b91883586f45b7278c118fd210834c069774891447f444fc9/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227", size = 384590, upload-time = "2025-05-24T19:06:58.286Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/9c/dd8ccd7553a5c1d0b4b69a0541611983a2f9bc2e8c5708a4bfffc0100468/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:98c54ae6fd682b2aceb264505af9b2255f3df9d84e6e4369bc44d2110f1f311d", size = 377659, upload-time = "2025-11-04T18:29:22.561Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/78/f92c24e8446697caa83c122f10b6cf5e155eddf81ce63905c8223a260482/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7", size = 478891, upload-time = "2025-05-24T19:07:00.126Z" },
|
{ url = "https://files.pythonhosted.org/packages/3d/08/3282d8f6330e742d4cdbcfbe2c100b403ae5526ae82a1c1b6a11b7967e37/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:857ab987c3502de08258cc4baf0e87267cb2c80931601084e13df3c355b1ab9d", size = 471391, upload-time = "2025-11-04T18:29:23.663Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/75/87449690253c64bea2b663c7c8f2dbc9ad39d73d0b38db74bdb0f3947b16/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84", size = 390121, upload-time = "2025-05-24T19:07:01.777Z" },
|
{ url = "https://files.pythonhosted.org/packages/18/d4/94a2fbfd4837754bda7a099b6a23b9d40aba9e76e1af8b8fb8133612eb54/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27579d45dc502ee736238e1024559cb0a01aa72a3b68827448b8edf6a2dcdc9c", size = 381501, upload-time = "2025-11-04T18:29:24.771Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/cc/c83257faf3a5169ec29dd87121317a25711da9412ee8c1e82f2e1a00c0be/ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07", size = 121196, upload-time = "2025-05-24T19:07:03.47Z" },
|
{ url = "https://files.pythonhosted.org/packages/d8/c6/1a9fa122cb5deb10b067bbaa43165b12291a914cc0ce364988ff17bbf405/ormsgpack-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:c78379d054760875540cf2e81f28da1bb78d09fda3eabdbeb6c53b3e297158cb", size = 112715, upload-time = "2025-11-04T18:29:26.016Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/27/7da748bc0d7d567950a378dee5a32477ed5d15462ab186918b5f25cac1ad/ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775", size = 376275, upload-time = "2025-05-24T19:07:05.128Z" },
|
{ url = "https://files.pythonhosted.org/packages/1a/ba/3cae83cf36420c1c8dd294f16c852c03313aafe2439a165c4c6ac611b1d0/ormsgpack-1.12.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c40d86d77391b18dd34de5295e3de2b8ad818bcab9c9def4121c8ec5c9714ae4", size = 369159, upload-time = "2025-11-04T18:29:27.057Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/65/c082cc8c74a914dbd05af0341c761c73c3d9960b7432bbf9b8e1e20811af/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af", size = 204335, upload-time = "2025-05-24T19:07:06.423Z" },
|
{ url = "https://files.pythonhosted.org/packages/97/d4/5e176309e01a8b9098d80201aac1eb7db9336c3b5b4fa6254a2bbb0d0fa0/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:777b7fab364dc0f200bb382a98a385c8222ffa6a2333d627d763797326202c86", size = 195744, upload-time = "2025-11-04T18:29:28.069Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/62/17ef7e5d9766c79355b9c594cc9328c204f1677bc35da0595cc4e46449f0/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e", size = 215372, upload-time = "2025-05-24T19:07:08.149Z" },
|
{ url = "https://files.pythonhosted.org/packages/4f/83/6d80c8c5571639c000a39f38f77752dfaf9d9e552d775331e8d280f66a4e/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b5089ad9dd5b3d3013b245a55e4abaea2f8ad70f4a78e1b002127b02340004", size = 206474, upload-time = "2025-11-04T18:29:29.034Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4e/92/7c91e8115fc37e88d1a35e13200fda3054ff5d2e5adf017345e58cea4834/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3", size = 216470, upload-time = "2025-05-24T19:07:09.903Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/e6/940311e48dc0cfc3e212bd7007a21ed0825158638057687d804f2c5c2cca/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaf0c87cace7bc08fbf68c5cc66605b593df6427e9f4de235b2da358787e008", size = 207959, upload-time = "2025-11-04T18:29:30.315Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2c/86/ce053c52e2517b90e390792d83e926a7a523c1bce5cc63d0a7cd05ce6cf6/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b", size = 384591, upload-time = "2025-05-24T19:07:11.24Z" },
|
{ url = "https://files.pythonhosted.org/packages/1a/e3/fbe94b0a311815343b86a95a0627e4901b11ff6fd522679ca29a2a88c99b/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f62d476fe28bc5675d9aff30341bfa9f41d7de332c5b63fbbe9aaf6bb7ec74d4", size = 377666, upload-time = "2025-11-04T18:29:31.38Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/07/e8/2ad59f2ab222c6029e500bc966bfd2fe5cb099f8ab6b7ebeb50ddb1a6fe5/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5", size = 478892, upload-time = "2025-05-24T19:07:13.147Z" },
|
{ url = "https://files.pythonhosted.org/packages/a3/3b/229cfa28076798ffb619aaa854b842de3f2ed5ea4e6509bf34d14c038c4d/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ded7810095b887e28434f32f5a345d354e88cf851bab3c5435aeb86a718618d2", size = 471394, upload-time = "2025-11-04T18:29:32.521Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/73/f55e4b47b7b18fd8e7789680051bf830f1e39c03f1d9ed993cd0c3e97215/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08", size = 390122, upload-time = "2025-05-24T19:07:14.557Z" },
|
{ url = "https://files.pythonhosted.org/packages/6b/bd/4eae4ab35586e4175c07acb5f98aec83aa9d8987f71ea0443aa900191bdf/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f72a1dea0c4ae7c4101dcfbe8133f274a9d769d0b87fe5188db4fab07ffabaee", size = 381506, upload-time = "2025-11-04T18:29:33.533Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f7/87/073251cdb93d4c6241748568b3ad1b2a76281fb2002eed16a3a4043d61cf/ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a", size = 121197, upload-time = "2025-05-24T19:07:15.981Z" },
|
{ url = "https://files.pythonhosted.org/packages/dd/51/f9d56d6d015cbfa1ce9a4358ca30a41744644f0cf606e060d7203efe5af8/ormsgpack-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:8f479bfef847255d7d0b12c7a198f6a21490155da2da3062e082ba370893d4a1", size = 112707, upload-time = "2025-11-04T18:29:34.898Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/95/f3ab1a7638f6aa9362e87916bb96087fbbc5909db57e19f12ad127560e1e/ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0", size = 376806, upload-time = "2025-05-24T19:07:17.221Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/07/bb189ef7072979f2f96e8716e952172efdce9c54930aa0814bec73aee19b/ormsgpack-1.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:3583ca410e4502144b2594170542e4bbef7b15643fd1208703ae820f11029036", size = 106533, upload-time = "2025-11-04T18:29:36.112Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/2b/42f559f13c0b0f647b09d749682851d47c1a7e48308c43612ae6833499c8/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6", size = 204433, upload-time = "2025-05-24T19:07:18.569Z" },
|
{ url = "https://files.pythonhosted.org/packages/a2/f2/c1036b2775fcc0cfa5fd618c53bcd3b862ee07298fb627f03af4c7982f84/ormsgpack-1.12.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e0c1e08b64d99076fee155276097489b82cc56e8d5951c03c721a65a32f44494", size = 369538, upload-time = "2025-11-04T18:29:37.125Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/42/1ca0cb4d8c80340a89a4af9e6d8951fb8ba0d076a899d2084eadf536f677/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5", size = 215547, upload-time = "2025-05-24T19:07:20.245Z" },
|
{ url = "https://files.pythonhosted.org/packages/d9/ca/526c4ae02f3cb34621af91bf8282a10d666757c2e0c6ff391ff5d403d607/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd43bcb299131690b8e0677af172020b2ada8e625169034b42ac0c13adf84aa", size = 195872, upload-time = "2025-11-04T18:29:38.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0a/38/184a570d7c44c0260bc576d1daaac35b2bfd465a50a08189518505748b9a/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07", size = 216746, upload-time = "2025-05-24T19:07:21.83Z" },
|
{ url = "https://files.pythonhosted.org/packages/7f/0f/83bb7968e9715f6a85be53d041b1e6324a05428f56b8b980dac866886871/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0149d595341e22ead340bf281b2995c4cc7dc8d522a6b5f575fe17aa407604", size = 206469, upload-time = "2025-11-04T18:29:39.749Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/2f/1aaffd08f6b7fdc2a57336a80bdfb8df24e6a65ada5aa769afecfcbc6cc6/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044", size = 384783, upload-time = "2025-05-24T19:07:23.674Z" },
|
{ url = "https://files.pythonhosted.org/packages/02/e3/9e93ca1065f2d4af035804a842b1ff3025bab580c7918239bb225cd1fee2/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19a1b27d169deb553c80fd10b589fc2be1fc14cee779fae79fcaf40db04de2b", size = 208273, upload-time = "2025-11-04T18:29:40.769Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/63/3e53d6f43bb35e00c98f2b8ab2006d5138089ad254bc405614fbf0213502/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd", size = 479076, upload-time = "2025-05-24T19:07:25.047Z" },
|
{ url = "https://files.pythonhosted.org/packages/b3/d8/6d6ef901b3a8b8f3ab8836b135a56eb7f66c559003e251d9530bedb12627/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f28896942d655064940dfe06118b7ce1e3468d051483148bf02c99ec157483a", size = 377839, upload-time = "2025-11-04T18:29:42.092Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/19/fa1121b03b61402bb4d04e35d164e2320ef73dfb001b57748110319dd014/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0", size = 390447, upload-time = "2025-05-24T19:07:26.568Z" },
|
{ url = "https://files.pythonhosted.org/packages/4c/72/fcb704bfa4c2c3a37b647d597cc45a13cffc9d50baac635a9ad620731d29/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9396efcfa48b4abbc06e44c5dbc3c4574a8381a80cb4cd01eea15d28b38c554e", size = 471446, upload-time = "2025-11-04T18:29:43.133Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/0d/73143ecb94ac4a5dcba223402139240a75dee0cc6ba8a543788a5646407a/ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722", size = 121401, upload-time = "2025-05-24T19:07:28.308Z" },
|
{ url = "https://files.pythonhosted.org/packages/84/f8/402e4e3eb997c2ee534c99bec4b5bb359c2a1f9edadf043e254a71e11378/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:96586ed537a5fb386a162c4f9f7d8e6f76e07b38a990d50c73f11131e00ff040", size = 381783, upload-time = "2025-11-04T18:29:44.466Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/61/f8/ec5f4e03268d0097545efaab2893aa63f171cf2959cb0ea678a5690e16a1/ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f", size = 376806, upload-time = "2025-05-24T19:07:29.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/8d/5897b700360bc00911b70ae5ef1134ee7abf5baa81a92a4be005917d3dfd/ormsgpack-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e70387112fb3870e4844de090014212cdcf1342f5022047aecca01ec7de05d7a", size = 112943, upload-time = "2025-11-04T18:29:45.468Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c1/19/b3c53284aad1e90d4d7ed8c881a373d218e16675b8b38e3569d5b40cc9b8/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643", size = 204433, upload-time = "2025-05-24T19:07:30.977Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/44/1e73649f79bb96d6cf9e5bcbac68b6216d238bba80af351c4c0cbcf7ee15/ormsgpack-1.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:d71290a23de5d4829610c42665d816c661ecad8979883f3f06b2e3ab9639962e", size = 106688, upload-time = "2025-11-04T18:29:46.411Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/0b/845c258f59df974a20a536c06cace593698491defdd3d026a8a5f9b6e745/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e", size = 215549, upload-time = "2025-05-24T19:07:32.345Z" },
|
{ url = "https://files.pythonhosted.org/packages/2e/e8/35f11ce9313111488b26b3035e4cbe55caa27909c0b6c8b5b5cd59f9661e/ormsgpack-1.12.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:766f2f3b512d85cd375b26a8b1329b99843560b50b93d3880718e634ad4a5de5", size = 369574, upload-time = "2025-11-04T18:29:47.431Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/61/56/57fce8fb34ca6c9543c026ebebf08344c64dbb7b6643d6ddd5355d37e724/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c", size = 216747, upload-time = "2025-05-24T19:07:34.075Z" },
|
{ url = "https://files.pythonhosted.org/packages/61/b0/77461587f412d4e598d3687bafe23455ed0f26269f44be20252eddaa624e/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84b285b1f3f185aad7da45641b873b30acfd13084cf829cf668c4c6480a81583", size = 195893, upload-time = "2025-11-04T18:29:48.735Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/3f/655b5f6a2475c8d209f5348cfbaaf73ce26237b92d79ef2ad439407dd0fa/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb", size = 384785, upload-time = "2025-05-24T19:07:35.83Z" },
|
{ url = "https://files.pythonhosted.org/packages/c6/67/e197ceb04c3b550589e5407fc9fdae10f4e2e2eba5fdac921a269e02e974/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e23604fc79fe110292cb365f4c8232e64e63a34f470538be320feae3921f271b", size = 206503, upload-time = "2025-11-04T18:29:49.99Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4b/94/687a0ad8afd17e4bce1892145d6a1111e58987ddb176810d02a1f3f18686/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935", size = 479076, upload-time = "2025-05-24T19:07:37.533Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/b1/7fa8ba82a25cef678983c7976f85edeef5014f5c26495f338258e6a3cf1c/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc32b156c113a0fae2975051417d8d9a7a5247c34b2d7239410c46b75ce9348a", size = 208257, upload-time = "2025-11-04T18:29:51.007Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/34/68925232e81e0e062a2f0ac678f62aa3b6f7009d6a759e19324dbbaebae7/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668", size = 390446, upload-time = "2025-05-24T19:07:39.469Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/b1/759e999390000d2589e6d0797f7265e6ec28378547075d28d3736248ab63/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:94ac500dd10c20fa8b8a23bc55606250bfe711bf9716828d9f3d44dfd1f25668", size = 377852, upload-time = "2025-11-04T18:29:52.103Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/ad/f4e1a36a6d1714afb7ffb74b3ababdcb96529cf4e7a216f9f7c8eda837b6/ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69", size = 121399, upload-time = "2025-05-24T19:07:40.854Z" },
|
{ url = "https://files.pythonhosted.org/packages/51/e7/0af737c94272494d9d84a3c29cc42c973ef7fd2342917020906596db863c/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c5201ff7ec24f721f813a182885a17064cffdbe46b2412685a52e6374a872c8f", size = 471456, upload-time = "2025-11-04T18:29:53.336Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/8f/bb80469db9d5b10708cba6997463d140486ca7053a5d18f99b5739cfecf7/ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32", size = 376272, upload-time = "2025-05-24T19:07:42.16Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/ba/c81f0aa4f19fbf457213395945b672e6fde3ce777e3587456e7f0fca2147/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a9740bb3839c9368aacae1cbcfc474ee6976458f41cc135372b7255d5206c953", size = 381813, upload-time = "2025-11-04T18:29:54.394Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/9c/48f714ed3d5a153f25e3b490496e6ba214aee265a82be1b61e39019ea146/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4", size = 204314, upload-time = "2025-05-24T19:07:43.444Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/15/429c72d64323503fd42cc4ca8398930ded8aa8b3470df8a86b3bbae7a35c/ormsgpack-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ed37f29772432048b58174e920a1d4c4cde0404a5d448d3d8bbcc95d86a6918", size = 112949, upload-time = "2025-11-04T18:29:55.371Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/42/7f9edf6e5511120b5304c76c5d3a8b4719ff927555a6dba41b6f9d041b30/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453", size = 215386, upload-time = "2025-05-24T19:07:45.232Z" },
|
{ url = "https://files.pythonhosted.org/packages/55/b9/e72c451a40f8c57bfc229e0b8e536ecea7203c8f0a839676df2ffb605c62/ormsgpack-1.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:b03994bbec5d6d42e03d6604e327863f885bde67aa61e06107ce1fa5bdd3e71d", size = 106689, upload-time = "2025-11-04T18:29:56.262Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/87/41e14485857fbe4ed5a530677fe60dd6910a254825c0b1cb5b04baaa4be0/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1", size = 216466, upload-time = "2025-05-24T19:07:46.548Z" },
|
{ url = "https://files.pythonhosted.org/packages/13/16/13eab1a75da531b359105fdee90dda0b6bd1ca0a09880250cf91d8bdfdea/ormsgpack-1.12.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0f3981ba3cba80656012090337e548e597799e14b41e3d0b595ab5ab05a23d7f", size = 369620, upload-time = "2025-11-04T18:29:57.255Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/68/769fa1c721d8aa6799c0ce98b1711ae57de3e6379b554ebf9a11be4c62ff/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681", size = 384600, upload-time = "2025-05-24T19:07:47.945Z" },
|
{ url = "https://files.pythonhosted.org/packages/a0/c1/cbcc38b7af4ce58d8893e56d3595c0c8dcd117093bf048f889cf351bdba0/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:901f6f55184d6776dbd5183cbce14caf05bf7f467eef52faf9b094686980bf71", size = 195925, upload-time = "2025-11-04T18:29:58.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4e/f9/b57fd387fe16753783a3cea0ed2471c727bbed4356d8a08e3f0340251870/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3", size = 478888, upload-time = "2025-05-24T19:07:49.801Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/59/4fa4dc0681490e12b75333440a1c0fd9741b0ebff272b1db4a29d35c2021/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13b15412571422b711b40f45e3fe6d993ea3314b5e97d1a853fe99226c5effc", size = 206594, upload-time = "2025-11-04T18:29:59.329Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/0f/464cdfa7f9ee817c2d94485880b6c3c4b9f22df9fcbf21c303bbfebcb3ed/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d", size = 390118, upload-time = "2025-05-24T19:07:51.193Z" },
|
{ url = "https://files.pythonhosted.org/packages/39/67/249770896bc32bb91b22c30256961f935d0915cbcf6e289a7fc961d9b14c/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91fa8a452553a62e5fb3fbab471e7faf7b3bec3c87a2f355ebf3d7aab290fe4f", size = 208307, upload-time = "2025-11-04T18:30:00.377Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ad/03/b9146dff5458def4c0a2b1e35c1c24e4d5e8083899aa0718b6eccba39317/ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749", size = 121199, upload-time = "2025-05-24T19:07:52.639Z" },
|
{ url = "https://files.pythonhosted.org/packages/07/0a/e041a248cd72f2f4c07e155913e0a3ede4c86cf21a40ae6cd79f135f2847/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74ec101f69624695eec4ce7c953192d97748254abe78fb01b591f06d529e1952", size = 377844, upload-time = "2025-11-04T18:30:01.389Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/71/6f7773e4ffda73a358ce4bba69b3e8bee9d40a7a06315e4c1cd7a3ea9d02/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:9bbf7896580848326c1f9bd7531f264e561f98db7e08e15aa75963d83832c717", size = 471572, upload-time = "2025-11-04T18:30:02.486Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/65/29/af6769a4289c07acc71e7bda1d64fb31800563147d73142686e185e82348/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7567917da613b8f8d591c1674e411fd3404bea41ef2b9a0e0a1e049c0f9406d7", size = 381842, upload-time = "2025-11-04T18:30:03.799Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/dd/0a86195ee7a1a96c088aefc8504385e881cf56f4563ed81bafe21cbf1fb0/ormsgpack-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e418256c5d8622b8bc92861936f7c6a0131355e7bcad88a42102ae8227f8a1c", size = 113008, upload-time = "2025-11-04T18:30:04.777Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4c/57/fafc79e32f3087f6f26f509d80b8167516326bfea38d30502627c01617e0/ormsgpack-1.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:433ace29aa02713554f714c62a4e4dcad0c9e32674ba4f66742c91a4c3b1b969", size = 106648, upload-time = "2025-11-04T18:30:05.708Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/cf/5d58d9b132128d2fe5d586355dde76af386554abef00d608f66b913bff1f/ormsgpack-1.12.0-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e57164be4ca34b64e210ec515059193280ac84df4d6f31a6fcbfb2fc8436de55", size = 369803, upload-time = "2025-11-04T18:30:06.728Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/67/42/968a2da361eaff2e4cbb17c82c7599787babf16684110ad70409646cc1e4/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:904f96289deaa92fc6440b122edc27c5bdc28234edd63717f6d853d88c823a83", size = 195991, upload-time = "2025-11-04T18:30:07.713Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/03/f0/9696c6c6cf8ad35170f0be8d0ef3523cc258083535f6c8071cb8235ebb8b/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b291d086e524a1062d57d1b7b5a8bcaaf29caebf0212fec12fd86240bd33633", size = 208316, upload-time = "2025-11-04T18:30:08.663Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -632,15 +653,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/6b/8c/9446e3a84187220a98657ef778518f9b44eba55b1f6c3e8300d229ec9930/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1f6982609b8ff8fcd67299b67cd5787da1876f3bb28fedd547262cfa8ddedf94", size = 3535121, upload-time = "2025-09-08T09:11:53.887Z" },
|
{ url = "https://files.pythonhosted.org/packages/6b/8c/9446e3a84187220a98657ef778518f9b44eba55b1f6c3e8300d229ec9930/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1f6982609b8ff8fcd67299b67cd5787da1876f3bb28fedd547262cfa8ddedf94", size = 3535121, upload-time = "2025-09-08T09:11:53.887Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b4/e1/f0382c956bfaa951a0dbd4d5a354acf093ef7e5219996958143dfd2bf37d/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bf30dcf6aaaa8d4779a20d2158bdf81cc8e84ce8eee595d748a7671c70c7b890", size = 3584235, upload-time = "2025-09-08T09:12:01.118Z" },
|
{ url = "https://files.pythonhosted.org/packages/b4/e1/f0382c956bfaa951a0dbd4d5a354acf093ef7e5219996958143dfd2bf37d/psycopg_binary-3.2.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bf30dcf6aaaa8d4779a20d2158bdf81cc8e84ce8eee595d748a7671c70c7b890", size = 3584235, upload-time = "2025-09-08T09:12:01.118Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/dd/464bd739bacb3b745a1c93bc15f20f0b1e27f0a64ec693367794b398673b/psycopg_binary-3.2.10-cp314-cp314-win_amd64.whl", hash = "sha256:d5c6a66a76022af41970bf19f51bc6bf87bd10165783dd1d40484bfd87d6b382", size = 2973554, upload-time = "2025-09-08T09:12:05.884Z" },
|
{ url = "https://files.pythonhosted.org/packages/5a/dd/464bd739bacb3b745a1c93bc15f20f0b1e27f0a64ec693367794b398673b/psycopg_binary-3.2.10-cp314-cp314-win_amd64.whl", hash = "sha256:d5c6a66a76022af41970bf19f51bc6bf87bd10165783dd1d40484bfd87d6b382", size = 2973554, upload-time = "2025-09-08T09:12:05.884Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/c0/f9fefea225c49b9c4528ce17d93f91d4687a7e619f4cd19818a0481e4066/psycopg_binary-3.2.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0738320a8d405f98743227ff70ed8fac9670870289435f4861dc640cef4a61d3", size = 3996466, upload-time = "2025-09-08T09:12:50.418Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/a9/505a7558ed4f0aaa1373f307a7f21cba480ef99063107e8809e0e45c73d1/psycopg_binary-3.2.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89440355d1b163b11dc661ae64a5667578aab1b80bbf71ced90693d88e9863e1", size = 4067930, upload-time = "2025-09-08T09:12:54.225Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/36/d1/b08bba8a017a24dfdd3844d5e1b080bba30fddb6b8d71316387772bcbdd3/psycopg_binary-3.2.10-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3234605839e7d7584bd0a20716395eba34d368a5099dafe7896c943facac98fc", size = 4627622, upload-time = "2025-09-08T09:13:05.429Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/27/e4cf67d8e9f9e045ef445832b1dcc6ed6173184d80740e40a7f35c57fa27/psycopg_binary-3.2.10-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:725843fd444075cc6c9989f5b25ca83ac68d8d70b58e1f476fbb4096975e43cc", size = 4722794, upload-time = "2025-09-08T09:13:11.155Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/aa/3b/31f7629360d2c36c0bba8897dafdc7482d71170f601bc79358fb3f099f88/psycopg_binary-3.2.10-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:447afc326cbc95ed67c0cd27606c0f81fa933b830061e096dbd37e08501cb3de", size = 4407119, upload-time = "2025-09-08T09:13:16.477Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/03/84/9610a633b33d685269318a92428619097d1a9fc0832ee6c4fd3d6ab75fb8/psycopg_binary-3.2.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5334a61a00ccb722f0b28789e265c7a273cfd10d5a1ed6bf062686fbb71e7032", size = 3880897, upload-time = "2025-09-08T09:13:20.716Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/0d/af7ba9bcb035454d19f88992a5cdd03313500a78f55d47f474b561ecf996/psycopg_binary-3.2.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:183a59cbdcd7e156669577fd73a9e917b1ee664e620f1e31ae138d24c7714693", size = 3563882, upload-time = "2025-09-08T09:13:25.919Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/b2/b6ba55c253208f03271b2c3d890fe5cbb8ef8f54551e6579a76f3978188f/psycopg_binary-3.2.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8fa2efaf5e2f8c289a185c91c80a624a8f97aa17fbedcbc68f373d089b332afd", size = 3604543, upload-time = "2025-09-08T09:13:31.075Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b7/3d/90ac8893003ed16eb2709d755bd8c53eb6330fc7f34774df166b2e00eed4/psycopg_binary-3.2.10-cp39-cp39-win_amd64.whl", hash = "sha256:6220d6efd6e2df7b67d70ed60d653106cd3b70c5cb8cbe4e9f0a142a5db14015", size = 2888394, upload-time = "2025-09-08T09:13:35.73Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -657,7 +669,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.11.9"
|
version = "2.12.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-types" },
|
{ name = "annotated-types" },
|
||||||
@@ -665,118 +677,123 @@ dependencies = [
|
|||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
{ name = "typing-inspection" },
|
{ name = "typing-inspection" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/8d/35/d319ed522433215526689bad428a94058b6dd12190ce7ddd78618ac14b28/pydantic-2.12.2.tar.gz", hash = "sha256:7b8fa15b831a4bbde9d5b84028641ac3080a4ca2cbd4a621a661687e741624fd", size = 816358, upload-time = "2025-10-14T15:02:21.842Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" },
|
{ url = "https://files.pythonhosted.org/packages/6c/98/468cb649f208a6f1279448e6e5247b37ae79cf5e4041186f1e2ef3d16345/pydantic-2.12.2-py3-none-any.whl", hash = "sha256:25ff718ee909acd82f1ff9b1a4acfd781bb23ab3739adaa7144f19a6a4e231ae", size = 460628, upload-time = "2025-10-14T15:02:19.623Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic-core"
|
name = "pydantic-core"
|
||||||
version = "2.33.2"
|
version = "2.41.4"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/df/18/d0944e8eaaa3efd0a91b0f1fc537d3be55ad35091b6a87638211ba691964/pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5", size = 457557, upload-time = "2025-10-14T10:23:47.909Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" },
|
{ url = "https://files.pythonhosted.org/packages/a7/3d/9b8ca77b0f76fcdbf8bc6b72474e264283f461284ca84ac3fde570c6c49a/pydantic_core-2.41.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2442d9a4d38f3411f22eb9dd0912b7cbf4b7d5b6c92c4173b75d3e1ccd84e36e", size = 2111197, upload-time = "2025-10-14T10:19:43.303Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" },
|
{ url = "https://files.pythonhosted.org/packages/59/92/b7b0fe6ed4781642232755cb7e56a86e2041e1292f16d9ae410a0ccee5ac/pydantic_core-2.41.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:30a9876226dda131a741afeab2702e2d127209bde3c65a2b8133f428bc5d006b", size = 1917909, upload-time = "2025-10-14T10:19:45.194Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" },
|
{ url = "https://files.pythonhosted.org/packages/52/8c/3eb872009274ffa4fb6a9585114e161aa1a0915af2896e2d441642929fe4/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d55bbac04711e2980645af68b97d445cdbcce70e5216de444a6c4b6943ebcccd", size = 1969905, upload-time = "2025-10-14T10:19:46.567Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/21/35adf4a753bcfaea22d925214a0c5b880792e3244731b3f3e6fec0d124f7/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1d778fb7849a42d0ee5927ab0f7453bf9f85eef8887a546ec87db5ddb178945", size = 2051938, upload-time = "2025-10-14T10:19:48.237Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" },
|
{ url = "https://files.pythonhosted.org/packages/7d/d0/cdf7d126825e36d6e3f1eccf257da8954452934ede275a8f390eac775e89/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b65077a4693a98b90ec5ad8f203ad65802a1b9b6d4a7e48066925a7e1606706", size = 2250710, upload-time = "2025-10-14T10:19:49.619Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" },
|
{ url = "https://files.pythonhosted.org/packages/2e/1c/af1e6fd5ea596327308f9c8d1654e1285cc3d8de0d584a3c9d7705bf8a7c/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62637c769dee16eddb7686bf421be48dfc2fae93832c25e25bc7242e698361ba", size = 2367445, upload-time = "2025-10-14T10:19:51.269Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" },
|
{ url = "https://files.pythonhosted.org/packages/d3/81/8cece29a6ef1b3a92f956ea6da6250d5b2d2e7e4d513dd3b4f0c7a83dfea/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfe3aa529c8f501babf6e502936b9e8d4698502b2cfab41e17a028d91b1ac7b", size = 2072875, upload-time = "2025-10-14T10:19:52.671Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" },
|
{ url = "https://files.pythonhosted.org/packages/e3/37/a6a579f5fc2cd4d5521284a0ab6a426cc6463a7b3897aeb95b12f1ba607b/pydantic_core-2.41.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca2322da745bf2eeb581fc9ea3bbb31147702163ccbcbf12a3bb630e4bf05e1d", size = 2191329, upload-time = "2025-10-14T10:19:54.214Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" },
|
{ url = "https://files.pythonhosted.org/packages/ae/03/505020dc5c54ec75ecba9f41119fd1e48f9e41e4629942494c4a8734ded1/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e8cd3577c796be7231dcf80badcf2e0835a46665eaafd8ace124d886bab4d700", size = 2151658, upload-time = "2025-10-14T10:19:55.843Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/5d/2c0d09fb53aa03bbd2a214d89ebfa6304be7df9ed86ee3dc7770257f41ee/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1cae8851e174c83633f0833e90636832857297900133705ee158cf79d40f03e6", size = 2316777, upload-time = "2025-10-14T10:19:57.607Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" },
|
{ url = "https://files.pythonhosted.org/packages/ea/4b/c2c9c8f5e1f9c864b57d08539d9d3db160e00491c9f5ee90e1bfd905e644/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a26d950449aae348afe1ac8be5525a00ae4235309b729ad4d3399623125b43c9", size = 2320705, upload-time = "2025-10-14T10:19:59.016Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/c3/a74c1c37f49c0a02c89c7340fafc0ba816b29bd495d1a31ce1bdeacc6085/pydantic_core-2.41.4-cp310-cp310-win32.whl", hash = "sha256:0cf2a1f599efe57fa0051312774280ee0f650e11152325e41dfd3018ef2c1b57", size = 1975464, upload-time = "2025-10-14T10:20:00.581Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" },
|
{ url = "https://files.pythonhosted.org/packages/d6/23/5dd5c1324ba80303368f7569e2e2e1a721c7d9eb16acb7eb7b7f85cb1be2/pydantic_core-2.41.4-cp310-cp310-win_amd64.whl", hash = "sha256:a8c2e340d7e454dc3340d3d2e8f23558ebe78c98aa8f68851b04dcb7bc37abdc", size = 2024497, upload-time = "2025-10-14T10:20:03.018Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" },
|
{ url = "https://files.pythonhosted.org/packages/62/4c/f6cbfa1e8efacd00b846764e8484fe173d25b8dab881e277a619177f3384/pydantic_core-2.41.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:28ff11666443a1a8cf2a044d6a545ebffa8382b5f7973f22c36109205e65dc80", size = 2109062, upload-time = "2025-10-14T10:20:04.486Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" },
|
{ url = "https://files.pythonhosted.org/packages/21/f8/40b72d3868896bfcd410e1bd7e516e762d326201c48e5b4a06446f6cf9e8/pydantic_core-2.41.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61760c3925d4633290292bad462e0f737b840508b4f722247d8729684f6539ae", size = 1916301, upload-time = "2025-10-14T10:20:06.857Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" },
|
{ url = "https://files.pythonhosted.org/packages/94/4d/d203dce8bee7faeca791671c88519969d98d3b4e8f225da5b96dad226fc8/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eae547b7315d055b0de2ec3965643b0ab82ad0106a7ffd29615ee9f266a02827", size = 1968728, upload-time = "2025-10-14T10:20:08.353Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" },
|
{ url = "https://files.pythonhosted.org/packages/65/f5/6a66187775df87c24d526985b3a5d78d861580ca466fbd9d4d0e792fcf6c/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef9ee5471edd58d1fcce1c80ffc8783a650e3e3a193fe90d52e43bb4d87bff1f", size = 2050238, upload-time = "2025-10-14T10:20:09.766Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/b9/78336345de97298cf53236b2f271912ce11f32c1e59de25a374ce12f9cce/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15dd504af121caaf2c95cb90c0ebf71603c53de98305621b94da0f967e572def", size = 2249424, upload-time = "2025-10-14T10:20:11.732Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" },
|
{ url = "https://files.pythonhosted.org/packages/99/bb/a4584888b70ee594c3d374a71af5075a68654d6c780369df269118af7402/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a926768ea49a8af4d36abd6a8968b8790f7f76dd7cbd5a4c180db2b4ac9a3a2", size = 2366047, upload-time = "2025-10-14T10:20:13.647Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" },
|
{ url = "https://files.pythonhosted.org/packages/5f/8d/17fc5de9d6418e4d2ae8c675f905cdafdc59d3bf3bf9c946b7ab796a992a/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916b9b7d134bff5440098a4deb80e4cb623e68974a87883299de9124126c2a8", size = 2071163, upload-time = "2025-10-14T10:20:15.307Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" },
|
{ url = "https://files.pythonhosted.org/packages/54/e7/03d2c5c0b8ed37a4617430db68ec5e7dbba66358b629cd69e11b4d564367/pydantic_core-2.41.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cf90535979089df02e6f17ffd076f07237efa55b7343d98760bde8743c4b265", size = 2190585, upload-time = "2025-10-14T10:20:17.3Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/fc/15d1c9fe5ad9266a5897d9b932b7f53d7e5cfc800573917a2c5d6eea56ec/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7533c76fa647fade2d7ec75ac5cc079ab3f34879626dae5689b27790a6cf5a5c", size = 2150109, upload-time = "2025-10-14T10:20:19.143Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" },
|
{ url = "https://files.pythonhosted.org/packages/26/ef/e735dd008808226c83ba56972566138665b71477ad580fa5a21f0851df48/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:37e516bca9264cbf29612539801ca3cd5d1be465f940417b002905e6ed79d38a", size = 2315078, upload-time = "2025-10-14T10:20:20.742Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" },
|
{ url = "https://files.pythonhosted.org/packages/90/00/806efdcf35ff2ac0f938362350cd9827b8afb116cc814b6b75cf23738c7c/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0c19cb355224037c83642429b8ce261ae108e1c5fbf5c028bac63c77b0f8646e", size = 2318737, upload-time = "2025-10-14T10:20:22.306Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" },
|
{ url = "https://files.pythonhosted.org/packages/41/7e/6ac90673fe6cb36621a2283552897838c020db343fa86e513d3f563b196f/pydantic_core-2.41.4-cp311-cp311-win32.whl", hash = "sha256:09c2a60e55b357284b5f31f5ab275ba9f7f70b7525e18a132ec1f9160b4f1f03", size = 1974160, upload-time = "2025-10-14T10:20:23.817Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" },
|
{ url = "https://files.pythonhosted.org/packages/e0/9d/7c5e24ee585c1f8b6356e1d11d40ab807ffde44d2db3b7dfd6d20b09720e/pydantic_core-2.41.4-cp311-cp311-win_amd64.whl", hash = "sha256:711156b6afb5cb1cb7c14a2cc2c4a8b4c717b69046f13c6b332d8a0a8f41ca3e", size = 2021883, upload-time = "2025-10-14T10:20:25.48Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" },
|
{ url = "https://files.pythonhosted.org/packages/33/90/5c172357460fc28b2871eb4a0fb3843b136b429c6fa827e4b588877bf115/pydantic_core-2.41.4-cp311-cp311-win_arm64.whl", hash = "sha256:6cb9cf7e761f4f8a8589a45e49ed3c0d92d1d696a45a6feaee8c904b26efc2db", size = 1968026, upload-time = "2025-10-14T10:20:27.039Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/81/d3b3e95929c4369d30b2a66a91db63c8ed0a98381ae55a45da2cd1cc1288/pydantic_core-2.41.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ab06d77e053d660a6faaf04894446df7b0a7e7aba70c2797465a0a1af00fc887", size = 2099043, upload-time = "2025-10-14T10:20:28.561Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" },
|
{ url = "https://files.pythonhosted.org/packages/58/da/46fdac49e6717e3a94fc9201403e08d9d61aa7a770fab6190b8740749047/pydantic_core-2.41.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c53ff33e603a9c1179a9364b0a24694f183717b2e0da2b5ad43c316c956901b2", size = 1910699, upload-time = "2025-10-14T10:20:30.217Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/63/4d948f1b9dd8e991a5a98b77dd66c74641f5f2e5225fee37994b2e07d391/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304c54176af2c143bd181d82e77c15c41cbacea8872a2225dd37e6544dce9999", size = 1952121, upload-time = "2025-10-14T10:20:32.246Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" },
|
{ url = "https://files.pythonhosted.org/packages/b2/a7/e5fc60a6f781fc634ecaa9ecc3c20171d238794cef69ae0af79ac11b89d7/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025ba34a4cf4fb32f917d5d188ab5e702223d3ba603be4d8aca2f82bede432a4", size = 2041590, upload-time = "2025-10-14T10:20:34.332Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" },
|
{ url = "https://files.pythonhosted.org/packages/70/69/dce747b1d21d59e85af433428978a1893c6f8a7068fa2bb4a927fba7a5ff/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9f5f30c402ed58f90c70e12eff65547d3ab74685ffe8283c719e6bead8ef53f", size = 2219869, upload-time = "2025-10-14T10:20:35.965Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" },
|
{ url = "https://files.pythonhosted.org/packages/83/6a/c070e30e295403bf29c4df1cb781317b6a9bac7cd07b8d3acc94d501a63c/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd96e5d15385d301733113bcaa324c8bcf111275b7675a9c6e88bfb19fc05e3b", size = 2345169, upload-time = "2025-10-14T10:20:37.627Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/83/06d001f8043c336baea7fd202a9ac7ad71f87e1c55d8112c50b745c40324/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f348cbb44fae6e9653c1055db7e29de67ea6a9ca03a5fa2c2e11a47cff0e47", size = 2070165, upload-time = "2025-10-14T10:20:39.246Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/14/0a/e567c2883588dd12bcbc110232d892cf385356f7c8a9910311ac997ab715/pydantic_core-2.41.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec22626a2d14620a83ca583c6f5a4080fa3155282718b6055c2ea48d3ef35970", size = 2189067, upload-time = "2025-10-14T10:20:41.015Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/1d/3d9fca34273ba03c9b1c5289f7618bc4bd09c3ad2289b5420481aa051a99/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a95d4590b1f1a43bf33ca6d647b990a88f4a3824a8c4572c708f0b45a5290ed", size = 2132997, upload-time = "2025-10-14T10:20:43.106Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" },
|
{ url = "https://files.pythonhosted.org/packages/52/70/d702ef7a6cd41a8afc61f3554922b3ed8d19dd54c3bd4bdbfe332e610827/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:f9672ab4d398e1b602feadcffcdd3af44d5f5e6ddc15bc7d15d376d47e8e19f8", size = 2307187, upload-time = "2025-10-14T10:20:44.849Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/4c/c06be6e27545d08b802127914156f38d10ca287a9e8489342793de8aae3c/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:84d8854db5f55fead3b579f04bda9a36461dab0730c5d570e1526483e7bb8431", size = 2305204, upload-time = "2025-10-14T10:20:46.781Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/e5/35ae4919bcd9f18603419e23c5eaf32750224a89d41a8df1a3704b69f77e/pydantic_core-2.41.4-cp312-cp312-win32.whl", hash = "sha256:9be1c01adb2ecc4e464392c36d17f97e9110fbbc906bcbe1c943b5b87a74aabd", size = 1972536, upload-time = "2025-10-14T10:20:48.39Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/c2/49c5bb6d2a49eb2ee3647a93e3dae7080c6409a8a7558b075027644e879c/pydantic_core-2.41.4-cp312-cp312-win_amd64.whl", hash = "sha256:d682cf1d22bab22a5be08539dca3d1593488a99998f9f412137bc323179067ff", size = 2031132, upload-time = "2025-10-14T10:20:50.421Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" },
|
{ url = "https://files.pythonhosted.org/packages/06/23/936343dbcba6eec93f73e95eb346810fc732f71ba27967b287b66f7b7097/pydantic_core-2.41.4-cp312-cp312-win_arm64.whl", hash = "sha256:833eebfd75a26d17470b58768c1834dfc90141b7afc6eb0429c21fc5a21dcfb8", size = 1969483, upload-time = "2025-10-14T10:20:52.35Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" },
|
{ url = "https://files.pythonhosted.org/packages/13/d0/c20adabd181a029a970738dfe23710b52a31f1258f591874fcdec7359845/pydantic_core-2.41.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:85e050ad9e5f6fe1004eec65c914332e52f429bc0ae12d6fa2092407a462c746", size = 2105688, upload-time = "2025-10-14T10:20:54.448Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" },
|
{ url = "https://files.pythonhosted.org/packages/00/b6/0ce5c03cec5ae94cca220dfecddc453c077d71363b98a4bbdb3c0b22c783/pydantic_core-2.41.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7393f1d64792763a48924ba31d1e44c2cfbc05e3b1c2c9abb4ceeadd912cced", size = 1910807, upload-time = "2025-10-14T10:20:56.115Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/3e/800d3d02c8beb0b5c069c870cbb83799d085debf43499c897bb4b4aaff0d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94dab0940b0d1fb28bcab847adf887c66a27a40291eedf0b473be58761c9799a", size = 1956669, upload-time = "2025-10-14T10:20:57.874Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/a4/24271cc71a17f64589be49ab8bd0751f6a0a03046c690df60989f2f95c2c/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de7c42f897e689ee6f9e93c4bec72b99ae3b32a2ade1c7e4798e690ff5246e02", size = 2051629, upload-time = "2025-10-14T10:21:00.006Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/de/45af3ca2f175d91b96bfb62e1f2d2f1f9f3b14a734afe0bfeff079f78181/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:664b3199193262277b8b3cd1e754fb07f2c6023289c815a1e1e8fb415cb247b1", size = 2224049, upload-time = "2025-10-14T10:21:01.801Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" },
|
{ url = "https://files.pythonhosted.org/packages/af/8f/ae4e1ff84672bf869d0a77af24fd78387850e9497753c432875066b5d622/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95b253b88f7d308b1c0b417c4624f44553ba4762816f94e6986819b9c273fb2", size = 2342409, upload-time = "2025-10-14T10:21:03.556Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" },
|
{ url = "https://files.pythonhosted.org/packages/18/62/273dd70b0026a085c7b74b000394e1ef95719ea579c76ea2f0cc8893736d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1351f5bbdbbabc689727cb91649a00cb9ee7203e0a6e54e9f5ba9e22e384b84", size = 2069635, upload-time = "2025-10-14T10:21:05.385Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" },
|
{ url = "https://files.pythonhosted.org/packages/30/03/cf485fff699b4cdaea469bc481719d3e49f023241b4abb656f8d422189fc/pydantic_core-2.41.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1affa4798520b148d7182da0615d648e752de4ab1a9566b7471bc803d88a062d", size = 2194284, upload-time = "2025-10-14T10:21:07.122Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" },
|
{ url = "https://files.pythonhosted.org/packages/f9/7e/c8e713db32405dfd97211f2fc0a15d6bf8adb7640f3d18544c1f39526619/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7b74e18052fea4aa8dea2fb7dbc23d15439695da6cbe6cfc1b694af1115df09d", size = 2137566, upload-time = "2025-10-14T10:21:08.981Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" },
|
{ url = "https://files.pythonhosted.org/packages/04/f7/db71fd4cdccc8b75990f79ccafbbd66757e19f6d5ee724a6252414483fb4/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:285b643d75c0e30abda9dc1077395624f314a37e3c09ca402d4015ef5979f1a2", size = 2316809, upload-time = "2025-10-14T10:21:10.805Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" },
|
{ url = "https://files.pythonhosted.org/packages/76/63/a54973ddb945f1bca56742b48b144d85c9fc22f819ddeb9f861c249d5464/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f52679ff4218d713b3b33f88c89ccbf3a5c2c12ba665fb80ccc4192b4608dbab", size = 2311119, upload-time = "2025-10-14T10:21:12.583Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/03/5d12891e93c19218af74843a27e32b94922195ded2386f7b55382f904d2f/pydantic_core-2.41.4-cp313-cp313-win32.whl", hash = "sha256:ecde6dedd6fff127c273c76821bb754d793be1024bc33314a120f83a3c69460c", size = 1981398, upload-time = "2025-10-14T10:21:14.584Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/d8/fd0de71f39db91135b7a26996160de71c073d8635edfce8b3c3681be0d6d/pydantic_core-2.41.4-cp313-cp313-win_amd64.whl", hash = "sha256:d081a1f3800f05409ed868ebb2d74ac39dd0c1ff6c035b5162356d76030736d4", size = 2030735, upload-time = "2025-10-14T10:21:16.432Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" },
|
{ url = "https://files.pythonhosted.org/packages/72/86/c99921c1cf6650023c08bfab6fe2d7057a5142628ef7ccfa9921f2dda1d5/pydantic_core-2.41.4-cp313-cp313-win_arm64.whl", hash = "sha256:f8e49c9c364a7edcbe2a310f12733aad95b022495ef2a8d653f645e5d20c1564", size = 1973209, upload-time = "2025-10-14T10:21:18.213Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" },
|
{ url = "https://files.pythonhosted.org/packages/36/0d/b5706cacb70a8414396efdda3d72ae0542e050b591119e458e2490baf035/pydantic_core-2.41.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ed97fd56a561f5eb5706cebe94f1ad7c13b84d98312a05546f2ad036bafe87f4", size = 1877324, upload-time = "2025-10-14T10:21:20.363Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/2d/cba1fa02cfdea72dfb3a9babb067c83b9dff0bbcb198368e000a6b756ea7/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a870c307bf1ee91fc58a9a61338ff780d01bfae45922624816878dce784095d2", size = 1884515, upload-time = "2025-10-14T10:21:22.339Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" },
|
{ url = "https://files.pythonhosted.org/packages/07/ea/3df927c4384ed9b503c9cc2d076cf983b4f2adb0c754578dfb1245c51e46/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf", size = 2042819, upload-time = "2025-10-14T10:21:26.683Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" },
|
{ url = "https://files.pythonhosted.org/packages/6a/ee/df8e871f07074250270a3b1b82aad4cd0026b588acd5d7d3eb2fcb1471a3/pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2", size = 1995866, upload-time = "2025-10-14T10:21:28.951Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" },
|
{ url = "https://files.pythonhosted.org/packages/fc/de/b20f4ab954d6d399499c33ec4fafc46d9551e11dc1858fb7f5dca0748ceb/pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89", size = 1970034, upload-time = "2025-10-14T10:21:30.869Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" },
|
{ url = "https://files.pythonhosted.org/packages/54/28/d3325da57d413b9819365546eb9a6e8b7cbd9373d9380efd5f74326143e6/pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1", size = 2102022, upload-time = "2025-10-14T10:21:32.809Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" },
|
{ url = "https://files.pythonhosted.org/packages/9e/24/b58a1bc0d834bf1acc4361e61233ee217169a42efbdc15a60296e13ce438/pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac", size = 1905495, upload-time = "2025-10-14T10:21:34.812Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" },
|
{ url = "https://files.pythonhosted.org/packages/fb/a4/71f759cc41b7043e8ecdaab81b985a9b6cad7cec077e0b92cff8b71ecf6b/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554", size = 1956131, upload-time = "2025-10-14T10:21:36.924Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/64/1e79ac7aa51f1eec7c4cda8cbe456d5d09f05fdd68b32776d72168d54275/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e", size = 2052236, upload-time = "2025-10-14T10:21:38.927Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/e3/a3ffc363bd4287b80f1d43dc1c28ba64831f8dfc237d6fec8f2661138d48/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616", size = 2223573, upload-time = "2025-10-14T10:21:41.574Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/27/78814089b4d2e684a9088ede3790763c64693c3d1408ddc0a248bc789126/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af", size = 2342467, upload-time = "2025-10-14T10:21:44.018Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" },
|
{ url = "https://files.pythonhosted.org/packages/92/97/4de0e2a1159cb85ad737e03306717637842c88c7fd6d97973172fb183149/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12", size = 2063754, upload-time = "2025-10-14T10:21:46.466Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" },
|
{ url = "https://files.pythonhosted.org/packages/0f/50/8cb90ce4b9efcf7ae78130afeb99fd1c86125ccdf9906ef64b9d42f37c25/pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d", size = 2196754, upload-time = "2025-10-14T10:21:48.486Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" },
|
{ url = "https://files.pythonhosted.org/packages/34/3b/ccdc77af9cd5082723574a1cc1bcae7a6acacc829d7c0a06201f7886a109/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad", size = 2137115, upload-time = "2025-10-14T10:21:50.63Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" },
|
{ url = "https://files.pythonhosted.org/packages/ca/ba/e7c7a02651a8f7c52dc2cff2b64a30c313e3b57c7d93703cecea76c09b71/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a", size = 2317400, upload-time = "2025-10-14T10:21:52.959Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" },
|
{ url = "https://files.pythonhosted.org/packages/2c/ba/6c533a4ee8aec6b812c643c49bb3bd88d3f01e3cebe451bb85512d37f00f/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025", size = 2312070, upload-time = "2025-10-14T10:21:55.419Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" },
|
{ url = "https://files.pythonhosted.org/packages/22/ae/f10524fcc0ab8d7f96cf9a74c880243576fd3e72bd8ce4f81e43d22bcab7/pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e", size = 1982277, upload-time = "2025-10-14T10:21:57.474Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" },
|
{ url = "https://files.pythonhosted.org/packages/b4/dc/e5aa27aea1ad4638f0c3fb41132f7eb583bd7420ee63204e2d4333a3bbf9/pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894", size = 2024608, upload-time = "2025-10-14T10:21:59.557Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" },
|
{ url = "https://files.pythonhosted.org/packages/3e/61/51d89cc2612bd147198e120a13f150afbf0bcb4615cddb049ab10b81b79e/pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d", size = 1967614, upload-time = "2025-10-14T10:22:01.847Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" },
|
{ url = "https://files.pythonhosted.org/packages/0d/c2/472f2e31b95eff099961fa050c376ab7156a81da194f9edb9f710f68787b/pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da", size = 1876904, upload-time = "2025-10-14T10:22:04.062Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" },
|
{ url = "https://files.pythonhosted.org/packages/4a/07/ea8eeb91173807ecdae4f4a5f4b150a520085b35454350fc219ba79e66a3/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e", size = 1882538, upload-time = "2025-10-14T10:22:06.39Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/29/b53a9ca6cd366bfc928823679c6a76c7a4c69f8201c0ba7903ad18ebae2f/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa", size = 2041183, upload-time = "2025-10-14T10:22:08.812Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" },
|
{ url = "https://files.pythonhosted.org/packages/c7/3d/f8c1a371ceebcaf94d6dd2d77c6cf4b1c078e13a5837aee83f760b4f7cfd/pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d", size = 1993542, upload-time = "2025-10-14T10:22:11.332Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/ac/9fc61b4f9d079482a290afe8d206b8f490e9fd32d4fc03ed4fc698214e01/pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0", size = 1973897, upload-time = "2025-10-14T10:22:13.444Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/12/5ba58daa7f453454464f92b3ca7b9d7c657d8641c48e370c3ebc9a82dd78/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:a1b2cfec3879afb742a7b0bcfa53e4f22ba96571c9e54d6a3afe1052d17d843b", size = 2122139, upload-time = "2025-10-14T10:22:47.288Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" },
|
{ url = "https://files.pythonhosted.org/packages/21/fb/6860126a77725c3108baecd10fd3d75fec25191d6381b6eb2ac660228eac/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:d175600d975b7c244af6eb9c9041f10059f20b8bbffec9e33fdd5ee3f67cdc42", size = 1936674, upload-time = "2025-10-14T10:22:49.555Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/be/57dcaa3ed595d81f8757e2b44a38240ac5d37628bce25fb20d02c7018776/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f184d657fa4947ae5ec9c47bd7e917730fa1cbb78195037e32dcbab50aca5ee", size = 1956398, upload-time = "2025-10-14T10:22:52.19Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" },
|
{ url = "https://files.pythonhosted.org/packages/2f/1d/679a344fadb9695f1a6a294d739fbd21d71fa023286daeea8c0ed49e7c2b/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed810568aeffed3edc78910af32af911c835cc39ebbfacd1f0ab5dd53028e5c", size = 2138674, upload-time = "2025-10-14T10:22:54.499Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" },
|
{ url = "https://files.pythonhosted.org/packages/c4/48/ae937e5a831b7c0dc646b2ef788c27cd003894882415300ed21927c21efa/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:4f5d640aeebb438517150fdeec097739614421900e4a08db4a3ef38898798537", size = 2112087, upload-time = "2025-10-14T10:22:56.818Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/db/6db8073e3d32dae017da7e0d16a9ecb897d0a4d92e00634916e486097961/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:4a9ab037b71927babc6d9e7fc01aea9e66dc2a4a34dff06ef0724a4049629f94", size = 1920387, upload-time = "2025-10-14T10:22:59.342Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" },
|
{ url = "https://files.pythonhosted.org/packages/0d/c1/dd3542d072fcc336030d66834872f0328727e3b8de289c662faa04aa270e/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4dab9484ec605c3016df9ad4fd4f9a390bc5d816a3b10c6550f8424bb80b18c", size = 1951495, upload-time = "2025-10-14T10:23:02.089Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" },
|
{ url = "https://files.pythonhosted.org/packages/2b/c6/db8d13a1f8ab3f1eb08c88bd00fd62d44311e3456d1e85c0e59e0a0376e7/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335", size = 2139008, upload-time = "2025-10-14T10:23:04.539Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" },
|
{ url = "https://files.pythonhosted.org/packages/5d/d4/912e976a2dd0b49f31c98a060ca90b353f3b73ee3ea2fd0030412f6ac5ec/pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e5ab4fc177dd41536b3c32b2ea11380dd3d4619a385860621478ac2d25ceb00", size = 2106739, upload-time = "2025-10-14T10:23:06.934Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" },
|
{ url = "https://files.pythonhosted.org/packages/71/f0/66ec5a626c81eba326072d6ee2b127f8c139543f1bf609b4842978d37833/pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3d88d0054d3fa11ce936184896bed3c1c5441d6fa483b498fac6a5d0dd6f64a9", size = 1932549, upload-time = "2025-10-14T10:23:09.24Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" },
|
{ url = "https://files.pythonhosted.org/packages/c4/af/625626278ca801ea0a658c2dcf290dc9f21bb383098e99e7c6a029fccfc0/pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2a054a8725f05b4b6503357e0ac1c4e8234ad3b0c2ac130d6ffc66f0e170e2", size = 2135093, upload-time = "2025-10-14T10:23:11.626Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" },
|
{ url = "https://files.pythonhosted.org/packages/20/f6/2fba049f54e0f4975fef66be654c597a1d005320fa141863699180c7697d/pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0d9db5a161c99375a0c68c058e227bee1d89303300802601d76a3d01f74e258", size = 2187971, upload-time = "2025-10-14T10:23:14.437Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" },
|
{ url = "https://files.pythonhosted.org/packages/0e/80/65ab839a2dfcd3b949202f9d920c34f9de5a537c3646662bdf2f7d999680/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6273ea2c8ffdac7b7fda2653c49682db815aebf4a89243a6feccf5e36c18c347", size = 2147939, upload-time = "2025-10-14T10:23:16.831Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" },
|
{ url = "https://files.pythonhosted.org/packages/44/58/627565d3d182ce6dfda18b8e1c841eede3629d59c9d7cbc1e12a03aeb328/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:4c973add636efc61de22530b2ef83a65f39b6d6f656df97f678720e20de26caa", size = 2311400, upload-time = "2025-10-14T10:23:19.234Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" },
|
{ url = "https://files.pythonhosted.org/packages/24/06/8a84711162ad5a5f19a88cead37cca81b4b1f294f46260ef7334ae4f24d3/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b69d1973354758007f46cf2d44a4f3d0933f10b6dc9bf15cf1356e037f6f731a", size = 2316840, upload-time = "2025-10-14T10:23:21.738Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" },
|
{ url = "https://files.pythonhosted.org/packages/aa/8b/b7bb512a4682a2f7fbfae152a755d37351743900226d29bd953aaf870eaa/pydantic_core-2.41.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3619320641fd212aaf5997b6ca505e97540b7e16418f4a241f44cdf108ffb50d", size = 2149135, upload-time = "2025-10-14T10:23:24.379Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" },
|
{ url = "https://files.pythonhosted.org/packages/7e/7d/138e902ed6399b866f7cfe4435d22445e16fff888a1c00560d9dc79a780f/pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:491535d45cd7ad7e4a2af4a5169b0d07bebf1adfd164b0368da8aa41e19907a5", size = 2104721, upload-time = "2025-10-14T10:23:26.906Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" },
|
{ url = "https://files.pythonhosted.org/packages/47/13/0525623cf94627f7b53b4c2034c81edc8491cbfc7c28d5447fa318791479/pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:54d86c0cada6aba4ec4c047d0e348cbad7063b87ae0f005d9f8c9ad04d4a92a2", size = 1931608, upload-time = "2025-10-14T10:23:29.306Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" },
|
{ url = "https://files.pythonhosted.org/packages/d6/f9/744bc98137d6ef0a233f808bfc9b18cf94624bf30836a18d3b05d08bf418/pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca1124aced216b2500dc2609eade086d718e8249cb9696660ab447d50a758bd", size = 2132986, upload-time = "2025-10-14T10:23:32.057Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/c8/629e88920171173f6049386cc71f893dff03209a9ef32b4d2f7e7c264bcf/pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c9024169becccf0cb470ada03ee578d7348c119a0d42af3dcf9eda96e3a247c", size = 2187516, upload-time = "2025-10-14T10:23:34.871Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/0f/4f2734688d98488782218ca61bcc118329bf5de05bb7fe3adc7dd79b0b86/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:26895a4268ae5a2849269f4991cdc97236e4b9c010e51137becf25182daac405", size = 2146146, upload-time = "2025-10-14T10:23:37.342Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ed/f2/ab385dbd94a052c62224b99cf99002eee99dbec40e10006c78575aead256/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:ca4df25762cf71308c446e33c9b1fdca2923a3f13de616e2a949f38bf21ff5a8", size = 2311296, upload-time = "2025-10-14T10:23:40.145Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/8e/e4f12afe1beeb9823bba5375f8f258df0cc61b056b0195fb1cf9f62a1a58/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5a28fcedd762349519276c36634e71853b4541079cab4acaaac60c4421827308", size = 2315386, upload-time = "2025-10-14T10:23:42.624Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/48/f7/925f65d930802e3ea2eb4d5afa4cb8730c8dc0d2cb89a59dc4ed2fcb2d74/pydantic_core-2.41.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c173ddcd86afd2535e2b695217e82191580663a1d1928239f877f5a1649ef39f", size = 2147775, upload-time = "2025-10-14T10:23:45.406Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -907,15 +924,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1039,14 +1047,14 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-inspection"
|
name = "typing-inspection"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" },
|
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1085,13 +1093,8 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" },
|
{ url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" },
|
{ url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/52/7223011bb760fce8ddc53416beb65b83a3ea6d7d13738dde75eeb2c89679/watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", size = 96390, upload-time = "2024-11-01T14:06:49.325Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/62/d2b21bc4e706d3a9d467561f487c2938cbd881c69f3808c43ac1ec242391/watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", size = 88386, upload-time = "2024-11-01T14:06:50.536Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ea/22/1c90b20eda9f4132e4603a26296108728a8bfe9584b006bd05dd94548853/watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", size = 89017, upload-time = "2024-11-01T14:06:51.717Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" },
|
{ url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/79/69f2b0e8d3f2afd462029031baafb1b75d11bb62703f0e1022b2e54d49ee/watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", size = 87903, upload-time = "2024-11-01T14:06:57.052Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/2b/dc048dd71c2e5f0f7ebc04dd7912981ec45793a03c0dc462438e0591ba5d/watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", size = 88381, upload-time = "2024-11-01T14:06:58.193Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
||||||
@@ -1192,20 +1195,4 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" },
|
{ url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
|
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/14/0d/d0a405dad6ab6f9f759c26d866cca66cb209bff6f8db656074d662a953dd/zstandard-0.25.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0", size = 795263, upload-time = "2025-09-14T22:18:21.683Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/aa/ceb8d79cbad6dabd4cb1178ca853f6a4374d791c5e0241a0988173e2a341/zstandard-0.25.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2", size = 640560, upload-time = "2025-09-14T22:18:22.867Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/cd/2cf6d476131b509cc122d25d3416a2d0aa17687ddbada7599149f9da620e/zstandard-0.25.0-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df", size = 5344244, upload-time = "2025-09-14T22:18:24.724Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/71/e14820b61a1c137966b7667b400b72fa4a45c836257e443f3d77607db268/zstandard-0.25.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53", size = 5054550, upload-time = "2025-09-14T22:18:26.445Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/ce/26dc5a6fa956be41d0e984909224ed196ee6f91d607f0b3fd84577741a77/zstandard-0.25.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3", size = 5401150, upload-time = "2025-09-14T22:18:28.745Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f2/1b/402cab5edcfe867465daf869d5ac2a94930931c0989633bc01d6a7d8bd68/zstandard-0.25.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362", size = 5448595, upload-time = "2025-09-14T22:18:30.475Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/b2/fc50c58271a1ead0e5a0a0e6311f4b221f35954dce438ce62751b3af9b68/zstandard-0.25.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530", size = 5555290, upload-time = "2025-09-14T22:18:32.336Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/20/5f72d6ba970690df90fdd37195c5caa992e70cb6f203f74cc2bcc0b8cf30/zstandard-0.25.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb", size = 5043898, upload-time = "2025-09-14T22:18:34.215Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/f1/131a0382b8b8d11e84690574645f528f5c5b9343e06cefd77f5fd730cd2b/zstandard-0.25.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751", size = 5571173, upload-time = "2025-09-14T22:18:36.117Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/f6/2a37931023f737fd849c5c28def57442bbafadb626da60cf9ed58461fe24/zstandard-0.25.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577", size = 4958261, upload-time = "2025-09-14T22:18:38.098Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b5/52/ca76ed6dbfd8845a5563d3af4e972da3b9da8a9308ca6b56b0b929d93e23/zstandard-0.25.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7", size = 5265680, upload-time = "2025-09-14T22:18:39.834Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7a/59/edd117dedb97a768578b49fb2f1156defb839d1aa5b06200a62be943667f/zstandard-0.25.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936", size = 5439747, upload-time = "2025-09-14T22:18:41.647Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/71/c2e9234643dcfbd6c5e975e9a2b0050e1b2afffda6c3a959e1b87997bc80/zstandard-0.25.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388", size = 5818805, upload-time = "2025-09-14T22:18:43.602Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/93/8ebc19f0a31c44ea0e7348f9b0d4b326ed413b6575a3c6ff4ed50222abb6/zstandard-0.25.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27", size = 5362280, upload-time = "2025-09-14T22:18:45.625Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/e9/29cc59d4a9d51b3fd8b477d858d0bd7ab627f700908bf1517f46ddd470ae/zstandard-0.25.0-cp39-cp39-win32.whl", hash = "sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649", size = 436460, upload-time = "2025-09-14T22:18:49.077Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/b5/bc7a92c116e2ef32dc8061c209d71e97ff6df37487d7d39adb51a343ee89/zstandard-0.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860", size = 506097, upload-time = "2025-09-14T22:18:47.342Z" },
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
import random
|
import random
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
@@ -184,7 +185,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the SQLite database based on the
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -192,7 +193,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -265,9 +266,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
self.serde.loads_typed((type, checkpoint)),
|
self.serde.loads_typed((type, checkpoint)),
|
||||||
cast(
|
cast(
|
||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
self.jsonplus_serde.loads(metadata)
|
json.loads(metadata) if metadata is not None else {},
|
||||||
if metadata is not None
|
|
||||||
else {},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -301,12 +300,12 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The config to use for listing the checkpoints.
|
config: The config to use for listing the checkpoints.
|
||||||
filter: Additional filtering criteria for metadata. Defaults to None.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: The maximum number of checkpoints to return. Defaults to None.
|
limit: The maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Iterator[CheckpointTuple]: An iterator of checkpoint tuples.
|
An iterator of checkpoint tuples.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> from langgraph.checkpoint.sqlite import SqliteSaver
|
>>> from langgraph.checkpoint.sqlite import SqliteSaver
|
||||||
@@ -358,9 +357,7 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
self.serde.loads_typed((type, checkpoint)),
|
self.serde.loads_typed((type, checkpoint)),
|
||||||
cast(
|
cast(
|
||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
self.jsonplus_serde.loads(metadata)
|
json.loads(metadata) if metadata is not None else {},
|
||||||
if metadata is not None
|
|
||||||
else {},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -413,9 +410,9 @@ class SqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
thread_id = config["configurable"]["thread_id"]
|
thread_id = config["configurable"]["thread_id"]
|
||||||
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
||||||
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
||||||
serialized_metadata = self.jsonplus_serde.dumps(
|
serialized_metadata = json.dumps(
|
||||||
get_checkpoint_metadata(config, metadata)
|
get_checkpoint_metadata(config, metadata), ensure_ascii=False
|
||||||
)
|
).encode("utf-8", "ignore")
|
||||||
with self.cursor() as cur:
|
with self.cursor() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
"INSERT OR REPLACE INTO checkpoints (thread_id, checkpoint_ns, checkpoint_id, parent_checkpoint_id, type, checkpoint, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import json
|
||||||
import random
|
import random
|
||||||
from collections.abc import AsyncIterator, Iterator, Sequence
|
from collections.abc import AsyncIterator, Callable, Iterator, Sequence
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import Any, Callable, TypeVar, cast
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
import aiosqlite
|
import aiosqlite
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
@@ -139,7 +140,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
"""Get a checkpoint tuple from the database.
|
"""Get a checkpoint tuple from the database.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the SQLite database based on the
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -147,7 +148,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# check if we are in the main thread, only bg threads can block
|
# check if we are in the main thread, only bg threads can block
|
||||||
@@ -181,11 +182,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
Args:
|
Args:
|
||||||
config: Base configuration for filtering checkpoints.
|
config: Base configuration for filtering checkpoints.
|
||||||
filter: Additional filtering criteria for metadata.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Iterator[CheckpointTuple]: An iterator of matching checkpoint tuples.
|
An iterator of matching checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# check if we are in the main thread, only bg threads can block
|
# check if we are in the main thread, only bg threads can block
|
||||||
@@ -316,7 +317,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
"""Get a checkpoint tuple from the database asynchronously.
|
"""Get a checkpoint tuple from the database asynchronously.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the SQLite database based on the
|
This method retrieves a checkpoint tuple from the SQLite database based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and checkpoint ID is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -324,7 +325,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
await self.setup()
|
await self.setup()
|
||||||
checkpoint_ns = config["configurable"].get("checkpoint_ns", "")
|
checkpoint_ns = config["configurable"].get("checkpoint_ns", "")
|
||||||
@@ -377,9 +378,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
self.serde.loads_typed((type, checkpoint)),
|
self.serde.loads_typed((type, checkpoint)),
|
||||||
cast(
|
cast(
|
||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
self.jsonplus_serde.loads(metadata)
|
(json.loads(metadata) if metadata is not None else {}),
|
||||||
if metadata is not None
|
|
||||||
else {},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -414,11 +413,11 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
Args:
|
Args:
|
||||||
config: Base configuration for filtering checkpoints.
|
config: Base configuration for filtering checkpoints.
|
||||||
filter: Additional filtering criteria for metadata.
|
filter: Additional filtering criteria for metadata.
|
||||||
before: If provided, only checkpoints before the specified checkpoint ID are returned. Defaults to None.
|
before: If provided, only checkpoints before the specified checkpoint ID are returned.
|
||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
AsyncIterator[CheckpointTuple]: An asynchronous iterator of matching checkpoint tuples.
|
An asynchronous iterator of matching checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
await self.setup()
|
await self.setup()
|
||||||
where, params = search_where(config, filter, before)
|
where, params = search_where(config, filter, before)
|
||||||
@@ -457,9 +456,7 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
self.serde.loads_typed((type, checkpoint)),
|
self.serde.loads_typed((type, checkpoint)),
|
||||||
cast(
|
cast(
|
||||||
CheckpointMetadata,
|
CheckpointMetadata,
|
||||||
self.jsonplus_serde.loads(metadata)
|
(json.loads(metadata) if metadata is not None else {}),
|
||||||
if metadata is not None
|
|
||||||
else {},
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -503,9 +500,9 @@ class AsyncSqliteSaver(BaseCheckpointSaver[str]):
|
|||||||
thread_id = config["configurable"]["thread_id"]
|
thread_id = config["configurable"]["thread_id"]
|
||||||
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
checkpoint_ns = config["configurable"]["checkpoint_ns"]
|
||||||
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
|
||||||
serialized_metadata = self.jsonplus_serde.dumps(
|
serialized_metadata = json.dumps(
|
||||||
get_checkpoint_metadata(config, metadata)
|
get_checkpoint_metadata(config, metadata), ensure_ascii=False
|
||||||
)
|
).encode("utf-8", "ignore")
|
||||||
async with (
|
async with (
|
||||||
self.lock,
|
self.lock,
|
||||||
self.conn.execute(
|
self.conn.execute(
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import AsyncIterator, Iterable, Sequence
|
from collections.abc import AsyncIterator, Callable, Iterable, Sequence
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
from typing import Any, Callable, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
import aiosqlite
|
import aiosqlite
|
||||||
import orjson
|
import orjson
|
||||||
@@ -303,7 +303,7 @@ class AsyncSqliteStore(AsyncBatchedBaseStore, BaseSqliteStore):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
timeout: Maximum time to wait for the task to stop, in seconds.
|
timeout: Maximum time to wait for the task to stop, in seconds.
|
||||||
If None, wait indefinitely.
|
If `None`, wait indefinitely.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if the task was successfully stopped or wasn't running,
|
bool: True if the task was successfully stopped or wasn't running,
|
||||||
@@ -484,7 +484,7 @@ class AsyncSqliteStore(AsyncBatchedBaseStore, BaseSqliteStore):
|
|||||||
|
|
||||||
# Convert vectors to SQLite-friendly format
|
# Convert vectors to SQLite-friendly format
|
||||||
vector_params = []
|
vector_params = []
|
||||||
for (ns, k, pathname, _), vector in zip(txt_params, vectors):
|
for (ns, k, pathname, _), vector in zip(txt_params, vectors, strict=False):
|
||||||
vector_params.extend(
|
vector_params.extend(
|
||||||
[ns, k, pathname, sqlite_vec.serialize_float32(vector)]
|
[ns, k, pathname, sqlite_vec.serialize_float32(vector)]
|
||||||
)
|
)
|
||||||
@@ -517,7 +517,9 @@ class AsyncSqliteStore(AsyncBatchedBaseStore, BaseSqliteStore):
|
|||||||
[query for _, query in embedding_requests]
|
[query for _, query in embedding_requests]
|
||||||
)
|
)
|
||||||
|
|
||||||
for (embed_req_idx, _), embedding in zip(embedding_requests, vectors):
|
for (embed_req_idx, _), embedding in zip(
|
||||||
|
embedding_requests, vectors, strict=False
|
||||||
|
):
|
||||||
# Find the corresponding query in prepared_queries
|
# Find the corresponding query in prepared_queries
|
||||||
# The embed_req_idx is the original index in search_ops, which should map to prepared_queries
|
# The embed_req_idx is the original index in search_ops, which should map to prepared_queries
|
||||||
if embed_req_idx < len(prepared_queries):
|
if embed_req_idx < len(prepared_queries):
|
||||||
@@ -531,7 +533,7 @@ class AsyncSqliteStore(AsyncBatchedBaseStore, BaseSqliteStore):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for (original_op_idx, _), (query, params, needs_refresh) in zip(
|
for (original_op_idx, _), (query, params, needs_refresh) in zip(
|
||||||
search_ops, prepared_queries
|
search_ops, prepared_queries, strict=False
|
||||||
):
|
):
|
||||||
await cur.execute(query, params)
|
await cur.execute(query, params)
|
||||||
rows = await cur.fetchall()
|
rows = await cur.fetchall()
|
||||||
@@ -614,7 +616,7 @@ class AsyncSqliteStore(AsyncBatchedBaseStore, BaseSqliteStore):
|
|||||||
cur: Database cursor.
|
cur: Database cursor.
|
||||||
"""
|
"""
|
||||||
queries = self._get_batch_list_namespaces_queries(list_ops)
|
queries = self._get_batch_list_namespaces_queries(list_ops)
|
||||||
for (query, params), (idx, _) in zip(queries, list_ops):
|
for (query, params), (idx, _) in zip(queries, list_ops, strict=False):
|
||||||
await cur.execute(query, params)
|
await cur.execute(query, params)
|
||||||
|
|
||||||
rows = await cur.fetchall()
|
rows = await cur.fetchall()
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import re
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import Iterable, Iterator, Sequence
|
from collections.abc import Callable, Iterable, Iterator, Sequence
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Any, Callable, Literal, NamedTuple, cast
|
from typing import Any, Literal, NamedTuple, cast
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
import sqlite_vec # type: ignore[import-untyped]
|
import sqlite_vec # type: ignore[import-untyped]
|
||||||
@@ -232,7 +232,7 @@ class BaseSqliteStore:
|
|||||||
|
|
||||||
results = []
|
results = []
|
||||||
for namespace, items in namespace_groups.items():
|
for namespace, items in namespace_groups.items():
|
||||||
_, keys = zip(*items)
|
_, keys = zip(*items, strict=False)
|
||||||
this_refresh_ttls = refresh_ttls[namespace]
|
this_refresh_ttls = refresh_ttls[namespace]
|
||||||
refresh_ttl_any = any(this_refresh_ttls)
|
refresh_ttl_any = any(this_refresh_ttls)
|
||||||
|
|
||||||
@@ -829,7 +829,7 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
|
|
||||||
results = []
|
results = []
|
||||||
for namespace, items in namespace_groups.items():
|
for namespace, items in namespace_groups.items():
|
||||||
_, keys = zip(*items)
|
_, keys = zip(*items, strict=False)
|
||||||
this_refresh_ttls = refresh_ttls[namespace]
|
this_refresh_ttls = refresh_ttls[namespace]
|
||||||
refresh_ttl_any = any(this_refresh_ttls)
|
refresh_ttl_any = any(this_refresh_ttls)
|
||||||
|
|
||||||
@@ -1156,7 +1156,7 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
timeout: Maximum time to wait for the thread to stop, in seconds.
|
timeout: Maximum time to wait for the thread to stop, in seconds.
|
||||||
If None, wait indefinitely.
|
If `None`, wait indefinitely.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if the thread was successfully stopped or wasn't running,
|
bool: True if the thread was successfully stopped or wasn't running,
|
||||||
@@ -1304,7 +1304,7 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
|
|
||||||
# Convert vectors to SQLite-friendly format
|
# Convert vectors to SQLite-friendly format
|
||||||
vector_params = []
|
vector_params = []
|
||||||
for (ns, k, pathname, _), vector in zip(txt_params, vectors):
|
for (ns, k, pathname, _), vector in zip(txt_params, vectors, strict=False):
|
||||||
vector_params.extend(
|
vector_params.extend(
|
||||||
[ns, k, pathname, sqlite_vec.serialize_float32(vector)]
|
[ns, k, pathname, sqlite_vec.serialize_float32(vector)]
|
||||||
)
|
)
|
||||||
@@ -1332,7 +1332,9 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Replace placeholders with actual embeddings
|
# Replace placeholders with actual embeddings
|
||||||
for (embed_req_idx, _), embedding in zip(embedding_requests, embeddings):
|
for (embed_req_idx, _), embedding in zip(
|
||||||
|
embedding_requests, embeddings, strict=False
|
||||||
|
):
|
||||||
if embed_req_idx < len(prepared_queries):
|
if embed_req_idx < len(prepared_queries):
|
||||||
_params_list: list = prepared_queries[embed_req_idx][1]
|
_params_list: list = prepared_queries[embed_req_idx][1]
|
||||||
for i, param in enumerate(_params_list):
|
for i, param in enumerate(_params_list):
|
||||||
@@ -1344,7 +1346,7 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for (original_op_idx, _), (query, params, needs_refresh) in zip(
|
for (original_op_idx, _), (query, params, needs_refresh) in zip(
|
||||||
search_ops, prepared_queries
|
search_ops, prepared_queries, strict=False
|
||||||
):
|
):
|
||||||
cur.execute(query, params)
|
cur.execute(query, params)
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
@@ -1417,7 +1419,7 @@ class SqliteStore(BaseSqliteStore, BaseStore):
|
|||||||
cur: sqlite3.Cursor,
|
cur: sqlite3.Cursor,
|
||||||
) -> None:
|
) -> None:
|
||||||
queries = self._get_batch_list_namespaces_queries(list_ops)
|
queries = self._get_batch_list_namespaces_queries(list_ops)
|
||||||
for (query, params), (idx, _) in zip(queries, list_ops):
|
for (query, params), (idx, _) in zip(queries, list_ops, strict=False):
|
||||||
cur.execute(query, params)
|
cur.execute(query, params)
|
||||||
results[idx] = [_decode_ns_text(row[0]) for row in cur.fetchall()]
|
results[idx] = [_decode_ns_text(row[0]) for row in cur.fetchall()]
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "langgraph-checkpoint-sqlite"
|
name = "langgraph-checkpoint-sqlite"
|
||||||
version = "2.0.11"
|
version = "3.0.0"
|
||||||
description = "Library with a SQLite implementation of LangGraph checkpoint saver."
|
description = "Library with a SQLite implementation of LangGraph checkpoint saver."
|
||||||
authors = []
|
authors = []
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
license-files = ['LICENSE']
|
license-files = ['LICENSE']
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langgraph-checkpoint>=2.0.21,<3.0.0",
|
"langgraph-checkpoint>=3,<4.0.0",
|
||||||
"aiosqlite>=0.20",
|
"aiosqlite>=0.20",
|
||||||
"sqlite-vec>=0.1.6",
|
"sqlite-vec>=0.1.6",
|
||||||
]
|
]
|
||||||
@@ -21,17 +21,23 @@ dependencies = [
|
|||||||
Repository = "https://www.github.com/langchain-ai/langgraph"
|
Repository = "https://www.github.com/langchain-ai/langgraph"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
test = [
|
||||||
"ruff",
|
|
||||||
"codespell",
|
|
||||||
"pytest",
|
"pytest",
|
||||||
"pytest-asyncio",
|
"pytest-asyncio",
|
||||||
"pytest-mock",
|
"pytest-mock",
|
||||||
"pytest-watcher",
|
"pytest-watcher",
|
||||||
"mypy",
|
|
||||||
"langgraph-checkpoint",
|
"langgraph-checkpoint",
|
||||||
"pytest-retry>=1.7.0",
|
"pytest-retry>=1.7.0",
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
"ruff",
|
||||||
|
"codespell",
|
||||||
|
"mypy",
|
||||||
|
]
|
||||||
|
dev = [
|
||||||
|
{include-group = "test"},
|
||||||
|
{include-group = "lint"},
|
||||||
|
]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
default-groups = ['dev']
|
default-groups = ['dev']
|
||||||
@@ -53,8 +59,10 @@ lint.select = [
|
|||||||
"UP", # pyupgrade
|
"UP", # pyupgrade
|
||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"I", # isort
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
]
|
]
|
||||||
lint.ignore = ["E501", "B008"]
|
lint.ignore = ["E501", "B008"]
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
[tool.pytest-watcher]
|
[tool.pytest-watcher]
|
||||||
now = true
|
now = true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import tempfile
|
|||||||
import uuid
|
import uuid
|
||||||
from collections.abc import AsyncIterator, Generator, Iterable
|
from collections.abc import AsyncIterator, Generator, Iterable
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import Optional, Union, cast
|
from typing import cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from langgraph.store.base import (
|
from langgraph.store.base import (
|
||||||
@@ -51,7 +51,7 @@ def fake_embeddings() -> CharacterEmbeddings:
|
|||||||
async def create_vector_store(
|
async def create_vector_store(
|
||||||
fake_embeddings: CharacterEmbeddings,
|
fake_embeddings: CharacterEmbeddings,
|
||||||
conn_string: str = ":memory:",
|
conn_string: str = ":memory:",
|
||||||
text_fields: Optional[list[str]] = None,
|
text_fields: list[str] | None = None,
|
||||||
) -> AsyncIterator[AsyncSqliteStore]:
|
) -> AsyncIterator[AsyncSqliteStore]:
|
||||||
"""Create an AsyncSqliteStore with vector search capabilities."""
|
"""Create an AsyncSqliteStore with vector search capabilities."""
|
||||||
index_config: SqliteIndexConfig = {
|
index_config: SqliteIndexConfig = {
|
||||||
@@ -168,7 +168,7 @@ async def test_abatch_order(store: AsyncSqliteStore) -> None:
|
|||||||
]
|
]
|
||||||
|
|
||||||
results = await store.abatch(
|
results = await store.abatch(
|
||||||
cast(Iterable[Union[GetOp, PutOp, SearchOp, ListNamespacesOp]], ops)
|
cast(Iterable[GetOp | PutOp | SearchOp | ListNamespacesOp], ops)
|
||||||
)
|
)
|
||||||
assert len(results) == 5
|
assert len(results) == 5
|
||||||
assert isinstance(results[0], Item)
|
assert isinstance(results[0], Item)
|
||||||
@@ -193,7 +193,7 @@ async def test_abatch_order(store: AsyncSqliteStore) -> None:
|
|||||||
]
|
]
|
||||||
|
|
||||||
results_reordered = await store.abatch(
|
results_reordered = await store.abatch(
|
||||||
cast(Iterable[Union[GetOp, PutOp, SearchOp, ListNamespacesOp]], ops_reordered)
|
cast(Iterable[GetOp | PutOp | SearchOp | ListNamespacesOp], ops_reordered)
|
||||||
)
|
)
|
||||||
assert len(results_reordered) == 5
|
assert len(results_reordered) == 5
|
||||||
assert isinstance(results_reordered[0], list)
|
assert isinstance(results_reordered[0], list)
|
||||||
@@ -681,7 +681,7 @@ async def test_search_items(
|
|||||||
fake_embeddings, text_fields=["key0", "key1", "key3"]
|
fake_embeddings, text_fields=["key0", "key1", "key3"]
|
||||||
) as store:
|
) as store:
|
||||||
# Insert test data
|
# Insert test data
|
||||||
for ns, item in zip(test_namespaces, test_items):
|
for ns, item in zip(test_namespaces, test_items, strict=False):
|
||||||
key = f"item_{ns[-1]}"
|
key = f"item_{ns[-1]}"
|
||||||
await store.aput(ns, key, item)
|
await store.aput(ns, key, item)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import tempfile
|
|||||||
import uuid
|
import uuid
|
||||||
from collections.abc import Generator, Iterable
|
from collections.abc import Generator, Iterable
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Any, Literal, Optional, Union, cast
|
from typing import Any, Literal, cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from langchain_core.embeddings import Embeddings
|
from langchain_core.embeddings import Embeddings
|
||||||
@@ -110,7 +110,7 @@ VECTOR_TYPES = ["cosine"] # SQLite only supports cosine similarity
|
|||||||
@contextmanager
|
@contextmanager
|
||||||
def create_vector_store(
|
def create_vector_store(
|
||||||
fake_embeddings: CharacterEmbeddings,
|
fake_embeddings: CharacterEmbeddings,
|
||||||
text_fields: Optional[list[str]] = None,
|
text_fields: list[str] | None = None,
|
||||||
distance_type: str = "cosine",
|
distance_type: str = "cosine",
|
||||||
conn_type: Literal["memory", "file"] = "memory",
|
conn_type: Literal["memory", "file"] = "memory",
|
||||||
) -> Generator[SqliteStore, None, None]:
|
) -> Generator[SqliteStore, None, None]:
|
||||||
@@ -153,7 +153,7 @@ def test_batch_order(store: SqliteStore) -> None:
|
|||||||
]
|
]
|
||||||
|
|
||||||
results = store.batch(
|
results = store.batch(
|
||||||
cast(Iterable[Union[GetOp, PutOp, SearchOp, ListNamespacesOp]], ops)
|
cast(Iterable[GetOp | PutOp | SearchOp | ListNamespacesOp], ops)
|
||||||
)
|
)
|
||||||
assert len(results) == 5
|
assert len(results) == 5
|
||||||
assert isinstance(results[0], Item)
|
assert isinstance(results[0], Item)
|
||||||
@@ -182,7 +182,7 @@ def test_batch_order(store: SqliteStore) -> None:
|
|||||||
]
|
]
|
||||||
|
|
||||||
results_reordered = store.batch(
|
results_reordered = store.batch(
|
||||||
cast(Iterable[Union[GetOp, PutOp, SearchOp, ListNamespacesOp]], ops_reordered)
|
cast(Iterable[GetOp | PutOp | SearchOp | ListNamespacesOp], ops_reordered)
|
||||||
)
|
)
|
||||||
assert len(results_reordered) == 5
|
assert len(results_reordered) == 5
|
||||||
assert isinstance(results_reordered[0], list)
|
assert isinstance(results_reordered[0], list)
|
||||||
@@ -301,7 +301,7 @@ def test_batch_list_namespaces_ops(store: SqliteStore) -> None:
|
|||||||
]
|
]
|
||||||
|
|
||||||
results = store.batch(
|
results = store.batch(
|
||||||
cast(Iterable[Union[GetOp, PutOp, SearchOp, ListNamespacesOp]], ops)
|
cast(Iterable[GetOp | PutOp | SearchOp | ListNamespacesOp], ops)
|
||||||
)
|
)
|
||||||
assert len(results) == 3
|
assert len(results) == 3
|
||||||
|
|
||||||
@@ -778,7 +778,7 @@ def _cosine_similarity(X: list[float], Y: list[list[float]]) -> list[float]:
|
|||||||
|
|
||||||
similarities = []
|
similarities = []
|
||||||
for y in Y:
|
for y in Y:
|
||||||
dot_product = sum(a * b for a, b in zip(X, y))
|
dot_product = sum(a * b for a, b in zip(X, y, strict=False))
|
||||||
norm1 = sum(a * a for a in X) ** 0.5
|
norm1 = sum(a * a for a in X) ** 0.5
|
||||||
norm2 = sum(a * a for a in y) ** 0.5
|
norm2 = sum(a * a for a in y) ** 0.5
|
||||||
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
||||||
@@ -1011,7 +1011,7 @@ def test_search_items(
|
|||||||
fake_embeddings, text_fields=["key0", "key1", "key3"]
|
fake_embeddings, text_fields=["key0", "key1", "key3"]
|
||||||
) as store:
|
) as store:
|
||||||
# Insert test data
|
# Insert test data
|
||||||
for ns, item in zip(test_namespaces, test_items):
|
for ns, item in zip(test_namespaces, test_items, strict=False):
|
||||||
key = f"item_{ns[-1]}"
|
key = f"item_{ns[-1]}"
|
||||||
store.put(ns, key, item)
|
store.put(ns, key, item)
|
||||||
|
|
||||||
|
|||||||
Generated
+206
-212
@@ -1,6 +1,6 @@
|
|||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 3
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiosqlite"
|
name = "aiosqlite"
|
||||||
@@ -117,17 +117,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" },
|
{ url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" },
|
{ url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" },
|
{ url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/ca/9a0983dd5c8e9733565cf3db4df2b0a2e9a82659fd8aa2a868ac6e4a991f/charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", size = 207520, upload-time = "2025-08-09T07:57:11.026Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/c6/99271dc37243a4f925b09090493fb96c9333d7992c6187f5cfe5312008d2/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", size = 147307, upload-time = "2025-08-09T07:57:12.4Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/69/132eab043356bba06eb333cc2cc60c6340857d0a2e4ca6dc2b51312886b3/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", size = 160448, upload-time = "2025-08-09T07:57:13.712Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/04/9a/914d294daa4809c57667b77470533e65def9c0be1ef8b4c1183a99170e9d/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", size = 157758, upload-time = "2025-08-09T07:57:14.979Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/a8/6f5bcf1bcf63cb45625f7c5cadca026121ff8a6c8a3256d8d8cd59302663/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", size = 152487, upload-time = "2025-08-09T07:57:16.332Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/72/d3d0e9592f4e504f9dea08b8db270821c909558c353dc3b457ed2509f2fb/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", size = 150054, upload-time = "2025-08-09T07:57:17.576Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/20/30/5f64fe3981677fe63fa987b80e6c01042eb5ff653ff7cec1b7bd9268e54e/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", size = 161703, upload-time = "2025-08-09T07:57:20.012Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e1/ef/dd08b2cac9284fd59e70f7d97382c33a3d0a926e45b15fc21b3308324ffd/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", size = 159096, upload-time = "2025-08-09T07:57:21.329Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/8c/dcef87cfc2b3f002a6478f38906f9040302c68aebe21468090e39cde1445/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", size = 153852, upload-time = "2025-08-09T07:57:22.608Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/63/86/9cbd533bd37883d467fcd1bd491b3547a3532d0fbb46de2b99feeebf185e/charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", size = 99840, upload-time = "2025-08-09T07:57:23.883Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/d6/7e805c8e5c46ff9729c49950acc4ee0aeb55efb8b3a56687658ad10c3216/charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", size = 107438, upload-time = "2025-08-09T07:57:25.287Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -257,7 +246,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langgraph-checkpoint"
|
name = "langgraph-checkpoint"
|
||||||
version = "2.1.1"
|
version = "3.0.1"
|
||||||
source = { editable = "../checkpoint" }
|
source = { editable = "../checkpoint" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "langchain-core" },
|
{ name = "langchain-core" },
|
||||||
@@ -267,7 +256,7 @@ dependencies = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "langchain-core", specifier = ">=0.2.38" },
|
{ name = "langchain-core", specifier = ">=0.2.38" },
|
||||||
{ name = "ormsgpack", specifier = ">=1.10.0" },
|
{ name = "ormsgpack", specifier = ">=1.12.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
@@ -285,10 +274,26 @@ dev = [
|
|||||||
{ name = "redis" },
|
{ name = "redis" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "dataclasses-json" },
|
||||||
|
{ name = "numpy" },
|
||||||
|
{ name = "pandas" },
|
||||||
|
{ name = "pandas-stubs", specifier = ">=2.2.2.240807" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
{ name = "redis" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langgraph-checkpoint-sqlite"
|
name = "langgraph-checkpoint-sqlite"
|
||||||
version = "2.0.11"
|
version = "3.0.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiosqlite" },
|
{ name = "aiosqlite" },
|
||||||
@@ -308,6 +313,19 @@ dev = [
|
|||||||
{ name = "pytest-watcher" },
|
{ name = "pytest-watcher" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "langgraph-checkpoint" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-retry" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
@@ -328,6 +346,19 @@ dev = [
|
|||||||
{ name = "pytest-watcher" },
|
{ name = "pytest-watcher" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
{ name = "codespell" },
|
||||||
|
{ name = "mypy" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
]
|
||||||
|
test = [
|
||||||
|
{ name = "langgraph-checkpoint", editable = "../checkpoint" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-mock" },
|
||||||
|
{ name = "pytest-retry", specifier = ">=1.7.0" },
|
||||||
|
{ name = "pytest-watcher" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langsmith"
|
name = "langsmith"
|
||||||
@@ -389,12 +420,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" },
|
{ url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/a6/490ff491d8ecddf8ab91762d4f67635040202f76a44171420bcbe38ceee5/mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b", size = 12807230, upload-time = "2025-09-19T00:09:49.471Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/2e/60076fc829645d167ece9e80db9e8375648d210dab44cc98beb5b322a826/mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133", size = 11895666, upload-time = "2025-09-19T00:10:53.678Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/4a/1e2880a2a5dda4dc8d9ecd1a7e7606bc0b0e14813637eeda40c38624e037/mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6", size = 12499608, upload-time = "2025-09-19T00:09:36.204Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/00/81/a117f1b73a3015b076b20246b1f341c34a578ebd9662848c6b80ad5c4138/mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac", size = 13244551, upload-time = "2025-09-19T00:10:17.531Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9b/61/b9f48e1714ce87c7bf0358eb93f60663740ebb08f9ea886ffc670cea7933/mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b", size = 13491552, upload-time = "2025-09-19T00:10:13.753Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/66/b2c0af3b684fa80d1b27501a8bdd3d2daa467ea3992a8aa612f5ca17c2db/mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0", size = 9765635, upload-time = "2025-09-19T00:10:30.993Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" },
|
{ url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -482,67 +507,61 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl", hash = "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", size = 136266, upload-time = "2025-08-26T17:46:13.853Z" },
|
{ url = "https://files.pythonhosted.org/packages/da/09/17d9d2b60592890ff7382e591aa1d9afb202a266b180c3d4049b1ec70e4a/orjson-3.11.3-cp314-cp314-win32.whl", hash = "sha256:0c6d7328c200c349e3a4c6d8c83e0a5ad029bdc2d417f234152bf34842d0fc8d", size = 136266, upload-time = "2025-08-26T17:46:13.853Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", size = 131351, upload-time = "2025-08-26T17:46:15.27Z" },
|
{ url = "https://files.pythonhosted.org/packages/15/58/358f6846410a6b4958b74734727e582ed971e13d335d6c7ce3e47730493e/orjson-3.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:317bbe2c069bbc757b1a2e4105b64aacd3bc78279b66a6b9e51e846e4809f804", size = 131351, upload-time = "2025-08-26T17:46:15.27Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", size = 125985, upload-time = "2025-08-26T17:46:16.67Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/01/d6b274a0635be0468d4dbd9cafe80c47105937a0d42434e805e67cd2ed8b/orjson-3.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:e8f6a7a27d7b7bec81bd5924163e9af03d49bbb63013f107b48eb5d16db711bc", size = 125985, upload-time = "2025-08-26T17:46:16.67Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/a6/18d88ccf8e5d8f711310eba9b4f6562f4aa9d594258efdc4dcf8c1550090/orjson-3.11.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:56afaf1e9b02302ba636151cfc49929c1bb66b98794291afd0e5f20fecaf757c", size = 238221, upload-time = "2025-08-26T17:46:18.113Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ee/18/e210365a17bf984c89db40c8be65da164b4ce6a866a2a0ae1d6407c2630b/orjson-3.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:913f629adef31d2d350d41c051ce7e33cf0fd06a5d1cb28d49b1899b23b903aa", size = 123209, upload-time = "2025-08-26T17:46:19.688Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/43/6b3f8ec15fa910726ed94bd2e618f86313ad1cae7c3c8c6b9b8a3a161814/orjson-3.11.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0a23b41f8f98b4e61150a03f83e4f0d566880fe53519d445a962929a4d21045", size = 127881, upload-time = "2025-08-26T17:46:21.502Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4a/ed/f41d2406355ce67efdd4ab504732b27bea37b7dbdab3eb86314fe764f1b9/orjson-3.11.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d721fee37380a44f9d9ce6c701b3960239f4fb3d5ceea7f31cbd43882edaa2f", size = 130306, upload-time = "2025-08-26T17:46:22.914Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/a1/1be02950f92c82e64602d3d284bd76d9fc82a6b92c9ce2a387e57a825a11/orjson-3.11.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73b92a5b69f31b1a58c0c7e31080aeaec49c6e01b9522e71ff38d08f15aa56de", size = 132383, upload-time = "2025-08-26T17:46:24.33Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/49/46766ac00c68192b516a15ffc44c2a9789ca3468b8dc8a500422d99bf0dd/orjson-3.11.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2489b241c19582b3f1430cc5d732caefc1aaf378d97e7fb95b9e56bed11725f", size = 135159, upload-time = "2025-08-26T17:46:25.741Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/e1/27fd5e7600fdd82996329d48ee56f6e9e9ae4d31eadbc7f93fd2ff0d8214/orjson-3.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5189a5dab8b0312eadaf9d58d3049b6a52c454256493a557405e77a3d67ab7f", size = 132690, upload-time = "2025-08-26T17:46:27.271Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/21/f57ef08799a68c36ef96fe561101afeef735caa80814636b2e18c234e405/orjson-3.11.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9d8787bdfbb65a85ea76d0e96a3b1bed7bf0fbcb16d40408dc1172ad784a49d2", size = 131086, upload-time = "2025-08-26T17:46:33.067Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/84/a3a24306a9dc482e929232c65f5b8c69188136edd6005441d8cc4754f7ea/orjson-3.11.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:8e531abd745f51f8035e207e75e049553a86823d189a51809c078412cefb399a", size = 403884, upload-time = "2025-08-26T17:46:34.55Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/11/98/fdae5b2c28bc358e6868e54c8eca7398c93d6a511f0436b61436ad1b04dc/orjson-3.11.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8ab962931015f170b97a3dd7bd933399c1bae8ed8ad0fb2a7151a5654b6941c7", size = 145837, upload-time = "2025-08-26T17:46:36.46Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7d/a9/2fe5cd69ed231f3ed88b1ad36a6957e3d2c876eb4b2c6b17b8ae0a6681fc/orjson-3.11.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:124d5ba71fee9c9902c4a7baa9425e663f7f0aecf73d31d54fe3dd357d62c1a7", size = 135325, upload-time = "2025-08-26T17:46:38.03Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ac/a4/7d4c8aefb45f6c8d7d527d84559a3a7e394b9fd1d424a2b5bcaf75fa68e7/orjson-3.11.3-cp39-cp39-win32.whl", hash = "sha256:22724d80ee5a815a44fc76274bb7ba2e7464f5564aacb6ecddaa9970a83e3225", size = 136184, upload-time = "2025-08-26T17:46:39.542Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/1f/1d6a24d22001e96c0afcf1806b6eabee1109aebd2ef20ec6698f6a6012d7/orjson-3.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:215c595c792a87d4407cb72dd5e0f6ee8e694ceeb7f9102b533c5a9bf2a916bb", size = 131373, upload-time = "2025-08-26T17:46:41.227Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ormsgpack"
|
name = "ormsgpack"
|
||||||
version = "1.10.0"
|
version = "1.12.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/92/36/44eed5ef8ce93cded76a576780bab16425ce7876f10d3e2e6265e46c21ea/ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16", size = 58629, upload-time = "2025-05-24T19:07:53.944Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/6c/67/d5ef41c3b4a94400be801984ef7c7fc9623e1a82b643e74eeec367e7462b/ormsgpack-1.12.0.tar.gz", hash = "sha256:94be818fdbb0285945839b88763b269987787cb2f7ef280cad5d6ec815b7e608", size = 49959, upload-time = "2025-11-04T18:30:10.083Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/fc/74/c2dd5daf069e3798d09d5746000f9b210de04df83834e5cb47f0ace51892/ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216", size = 376280, upload-time = "2025-05-24T19:06:51.3Z" },
|
{ url = "https://files.pythonhosted.org/packages/4d/0c/8f45fcd22c95190b05d4fba71375d8f783a9e3b0b6aaf476812b693e3868/ormsgpack-1.12.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e08904c232358b94a682ccfbb680bc47d3fd5c424bb7dccb65974dd20c95e8e1", size = 369156, upload-time = "2025-11-04T18:29:17.629Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/78/7b/30ff4bffb709e8a242005a8c4d65714fd96308ad640d31cff1b85c0d8cc4/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373", size = 204335, upload-time = "2025-05-24T19:06:53.442Z" },
|
{ url = "https://files.pythonhosted.org/packages/d2/f8/c7adc093d4ceb05e38786906815f868210f808326c27f8124b4d9466a26b/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9ed7a4b0037d69c8ba7e670e03ee65ae8d5c5114a409e73c5770d7fb5e4b895", size = 195743, upload-time = "2025-11-04T18:29:18.964Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8f/3f/c95b7d142819f801a0acdbd04280e8132e43b6e5a8920173e8eb92ea0e6a/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5", size = 215373, upload-time = "2025-05-24T19:06:55.153Z" },
|
{ url = "https://files.pythonhosted.org/packages/fe/b8/bf002648fa6c150ed6157837b00303edafb35f65c352429463f83214de18/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:db2928525b684f3f2af0367aef7ae8d20cde37fc5349c700017129d493a755aa", size = 206472, upload-time = "2025-11-04T18:29:19.951Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/1a/e30f4bcf386db2015d1686d1da6110c95110294d8ea04f86091dd5eb3361/ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a", size = 216469, upload-time = "2025-05-24T19:06:56.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/23/d6/1f445947c95a931bb189b7864a3f9dcbeebe7dcbc1b3c7387427b3779228/ormsgpack-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45f911d9c5b23d11e49ff03fc8f9566745a2b1a7d9033733a1c0a2fa9301cd60", size = 207959, upload-time = "2025-11-04T18:29:21.282Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/96/fc/7e44aeade22b91883586f45b7278c118fd210834c069774891447f444fc9/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227", size = 384590, upload-time = "2025-05-24T19:06:58.286Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/9c/dd8ccd7553a5c1d0b4b69a0541611983a2f9bc2e8c5708a4bfffc0100468/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:98c54ae6fd682b2aceb264505af9b2255f3df9d84e6e4369bc44d2110f1f311d", size = 377659, upload-time = "2025-11-04T18:29:22.561Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/78/f92c24e8446697caa83c122f10b6cf5e155eddf81ce63905c8223a260482/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7", size = 478891, upload-time = "2025-05-24T19:07:00.126Z" },
|
{ url = "https://files.pythonhosted.org/packages/3d/08/3282d8f6330e742d4cdbcfbe2c100b403ae5526ae82a1c1b6a11b7967e37/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:857ab987c3502de08258cc4baf0e87267cb2c80931601084e13df3c355b1ab9d", size = 471391, upload-time = "2025-11-04T18:29:23.663Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/75/87449690253c64bea2b663c7c8f2dbc9ad39d73d0b38db74bdb0f3947b16/ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84", size = 390121, upload-time = "2025-05-24T19:07:01.777Z" },
|
{ url = "https://files.pythonhosted.org/packages/18/d4/94a2fbfd4837754bda7a099b6a23b9d40aba9e76e1af8b8fb8133612eb54/ormsgpack-1.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27579d45dc502ee736238e1024559cb0a01aa72a3b68827448b8edf6a2dcdc9c", size = 381501, upload-time = "2025-11-04T18:29:24.771Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/cc/c83257faf3a5169ec29dd87121317a25711da9412ee8c1e82f2e1a00c0be/ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07", size = 121196, upload-time = "2025-05-24T19:07:03.47Z" },
|
{ url = "https://files.pythonhosted.org/packages/d8/c6/1a9fa122cb5deb10b067bbaa43165b12291a914cc0ce364988ff17bbf405/ormsgpack-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:c78379d054760875540cf2e81f28da1bb78d09fda3eabdbeb6c53b3e297158cb", size = 112715, upload-time = "2025-11-04T18:29:26.016Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/27/7da748bc0d7d567950a378dee5a32477ed5d15462ab186918b5f25cac1ad/ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775", size = 376275, upload-time = "2025-05-24T19:07:05.128Z" },
|
{ url = "https://files.pythonhosted.org/packages/1a/ba/3cae83cf36420c1c8dd294f16c852c03313aafe2439a165c4c6ac611b1d0/ormsgpack-1.12.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c40d86d77391b18dd34de5295e3de2b8ad818bcab9c9def4121c8ec5c9714ae4", size = 369159, upload-time = "2025-11-04T18:29:27.057Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/65/c082cc8c74a914dbd05af0341c761c73c3d9960b7432bbf9b8e1e20811af/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af", size = 204335, upload-time = "2025-05-24T19:07:06.423Z" },
|
{ url = "https://files.pythonhosted.org/packages/97/d4/5e176309e01a8b9098d80201aac1eb7db9336c3b5b4fa6254a2bbb0d0fa0/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:777b7fab364dc0f200bb382a98a385c8222ffa6a2333d627d763797326202c86", size = 195744, upload-time = "2025-11-04T18:29:28.069Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/62/17ef7e5d9766c79355b9c594cc9328c204f1677bc35da0595cc4e46449f0/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e", size = 215372, upload-time = "2025-05-24T19:07:08.149Z" },
|
{ url = "https://files.pythonhosted.org/packages/4f/83/6d80c8c5571639c000a39f38f77752dfaf9d9e552d775331e8d280f66a4e/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b5089ad9dd5b3d3013b245a55e4abaea2f8ad70f4a78e1b002127b02340004", size = 206474, upload-time = "2025-11-04T18:29:29.034Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4e/92/7c91e8115fc37e88d1a35e13200fda3054ff5d2e5adf017345e58cea4834/ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3", size = 216470, upload-time = "2025-05-24T19:07:09.903Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/e6/940311e48dc0cfc3e212bd7007a21ed0825158638057687d804f2c5c2cca/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaf0c87cace7bc08fbf68c5cc66605b593df6427e9f4de235b2da358787e008", size = 207959, upload-time = "2025-11-04T18:29:30.315Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2c/86/ce053c52e2517b90e390792d83e926a7a523c1bce5cc63d0a7cd05ce6cf6/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b", size = 384591, upload-time = "2025-05-24T19:07:11.24Z" },
|
{ url = "https://files.pythonhosted.org/packages/1a/e3/fbe94b0a311815343b86a95a0627e4901b11ff6fd522679ca29a2a88c99b/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f62d476fe28bc5675d9aff30341bfa9f41d7de332c5b63fbbe9aaf6bb7ec74d4", size = 377666, upload-time = "2025-11-04T18:29:31.38Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/07/e8/2ad59f2ab222c6029e500bc966bfd2fe5cb099f8ab6b7ebeb50ddb1a6fe5/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5", size = 478892, upload-time = "2025-05-24T19:07:13.147Z" },
|
{ url = "https://files.pythonhosted.org/packages/a3/3b/229cfa28076798ffb619aaa854b842de3f2ed5ea4e6509bf34d14c038c4d/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ded7810095b887e28434f32f5a345d354e88cf851bab3c5435aeb86a718618d2", size = 471394, upload-time = "2025-11-04T18:29:32.521Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/73/f55e4b47b7b18fd8e7789680051bf830f1e39c03f1d9ed993cd0c3e97215/ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08", size = 390122, upload-time = "2025-05-24T19:07:14.557Z" },
|
{ url = "https://files.pythonhosted.org/packages/6b/bd/4eae4ab35586e4175c07acb5f98aec83aa9d8987f71ea0443aa900191bdf/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f72a1dea0c4ae7c4101dcfbe8133f274a9d769d0b87fe5188db4fab07ffabaee", size = 381506, upload-time = "2025-11-04T18:29:33.533Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f7/87/073251cdb93d4c6241748568b3ad1b2a76281fb2002eed16a3a4043d61cf/ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a", size = 121197, upload-time = "2025-05-24T19:07:15.981Z" },
|
{ url = "https://files.pythonhosted.org/packages/dd/51/f9d56d6d015cbfa1ce9a4358ca30a41744644f0cf606e060d7203efe5af8/ormsgpack-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:8f479bfef847255d7d0b12c7a198f6a21490155da2da3062e082ba370893d4a1", size = 112707, upload-time = "2025-11-04T18:29:34.898Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/99/95/f3ab1a7638f6aa9362e87916bb96087fbbc5909db57e19f12ad127560e1e/ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0", size = 376806, upload-time = "2025-05-24T19:07:17.221Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/07/bb189ef7072979f2f96e8716e952172efdce9c54930aa0814bec73aee19b/ormsgpack-1.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:3583ca410e4502144b2594170542e4bbef7b15643fd1208703ae820f11029036", size = 106533, upload-time = "2025-11-04T18:29:36.112Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/2b/42f559f13c0b0f647b09d749682851d47c1a7e48308c43612ae6833499c8/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6", size = 204433, upload-time = "2025-05-24T19:07:18.569Z" },
|
{ url = "https://files.pythonhosted.org/packages/a2/f2/c1036b2775fcc0cfa5fd618c53bcd3b862ee07298fb627f03af4c7982f84/ormsgpack-1.12.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e0c1e08b64d99076fee155276097489b82cc56e8d5951c03c721a65a32f44494", size = 369538, upload-time = "2025-11-04T18:29:37.125Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/42/1ca0cb4d8c80340a89a4af9e6d8951fb8ba0d076a899d2084eadf536f677/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5", size = 215547, upload-time = "2025-05-24T19:07:20.245Z" },
|
{ url = "https://files.pythonhosted.org/packages/d9/ca/526c4ae02f3cb34621af91bf8282a10d666757c2e0c6ff391ff5d403d607/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd43bcb299131690b8e0677af172020b2ada8e625169034b42ac0c13adf84aa", size = 195872, upload-time = "2025-11-04T18:29:38.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0a/38/184a570d7c44c0260bc576d1daaac35b2bfd465a50a08189518505748b9a/ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07", size = 216746, upload-time = "2025-05-24T19:07:21.83Z" },
|
{ url = "https://files.pythonhosted.org/packages/7f/0f/83bb7968e9715f6a85be53d041b1e6324a05428f56b8b980dac866886871/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0149d595341e22ead340bf281b2995c4cc7dc8d522a6b5f575fe17aa407604", size = 206469, upload-time = "2025-11-04T18:29:39.749Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/69/2f/1aaffd08f6b7fdc2a57336a80bdfb8df24e6a65ada5aa769afecfcbc6cc6/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044", size = 384783, upload-time = "2025-05-24T19:07:23.674Z" },
|
{ url = "https://files.pythonhosted.org/packages/02/e3/9e93ca1065f2d4af035804a842b1ff3025bab580c7918239bb225cd1fee2/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19a1b27d169deb553c80fd10b589fc2be1fc14cee779fae79fcaf40db04de2b", size = 208273, upload-time = "2025-11-04T18:29:40.769Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/63/3e53d6f43bb35e00c98f2b8ab2006d5138089ad254bc405614fbf0213502/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd", size = 479076, upload-time = "2025-05-24T19:07:25.047Z" },
|
{ url = "https://files.pythonhosted.org/packages/b3/d8/6d6ef901b3a8b8f3ab8836b135a56eb7f66c559003e251d9530bedb12627/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f28896942d655064940dfe06118b7ce1e3468d051483148bf02c99ec157483a", size = 377839, upload-time = "2025-11-04T18:29:42.092Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/19/fa1121b03b61402bb4d04e35d164e2320ef73dfb001b57748110319dd014/ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0", size = 390447, upload-time = "2025-05-24T19:07:26.568Z" },
|
{ url = "https://files.pythonhosted.org/packages/4c/72/fcb704bfa4c2c3a37b647d597cc45a13cffc9d50baac635a9ad620731d29/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9396efcfa48b4abbc06e44c5dbc3c4574a8381a80cb4cd01eea15d28b38c554e", size = 471446, upload-time = "2025-11-04T18:29:43.133Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/0d/73143ecb94ac4a5dcba223402139240a75dee0cc6ba8a543788a5646407a/ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722", size = 121401, upload-time = "2025-05-24T19:07:28.308Z" },
|
{ url = "https://files.pythonhosted.org/packages/84/f8/402e4e3eb997c2ee534c99bec4b5bb359c2a1f9edadf043e254a71e11378/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:96586ed537a5fb386a162c4f9f7d8e6f76e07b38a990d50c73f11131e00ff040", size = 381783, upload-time = "2025-11-04T18:29:44.466Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/61/f8/ec5f4e03268d0097545efaab2893aa63f171cf2959cb0ea678a5690e16a1/ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f", size = 376806, upload-time = "2025-05-24T19:07:29.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/8d/5897b700360bc00911b70ae5ef1134ee7abf5baa81a92a4be005917d3dfd/ormsgpack-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e70387112fb3870e4844de090014212cdcf1342f5022047aecca01ec7de05d7a", size = 112943, upload-time = "2025-11-04T18:29:45.468Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c1/19/b3c53284aad1e90d4d7ed8c881a373d218e16675b8b38e3569d5b40cc9b8/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643", size = 204433, upload-time = "2025-05-24T19:07:30.977Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/44/1e73649f79bb96d6cf9e5bcbac68b6216d238bba80af351c4c0cbcf7ee15/ormsgpack-1.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:d71290a23de5d4829610c42665d816c661ecad8979883f3f06b2e3ab9639962e", size = 106688, upload-time = "2025-11-04T18:29:46.411Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/0b/845c258f59df974a20a536c06cace593698491defdd3d026a8a5f9b6e745/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e", size = 215549, upload-time = "2025-05-24T19:07:32.345Z" },
|
{ url = "https://files.pythonhosted.org/packages/2e/e8/35f11ce9313111488b26b3035e4cbe55caa27909c0b6c8b5b5cd59f9661e/ormsgpack-1.12.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:766f2f3b512d85cd375b26a8b1329b99843560b50b93d3880718e634ad4a5de5", size = 369574, upload-time = "2025-11-04T18:29:47.431Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/61/56/57fce8fb34ca6c9543c026ebebf08344c64dbb7b6643d6ddd5355d37e724/ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c", size = 216747, upload-time = "2025-05-24T19:07:34.075Z" },
|
{ url = "https://files.pythonhosted.org/packages/61/b0/77461587f412d4e598d3687bafe23455ed0f26269f44be20252eddaa624e/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84b285b1f3f185aad7da45641b873b30acfd13084cf829cf668c4c6480a81583", size = 195893, upload-time = "2025-11-04T18:29:48.735Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/3f/655b5f6a2475c8d209f5348cfbaaf73ce26237b92d79ef2ad439407dd0fa/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb", size = 384785, upload-time = "2025-05-24T19:07:35.83Z" },
|
{ url = "https://files.pythonhosted.org/packages/c6/67/e197ceb04c3b550589e5407fc9fdae10f4e2e2eba5fdac921a269e02e974/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e23604fc79fe110292cb365f4c8232e64e63a34f470538be320feae3921f271b", size = 206503, upload-time = "2025-11-04T18:29:49.99Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4b/94/687a0ad8afd17e4bce1892145d6a1111e58987ddb176810d02a1f3f18686/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935", size = 479076, upload-time = "2025-05-24T19:07:37.533Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/b1/7fa8ba82a25cef678983c7976f85edeef5014f5c26495f338258e6a3cf1c/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc32b156c113a0fae2975051417d8d9a7a5247c34b2d7239410c46b75ce9348a", size = 208257, upload-time = "2025-11-04T18:29:51.007Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/34/68925232e81e0e062a2f0ac678f62aa3b6f7009d6a759e19324dbbaebae7/ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668", size = 390446, upload-time = "2025-05-24T19:07:39.469Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/b1/759e999390000d2589e6d0797f7265e6ec28378547075d28d3736248ab63/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:94ac500dd10c20fa8b8a23bc55606250bfe711bf9716828d9f3d44dfd1f25668", size = 377852, upload-time = "2025-11-04T18:29:52.103Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/ad/f4e1a36a6d1714afb7ffb74b3ababdcb96529cf4e7a216f9f7c8eda837b6/ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69", size = 121399, upload-time = "2025-05-24T19:07:40.854Z" },
|
{ url = "https://files.pythonhosted.org/packages/51/e7/0af737c94272494d9d84a3c29cc42c973ef7fd2342917020906596db863c/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c5201ff7ec24f721f813a182885a17064cffdbe46b2412685a52e6374a872c8f", size = 471456, upload-time = "2025-11-04T18:29:53.336Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/8f/bb80469db9d5b10708cba6997463d140486ca7053a5d18f99b5739cfecf7/ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32", size = 376272, upload-time = "2025-05-24T19:07:42.16Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/ba/c81f0aa4f19fbf457213395945b672e6fde3ce777e3587456e7f0fca2147/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a9740bb3839c9368aacae1cbcfc474ee6976458f41cc135372b7255d5206c953", size = 381813, upload-time = "2025-11-04T18:29:54.394Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/9c/48f714ed3d5a153f25e3b490496e6ba214aee265a82be1b61e39019ea146/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4", size = 204314, upload-time = "2025-05-24T19:07:43.444Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/15/429c72d64323503fd42cc4ca8398930ded8aa8b3470df8a86b3bbae7a35c/ormsgpack-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ed37f29772432048b58174e920a1d4c4cde0404a5d448d3d8bbcc95d86a6918", size = 112949, upload-time = "2025-11-04T18:29:55.371Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/42/7f9edf6e5511120b5304c76c5d3a8b4719ff927555a6dba41b6f9d041b30/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453", size = 215386, upload-time = "2025-05-24T19:07:45.232Z" },
|
{ url = "https://files.pythonhosted.org/packages/55/b9/e72c451a40f8c57bfc229e0b8e536ecea7203c8f0a839676df2ffb605c62/ormsgpack-1.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:b03994bbec5d6d42e03d6604e327863f885bde67aa61e06107ce1fa5bdd3e71d", size = 106689, upload-time = "2025-11-04T18:29:56.262Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/87/41e14485857fbe4ed5a530677fe60dd6910a254825c0b1cb5b04baaa4be0/ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1", size = 216466, upload-time = "2025-05-24T19:07:46.548Z" },
|
{ url = "https://files.pythonhosted.org/packages/13/16/13eab1a75da531b359105fdee90dda0b6bd1ca0a09880250cf91d8bdfdea/ormsgpack-1.12.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0f3981ba3cba80656012090337e548e597799e14b41e3d0b595ab5ab05a23d7f", size = 369620, upload-time = "2025-11-04T18:29:57.255Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/68/769fa1c721d8aa6799c0ce98b1711ae57de3e6379b554ebf9a11be4c62ff/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681", size = 384600, upload-time = "2025-05-24T19:07:47.945Z" },
|
{ url = "https://files.pythonhosted.org/packages/a0/c1/cbcc38b7af4ce58d8893e56d3595c0c8dcd117093bf048f889cf351bdba0/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:901f6f55184d6776dbd5183cbce14caf05bf7f467eef52faf9b094686980bf71", size = 195925, upload-time = "2025-11-04T18:29:58.34Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4e/f9/b57fd387fe16753783a3cea0ed2471c727bbed4356d8a08e3f0340251870/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3", size = 478888, upload-time = "2025-05-24T19:07:49.801Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/59/4fa4dc0681490e12b75333440a1c0fd9741b0ebff272b1db4a29d35c2021/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13b15412571422b711b40f45e3fe6d993ea3314b5e97d1a853fe99226c5effc", size = 206594, upload-time = "2025-11-04T18:29:59.329Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/0f/464cdfa7f9ee817c2d94485880b6c3c4b9f22df9fcbf21c303bbfebcb3ed/ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d", size = 390118, upload-time = "2025-05-24T19:07:51.193Z" },
|
{ url = "https://files.pythonhosted.org/packages/39/67/249770896bc32bb91b22c30256961f935d0915cbcf6e289a7fc961d9b14c/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91fa8a452553a62e5fb3fbab471e7faf7b3bec3c87a2f355ebf3d7aab290fe4f", size = 208307, upload-time = "2025-11-04T18:30:00.377Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ad/03/b9146dff5458def4c0a2b1e35c1c24e4d5e8083899aa0718b6eccba39317/ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749", size = 121199, upload-time = "2025-05-24T19:07:52.639Z" },
|
{ url = "https://files.pythonhosted.org/packages/07/0a/e041a248cd72f2f4c07e155913e0a3ede4c86cf21a40ae6cd79f135f2847/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74ec101f69624695eec4ce7c953192d97748254abe78fb01b591f06d529e1952", size = 377844, upload-time = "2025-11-04T18:30:01.389Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/71/6f7773e4ffda73a358ce4bba69b3e8bee9d40a7a06315e4c1cd7a3ea9d02/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:9bbf7896580848326c1f9bd7531f264e561f98db7e08e15aa75963d83832c717", size = 471572, upload-time = "2025-11-04T18:30:02.486Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/65/29/af6769a4289c07acc71e7bda1d64fb31800563147d73142686e185e82348/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7567917da613b8f8d591c1674e411fd3404bea41ef2b9a0e0a1e049c0f9406d7", size = 381842, upload-time = "2025-11-04T18:30:03.799Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/dd/0a86195ee7a1a96c088aefc8504385e881cf56f4563ed81bafe21cbf1fb0/ormsgpack-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e418256c5d8622b8bc92861936f7c6a0131355e7bcad88a42102ae8227f8a1c", size = 113008, upload-time = "2025-11-04T18:30:04.777Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4c/57/fafc79e32f3087f6f26f509d80b8167516326bfea38d30502627c01617e0/ormsgpack-1.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:433ace29aa02713554f714c62a4e4dcad0c9e32674ba4f66742c91a4c3b1b969", size = 106648, upload-time = "2025-11-04T18:30:05.708Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/cf/5d58d9b132128d2fe5d586355dde76af386554abef00d608f66b913bff1f/ormsgpack-1.12.0-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e57164be4ca34b64e210ec515059193280ac84df4d6f31a6fcbfb2fc8436de55", size = 369803, upload-time = "2025-11-04T18:30:06.728Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/67/42/968a2da361eaff2e4cbb17c82c7599787babf16684110ad70409646cc1e4/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:904f96289deaa92fc6440b122edc27c5bdc28234edd63717f6d853d88c823a83", size = 195991, upload-time = "2025-11-04T18:30:07.713Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/03/f0/9696c6c6cf8ad35170f0be8d0ef3523cc258083535f6c8071cb8235ebb8b/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b291d086e524a1062d57d1b7b5a8bcaaf29caebf0212fec12fd86240bd33633", size = 208316, upload-time = "2025-11-04T18:30:08.663Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -574,7 +593,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.11.9"
|
version = "2.12.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "annotated-types" },
|
{ name = "annotated-types" },
|
||||||
@@ -582,118 +601,123 @@ dependencies = [
|
|||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
{ name = "typing-inspection" },
|
{ name = "typing-inspection" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/8d/35/d319ed522433215526689bad428a94058b6dd12190ce7ddd78618ac14b28/pydantic-2.12.2.tar.gz", hash = "sha256:7b8fa15b831a4bbde9d5b84028641ac3080a4ca2cbd4a621a661687e741624fd", size = 816358, upload-time = "2025-10-14T15:02:21.842Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" },
|
{ url = "https://files.pythonhosted.org/packages/6c/98/468cb649f208a6f1279448e6e5247b37ae79cf5e4041186f1e2ef3d16345/pydantic-2.12.2-py3-none-any.whl", hash = "sha256:25ff718ee909acd82f1ff9b1a4acfd781bb23ab3739adaa7144f19a6a4e231ae", size = 460628, upload-time = "2025-10-14T15:02:19.623Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic-core"
|
name = "pydantic-core"
|
||||||
version = "2.33.2"
|
version = "2.41.4"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/df/18/d0944e8eaaa3efd0a91b0f1fc537d3be55ad35091b6a87638211ba691964/pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5", size = 457557, upload-time = "2025-10-14T10:23:47.909Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" },
|
{ url = "https://files.pythonhosted.org/packages/a7/3d/9b8ca77b0f76fcdbf8bc6b72474e264283f461284ca84ac3fde570c6c49a/pydantic_core-2.41.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2442d9a4d38f3411f22eb9dd0912b7cbf4b7d5b6c92c4173b75d3e1ccd84e36e", size = 2111197, upload-time = "2025-10-14T10:19:43.303Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" },
|
{ url = "https://files.pythonhosted.org/packages/59/92/b7b0fe6ed4781642232755cb7e56a86e2041e1292f16d9ae410a0ccee5ac/pydantic_core-2.41.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:30a9876226dda131a741afeab2702e2d127209bde3c65a2b8133f428bc5d006b", size = 1917909, upload-time = "2025-10-14T10:19:45.194Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" },
|
{ url = "https://files.pythonhosted.org/packages/52/8c/3eb872009274ffa4fb6a9585114e161aa1a0915af2896e2d441642929fe4/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d55bbac04711e2980645af68b97d445cdbcce70e5216de444a6c4b6943ebcccd", size = 1969905, upload-time = "2025-10-14T10:19:46.567Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/21/35adf4a753bcfaea22d925214a0c5b880792e3244731b3f3e6fec0d124f7/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1d778fb7849a42d0ee5927ab0f7453bf9f85eef8887a546ec87db5ddb178945", size = 2051938, upload-time = "2025-10-14T10:19:48.237Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" },
|
{ url = "https://files.pythonhosted.org/packages/7d/d0/cdf7d126825e36d6e3f1eccf257da8954452934ede275a8f390eac775e89/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b65077a4693a98b90ec5ad8f203ad65802a1b9b6d4a7e48066925a7e1606706", size = 2250710, upload-time = "2025-10-14T10:19:49.619Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" },
|
{ url = "https://files.pythonhosted.org/packages/2e/1c/af1e6fd5ea596327308f9c8d1654e1285cc3d8de0d584a3c9d7705bf8a7c/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62637c769dee16eddb7686bf421be48dfc2fae93832c25e25bc7242e698361ba", size = 2367445, upload-time = "2025-10-14T10:19:51.269Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" },
|
{ url = "https://files.pythonhosted.org/packages/d3/81/8cece29a6ef1b3a92f956ea6da6250d5b2d2e7e4d513dd3b4f0c7a83dfea/pydantic_core-2.41.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfe3aa529c8f501babf6e502936b9e8d4698502b2cfab41e17a028d91b1ac7b", size = 2072875, upload-time = "2025-10-14T10:19:52.671Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" },
|
{ url = "https://files.pythonhosted.org/packages/e3/37/a6a579f5fc2cd4d5521284a0ab6a426cc6463a7b3897aeb95b12f1ba607b/pydantic_core-2.41.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca2322da745bf2eeb581fc9ea3bbb31147702163ccbcbf12a3bb630e4bf05e1d", size = 2191329, upload-time = "2025-10-14T10:19:54.214Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" },
|
{ url = "https://files.pythonhosted.org/packages/ae/03/505020dc5c54ec75ecba9f41119fd1e48f9e41e4629942494c4a8734ded1/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e8cd3577c796be7231dcf80badcf2e0835a46665eaafd8ace124d886bab4d700", size = 2151658, upload-time = "2025-10-14T10:19:55.843Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/5d/2c0d09fb53aa03bbd2a214d89ebfa6304be7df9ed86ee3dc7770257f41ee/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1cae8851e174c83633f0833e90636832857297900133705ee158cf79d40f03e6", size = 2316777, upload-time = "2025-10-14T10:19:57.607Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" },
|
{ url = "https://files.pythonhosted.org/packages/ea/4b/c2c9c8f5e1f9c864b57d08539d9d3db160e00491c9f5ee90e1bfd905e644/pydantic_core-2.41.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a26d950449aae348afe1ac8be5525a00ae4235309b729ad4d3399623125b43c9", size = 2320705, upload-time = "2025-10-14T10:19:59.016Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/c3/a74c1c37f49c0a02c89c7340fafc0ba816b29bd495d1a31ce1bdeacc6085/pydantic_core-2.41.4-cp310-cp310-win32.whl", hash = "sha256:0cf2a1f599efe57fa0051312774280ee0f650e11152325e41dfd3018ef2c1b57", size = 1975464, upload-time = "2025-10-14T10:20:00.581Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" },
|
{ url = "https://files.pythonhosted.org/packages/d6/23/5dd5c1324ba80303368f7569e2e2e1a721c7d9eb16acb7eb7b7f85cb1be2/pydantic_core-2.41.4-cp310-cp310-win_amd64.whl", hash = "sha256:a8c2e340d7e454dc3340d3d2e8f23558ebe78c98aa8f68851b04dcb7bc37abdc", size = 2024497, upload-time = "2025-10-14T10:20:03.018Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" },
|
{ url = "https://files.pythonhosted.org/packages/62/4c/f6cbfa1e8efacd00b846764e8484fe173d25b8dab881e277a619177f3384/pydantic_core-2.41.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:28ff11666443a1a8cf2a044d6a545ebffa8382b5f7973f22c36109205e65dc80", size = 2109062, upload-time = "2025-10-14T10:20:04.486Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" },
|
{ url = "https://files.pythonhosted.org/packages/21/f8/40b72d3868896bfcd410e1bd7e516e762d326201c48e5b4a06446f6cf9e8/pydantic_core-2.41.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61760c3925d4633290292bad462e0f737b840508b4f722247d8729684f6539ae", size = 1916301, upload-time = "2025-10-14T10:20:06.857Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" },
|
{ url = "https://files.pythonhosted.org/packages/94/4d/d203dce8bee7faeca791671c88519969d98d3b4e8f225da5b96dad226fc8/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eae547b7315d055b0de2ec3965643b0ab82ad0106a7ffd29615ee9f266a02827", size = 1968728, upload-time = "2025-10-14T10:20:08.353Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" },
|
{ url = "https://files.pythonhosted.org/packages/65/f5/6a66187775df87c24d526985b3a5d78d861580ca466fbd9d4d0e792fcf6c/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef9ee5471edd58d1fcce1c80ffc8783a650e3e3a193fe90d52e43bb4d87bff1f", size = 2050238, upload-time = "2025-10-14T10:20:09.766Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/b9/78336345de97298cf53236b2f271912ce11f32c1e59de25a374ce12f9cce/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15dd504af121caaf2c95cb90c0ebf71603c53de98305621b94da0f967e572def", size = 2249424, upload-time = "2025-10-14T10:20:11.732Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" },
|
{ url = "https://files.pythonhosted.org/packages/99/bb/a4584888b70ee594c3d374a71af5075a68654d6c780369df269118af7402/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a926768ea49a8af4d36abd6a8968b8790f7f76dd7cbd5a4c180db2b4ac9a3a2", size = 2366047, upload-time = "2025-10-14T10:20:13.647Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" },
|
{ url = "https://files.pythonhosted.org/packages/5f/8d/17fc5de9d6418e4d2ae8c675f905cdafdc59d3bf3bf9c946b7ab796a992a/pydantic_core-2.41.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916b9b7d134bff5440098a4deb80e4cb623e68974a87883299de9124126c2a8", size = 2071163, upload-time = "2025-10-14T10:20:15.307Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" },
|
{ url = "https://files.pythonhosted.org/packages/54/e7/03d2c5c0b8ed37a4617430db68ec5e7dbba66358b629cd69e11b4d564367/pydantic_core-2.41.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cf90535979089df02e6f17ffd076f07237efa55b7343d98760bde8743c4b265", size = 2190585, upload-time = "2025-10-14T10:20:17.3Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/fc/15d1c9fe5ad9266a5897d9b932b7f53d7e5cfc800573917a2c5d6eea56ec/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7533c76fa647fade2d7ec75ac5cc079ab3f34879626dae5689b27790a6cf5a5c", size = 2150109, upload-time = "2025-10-14T10:20:19.143Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" },
|
{ url = "https://files.pythonhosted.org/packages/26/ef/e735dd008808226c83ba56972566138665b71477ad580fa5a21f0851df48/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:37e516bca9264cbf29612539801ca3cd5d1be465f940417b002905e6ed79d38a", size = 2315078, upload-time = "2025-10-14T10:20:20.742Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" },
|
{ url = "https://files.pythonhosted.org/packages/90/00/806efdcf35ff2ac0f938362350cd9827b8afb116cc814b6b75cf23738c7c/pydantic_core-2.41.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0c19cb355224037c83642429b8ce261ae108e1c5fbf5c028bac63c77b0f8646e", size = 2318737, upload-time = "2025-10-14T10:20:22.306Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" },
|
{ url = "https://files.pythonhosted.org/packages/41/7e/6ac90673fe6cb36621a2283552897838c020db343fa86e513d3f563b196f/pydantic_core-2.41.4-cp311-cp311-win32.whl", hash = "sha256:09c2a60e55b357284b5f31f5ab275ba9f7f70b7525e18a132ec1f9160b4f1f03", size = 1974160, upload-time = "2025-10-14T10:20:23.817Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" },
|
{ url = "https://files.pythonhosted.org/packages/e0/9d/7c5e24ee585c1f8b6356e1d11d40ab807ffde44d2db3b7dfd6d20b09720e/pydantic_core-2.41.4-cp311-cp311-win_amd64.whl", hash = "sha256:711156b6afb5cb1cb7c14a2cc2c4a8b4c717b69046f13c6b332d8a0a8f41ca3e", size = 2021883, upload-time = "2025-10-14T10:20:25.48Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" },
|
{ url = "https://files.pythonhosted.org/packages/33/90/5c172357460fc28b2871eb4a0fb3843b136b429c6fa827e4b588877bf115/pydantic_core-2.41.4-cp311-cp311-win_arm64.whl", hash = "sha256:6cb9cf7e761f4f8a8589a45e49ed3c0d92d1d696a45a6feaee8c904b26efc2db", size = 1968026, upload-time = "2025-10-14T10:20:27.039Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/81/d3b3e95929c4369d30b2a66a91db63c8ed0a98381ae55a45da2cd1cc1288/pydantic_core-2.41.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ab06d77e053d660a6faaf04894446df7b0a7e7aba70c2797465a0a1af00fc887", size = 2099043, upload-time = "2025-10-14T10:20:28.561Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" },
|
{ url = "https://files.pythonhosted.org/packages/58/da/46fdac49e6717e3a94fc9201403e08d9d61aa7a770fab6190b8740749047/pydantic_core-2.41.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c53ff33e603a9c1179a9364b0a24694f183717b2e0da2b5ad43c316c956901b2", size = 1910699, upload-time = "2025-10-14T10:20:30.217Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/63/4d948f1b9dd8e991a5a98b77dd66c74641f5f2e5225fee37994b2e07d391/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304c54176af2c143bd181d82e77c15c41cbacea8872a2225dd37e6544dce9999", size = 1952121, upload-time = "2025-10-14T10:20:32.246Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" },
|
{ url = "https://files.pythonhosted.org/packages/b2/a7/e5fc60a6f781fc634ecaa9ecc3c20171d238794cef69ae0af79ac11b89d7/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025ba34a4cf4fb32f917d5d188ab5e702223d3ba603be4d8aca2f82bede432a4", size = 2041590, upload-time = "2025-10-14T10:20:34.332Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" },
|
{ url = "https://files.pythonhosted.org/packages/70/69/dce747b1d21d59e85af433428978a1893c6f8a7068fa2bb4a927fba7a5ff/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9f5f30c402ed58f90c70e12eff65547d3ab74685ffe8283c719e6bead8ef53f", size = 2219869, upload-time = "2025-10-14T10:20:35.965Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" },
|
{ url = "https://files.pythonhosted.org/packages/83/6a/c070e30e295403bf29c4df1cb781317b6a9bac7cd07b8d3acc94d501a63c/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd96e5d15385d301733113bcaa324c8bcf111275b7675a9c6e88bfb19fc05e3b", size = 2345169, upload-time = "2025-10-14T10:20:37.627Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/83/06d001f8043c336baea7fd202a9ac7ad71f87e1c55d8112c50b745c40324/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f348cbb44fae6e9653c1055db7e29de67ea6a9ca03a5fa2c2e11a47cff0e47", size = 2070165, upload-time = "2025-10-14T10:20:39.246Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/14/0a/e567c2883588dd12bcbc110232d892cf385356f7c8a9910311ac997ab715/pydantic_core-2.41.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec22626a2d14620a83ca583c6f5a4080fa3155282718b6055c2ea48d3ef35970", size = 2189067, upload-time = "2025-10-14T10:20:41.015Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/1d/3d9fca34273ba03c9b1c5289f7618bc4bd09c3ad2289b5420481aa051a99/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a95d4590b1f1a43bf33ca6d647b990a88f4a3824a8c4572c708f0b45a5290ed", size = 2132997, upload-time = "2025-10-14T10:20:43.106Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" },
|
{ url = "https://files.pythonhosted.org/packages/52/70/d702ef7a6cd41a8afc61f3554922b3ed8d19dd54c3bd4bdbfe332e610827/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:f9672ab4d398e1b602feadcffcdd3af44d5f5e6ddc15bc7d15d376d47e8e19f8", size = 2307187, upload-time = "2025-10-14T10:20:44.849Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/4c/c06be6e27545d08b802127914156f38d10ca287a9e8489342793de8aae3c/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:84d8854db5f55fead3b579f04bda9a36461dab0730c5d570e1526483e7bb8431", size = 2305204, upload-time = "2025-10-14T10:20:46.781Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/e5/35ae4919bcd9f18603419e23c5eaf32750224a89d41a8df1a3704b69f77e/pydantic_core-2.41.4-cp312-cp312-win32.whl", hash = "sha256:9be1c01adb2ecc4e464392c36d17f97e9110fbbc906bcbe1c943b5b87a74aabd", size = 1972536, upload-time = "2025-10-14T10:20:48.39Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/c2/49c5bb6d2a49eb2ee3647a93e3dae7080c6409a8a7558b075027644e879c/pydantic_core-2.41.4-cp312-cp312-win_amd64.whl", hash = "sha256:d682cf1d22bab22a5be08539dca3d1593488a99998f9f412137bc323179067ff", size = 2031132, upload-time = "2025-10-14T10:20:50.421Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" },
|
{ url = "https://files.pythonhosted.org/packages/06/23/936343dbcba6eec93f73e95eb346810fc732f71ba27967b287b66f7b7097/pydantic_core-2.41.4-cp312-cp312-win_arm64.whl", hash = "sha256:833eebfd75a26d17470b58768c1834dfc90141b7afc6eb0429c21fc5a21dcfb8", size = 1969483, upload-time = "2025-10-14T10:20:52.35Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" },
|
{ url = "https://files.pythonhosted.org/packages/13/d0/c20adabd181a029a970738dfe23710b52a31f1258f591874fcdec7359845/pydantic_core-2.41.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:85e050ad9e5f6fe1004eec65c914332e52f429bc0ae12d6fa2092407a462c746", size = 2105688, upload-time = "2025-10-14T10:20:54.448Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" },
|
{ url = "https://files.pythonhosted.org/packages/00/b6/0ce5c03cec5ae94cca220dfecddc453c077d71363b98a4bbdb3c0b22c783/pydantic_core-2.41.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7393f1d64792763a48924ba31d1e44c2cfbc05e3b1c2c9abb4ceeadd912cced", size = 1910807, upload-time = "2025-10-14T10:20:56.115Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/3e/800d3d02c8beb0b5c069c870cbb83799d085debf43499c897bb4b4aaff0d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94dab0940b0d1fb28bcab847adf887c66a27a40291eedf0b473be58761c9799a", size = 1956669, upload-time = "2025-10-14T10:20:57.874Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/a4/24271cc71a17f64589be49ab8bd0751f6a0a03046c690df60989f2f95c2c/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de7c42f897e689ee6f9e93c4bec72b99ae3b32a2ade1c7e4798e690ff5246e02", size = 2051629, upload-time = "2025-10-14T10:21:00.006Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/de/45af3ca2f175d91b96bfb62e1f2d2f1f9f3b14a734afe0bfeff079f78181/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:664b3199193262277b8b3cd1e754fb07f2c6023289c815a1e1e8fb415cb247b1", size = 2224049, upload-time = "2025-10-14T10:21:01.801Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" },
|
{ url = "https://files.pythonhosted.org/packages/af/8f/ae4e1ff84672bf869d0a77af24fd78387850e9497753c432875066b5d622/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95b253b88f7d308b1c0b417c4624f44553ba4762816f94e6986819b9c273fb2", size = 2342409, upload-time = "2025-10-14T10:21:03.556Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" },
|
{ url = "https://files.pythonhosted.org/packages/18/62/273dd70b0026a085c7b74b000394e1ef95719ea579c76ea2f0cc8893736d/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1351f5bbdbbabc689727cb91649a00cb9ee7203e0a6e54e9f5ba9e22e384b84", size = 2069635, upload-time = "2025-10-14T10:21:05.385Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" },
|
{ url = "https://files.pythonhosted.org/packages/30/03/cf485fff699b4cdaea469bc481719d3e49f023241b4abb656f8d422189fc/pydantic_core-2.41.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1affa4798520b148d7182da0615d648e752de4ab1a9566b7471bc803d88a062d", size = 2194284, upload-time = "2025-10-14T10:21:07.122Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" },
|
{ url = "https://files.pythonhosted.org/packages/f9/7e/c8e713db32405dfd97211f2fc0a15d6bf8adb7640f3d18544c1f39526619/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7b74e18052fea4aa8dea2fb7dbc23d15439695da6cbe6cfc1b694af1115df09d", size = 2137566, upload-time = "2025-10-14T10:21:08.981Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" },
|
{ url = "https://files.pythonhosted.org/packages/04/f7/db71fd4cdccc8b75990f79ccafbbd66757e19f6d5ee724a6252414483fb4/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:285b643d75c0e30abda9dc1077395624f314a37e3c09ca402d4015ef5979f1a2", size = 2316809, upload-time = "2025-10-14T10:21:10.805Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" },
|
{ url = "https://files.pythonhosted.org/packages/76/63/a54973ddb945f1bca56742b48b144d85c9fc22f819ddeb9f861c249d5464/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f52679ff4218d713b3b33f88c89ccbf3a5c2c12ba665fb80ccc4192b4608dbab", size = 2311119, upload-time = "2025-10-14T10:21:12.583Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/03/5d12891e93c19218af74843a27e32b94922195ded2386f7b55382f904d2f/pydantic_core-2.41.4-cp313-cp313-win32.whl", hash = "sha256:ecde6dedd6fff127c273c76821bb754d793be1024bc33314a120f83a3c69460c", size = 1981398, upload-time = "2025-10-14T10:21:14.584Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/d8/fd0de71f39db91135b7a26996160de71c073d8635edfce8b3c3681be0d6d/pydantic_core-2.41.4-cp313-cp313-win_amd64.whl", hash = "sha256:d081a1f3800f05409ed868ebb2d74ac39dd0c1ff6c035b5162356d76030736d4", size = 2030735, upload-time = "2025-10-14T10:21:16.432Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" },
|
{ url = "https://files.pythonhosted.org/packages/72/86/c99921c1cf6650023c08bfab6fe2d7057a5142628ef7ccfa9921f2dda1d5/pydantic_core-2.41.4-cp313-cp313-win_arm64.whl", hash = "sha256:f8e49c9c364a7edcbe2a310f12733aad95b022495ef2a8d653f645e5d20c1564", size = 1973209, upload-time = "2025-10-14T10:21:18.213Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" },
|
{ url = "https://files.pythonhosted.org/packages/36/0d/b5706cacb70a8414396efdda3d72ae0542e050b591119e458e2490baf035/pydantic_core-2.41.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ed97fd56a561f5eb5706cebe94f1ad7c13b84d98312a05546f2ad036bafe87f4", size = 1877324, upload-time = "2025-10-14T10:21:20.363Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/2d/cba1fa02cfdea72dfb3a9babb067c83b9dff0bbcb198368e000a6b756ea7/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a870c307bf1ee91fc58a9a61338ff780d01bfae45922624816878dce784095d2", size = 1884515, upload-time = "2025-10-14T10:21:22.339Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" },
|
{ url = "https://files.pythonhosted.org/packages/07/ea/3df927c4384ed9b503c9cc2d076cf983b4f2adb0c754578dfb1245c51e46/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf", size = 2042819, upload-time = "2025-10-14T10:21:26.683Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" },
|
{ url = "https://files.pythonhosted.org/packages/6a/ee/df8e871f07074250270a3b1b82aad4cd0026b588acd5d7d3eb2fcb1471a3/pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2", size = 1995866, upload-time = "2025-10-14T10:21:28.951Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" },
|
{ url = "https://files.pythonhosted.org/packages/fc/de/b20f4ab954d6d399499c33ec4fafc46d9551e11dc1858fb7f5dca0748ceb/pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89", size = 1970034, upload-time = "2025-10-14T10:21:30.869Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" },
|
{ url = "https://files.pythonhosted.org/packages/54/28/d3325da57d413b9819365546eb9a6e8b7cbd9373d9380efd5f74326143e6/pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1", size = 2102022, upload-time = "2025-10-14T10:21:32.809Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" },
|
{ url = "https://files.pythonhosted.org/packages/9e/24/b58a1bc0d834bf1acc4361e61233ee217169a42efbdc15a60296e13ce438/pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac", size = 1905495, upload-time = "2025-10-14T10:21:34.812Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" },
|
{ url = "https://files.pythonhosted.org/packages/fb/a4/71f759cc41b7043e8ecdaab81b985a9b6cad7cec077e0b92cff8b71ecf6b/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554", size = 1956131, upload-time = "2025-10-14T10:21:36.924Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/64/1e79ac7aa51f1eec7c4cda8cbe456d5d09f05fdd68b32776d72168d54275/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e", size = 2052236, upload-time = "2025-10-14T10:21:38.927Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" },
|
{ url = "https://files.pythonhosted.org/packages/e9/e3/a3ffc363bd4287b80f1d43dc1c28ba64831f8dfc237d6fec8f2661138d48/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616", size = 2223573, upload-time = "2025-10-14T10:21:41.574Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" },
|
{ url = "https://files.pythonhosted.org/packages/28/27/78814089b4d2e684a9088ede3790763c64693c3d1408ddc0a248bc789126/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af", size = 2342467, upload-time = "2025-10-14T10:21:44.018Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" },
|
{ url = "https://files.pythonhosted.org/packages/92/97/4de0e2a1159cb85ad737e03306717637842c88c7fd6d97973172fb183149/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12", size = 2063754, upload-time = "2025-10-14T10:21:46.466Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" },
|
{ url = "https://files.pythonhosted.org/packages/0f/50/8cb90ce4b9efcf7ae78130afeb99fd1c86125ccdf9906ef64b9d42f37c25/pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d", size = 2196754, upload-time = "2025-10-14T10:21:48.486Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" },
|
{ url = "https://files.pythonhosted.org/packages/34/3b/ccdc77af9cd5082723574a1cc1bcae7a6acacc829d7c0a06201f7886a109/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad", size = 2137115, upload-time = "2025-10-14T10:21:50.63Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" },
|
{ url = "https://files.pythonhosted.org/packages/ca/ba/e7c7a02651a8f7c52dc2cff2b64a30c313e3b57c7d93703cecea76c09b71/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a", size = 2317400, upload-time = "2025-10-14T10:21:52.959Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" },
|
{ url = "https://files.pythonhosted.org/packages/2c/ba/6c533a4ee8aec6b812c643c49bb3bd88d3f01e3cebe451bb85512d37f00f/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025", size = 2312070, upload-time = "2025-10-14T10:21:55.419Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" },
|
{ url = "https://files.pythonhosted.org/packages/22/ae/f10524fcc0ab8d7f96cf9a74c880243576fd3e72bd8ce4f81e43d22bcab7/pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e", size = 1982277, upload-time = "2025-10-14T10:21:57.474Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" },
|
{ url = "https://files.pythonhosted.org/packages/b4/dc/e5aa27aea1ad4638f0c3fb41132f7eb583bd7420ee63204e2d4333a3bbf9/pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894", size = 2024608, upload-time = "2025-10-14T10:21:59.557Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" },
|
{ url = "https://files.pythonhosted.org/packages/3e/61/51d89cc2612bd147198e120a13f150afbf0bcb4615cddb049ab10b81b79e/pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d", size = 1967614, upload-time = "2025-10-14T10:22:01.847Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" },
|
{ url = "https://files.pythonhosted.org/packages/0d/c2/472f2e31b95eff099961fa050c376ab7156a81da194f9edb9f710f68787b/pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da", size = 1876904, upload-time = "2025-10-14T10:22:04.062Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" },
|
{ url = "https://files.pythonhosted.org/packages/4a/07/ea8eeb91173807ecdae4f4a5f4b150a520085b35454350fc219ba79e66a3/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e", size = 1882538, upload-time = "2025-10-14T10:22:06.39Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/29/b53a9ca6cd366bfc928823679c6a76c7a4c69f8201c0ba7903ad18ebae2f/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa", size = 2041183, upload-time = "2025-10-14T10:22:08.812Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" },
|
{ url = "https://files.pythonhosted.org/packages/c7/3d/f8c1a371ceebcaf94d6dd2d77c6cf4b1c078e13a5837aee83f760b4f7cfd/pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d", size = 1993542, upload-time = "2025-10-14T10:22:11.332Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/ac/9fc61b4f9d079482a290afe8d206b8f490e9fd32d4fc03ed4fc698214e01/pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0", size = 1973897, upload-time = "2025-10-14T10:22:13.444Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/12/5ba58daa7f453454464f92b3ca7b9d7c657d8641c48e370c3ebc9a82dd78/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:a1b2cfec3879afb742a7b0bcfa53e4f22ba96571c9e54d6a3afe1052d17d843b", size = 2122139, upload-time = "2025-10-14T10:22:47.288Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" },
|
{ url = "https://files.pythonhosted.org/packages/21/fb/6860126a77725c3108baecd10fd3d75fec25191d6381b6eb2ac660228eac/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:d175600d975b7c244af6eb9c9041f10059f20b8bbffec9e33fdd5ee3f67cdc42", size = 1936674, upload-time = "2025-10-14T10:22:49.555Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/be/57dcaa3ed595d81f8757e2b44a38240ac5d37628bce25fb20d02c7018776/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f184d657fa4947ae5ec9c47bd7e917730fa1cbb78195037e32dcbab50aca5ee", size = 1956398, upload-time = "2025-10-14T10:22:52.19Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" },
|
{ url = "https://files.pythonhosted.org/packages/2f/1d/679a344fadb9695f1a6a294d739fbd21d71fa023286daeea8c0ed49e7c2b/pydantic_core-2.41.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed810568aeffed3edc78910af32af911c835cc39ebbfacd1f0ab5dd53028e5c", size = 2138674, upload-time = "2025-10-14T10:22:54.499Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" },
|
{ url = "https://files.pythonhosted.org/packages/c4/48/ae937e5a831b7c0dc646b2ef788c27cd003894882415300ed21927c21efa/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:4f5d640aeebb438517150fdeec097739614421900e4a08db4a3ef38898798537", size = 2112087, upload-time = "2025-10-14T10:22:56.818Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" },
|
{ url = "https://files.pythonhosted.org/packages/5e/db/6db8073e3d32dae017da7e0d16a9ecb897d0a4d92e00634916e486097961/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:4a9ab037b71927babc6d9e7fc01aea9e66dc2a4a34dff06ef0724a4049629f94", size = 1920387, upload-time = "2025-10-14T10:22:59.342Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" },
|
{ url = "https://files.pythonhosted.org/packages/0d/c1/dd3542d072fcc336030d66834872f0328727e3b8de289c662faa04aa270e/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4dab9484ec605c3016df9ad4fd4f9a390bc5d816a3b10c6550f8424bb80b18c", size = 1951495, upload-time = "2025-10-14T10:23:02.089Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" },
|
{ url = "https://files.pythonhosted.org/packages/2b/c6/db8d13a1f8ab3f1eb08c88bd00fd62d44311e3456d1e85c0e59e0a0376e7/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335", size = 2139008, upload-time = "2025-10-14T10:23:04.539Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" },
|
{ url = "https://files.pythonhosted.org/packages/5d/d4/912e976a2dd0b49f31c98a060ca90b353f3b73ee3ea2fd0030412f6ac5ec/pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e5ab4fc177dd41536b3c32b2ea11380dd3d4619a385860621478ac2d25ceb00", size = 2106739, upload-time = "2025-10-14T10:23:06.934Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" },
|
{ url = "https://files.pythonhosted.org/packages/71/f0/66ec5a626c81eba326072d6ee2b127f8c139543f1bf609b4842978d37833/pydantic_core-2.41.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3d88d0054d3fa11ce936184896bed3c1c5441d6fa483b498fac6a5d0dd6f64a9", size = 1932549, upload-time = "2025-10-14T10:23:09.24Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" },
|
{ url = "https://files.pythonhosted.org/packages/c4/af/625626278ca801ea0a658c2dcf290dc9f21bb383098e99e7c6a029fccfc0/pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2a054a8725f05b4b6503357e0ac1c4e8234ad3b0c2ac130d6ffc66f0e170e2", size = 2135093, upload-time = "2025-10-14T10:23:11.626Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" },
|
{ url = "https://files.pythonhosted.org/packages/20/f6/2fba049f54e0f4975fef66be654c597a1d005320fa141863699180c7697d/pydantic_core-2.41.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0d9db5a161c99375a0c68c058e227bee1d89303300802601d76a3d01f74e258", size = 2187971, upload-time = "2025-10-14T10:23:14.437Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" },
|
{ url = "https://files.pythonhosted.org/packages/0e/80/65ab839a2dfcd3b949202f9d920c34f9de5a537c3646662bdf2f7d999680/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6273ea2c8ffdac7b7fda2653c49682db815aebf4a89243a6feccf5e36c18c347", size = 2147939, upload-time = "2025-10-14T10:23:16.831Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" },
|
{ url = "https://files.pythonhosted.org/packages/44/58/627565d3d182ce6dfda18b8e1c841eede3629d59c9d7cbc1e12a03aeb328/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:4c973add636efc61de22530b2ef83a65f39b6d6f656df97f678720e20de26caa", size = 2311400, upload-time = "2025-10-14T10:23:19.234Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" },
|
{ url = "https://files.pythonhosted.org/packages/24/06/8a84711162ad5a5f19a88cead37cca81b4b1f294f46260ef7334ae4f24d3/pydantic_core-2.41.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b69d1973354758007f46cf2d44a4f3d0933f10b6dc9bf15cf1356e037f6f731a", size = 2316840, upload-time = "2025-10-14T10:23:21.738Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" },
|
{ url = "https://files.pythonhosted.org/packages/aa/8b/b7bb512a4682a2f7fbfae152a755d37351743900226d29bd953aaf870eaa/pydantic_core-2.41.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3619320641fd212aaf5997b6ca505e97540b7e16418f4a241f44cdf108ffb50d", size = 2149135, upload-time = "2025-10-14T10:23:24.379Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" },
|
{ url = "https://files.pythonhosted.org/packages/7e/7d/138e902ed6399b866f7cfe4435d22445e16fff888a1c00560d9dc79a780f/pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:491535d45cd7ad7e4a2af4a5169b0d07bebf1adfd164b0368da8aa41e19907a5", size = 2104721, upload-time = "2025-10-14T10:23:26.906Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" },
|
{ url = "https://files.pythonhosted.org/packages/47/13/0525623cf94627f7b53b4c2034c81edc8491cbfc7c28d5447fa318791479/pydantic_core-2.41.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:54d86c0cada6aba4ec4c047d0e348cbad7063b87ae0f005d9f8c9ad04d4a92a2", size = 1931608, upload-time = "2025-10-14T10:23:29.306Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" },
|
{ url = "https://files.pythonhosted.org/packages/d6/f9/744bc98137d6ef0a233f808bfc9b18cf94624bf30836a18d3b05d08bf418/pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca1124aced216b2500dc2609eade086d718e8249cb9696660ab447d50a758bd", size = 2132986, upload-time = "2025-10-14T10:23:32.057Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/c8/629e88920171173f6049386cc71f893dff03209a9ef32b4d2f7e7c264bcf/pydantic_core-2.41.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c9024169becccf0cb470ada03ee578d7348c119a0d42af3dcf9eda96e3a247c", size = 2187516, upload-time = "2025-10-14T10:23:34.871Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/0f/4f2734688d98488782218ca61bcc118329bf5de05bb7fe3adc7dd79b0b86/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:26895a4268ae5a2849269f4991cdc97236e4b9c010e51137becf25182daac405", size = 2146146, upload-time = "2025-10-14T10:23:37.342Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ed/f2/ab385dbd94a052c62224b99cf99002eee99dbec40e10006c78575aead256/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:ca4df25762cf71308c446e33c9b1fdca2923a3f13de616e2a949f38bf21ff5a8", size = 2311296, upload-time = "2025-10-14T10:23:40.145Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/8e/e4f12afe1beeb9823bba5375f8f258df0cc61b056b0195fb1cf9f62a1a58/pydantic_core-2.41.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5a28fcedd762349519276c36634e71853b4541079cab4acaaac60c4421827308", size = 2315386, upload-time = "2025-10-14T10:23:42.624Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/48/f7/925f65d930802e3ea2eb4d5afa4cb8730c8dc0d2cb89a59dc4ed2fcb2d74/pydantic_core-2.41.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c173ddcd86afd2535e2b695217e82191580663a1d1928239f877f5a1649ef39f", size = 2147775, upload-time = "2025-10-14T10:23:45.406Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -836,15 +860,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -980,14 +995,14 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-inspection"
|
name = "typing-inspection"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" },
|
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1017,13 +1032,8 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" },
|
{ url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" },
|
{ url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" },
|
{ url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/05/52/7223011bb760fce8ddc53416beb65b83a3ea6d7d13738dde75eeb2c89679/watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", size = 96390, upload-time = "2024-11-01T14:06:49.325Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/62/d2b21bc4e706d3a9d467561f487c2938cbd881c69f3808c43ac1ec242391/watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", size = 88386, upload-time = "2024-11-01T14:06:50.536Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ea/22/1c90b20eda9f4132e4603a26296108728a8bfe9584b006bd05dd94548853/watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", size = 89017, upload-time = "2024-11-01T14:06:51.717Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" },
|
{ url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/79/69f2b0e8d3f2afd462029031baafb1b75d11bb62703f0e1022b2e54d49ee/watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", size = 87903, upload-time = "2024-11-01T14:06:57.052Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/2b/dc048dd71c2e5f0f7ebc04dd7912981ec45793a03c0dc462438e0591ba5d/watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", size = 88381, upload-time = "2024-11-01T14:06:58.193Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
{ url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
{ url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
{ url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" },
|
||||||
@@ -1124,20 +1134,4 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" },
|
{ url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513, upload-time = "2025-09-14T22:18:20.61Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
|
{ url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118, upload-time = "2025-09-14T22:18:17.849Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
|
{ url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940, upload-time = "2025-09-14T22:18:19.088Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/14/0d/d0a405dad6ab6f9f759c26d866cca66cb209bff6f8db656074d662a953dd/zstandard-0.25.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0", size = 795263, upload-time = "2025-09-14T22:18:21.683Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/aa/ceb8d79cbad6dabd4cb1178ca853f6a4374d791c5e0241a0988173e2a341/zstandard-0.25.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2", size = 640560, upload-time = "2025-09-14T22:18:22.867Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/cd/2cf6d476131b509cc122d25d3416a2d0aa17687ddbada7599149f9da620e/zstandard-0.25.0-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df", size = 5344244, upload-time = "2025-09-14T22:18:24.724Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5c/71/e14820b61a1c137966b7667b400b72fa4a45c836257e443f3d77607db268/zstandard-0.25.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53", size = 5054550, upload-time = "2025-09-14T22:18:26.445Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/ce/26dc5a6fa956be41d0e984909224ed196ee6f91d607f0b3fd84577741a77/zstandard-0.25.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3", size = 5401150, upload-time = "2025-09-14T22:18:28.745Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f2/1b/402cab5edcfe867465daf869d5ac2a94930931c0989633bc01d6a7d8bd68/zstandard-0.25.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362", size = 5448595, upload-time = "2025-09-14T22:18:30.475Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/b2/fc50c58271a1ead0e5a0a0e6311f4b221f35954dce438ce62751b3af9b68/zstandard-0.25.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530", size = 5555290, upload-time = "2025-09-14T22:18:32.336Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d2/20/5f72d6ba970690df90fdd37195c5caa992e70cb6f203f74cc2bcc0b8cf30/zstandard-0.25.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb", size = 5043898, upload-time = "2025-09-14T22:18:34.215Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e4/f1/131a0382b8b8d11e84690574645f528f5c5b9343e06cefd77f5fd730cd2b/zstandard-0.25.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751", size = 5571173, upload-time = "2025-09-14T22:18:36.117Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/f6/2a37931023f737fd849c5c28def57442bbafadb626da60cf9ed58461fe24/zstandard-0.25.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577", size = 4958261, upload-time = "2025-09-14T22:18:38.098Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b5/52/ca76ed6dbfd8845a5563d3af4e972da3b9da8a9308ca6b56b0b929d93e23/zstandard-0.25.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7", size = 5265680, upload-time = "2025-09-14T22:18:39.834Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7a/59/edd117dedb97a768578b49fb2f1156defb839d1aa5b06200a62be943667f/zstandard-0.25.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936", size = 5439747, upload-time = "2025-09-14T22:18:41.647Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/71/c2e9234643dcfbd6c5e975e9a2b0050e1b2afffda6c3a959e1b87997bc80/zstandard-0.25.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388", size = 5818805, upload-time = "2025-09-14T22:18:43.602Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f5/93/8ebc19f0a31c44ea0e7348f9b0d4b326ed413b6575a3c6ff4ed50222abb6/zstandard-0.25.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27", size = 5362280, upload-time = "2025-09-14T22:18:45.625Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b8/e9/29cc59d4a9d51b3fd8b477d858d0bd7ab627f700908bf1517f46ddd470ae/zstandard-0.25.0-cp39-cp39-win32.whl", hash = "sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649", size = 436460, upload-time = "2025-09-14T22:18:49.077Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/41/b5/bc7a92c116e2ef32dc8061c209d71e97ff6df37487d7d39adb51a343ee89/zstandard-0.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860", size = 506097, upload-time = "2025-09-14T22:18:47.342Z" },
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ Each checkpointer should conform to `langgraph.checkpoint.base.BaseCheckpointSav
|
|||||||
- `.put_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).
|
- `.put_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).
|
||||||
- `.get_tuple` - Fetch a checkpoint tuple using for a given configuration (`thread_id` and `checkpoint_id`).
|
- `.get_tuple` - Fetch a checkpoint tuple using for a given configuration (`thread_id` and `checkpoint_id`).
|
||||||
- `.list` - List checkpoints that match a given configuration and filter criteria.
|
- `.list` - List checkpoints that match a given configuration and filter criteria.
|
||||||
|
- `.delete_thread()` - Delete all checkpoints and writes associated with a thread.
|
||||||
|
- `.get_next_version()` - Generate the next version ID for a channel.
|
||||||
|
|
||||||
If the checkpointer will be used with asynchronous graph execution (i.e. executing the graph via `.ainvoke`, `.astream`, `.abatch`), checkpointer must implement asynchronous versions of the above methods (`.aput`, `.aput_writes`, `.aget_tuple`, `.alist`).
|
If the checkpointer will be used with asynchronous graph execution (i.e. executing the graph via `.ainvoke`, `.astream`, `.abatch`), checkpointer must implement asynchronous versions of the above methods (`.aput`, `.aput_writes`, `.aget_tuple`, `.alist`). Similarly, the checkpointer must implement `.adelete_thread()` if asynchronous thread cleanup is desired. The base class provides a default implementation of `.get_next_version()` that generates an integer sequence starting from 1, but this method should be overridden for custom versioning schemes.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from typing import ( # noqa: UP035
|
|||||||
NamedTuple,
|
NamedTuple,
|
||||||
TypedDict,
|
TypedDict,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from langchain_core.runnables import RunnableConfig
|
from langchain_core.runnables import RunnableConfig
|
||||||
@@ -35,17 +34,17 @@ class CheckpointMetadata(TypedDict, total=False):
|
|||||||
source: Literal["input", "loop", "update", "fork"]
|
source: Literal["input", "loop", "update", "fork"]
|
||||||
"""The source of the checkpoint.
|
"""The source of the checkpoint.
|
||||||
|
|
||||||
- "input": The checkpoint was created from an input to invoke/stream/batch.
|
- `"input"`: The checkpoint was created from an input to invoke/stream/batch.
|
||||||
- "loop": The checkpoint was created from inside the pregel loop.
|
- `"loop"`: The checkpoint was created from inside the pregel loop.
|
||||||
- "update": The checkpoint was created from a manual state update.
|
- `"update"`: The checkpoint was created from a manual state update.
|
||||||
- "fork": The checkpoint was created as a copy of another checkpoint.
|
- `"fork"`: The checkpoint was created as a copy of another checkpoint.
|
||||||
"""
|
"""
|
||||||
step: int
|
step: int
|
||||||
"""The step number of the checkpoint.
|
"""The step number of the checkpoint.
|
||||||
|
|
||||||
-1 for the first "input" checkpoint.
|
`-1` for the first `"input"` checkpoint.
|
||||||
0 for the first "loop" checkpoint.
|
`0` for the first `"loop"` checkpoint.
|
||||||
... for the nth checkpoint afterwards.
|
`...` for the `nth` checkpoint afterwards.
|
||||||
"""
|
"""
|
||||||
parents: dict[str, str]
|
parents: dict[str, str]
|
||||||
"""The IDs of the parent checkpoints.
|
"""The IDs of the parent checkpoints.
|
||||||
@@ -54,7 +53,7 @@ class CheckpointMetadata(TypedDict, total=False):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
ChannelVersions = dict[str, Union[str, int, float]]
|
ChannelVersions = dict[str, str | int | float]
|
||||||
|
|
||||||
|
|
||||||
class Checkpoint(TypedDict):
|
class Checkpoint(TypedDict):
|
||||||
@@ -148,7 +147,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
config: Configuration specifying which checkpoint to retrieve.
|
config: Configuration specifying which checkpoint to retrieve.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[Checkpoint]: The requested checkpoint, or None if not found.
|
The requested checkpoint, or `None` if not found.
|
||||||
"""
|
"""
|
||||||
if value := self.get_tuple(config):
|
if value := self.get_tuple(config):
|
||||||
return value.checkpoint
|
return value.checkpoint
|
||||||
@@ -160,7 +159,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
config: Configuration specifying which checkpoint to retrieve.
|
config: Configuration specifying which checkpoint to retrieve.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The requested checkpoint tuple, or None if not found.
|
The requested checkpoint tuple, or `None` if not found.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotImplementedError: Implement this method in your custom checkpoint saver.
|
NotImplementedError: Implement this method in your custom checkpoint saver.
|
||||||
@@ -184,7 +183,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Iterator[CheckpointTuple]: Iterator of matching checkpoint tuples.
|
Iterator of matching checkpoint tuples.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotImplementedError: Implement this method in your custom checkpoint saver.
|
NotImplementedError: Implement this method in your custom checkpoint saver.
|
||||||
@@ -252,7 +251,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
config: Configuration specifying which checkpoint to retrieve.
|
config: Configuration specifying which checkpoint to retrieve.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[Checkpoint]: The requested checkpoint, or None if not found.
|
The requested checkpoint, or `None` if not found.
|
||||||
"""
|
"""
|
||||||
if value := await self.aget_tuple(config):
|
if value := await self.aget_tuple(config):
|
||||||
return value.checkpoint
|
return value.checkpoint
|
||||||
@@ -264,7 +263,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
config: Configuration specifying which checkpoint to retrieve.
|
config: Configuration specifying which checkpoint to retrieve.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The requested checkpoint tuple, or None if not found.
|
The requested checkpoint tuple, or `None` if not found.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotImplementedError: Implement this method in your custom checkpoint saver.
|
NotImplementedError: Implement this method in your custom checkpoint saver.
|
||||||
@@ -288,7 +287,7 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AsyncIterator[CheckpointTuple]: Async iterator of matching checkpoint tuples.
|
Async iterator of matching checkpoint tuples.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotImplementedError: Implement this method in your custom checkpoint saver.
|
NotImplementedError: Implement this method in your custom checkpoint saver.
|
||||||
@@ -353,11 +352,11 @@ class BaseCheckpointSaver(Generic[V]):
|
|||||||
def get_next_version(self, current: V | None, channel: None) -> V:
|
def get_next_version(self, current: V | None, channel: None) -> V:
|
||||||
"""Generate the next version ID for a channel.
|
"""Generate the next version ID for a channel.
|
||||||
|
|
||||||
Default is to use integer versions, incrementing by 1. If you override, you can use str/int/float versions,
|
Default is to use integer versions, incrementing by `1`. If you override, you can use `str`/`int`/`float`
|
||||||
as long as they are monotonically increasing.
|
versions, as long as they are monotonically increasing.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
current: The current version identifier (int, float, or str).
|
current: The current version identifier (`int`, `float`, or `str`).
|
||||||
channel: Deprecated argument, kept for backwards compatibility.
|
channel: Deprecated argument, kept for backwards compatibility.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -404,6 +403,16 @@ def get_checkpoint_metadata(
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
|
def get_serializable_checkpoint_metadata(
|
||||||
|
config: RunnableConfig, metadata: CheckpointMetadata
|
||||||
|
) -> CheckpointMetadata:
|
||||||
|
"""Get checkpoint metadata in a backwards-compatible manner."""
|
||||||
|
checkpoint_metadata = get_checkpoint_metadata(config, metadata)
|
||||||
|
if "writes" in checkpoint_metadata:
|
||||||
|
checkpoint_metadata.pop("writes")
|
||||||
|
return checkpoint_metadata
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Mapping from error type to error index.
|
Mapping from error type to error index.
|
||||||
Regular writes just map to their index in the list of writes being saved.
|
Regular writes just map to their index in the list of writes being saved.
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class InMemorySaver(
|
|||||||
Only use `InMemorySaver` for debugging or testing purposes.
|
Only use `InMemorySaver` for debugging or testing purposes.
|
||||||
For production use cases we recommend installing [langgraph-checkpoint-postgres](https://pypi.org/project/langgraph-checkpoint-postgres/) and using `PostgresSaver` / `AsyncPostgresSaver`.
|
For production use cases we recommend installing [langgraph-checkpoint-postgres](https://pypi.org/project/langgraph-checkpoint-postgres/) and using `PostgresSaver` / `AsyncPostgresSaver`.
|
||||||
|
|
||||||
If you are using the LangGraph Platform, no checkpointer needs to be specified. The correct managed checkpointer will be used automatically.
|
If you are using LangSmith Deployment, no checkpointer needs to be specified. The correct managed checkpointer will be used automatically.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
serde: The serializer to use for serializing and deserializing checkpoints. Defaults to None.
|
serde: The serializer to use for serializing and deserializing checkpoints.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ class InMemorySaver(
|
|||||||
"""Get a checkpoint tuple from the in-memory storage.
|
"""Get a checkpoint tuple from the in-memory storage.
|
||||||
|
|
||||||
This method retrieves a checkpoint tuple from the in-memory storage based on the
|
This method retrieves a checkpoint tuple from the in-memory storage based on the
|
||||||
provided config. If the config contains a "checkpoint_id" key, the checkpoint with
|
provided config. If the config contains a `checkpoint_id` key, the checkpoint with
|
||||||
the matching thread ID and timestamp is retrieved. Otherwise, the latest checkpoint
|
the matching thread ID and timestamp is retrieved. Otherwise, the latest checkpoint
|
||||||
for the given thread ID is retrieved.
|
for the given thread ID is retrieved.
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class InMemorySaver(
|
|||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
thread_id: str = config["configurable"]["thread_id"]
|
thread_id: str = config["configurable"]["thread_id"]
|
||||||
checkpoint_ns: str = config["configurable"].get("checkpoint_ns", "")
|
checkpoint_ns: str = config["configurable"].get("checkpoint_ns", "")
|
||||||
@@ -231,7 +231,7 @@ class InMemorySaver(
|
|||||||
limit: Maximum number of checkpoints to return.
|
limit: Maximum number of checkpoints to return.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Iterator[CheckpointTuple]: An iterator of matching checkpoint tuples.
|
An iterator of matching checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
thread_ids = (config["configurable"]["thread_id"],) if config else self.storage
|
thread_ids = (config["configurable"]["thread_id"],) if config else self.storage
|
||||||
config_checkpoint_ns = (
|
config_checkpoint_ns = (
|
||||||
@@ -423,16 +423,16 @@ class InMemorySaver(
|
|||||||
del self.blobs[k]
|
del self.blobs[k]
|
||||||
|
|
||||||
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
||||||
"""Asynchronous version of get_tuple.
|
"""Asynchronous version of `get_tuple`.
|
||||||
|
|
||||||
This method is an asynchronous wrapper around get_tuple that runs the synchronous
|
This method is an asynchronous wrapper around `get_tuple` that runs the synchronous
|
||||||
method in a separate thread using asyncio.
|
method in a separate thread using asyncio.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The config to use for retrieving the checkpoint.
|
config: The config to use for retrieving the checkpoint.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
The retrieved checkpoint tuple, or None if no matching checkpoint was found.
|
||||||
"""
|
"""
|
||||||
return self.get_tuple(config)
|
return self.get_tuple(config)
|
||||||
|
|
||||||
@@ -444,16 +444,16 @@ class InMemorySaver(
|
|||||||
before: RunnableConfig | None = None,
|
before: RunnableConfig | None = None,
|
||||||
limit: int | None = None,
|
limit: int | None = None,
|
||||||
) -> AsyncIterator[CheckpointTuple]:
|
) -> AsyncIterator[CheckpointTuple]:
|
||||||
"""Asynchronous version of list.
|
"""Asynchronous version of `list`.
|
||||||
|
|
||||||
This method is an asynchronous wrapper around list that runs the synchronous
|
This method is an asynchronous wrapper around `list` that runs the synchronous
|
||||||
method in a separate thread using asyncio.
|
method in a separate thread using asyncio.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The config to use for listing the checkpoints.
|
config: The config to use for listing the checkpoints.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
AsyncIterator[CheckpointTuple]: An asynchronous iterator of checkpoint tuples.
|
An asynchronous iterator of checkpoint tuples.
|
||||||
"""
|
"""
|
||||||
for item in self.list(config, filter=filter, before=before, limit=limit):
|
for item in self.list(config, filter=filter, before=before, limit=limit):
|
||||||
yield item
|
yield item
|
||||||
@@ -465,7 +465,7 @@ class InMemorySaver(
|
|||||||
metadata: CheckpointMetadata,
|
metadata: CheckpointMetadata,
|
||||||
new_versions: ChannelVersions,
|
new_versions: ChannelVersions,
|
||||||
) -> RunnableConfig:
|
) -> RunnableConfig:
|
||||||
"""Asynchronous version of put.
|
"""Asynchronous version of `put`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
config: The config to associate with the checkpoint.
|
config: The config to associate with the checkpoint.
|
||||||
@@ -485,9 +485,9 @@ class InMemorySaver(
|
|||||||
task_id: str,
|
task_id: str,
|
||||||
task_path: str = "",
|
task_path: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Asynchronous version of put_writes.
|
"""Asynchronous version of `put_writes`.
|
||||||
|
|
||||||
This method is an asynchronous wrapper around put_writes that runs the synchronous
|
This method is an asynchronous wrapper around `put_writes` that runs the synchronous
|
||||||
method in a separate thread using asyncio.
|
method in a separate thread using asyncio.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Protocol
|
from typing import Any, Protocol, runtime_checkable
|
||||||
|
|
||||||
|
|
||||||
class UntypedSerializerProtocol(Protocol):
|
class UntypedSerializerProtocol(Protocol):
|
||||||
@@ -11,13 +11,14 @@ class UntypedSerializerProtocol(Protocol):
|
|||||||
def loads(self, data: bytes) -> Any: ...
|
def loads(self, data: bytes) -> Any: ...
|
||||||
|
|
||||||
|
|
||||||
class SerializerProtocol(UntypedSerializerProtocol, Protocol):
|
@runtime_checkable
|
||||||
|
class SerializerProtocol(Protocol):
|
||||||
"""Protocol for serialization and deserialization of objects.
|
"""Protocol for serialization and deserialization of objects.
|
||||||
|
|
||||||
- `dumps`: Serialize an object to bytes.
|
- `dumps`: Serialize an object to bytes.
|
||||||
- `dumps_typed`: Serialize an object to a tuple (type, bytes).
|
- `dumps_typed`: Serialize an object to a tuple `(type, bytes)`.
|
||||||
- `loads`: Deserialize an object from bytes.
|
- `loads`: Deserialize an object from bytes.
|
||||||
- `loads_typed`: Deserialize an object from a tuple (type, bytes).
|
- `loads_typed`: Deserialize an object from a tuple `(type, bytes)`.
|
||||||
|
|
||||||
Valid implementations include the `pickle`, `json` and `orjson` modules.
|
Valid implementations include the `pickle`, `json` and `orjson` modules.
|
||||||
"""
|
"""
|
||||||
@@ -31,12 +32,6 @@ class SerializerCompat(SerializerProtocol):
|
|||||||
def __init__(self, serde: UntypedSerializerProtocol) -> None:
|
def __init__(self, serde: UntypedSerializerProtocol) -> None:
|
||||||
self.serde = serde
|
self.serde = serde
|
||||||
|
|
||||||
def dumps(self, obj: Any) -> bytes:
|
|
||||||
return self.serde.dumps(obj)
|
|
||||||
|
|
||||||
def loads(self, data: bytes) -> Any:
|
|
||||||
return self.serde.loads(data)
|
|
||||||
|
|
||||||
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
||||||
return type(obj).__name__, self.serde.dumps(obj)
|
return type(obj).__name__, self.serde.dumps(obj)
|
||||||
|
|
||||||
@@ -49,7 +44,7 @@ def maybe_add_typed_methods(
|
|||||||
) -> SerializerProtocol:
|
) -> SerializerProtocol:
|
||||||
"""Wrap serde old serde implementations in a class with loads_typed and dumps_typed for backwards compatibility."""
|
"""Wrap serde old serde implementations in a class with loads_typed and dumps_typed for backwards compatibility."""
|
||||||
|
|
||||||
if not hasattr(serde, "loads_typed") or not hasattr(serde, "dumps_typed"):
|
if not isinstance(serde, SerializerProtocol):
|
||||||
return SerializerCompat(serde)
|
return SerializerCompat(serde)
|
||||||
|
|
||||||
return serde
|
return serde
|
||||||
|
|||||||
@@ -14,14 +14,8 @@ class EncryptedSerializer(SerializerProtocol):
|
|||||||
self.cipher = cipher
|
self.cipher = cipher
|
||||||
self.serde = serde
|
self.serde = serde
|
||||||
|
|
||||||
def dumps(self, obj: Any) -> bytes:
|
|
||||||
return self.serde.dumps(obj)
|
|
||||||
|
|
||||||
def loads(self, data: bytes) -> Any:
|
|
||||||
return self.serde.loads(data)
|
|
||||||
|
|
||||||
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
||||||
"""Serialize an object to a tuple (type, bytes) and encrypt the bytes."""
|
"""Serialize an object to a tuple `(type, bytes)` and encrypt the bytes."""
|
||||||
# serialize data
|
# serialize data
|
||||||
typ, data = self.serde.dumps_typed(obj)
|
typ, data = self.serde.dumps_typed(obj)
|
||||||
# encrypt data
|
# encrypt data
|
||||||
@@ -45,7 +39,7 @@ class EncryptedSerializer(SerializerProtocol):
|
|||||||
def from_pycryptodome_aes(
|
def from_pycryptodome_aes(
|
||||||
cls, serde: SerializerProtocol = JsonPlusSerializer(), **kwargs: Any
|
cls, serde: SerializerProtocol = JsonPlusSerializer(), **kwargs: Any
|
||||||
) -> "EncryptedSerializer":
|
) -> "EncryptedSerializer":
|
||||||
"""Create an EncryptedSerializer using AES encryption."""
|
"""Create an `EncryptedSerializer` using AES encryption."""
|
||||||
try:
|
try:
|
||||||
from Crypto.Cipher import AES # type: ignore
|
from Crypto.Cipher import AES # type: ignore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import dataclasses
|
|||||||
import decimal
|
import decimal
|
||||||
import importlib
|
import importlib
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
import pickle
|
import pickle
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from collections.abc import Sequence
|
from collections.abc import Callable, Sequence
|
||||||
from datetime import date, datetime, time, timedelta, timezone
|
from datetime import date, datetime, time, timedelta, timezone
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
@@ -21,13 +22,12 @@ from ipaddress import (
|
|||||||
IPv6Interface,
|
IPv6Interface,
|
||||||
IPv6Network,
|
IPv6Network,
|
||||||
)
|
)
|
||||||
from typing import Any, Callable, cast
|
from typing import Any, Literal
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
import ormsgpack
|
import ormsgpack
|
||||||
from langchain_core.load.load import Reviver
|
from langchain_core.load.load import Reviver
|
||||||
from langchain_core.load.serializable import Serializable
|
|
||||||
|
|
||||||
from langgraph.checkpoint.serde.base import SerializerProtocol
|
from langgraph.checkpoint.serde.base import SerializerProtocol
|
||||||
from langgraph.checkpoint.serde.types import SendProtocol
|
from langgraph.checkpoint.serde.types import SendProtocol
|
||||||
@@ -35,18 +35,31 @@ from langgraph.store.base import Item
|
|||||||
|
|
||||||
LC_REVIVER = Reviver()
|
LC_REVIVER = Reviver()
|
||||||
EMPTY_BYTES = b""
|
EMPTY_BYTES = b""
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class JsonPlusSerializer(SerializerProtocol):
|
class JsonPlusSerializer(SerializerProtocol):
|
||||||
"""Serializer that uses ormsgpack, with a fallback to extended JSON serializer."""
|
"""Serializer that uses ormsgpack, with optional fallbacks.
|
||||||
|
|
||||||
|
Security note: this serializer is intended for use within the BaseCheckpointSaver
|
||||||
|
class and called within the Pregel loop. It should not be used on untrusted
|
||||||
|
python objects. If an attacker can write directly to your checkpoint database,
|
||||||
|
they may be able to trigger code execution when data is deserialized.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
pickle_fallback: bool = False,
|
pickle_fallback: bool = False,
|
||||||
|
allowed_json_modules: Sequence[tuple[str, ...]] | Literal[True] | None = None,
|
||||||
__unpack_ext_hook__: Callable[[int, bytes], Any] | None = None,
|
__unpack_ext_hook__: Callable[[int, bytes], Any] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.pickle_fallback = pickle_fallback
|
self.pickle_fallback = pickle_fallback
|
||||||
|
self._allowed_modules = (
|
||||||
|
{mod_and_name for mod_and_name in allowed_json_modules}
|
||||||
|
if allowed_json_modules and allowed_json_modules is not True
|
||||||
|
else (allowed_json_modules if allowed_json_modules is True else None)
|
||||||
|
)
|
||||||
self._unpack_ext_hook = (
|
self._unpack_ext_hook = (
|
||||||
__unpack_ext_hook__
|
__unpack_ext_hook__
|
||||||
if __unpack_ext_hook__ is not None
|
if __unpack_ext_hook__ is not None
|
||||||
@@ -74,134 +87,90 @@ class JsonPlusSerializer(SerializerProtocol):
|
|||||||
out["kwargs"] = kwargs
|
out["kwargs"] = kwargs
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def _default(self, obj: Any) -> str | dict[str, Any]:
|
|
||||||
if isinstance(obj, Serializable):
|
|
||||||
return cast(dict[str, Any], obj.to_json())
|
|
||||||
elif hasattr(obj, "model_dump") and callable(obj.model_dump):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
obj.__class__, method=(None, "model_construct"), kwargs=obj.model_dump()
|
|
||||||
)
|
|
||||||
elif hasattr(obj, "dict") and callable(obj.dict):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
obj.__class__, method=(None, "construct"), kwargs=obj.dict()
|
|
||||||
)
|
|
||||||
elif hasattr(obj, "_asdict") and callable(obj._asdict):
|
|
||||||
return self._encode_constructor_args(obj.__class__, kwargs=obj._asdict())
|
|
||||||
elif isinstance(obj, pathlib.Path):
|
|
||||||
return self._encode_constructor_args(pathlib.Path, args=obj.parts)
|
|
||||||
elif isinstance(obj, re.Pattern):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
re.compile, args=(obj.pattern, obj.flags)
|
|
||||||
)
|
|
||||||
elif isinstance(obj, UUID):
|
|
||||||
return self._encode_constructor_args(UUID, args=(obj.hex,))
|
|
||||||
elif isinstance(obj, decimal.Decimal):
|
|
||||||
return self._encode_constructor_args(decimal.Decimal, args=(str(obj),))
|
|
||||||
elif isinstance(obj, (set, frozenset, deque)):
|
|
||||||
return self._encode_constructor_args(type(obj), args=(tuple(obj),))
|
|
||||||
elif isinstance(obj, (IPv4Address, IPv4Interface, IPv4Network)):
|
|
||||||
return self._encode_constructor_args(obj.__class__, args=(str(obj),))
|
|
||||||
elif isinstance(obj, (IPv6Address, IPv6Interface, IPv6Network)):
|
|
||||||
return self._encode_constructor_args(obj.__class__, args=(str(obj),))
|
|
||||||
|
|
||||||
elif isinstance(obj, datetime):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
datetime, method="fromisoformat", args=(obj.isoformat(),)
|
|
||||||
)
|
|
||||||
elif isinstance(obj, timezone):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
timezone,
|
|
||||||
args=obj.__getinitargs__(), # type: ignore[attr-defined]
|
|
||||||
)
|
|
||||||
elif isinstance(obj, ZoneInfo):
|
|
||||||
return self._encode_constructor_args(ZoneInfo, args=(obj.key,))
|
|
||||||
elif isinstance(obj, timedelta):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
timedelta, args=(obj.days, obj.seconds, obj.microseconds)
|
|
||||||
)
|
|
||||||
elif isinstance(obj, date):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
date, args=(obj.year, obj.month, obj.day)
|
|
||||||
)
|
|
||||||
elif isinstance(obj, time):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
time,
|
|
||||||
args=(obj.hour, obj.minute, obj.second, obj.microsecond, obj.tzinfo),
|
|
||||||
kwargs={"fold": obj.fold},
|
|
||||||
)
|
|
||||||
elif dataclasses.is_dataclass(obj):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
obj.__class__,
|
|
||||||
kwargs={
|
|
||||||
field.name: getattr(obj, field.name)
|
|
||||||
for field in dataclasses.fields(obj)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
elif isinstance(obj, Enum):
|
|
||||||
return self._encode_constructor_args(obj.__class__, args=(obj.value,))
|
|
||||||
elif isinstance(obj, SendProtocol):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
obj.__class__, kwargs={"node": obj.node, "arg": obj.arg}
|
|
||||||
)
|
|
||||||
elif isinstance(obj, (bytes, bytearray)):
|
|
||||||
return self._encode_constructor_args(
|
|
||||||
obj.__class__, method="fromhex", args=(obj.hex(),)
|
|
||||||
)
|
|
||||||
elif isinstance(obj, BaseException):
|
|
||||||
return repr(obj)
|
|
||||||
else:
|
|
||||||
raise TypeError(
|
|
||||||
f"Object of type {obj.__class__.__name__} is not JSON serializable"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _reviver(self, value: dict[str, Any]) -> Any:
|
def _reviver(self, value: dict[str, Any]) -> Any:
|
||||||
if (
|
if self._allowed_modules and (
|
||||||
value.get("lc", None) == 2
|
value.get("lc", None) == 2
|
||||||
and value.get("type", None) == "constructor"
|
and value.get("type", None) == "constructor"
|
||||||
and value.get("id", None) is not None
|
and value.get("id", None) is not None
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
# Get module and class name
|
return self._revive_lc2(value)
|
||||||
[*module, name] = value["id"]
|
except InvalidModuleError as e:
|
||||||
# Import module
|
logger.warning(
|
||||||
mod = importlib.import_module(".".join(module))
|
"Object %s is not in the deserialization allowlist.\n%s",
|
||||||
# Import class
|
value["id"],
|
||||||
cls = getattr(mod, name)
|
e.message,
|
||||||
# Instantiate class
|
)
|
||||||
method = value.get("method")
|
|
||||||
if isinstance(method, str):
|
|
||||||
methods = [getattr(cls, method)]
|
|
||||||
elif isinstance(method, list):
|
|
||||||
methods = [
|
|
||||||
cls if method is None else getattr(cls, method)
|
|
||||||
for method in method
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
methods = [cls]
|
|
||||||
args = value.get("args")
|
|
||||||
kwargs = value.get("kwargs")
|
|
||||||
for method in methods:
|
|
||||||
try:
|
|
||||||
if isclass(method) and issubclass(method, BaseException):
|
|
||||||
return None
|
|
||||||
if args and kwargs:
|
|
||||||
return method(*args, **kwargs)
|
|
||||||
elif args:
|
|
||||||
return method(*args)
|
|
||||||
elif kwargs:
|
|
||||||
return method(**kwargs)
|
|
||||||
else:
|
|
||||||
return method()
|
|
||||||
except Exception:
|
|
||||||
continue
|
|
||||||
except Exception:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return LC_REVIVER(value)
|
return LC_REVIVER(value)
|
||||||
|
|
||||||
def dumps(self, obj: Any) -> bytes:
|
def _revive_lc2(self, value: dict[str, Any]) -> Any:
|
||||||
return json.dumps(obj, default=self._default, ensure_ascii=False).encode(
|
self._check_allowed_modules(value)
|
||||||
"utf-8", "ignore"
|
|
||||||
|
[*module, name] = value["id"]
|
||||||
|
try:
|
||||||
|
mod = importlib.import_module(".".join(module))
|
||||||
|
cls = getattr(mod, name)
|
||||||
|
method = value.get("method")
|
||||||
|
if isinstance(method, str):
|
||||||
|
methods = [getattr(cls, method)]
|
||||||
|
elif isinstance(method, list):
|
||||||
|
methods = [cls if m is None else getattr(cls, m) for m in method]
|
||||||
|
else:
|
||||||
|
methods = [cls]
|
||||||
|
args = value.get("args")
|
||||||
|
kwargs = value.get("kwargs")
|
||||||
|
for method in methods:
|
||||||
|
try:
|
||||||
|
if isclass(method) and issubclass(method, BaseException):
|
||||||
|
return None
|
||||||
|
if args and kwargs:
|
||||||
|
return method(*args, **kwargs)
|
||||||
|
elif args:
|
||||||
|
return method(*args)
|
||||||
|
elif kwargs:
|
||||||
|
return method(**kwargs)
|
||||||
|
else:
|
||||||
|
return method()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _check_allowed_modules(self, value: dict[str, Any]) -> None:
|
||||||
|
needed = tuple(value["id"])
|
||||||
|
method = value.get("method")
|
||||||
|
if isinstance(method, list):
|
||||||
|
method_display = ",".join(m or "<init>" for m in method)
|
||||||
|
elif isinstance(method, str):
|
||||||
|
method_display = method
|
||||||
|
else:
|
||||||
|
method_display = "<init>"
|
||||||
|
|
||||||
|
dotted = ".".join(needed)
|
||||||
|
if not self._allowed_modules:
|
||||||
|
raise InvalidModuleError(
|
||||||
|
f"Refused to deserialize JSON constructor: {dotted} (method: {method_display}). "
|
||||||
|
"No allowed_json_modules configured.\n\n"
|
||||||
|
"Unblock with ONE of:\n"
|
||||||
|
f" • JsonPlusSerializer(allowed_json_modules=[{needed!r}, ...])\n"
|
||||||
|
" • (DANGEROUS) JsonPlusSerializer(allowed_json_modules=True)\n\n"
|
||||||
|
"Note: Prefix allowlists are intentionally unsupported; prefer exact symbols "
|
||||||
|
"or plain-JSON representations revived without import-time side effects."
|
||||||
|
)
|
||||||
|
|
||||||
|
if self._allowed_modules is True:
|
||||||
|
return
|
||||||
|
if needed in self._allowed_modules:
|
||||||
|
return
|
||||||
|
|
||||||
|
raise InvalidModuleError(
|
||||||
|
f"Refused to deserialize JSON constructor: {dotted} (method: {method_display}). "
|
||||||
|
"Symbol is not in the deserialization allowlist.\n\n"
|
||||||
|
"Add exactly this symbol to unblock:\n"
|
||||||
|
f" JsonPlusSerializer(allowed_json_modules=[{needed!r}, ...])\n"
|
||||||
|
"Or, as a last resort (DANGEROUS):\n"
|
||||||
|
" JsonPlusSerializer(allowed_json_modules=True)"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
|
||||||
@@ -215,15 +184,10 @@ class JsonPlusSerializer(SerializerProtocol):
|
|||||||
try:
|
try:
|
||||||
return "msgpack", _msgpack_enc(obj)
|
return "msgpack", _msgpack_enc(obj)
|
||||||
except ormsgpack.MsgpackEncodeError as exc:
|
except ormsgpack.MsgpackEncodeError as exc:
|
||||||
if "valid UTF-8" in str(exc):
|
if self.pickle_fallback:
|
||||||
return "json", self.dumps(obj)
|
|
||||||
elif self.pickle_fallback:
|
|
||||||
return "pickle", pickle.dumps(obj)
|
return "pickle", pickle.dumps(obj)
|
||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
def loads(self, data: bytes) -> Any:
|
|
||||||
return json.loads(data, object_hook=self._reviver)
|
|
||||||
|
|
||||||
def loads_typed(self, data: tuple[str, bytes]) -> Any:
|
def loads_typed(self, data: tuple[str, bytes]) -> Any:
|
||||||
type_, data_ = data
|
type_, data_ = data
|
||||||
if type_ == "null":
|
if type_ == "null":
|
||||||
@@ -233,7 +197,7 @@ class JsonPlusSerializer(SerializerProtocol):
|
|||||||
elif type_ == "bytearray":
|
elif type_ == "bytearray":
|
||||||
return bytearray(data_)
|
return bytearray(data_)
|
||||||
elif type_ == "json":
|
elif type_ == "json":
|
||||||
return self.loads(data_)
|
return json.loads(data_, object_hook=self._reviver)
|
||||||
elif type_ == "msgpack":
|
elif type_ == "msgpack":
|
||||||
return ormsgpack.unpackb(
|
return ormsgpack.unpackb(
|
||||||
data_, ext_hook=self._unpack_ext_hook, option=ormsgpack.OPT_NON_STR_KEYS
|
data_, ext_hook=self._unpack_ext_hook, option=ormsgpack.OPT_NON_STR_KEYS
|
||||||
@@ -663,12 +627,20 @@ def _msgpack_ext_hook_to_json(code: int, data: bytes) -> Any:
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidModuleError(Exception):
|
||||||
|
"""Exception raised when a module is not in the allowlist."""
|
||||||
|
|
||||||
|
def __init__(self, message: str):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
_option = (
|
_option = (
|
||||||
ormsgpack.OPT_NON_STR_KEYS
|
ormsgpack.OPT_NON_STR_KEYS
|
||||||
| ormsgpack.OPT_PASSTHROUGH_DATACLASS
|
| ormsgpack.OPT_PASSTHROUGH_DATACLASS
|
||||||
| ormsgpack.OPT_PASSTHROUGH_DATETIME
|
| ormsgpack.OPT_PASSTHROUGH_DATETIME
|
||||||
| ormsgpack.OPT_PASSTHROUGH_ENUM
|
| ormsgpack.OPT_PASSTHROUGH_ENUM
|
||||||
| ormsgpack.OPT_PASSTHROUGH_UUID
|
| ormsgpack.OPT_PASSTHROUGH_UUID
|
||||||
|
| ormsgpack.OPT_REPLACE_SURROGATES
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Optional,
|
|
||||||
Protocol,
|
Protocol,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
runtime_checkable,
|
runtime_checkable,
|
||||||
@@ -28,9 +27,9 @@ class ChannelProtocol(Protocol[Value, Update, C]):
|
|||||||
@property
|
@property
|
||||||
def UpdateType(self) -> Any: ...
|
def UpdateType(self) -> Any: ...
|
||||||
|
|
||||||
def checkpoint(self) -> Optional[C]: ...
|
def checkpoint(self) -> C | None: ...
|
||||||
|
|
||||||
def from_checkpoint(self, checkpoint: Optional[C]) -> Self: ...
|
def from_checkpoint(self, checkpoint: C | None) -> Self: ...
|
||||||
|
|
||||||
def update(self, values: Sequence[Update]) -> bool: ...
|
def update(self, values: Sequence[Update]) -> bool: ...
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ Stores provide long-term memory that persists across threads and conversations.
|
|||||||
Supports hierarchical namespaces, key-value storage, and optional vector search.
|
Supports hierarchical namespaces, key-value storage, and optional vector search.
|
||||||
|
|
||||||
Core types:
|
Core types:
|
||||||
- BaseStore: Store interface with sync/async operations
|
- `BaseStore`: Store interface with sync/async operations
|
||||||
- Item: Stored key-value pairs with metadata
|
- `Item`: Stored key-value pairs with metadata
|
||||||
- Op: Get/Put/Search/List operations
|
- `Op`: Get/Put/Search/List operations
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -19,7 +19,6 @@ from typing import (
|
|||||||
Literal,
|
Literal,
|
||||||
NamedTuple,
|
NamedTuple,
|
||||||
TypedDict,
|
TypedDict,
|
||||||
Union,
|
|
||||||
cast,
|
cast,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -57,7 +56,7 @@ class Item:
|
|||||||
key: Unique identifier within the namespace.
|
key: Unique identifier within the namespace.
|
||||||
namespace: Hierarchical path defining the collection in which this document resides.
|
namespace: Hierarchical path defining the collection in which this document resides.
|
||||||
Represented as a tuple of strings, allowing for nested categorization.
|
Represented as a tuple of strings, allowing for nested categorization.
|
||||||
For example: ("documents", 'user123')
|
For example: `("documents", 'user123')`
|
||||||
created_at: Timestamp of item creation.
|
created_at: Timestamp of item creation.
|
||||||
updated_at: Timestamp of last update.
|
updated_at: Timestamp of last update.
|
||||||
"""
|
"""
|
||||||
@@ -164,6 +163,7 @@ class GetOp(NamedTuple):
|
|||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Basic item retrieval:
|
Basic item retrieval:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
GetOp(namespace=("users", "profiles"), key="user123")
|
GetOp(namespace=("users", "profiles"), key="user123")
|
||||||
GetOp(namespace=("cache", "embeddings"), key="doc456")
|
GetOp(namespace=("cache", "embeddings"), key="doc456")
|
||||||
@@ -207,11 +207,14 @@ class SearchOp(NamedTuple):
|
|||||||
within a given namespace prefix. It provides pagination through limit and offset
|
within a given namespace prefix. It provides pagination through limit and offset
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
Note:
|
!!! note
|
||||||
|
|
||||||
Natural language search support depends on your store implementation.
|
Natural language search support depends on your store implementation.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Search with filters and pagination:
|
Search with filters and pagination:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
SearchOp(
|
SearchOp(
|
||||||
namespace_prefix=("documents",),
|
namespace_prefix=("documents",),
|
||||||
@@ -222,6 +225,7 @@ class SearchOp(NamedTuple):
|
|||||||
```
|
```
|
||||||
|
|
||||||
Natural language search:
|
Natural language search:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
SearchOp(
|
SearchOp(
|
||||||
namespace_prefix=("users", "content"),
|
namespace_prefix=("users", "content"),
|
||||||
@@ -249,14 +253,15 @@ class SearchOp(NamedTuple):
|
|||||||
The filter supports both exact matches and operator-based comparisons.
|
The filter supports both exact matches and operator-based comparisons.
|
||||||
|
|
||||||
Supported Operators:
|
Supported Operators:
|
||||||
- $eq: Equal to (same as direct value comparison)
|
- `$eq`: Equal to (same as direct value comparison)
|
||||||
- $ne: Not equal to
|
- `$ne`: Not equal to
|
||||||
- $gt: Greater than
|
- `$gt`: Greater than
|
||||||
- $gte: Greater than or equal to
|
- `$gte`: Greater than or equal to
|
||||||
- $lt: Less than
|
- `$lt`: Less than
|
||||||
- $lte: Less than or equal to
|
- `$lte`: Less than or equal to
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Simple exact match:
|
Simple exact match:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -289,6 +294,7 @@ class SearchOp(NamedTuple):
|
|||||||
"""Natural language search query for semantic search capabilities.
|
"""Natural language search query for semantic search capabilities.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
- "technical documentation about REST APIs"
|
- "technical documentation about REST APIs"
|
||||||
- "machine learning papers from 2023"
|
- "machine learning papers from 2023"
|
||||||
"""
|
"""
|
||||||
@@ -302,10 +308,11 @@ class SearchOp(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
# Type representing a namespace path that can include wildcards
|
# Type representing a namespace path that can include wildcards
|
||||||
NamespacePath = tuple[Union[str, Literal["*"]], ...]
|
NamespacePath = tuple[str | Literal["*"], ...]
|
||||||
"""A tuple representing a namespace path that can include wildcards.
|
"""A tuple representing a namespace path that can include wildcards.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
```python
|
```python
|
||||||
("users",) # Exact users namespace
|
("users",) # Exact users namespace
|
||||||
("documents", "*") # Any sub-namespace under documents
|
("documents", "*") # Any sub-namespace under documents
|
||||||
@@ -331,17 +338,21 @@ class MatchCondition(NamedTuple):
|
|||||||
hierarchies.
|
hierarchies.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Prefix matching:
|
Prefix matching:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
MatchCondition(match_type="prefix", path=("users", "profiles"))
|
MatchCondition(match_type="prefix", path=("users", "profiles"))
|
||||||
```
|
```
|
||||||
|
|
||||||
Suffix matching with wildcard:
|
Suffix matching with wildcard:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
MatchCondition(match_type="suffix", path=("cache", "*"))
|
MatchCondition(match_type="suffix", path=("cache", "*"))
|
||||||
```
|
```
|
||||||
|
|
||||||
Simple suffix matching:
|
Simple suffix matching:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
MatchCondition(match_type="suffix", path=("v1",))
|
MatchCondition(match_type="suffix", path=("v1",))
|
||||||
```
|
```
|
||||||
@@ -362,7 +373,8 @@ class ListNamespacesOp(NamedTuple):
|
|||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
List all namespaces under the "documents" path:
|
List all namespaces under the `"documents"` path:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ListNamespacesOp(
|
ListNamespacesOp(
|
||||||
match_conditions=(MatchCondition(match_type="prefix", path=("documents",)),),
|
match_conditions=(MatchCondition(match_type="prefix", path=("documents",)),),
|
||||||
@@ -370,7 +382,8 @@ class ListNamespacesOp(NamedTuple):
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
List all namespaces that end with "v1":
|
List all namespaces that end with `"v1"`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ListNamespacesOp(
|
ListNamespacesOp(
|
||||||
match_conditions=(MatchCondition(match_type="suffix", path=("v1",)),),
|
match_conditions=(MatchCondition(match_type="suffix", path=("v1",)),),
|
||||||
@@ -384,12 +397,15 @@ class ListNamespacesOp(NamedTuple):
|
|||||||
"""Optional conditions for filtering namespaces.
|
"""Optional conditions for filtering namespaces.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
All user namespaces:
|
All user namespaces:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(MatchCondition(match_type="prefix", path=("users",)),)
|
(MatchCondition(match_type="prefix", path=("users",)),)
|
||||||
```
|
```
|
||||||
|
|
||||||
All namespaces that start with "docs" and end with "draft":
|
All namespaces that start with `"docs"` and end with `"draft"`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
(
|
(
|
||||||
MatchCondition(match_type="prefix", path=("docs",)),
|
MatchCondition(match_type="prefix", path=("docs",)),
|
||||||
@@ -426,17 +442,21 @@ class PutOp(NamedTuple):
|
|||||||
Each element in the tuple represents one level in the hierarchy.
|
Each element in the tuple represents one level in the hierarchy.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
Root level documents
|
|
||||||
|
Root level documents:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
("documents",)
|
("documents",)
|
||||||
```
|
```
|
||||||
|
|
||||||
User-specific documents
|
User-specific documents:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
("documents", "user123")
|
("documents", "user123")
|
||||||
```
|
```
|
||||||
|
|
||||||
Nested cache structure
|
Nested cache structure:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
("cache", "embeddings", "v1")
|
("cache", "embeddings", "v1")
|
||||||
```
|
```
|
||||||
@@ -449,15 +469,15 @@ class PutOp(NamedTuple):
|
|||||||
Together with the namespace, it forms a complete path to the item.
|
Together with the namespace, it forms a complete path to the item.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
If namespace is ("documents", "user123") and key is "report1",
|
If namespace is `("documents", "user123")` and key is `"report1"`,
|
||||||
the full path would effectively be "documents/user123/report1"
|
the full path would effectively be `"documents/user123/report1"`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
value: dict[str, Any] | None
|
value: dict[str, Any] | None
|
||||||
"""The data to store, or None to mark the item for deletion.
|
"""The data to store, or `None` to mark the item for deletion.
|
||||||
|
|
||||||
The value must be a dictionary with string keys and JSON-serializable values.
|
The value must be a dictionary with string keys and JSON-serializable values.
|
||||||
Setting this to None signals that the item should be deleted.
|
Setting this to `None` signals that the item should be deleted.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
{
|
{
|
||||||
@@ -471,25 +491,26 @@ class PutOp(NamedTuple):
|
|||||||
"""Controls how the item's fields are indexed for search operations.
|
"""Controls how the item's fields are indexed for search operations.
|
||||||
|
|
||||||
Indexing configuration determines how the item can be found through search:
|
Indexing configuration determines how the item can be found through search:
|
||||||
- None (default): Uses the store's default indexing configuration (if provided)
|
- `None` (default): Uses the store's default indexing configuration (if provided)
|
||||||
- False: Disables indexing for this item
|
- `False`: Disables indexing for this item
|
||||||
- list[str]: Specifies which json path fields to index for search
|
- `list[str]`: Specifies which json path fields to index for search
|
||||||
|
|
||||||
The item remains accessible through direct get() operations regardless of indexing.
|
The item remains accessible through direct get() operations regardless of indexing.
|
||||||
When indexed, fields can be searched using natural language queries through
|
When indexed, fields can be searched using natural language queries through
|
||||||
vector similarity search (if supported by the store implementation).
|
vector similarity search (if supported by the store implementation).
|
||||||
|
|
||||||
Path Syntax:
|
Path Syntax:
|
||||||
- Simple field access: "field"
|
- Simple field access: `"field"`
|
||||||
- Nested fields: "parent.child.grandchild"
|
- Nested fields: `"parent.child.grandchild"`
|
||||||
- Array indexing:
|
- Array indexing:
|
||||||
- Specific index: "array[0]"
|
- Specific index: `"array[0]"`
|
||||||
- Last element: "array[-1]"
|
- Last element: `"array[-1]"`
|
||||||
- All elements (each individually): "array[*]"
|
- All elements (each individually): `"array[*]"`
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
- None - Use store defaults (whole item)
|
|
||||||
- list[str] - List of fields to index
|
- `None` - Use store defaults (whole item)
|
||||||
|
- `list[str]` - List of fields to index
|
||||||
|
|
||||||
```python
|
```python
|
||||||
[
|
[
|
||||||
@@ -509,12 +530,12 @@ class PutOp(NamedTuple):
|
|||||||
will expire this many minutes after it was last accessed. The expiration timer
|
will expire this many minutes after it was last accessed. The expiration timer
|
||||||
refreshes on both read operations (get/search) and write operations (put/update).
|
refreshes on both read operations (get/search) and write operations (put/update).
|
||||||
When the TTL expires, the item will be scheduled for deletion on a best-effort basis.
|
When the TTL expires, the item will be scheduled for deletion on a best-effort basis.
|
||||||
Defaults to None (no expiration).
|
Defaults to `None` (no expiration).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
Op = Union[GetOp, SearchOp, PutOp, ListNamespacesOp]
|
Op = GetOp | SearchOp | PutOp | ListNamespacesOp
|
||||||
Result = Union[Item, list[Item], list[SearchItem], list[tuple[str, ...]], None]
|
Result = Item | list[Item] | list[SearchItem] | list[tuple[str, ...]] | None
|
||||||
|
|
||||||
|
|
||||||
class InvalidNamespaceError(ValueError):
|
class InvalidNamespaceError(ValueError):
|
||||||
@@ -525,18 +546,18 @@ class TTLConfig(TypedDict, total=False):
|
|||||||
"""Configuration for TTL (time-to-live) behavior in the store."""
|
"""Configuration for TTL (time-to-live) behavior in the store."""
|
||||||
|
|
||||||
refresh_on_read: bool
|
refresh_on_read: bool
|
||||||
"""Default behavior for refreshing TTLs on read operations (GET and SEARCH).
|
"""Default behavior for refreshing TTLs on read operations (`GET` and `SEARCH`).
|
||||||
|
|
||||||
If True, TTLs will be refreshed on read operations (get/search) by default.
|
If `True`, TTLs will be refreshed on read operations (get/search) by default.
|
||||||
This can be overridden per-operation by explicitly setting refresh_ttl.
|
This can be overridden per-operation by explicitly setting `refresh_ttl`.
|
||||||
Defaults to True if not configured.
|
Defaults to `True` if not configured.
|
||||||
"""
|
"""
|
||||||
default_ttl: float | None
|
default_ttl: float | None
|
||||||
"""Default TTL (time-to-live) in minutes for new items.
|
"""Default TTL (time-to-live) in minutes for new items.
|
||||||
|
|
||||||
If provided, new items will expire after this many minutes after their last access.
|
If provided, new items will expire after this many minutes after their last access.
|
||||||
The expiration timer refreshes on both read and write operations.
|
The expiration timer refreshes on both read and write operations.
|
||||||
Defaults to None (no expiration).
|
Defaults to `None` (no expiration).
|
||||||
"""
|
"""
|
||||||
sweep_interval_minutes: int | None
|
sweep_interval_minutes: int | None
|
||||||
"""Interval in minutes between TTL sweep operations.
|
"""Interval in minutes between TTL sweep operations.
|
||||||
@@ -550,33 +571,35 @@ class IndexConfig(TypedDict, total=False):
|
|||||||
"""Configuration for indexing documents for semantic search in the store.
|
"""Configuration for indexing documents for semantic search in the store.
|
||||||
|
|
||||||
If not provided to the store, the store will not support vector search.
|
If not provided to the store, the store will not support vector search.
|
||||||
In that case, all `index` arguments to put() and `aput()` operations will be ignored.
|
In that case, all `index` arguments to `put()` and `aput()` operations will be ignored.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dims: int
|
dims: int
|
||||||
"""Number of dimensions in the embedding vectors.
|
"""Number of dimensions in the embedding vectors.
|
||||||
|
|
||||||
Common embedding models have the following dimensions:
|
Common embedding models have the following dimensions:
|
||||||
- openai:text-embedding-3-large: 3072
|
- `openai:text-embedding-3-large`: `3072`
|
||||||
- openai:text-embedding-3-small: 1536
|
- `openai:text-embedding-3-small`: `1536`
|
||||||
- openai:text-embedding-ada-002: 1536
|
- `openai:text-embedding-ada-002`: `1536`
|
||||||
- cohere:embed-english-v3.0: 1024
|
- `cohere:embed-english-v3.0`: `1024`
|
||||||
- cohere:embed-english-light-v3.0: 384
|
- `cohere:embed-english-light-v3.0`: `384`
|
||||||
- cohere:embed-multilingual-v3.0: 1024
|
- `cohere:embed-multilingual-v3.0`: `1024`
|
||||||
- cohere:embed-multilingual-light-v3.0: 384
|
- `cohere:embed-multilingual-light-v3.0`: `384`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
embed: Embeddings | EmbeddingsFunc | AEmbeddingsFunc | str
|
embed: Embeddings | EmbeddingsFunc | AEmbeddingsFunc | str
|
||||||
"""Optional function to generate embeddings from text.
|
"""Optional function to generate embeddings from text.
|
||||||
|
|
||||||
Can be specified in three ways:
|
Can be specified in three ways:
|
||||||
1. A LangChain Embeddings instance
|
1. A LangChain `Embeddings` instance
|
||||||
2. A synchronous embedding function (EmbeddingsFunc)
|
2. A synchronous embedding function (`EmbeddingsFunc`)
|
||||||
3. An asynchronous embedding function (AEmbeddingsFunc)
|
3. An asynchronous embedding function (`AEmbeddingsFunc`)
|
||||||
4. A provider string (e.g., "openai:text-embedding-3-small")
|
4. A provider string (e.g., `"openai:text-embedding-3-small"`)
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
Using LangChain's initialization with InMemoryStore:
|
|
||||||
|
Using LangChain's initialization with `InMemoryStore`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from langchain.embeddings import init_embeddings
|
from langchain.embeddings import init_embeddings
|
||||||
from langgraph.store.memory import InMemoryStore
|
from langgraph.store.memory import InMemoryStore
|
||||||
@@ -589,7 +612,8 @@ class IndexConfig(TypedDict, total=False):
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Using a custom embedding function with InMemoryStore:
|
Using a custom embedding function with `InMemoryStore`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
from langgraph.store.memory import InMemoryStore
|
from langgraph.store.memory import InMemoryStore
|
||||||
@@ -611,7 +635,8 @@ class IndexConfig(TypedDict, total=False):
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Using an asynchronous embedding function with InMemoryStore:
|
Using an asynchronous embedding function with `InMemoryStore`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from openai import AsyncOpenAI
|
from openai import AsyncOpenAI
|
||||||
from langgraph.store.memory import InMemoryStore
|
from langgraph.store.memory import InMemoryStore
|
||||||
@@ -639,16 +664,17 @@ class IndexConfig(TypedDict, total=False):
|
|||||||
|
|
||||||
Controls which parts of stored items are embedded for semantic search. Follows JSON path syntax:
|
Controls which parts of stored items are embedded for semantic search. Follows JSON path syntax:
|
||||||
|
|
||||||
- ["$"]: Embeds the entire JSON object as one vector (default)
|
- `["$"]`: Embeds the entire JSON object as one vector (default)
|
||||||
- ["field1", "field2"]: Embeds specific top-level fields
|
- `["field1", "field2"]`: Embeds specific top-level fields
|
||||||
- ["parent.child"]: Embeds nested fields using dot notation
|
- `["parent.child"]`: Embeds nested fields using dot notation
|
||||||
- ["array[*].field"]: Embeds field from each array element separately
|
- `["array[*].field"]`: Embeds field from each array element separately
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
You can always override this behavior when storing an item using the
|
You can always override this behavior when storing an item using the
|
||||||
`index` parameter in the `put` or `aput` operations.
|
`index` parameter in the `put` or `aput` operations.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Embed entire document (default)
|
# Embed entire document (default)
|
||||||
fields=["$"]
|
fields=["$"]
|
||||||
@@ -667,7 +693,7 @@ class IndexConfig(TypedDict, total=False):
|
|||||||
Note:
|
Note:
|
||||||
- Fields missing from a document are skipped
|
- Fields missing from a document are skipped
|
||||||
- Array notation creates separate embeddings for each element
|
- Array notation creates separate embeddings for each element
|
||||||
- Complex nested paths are supported (e.g., "a.b[*].c.d")
|
- Complex nested paths are supported (e.g., `"a.b[*].c.d"`)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -732,11 +758,11 @@ class BaseStore(ABC):
|
|||||||
namespace: Hierarchical path for the item.
|
namespace: Hierarchical path for the item.
|
||||||
key: Unique identifier within the namespace.
|
key: Unique identifier within the namespace.
|
||||||
refresh_ttl: Whether to refresh TTLs for the returned item.
|
refresh_ttl: Whether to refresh TTLs for the returned item.
|
||||||
If None (default), uses the store's default refresh_ttl setting.
|
If `None`, uses the store's default `refresh_ttl` setting.
|
||||||
If no TTL is specified, this argument is ignored.
|
If no TTL is specified, this argument is ignored.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The retrieved item or None if not found.
|
The retrieved item or `None` if not found.
|
||||||
"""
|
"""
|
||||||
return self.batch(
|
return self.batch(
|
||||||
[GetOp(namespace, str(key), _ensure_refresh(self.ttl_config, refresh_ttl))]
|
[GetOp(namespace, str(key), _ensure_refresh(self.ttl_config, refresh_ttl))]
|
||||||
@@ -768,7 +794,9 @@ class BaseStore(ABC):
|
|||||||
List of items matching the search criteria.
|
List of items matching the search criteria.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Basic filtering:
|
Basic filtering:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Search for documents with specific metadata
|
# Search for documents with specific metadata
|
||||||
results = store.search(
|
results = store.search(
|
||||||
@@ -778,6 +806,7 @@ class BaseStore(ABC):
|
|||||||
```
|
```
|
||||||
|
|
||||||
Natural language search (requires vector store implementation):
|
Natural language search (requires vector store implementation):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Initialize store with embedding configuration
|
# Initialize store with embedding configuration
|
||||||
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
|
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
|
||||||
@@ -789,6 +818,7 @@ class BaseStore(ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Search for semantically similar documents
|
# Search for semantically similar documents
|
||||||
|
|
||||||
results = store.search(
|
results = store.search(
|
||||||
("docs",),
|
("docs",),
|
||||||
query="machine learning applications in healthcare",
|
query="machine learning applications in healthcare",
|
||||||
@@ -797,8 +827,10 @@ class BaseStore(ABC):
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Natural language search support depends on your store implementation
|
!!! note
|
||||||
and requires proper embedding configuration.
|
|
||||||
|
Natural language search support depends on your store implementation
|
||||||
|
and requires proper embedding configuration.
|
||||||
"""
|
"""
|
||||||
return self.batch(
|
return self.batch(
|
||||||
[
|
[
|
||||||
@@ -826,7 +858,7 @@ class BaseStore(ABC):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
namespace: Hierarchical path for the item, represented as a tuple of strings.
|
namespace: Hierarchical path for the item, represented as a tuple of strings.
|
||||||
Example: ("documents", "user123")
|
Example: `("documents", "user123")`
|
||||||
key: Unique identifier within the namespace. Together with namespace forms
|
key: Unique identifier within the namespace. Together with namespace forms
|
||||||
the complete path to the item.
|
the complete path to the item.
|
||||||
value: Dictionary containing the item's data. Must contain string keys
|
value: Dictionary containing the item's data. Must contain string keys
|
||||||
@@ -837,10 +869,10 @@ class BaseStore(ABC):
|
|||||||
If you do not initialize the store with indexing capabilities,
|
If you do not initialize the store with indexing capabilities,
|
||||||
the `index` parameter will be ignored
|
the `index` parameter will be ignored
|
||||||
- False: Disable indexing for this item
|
- False: Disable indexing for this item
|
||||||
- list[str]: List of field paths to index, supporting:
|
- `list[str]`: List of field paths to index, supporting:
|
||||||
- Nested fields: "metadata.title"
|
- Nested fields: `"metadata.title"`
|
||||||
- Array access: "chapters[*].content" (each indexed separately)
|
- Array access: `"chapters[*].content"` (each indexed separately)
|
||||||
- Specific indices: "authors[0].name"
|
- Specific indices: `"authors[0].name"`
|
||||||
ttl: Time to live in minutes. Support for this argument depends on your store adapter.
|
ttl: Time to live in minutes. Support for this argument depends on your store adapter.
|
||||||
If specified, the item will expire after this many minutes from when it was last accessed.
|
If specified, the item will expire after this many minutes from when it was last accessed.
|
||||||
None means no expiration. Expired runs will be deleted opportunistically.
|
None means no expiration. Expired runs will be deleted opportunistically.
|
||||||
@@ -856,18 +888,22 @@ class BaseStore(ABC):
|
|||||||
Some implementations may not support expiration of items.
|
Some implementations may not support expiration of items.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
Store item. Indexing depends on how you configure the store.
|
|
||||||
|
Store item. Indexing depends on how you configure the store:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
store.put(("docs",), "report", {"memory": "Will likes ai"})
|
store.put(("docs",), "report", {"memory": "Will likes ai"})
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not index item for semantic search. Still accessible through get()
|
Do not index item for semantic search. Still accessible through `get()`
|
||||||
and search() operations but won't have a vector representation.
|
and `search()` operations but won't have a vector representation.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
store.put(("docs",), "report", {"memory": "Will likes ai"}, index=False)
|
store.put(("docs",), "report", {"memory": "Will likes ai"}, index=False)
|
||||||
```
|
```
|
||||||
|
|
||||||
Index specific fields for search.
|
Index specific fields for search:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
store.put(("docs",), "report", {"memory": "Will likes ai"}, index=["memory"])
|
store.put(("docs",), "report", {"memory": "Will likes ai"}, index=["memory"])
|
||||||
```
|
```
|
||||||
@@ -918,15 +954,17 @@ class BaseStore(ABC):
|
|||||||
suffix: Filter namespaces that end with this path.
|
suffix: Filter namespaces that end with this path.
|
||||||
max_depth: Return namespaces up to this depth in the hierarchy.
|
max_depth: Return namespaces up to this depth in the hierarchy.
|
||||||
Namespaces deeper than this level will be truncated.
|
Namespaces deeper than this level will be truncated.
|
||||||
limit: Maximum number of namespaces to return (default 100).
|
limit: Maximum number of namespaces to return.
|
||||||
offset: Number of namespaces to skip for pagination (default 0).
|
offset: Number of namespaces to skip for pagination.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Tuple[str, ...]]: A list of namespace tuples that match the criteria.
|
A list of namespace tuples that match the criteria. Each tuple represents a
|
||||||
Each tuple represents a full namespace path up to `max_depth`.
|
full namespace path up to `max_depth`.
|
||||||
|
|
||||||
???+ example "Examples":
|
???+ example "Examples":
|
||||||
Setting max_depth=3. Given the namespaces:
|
|
||||||
|
Setting `max_depth=3`. Given the namespaces:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Example if you have the following namespaces:
|
# Example if you have the following namespaces:
|
||||||
# ("a", "b", "c")
|
# ("a", "b", "c")
|
||||||
@@ -966,7 +1004,7 @@ class BaseStore(ABC):
|
|||||||
key: Unique identifier within the namespace.
|
key: Unique identifier within the namespace.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The retrieved item or None if not found.
|
The retrieved item or `None` if not found.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
await self.abatch(
|
await self.abatch(
|
||||||
@@ -1000,14 +1038,16 @@ class BaseStore(ABC):
|
|||||||
limit: Maximum number of items to return.
|
limit: Maximum number of items to return.
|
||||||
offset: Number of items to skip before returning results.
|
offset: Number of items to skip before returning results.
|
||||||
refresh_ttl: Whether to refresh TTLs for the returned items.
|
refresh_ttl: Whether to refresh TTLs for the returned items.
|
||||||
If None (default), uses the store's TTLConfig.refresh_default setting.
|
If `None`, uses the store's `TTLConfig.refresh_default` setting.
|
||||||
If TTLConfig is not provided or no TTL is specified, this argument is ignored.
|
If `TTLConfig` is not provided or no TTL is specified, this argument is ignored.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of items matching the search criteria.
|
List of items matching the search criteria.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
|
|
||||||
Basic filtering:
|
Basic filtering:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Search for documents with specific metadata
|
# Search for documents with specific metadata
|
||||||
results = await store.asearch(
|
results = await store.asearch(
|
||||||
@@ -1017,6 +1057,7 @@ class BaseStore(ABC):
|
|||||||
```
|
```
|
||||||
|
|
||||||
Natural language search (requires vector store implementation):
|
Natural language search (requires vector store implementation):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Initialize store with embedding configuration
|
# Initialize store with embedding configuration
|
||||||
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
|
store = YourStore( # e.g., InMemoryStore, AsyncPostgresStore
|
||||||
@@ -1028,6 +1069,7 @@ class BaseStore(ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Search for semantically similar documents
|
# Search for semantically similar documents
|
||||||
|
|
||||||
results = await store.asearch(
|
results = await store.asearch(
|
||||||
("docs",),
|
("docs",),
|
||||||
query="machine learning applications in healthcare",
|
query="machine learning applications in healthcare",
|
||||||
@@ -1036,8 +1078,10 @@ class BaseStore(ABC):
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Natural language search support depends on your store implementation
|
!!! note
|
||||||
and requires proper embedding configuration.
|
|
||||||
|
Natural language search support depends on your store implementation
|
||||||
|
and requires proper embedding configuration.
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
await self.abatch(
|
await self.abatch(
|
||||||
@@ -1067,7 +1111,7 @@ class BaseStore(ABC):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
namespace: Hierarchical path for the item, represented as a tuple of strings.
|
namespace: Hierarchical path for the item, represented as a tuple of strings.
|
||||||
Example: ("documents", "user123")
|
Example: `("documents", "user123")`
|
||||||
key: Unique identifier within the namespace. Together with namespace forms
|
key: Unique identifier within the namespace. Together with namespace forms
|
||||||
the complete path to the item.
|
the complete path to the item.
|
||||||
value: Dictionary containing the item's data. Must contain string keys
|
value: Dictionary containing the item's data. Must contain string keys
|
||||||
@@ -1078,10 +1122,10 @@ class BaseStore(ABC):
|
|||||||
If you do not initialize the store with indexing capabilities,
|
If you do not initialize the store with indexing capabilities,
|
||||||
the `index` parameter will be ignored
|
the `index` parameter will be ignored
|
||||||
- False: Disable indexing for this item
|
- False: Disable indexing for this item
|
||||||
- list[str]: List of field paths to index, supporting:
|
- `list[str]`: List of field paths to index, supporting:
|
||||||
- Nested fields: "metadata.title"
|
- Nested fields: `"metadata.title"`
|
||||||
- Array access: "chapters[*].content" (each indexed separately)
|
- Array access: `"chapters[*].content"` (each indexed separately)
|
||||||
- Specific indices: "authors[0].name"
|
- Specific indices: `"authors[0].name"`
|
||||||
ttl: Time to live in minutes. Support for this argument depends on your store adapter.
|
ttl: Time to live in minutes. Support for this argument depends on your store adapter.
|
||||||
If specified, the item will expire after this many minutes from when it was last accessed.
|
If specified, the item will expire after this many minutes from when it was last accessed.
|
||||||
None means no expiration. Expired runs will be deleted opportunistically.
|
None means no expiration. Expired runs will be deleted opportunistically.
|
||||||
@@ -1097,18 +1141,22 @@ class BaseStore(ABC):
|
|||||||
Some implementations may not support expiration of items.
|
Some implementations may not support expiration of items.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
Store item. Indexing depends on how you configure the store.
|
|
||||||
|
Store item. Indexing depends on how you configure the store:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
await store.aput(("docs",), "report", {"memory": "Will likes ai"})
|
await store.aput(("docs",), "report", {"memory": "Will likes ai"})
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not index item for semantic search. Still accessible through get()
|
Do not index item for semantic search. Still accessible through `get()`
|
||||||
and search() operations but won't have a vector representation.
|
and `search()` operations but won't have a vector representation.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
await store.aput(("docs",), "report", {"memory": "Will likes ai"}, index=False)
|
await store.aput(("docs",), "report", {"memory": "Will likes ai"}, index=False)
|
||||||
```
|
```
|
||||||
|
|
||||||
Index specific fields for search (if store configured to index items):
|
Index specific fields for search (if store configured to index items):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
await store.aput(
|
await store.aput(
|
||||||
("docs",),
|
("docs",),
|
||||||
@@ -1167,15 +1215,16 @@ class BaseStore(ABC):
|
|||||||
suffix: Filter namespaces that end with this path.
|
suffix: Filter namespaces that end with this path.
|
||||||
max_depth: Return namespaces up to this depth in the hierarchy.
|
max_depth: Return namespaces up to this depth in the hierarchy.
|
||||||
Namespaces deeper than this level will be truncated to this depth.
|
Namespaces deeper than this level will be truncated to this depth.
|
||||||
limit: Maximum number of namespaces to return (default 100).
|
limit: Maximum number of namespaces to return.
|
||||||
offset: Number of namespaces to skip for pagination (default 0).
|
offset: Number of namespaces to skip for pagination.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Tuple[str, ...]]: A list of namespace tuples that match the criteria.
|
A list of namespace tuples that match the criteria. Each tuple represents a
|
||||||
Each tuple represents a full namespace path up to `max_depth`.
|
full namespace path up to `max_depth`.
|
||||||
|
|
||||||
???+ example "Examples"
|
???+ example "Examples"
|
||||||
Setting max_depth=3 with existing namespaces:
|
|
||||||
|
Setting `max_depth=3` with existing namespaces:
|
||||||
```python
|
```python
|
||||||
# Given the following namespaces:
|
# Given the following namespaces:
|
||||||
# ("a", "b", "c")
|
# ("a", "b", "c")
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import functools
|
import functools
|
||||||
import weakref
|
import weakref
|
||||||
from collections.abc import Iterable
|
from collections.abc import Callable, Iterable
|
||||||
from typing import Any, Callable, Literal, TypeVar
|
from typing import Any, Literal, TypeVar
|
||||||
|
|
||||||
from langgraph.store.base import (
|
from langgraph.store.base import (
|
||||||
NOT_PROVIDED,
|
NOT_PROVIDED,
|
||||||
@@ -349,7 +349,7 @@ async def _run(
|
|||||||
results = [results[ix] for ix in listen]
|
results = [results[ix] for ix in listen]
|
||||||
|
|
||||||
# set the results of each operation
|
# set the results of each operation
|
||||||
for fut, result in zip(futs, results):
|
for fut, result in zip(futs, results, strict=False):
|
||||||
# guard against future being done (e.g. cancelled)
|
# guard against future being done (e.g. cancelled)
|
||||||
if not fut.done():
|
if not fut.done():
|
||||||
fut.set_result(result)
|
fut.set_result(result)
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import functools
|
import functools
|
||||||
import json
|
import json
|
||||||
from collections.abc import Awaitable, Sequence
|
from collections.abc import Awaitable, Callable, Sequence
|
||||||
from typing import Any, Callable
|
from typing import Any
|
||||||
|
|
||||||
from langchain_core.embeddings import Embeddings
|
from langchain_core.embeddings import Embeddings
|
||||||
|
|
||||||
@@ -49,7 +49,9 @@ def ensure_embeddings(
|
|||||||
An Embeddings instance that wraps the provided function(s).
|
An Embeddings instance that wraps the provided function(s).
|
||||||
|
|
||||||
??? example "Examples"
|
??? example "Examples"
|
||||||
|
|
||||||
Wrap a synchronous embedding function:
|
Wrap a synchronous embedding function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def my_embed_fn(texts):
|
def my_embed_fn(texts):
|
||||||
return [[0.1, 0.2] for _ in texts]
|
return [[0.1, 0.2] for _ in texts]
|
||||||
@@ -59,6 +61,7 @@ def ensure_embeddings(
|
|||||||
```
|
```
|
||||||
|
|
||||||
Wrap an asynchronous embedding function:
|
Wrap an asynchronous embedding function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
async def my_async_fn(texts):
|
async def my_async_fn(texts):
|
||||||
return [[0.1, 0.2] for _ in texts]
|
return [[0.1, 0.2] for _ in texts]
|
||||||
@@ -68,6 +71,7 @@ def ensure_embeddings(
|
|||||||
```
|
```
|
||||||
|
|
||||||
Initialize embeddings using a provider string:
|
Initialize embeddings using a provider string:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Requires langchain>=0.3.9 and langgraph-checkpoint>=2.0.11
|
# Requires langchain>=0.3.9 and langgraph-checkpoint>=2.0.11
|
||||||
embeddings = ensure_embeddings("openai:text-embedding-3-small")
|
embeddings = ensure_embeddings("openai:text-embedding-3-small")
|
||||||
@@ -119,7 +123,9 @@ class EmbeddingsLambda(Embeddings):
|
|||||||
will raise an error. If sync, it will be used for both sync and async operations.
|
will raise an error. If sync, it will be used for both sync and async operations.
|
||||||
|
|
||||||
??? example "Examples"
|
??? example "Examples"
|
||||||
|
|
||||||
With a sync function:
|
With a sync function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def my_embed_fn(texts):
|
def my_embed_fn(texts):
|
||||||
# Return 2D embeddings for each text
|
# Return 2D embeddings for each text
|
||||||
@@ -131,6 +137,7 @@ class EmbeddingsLambda(Embeddings):
|
|||||||
```
|
```
|
||||||
|
|
||||||
With an async function:
|
With an async function:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
async def my_async_fn(texts):
|
async def my_async_fn(texts):
|
||||||
return [[0.1, 0.2] for _ in texts]
|
return [[0.1, 0.2] for _ in texts]
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ class InMemoryStore(BaseStore):
|
|||||||
if queries:
|
if queries:
|
||||||
coros = [self.embeddings.aembed_query(q) for q in list(queries)]
|
coros = [self.embeddings.aembed_query(q) for q in list(queries)]
|
||||||
results = await asyncio.gather(*coros)
|
results = await asyncio.gather(*coros)
|
||||||
queryinmem_store = dict(zip(queries, results))
|
queryinmem_store = dict(zip(queries, results, strict=False))
|
||||||
|
|
||||||
return queryinmem_store
|
return queryinmem_store
|
||||||
|
|
||||||
@@ -323,7 +323,9 @@ class InMemoryStore(BaseStore):
|
|||||||
|
|
||||||
scores = _cosine_similarity(query_embedding, flat_vectors)
|
scores = _cosine_similarity(query_embedding, flat_vectors)
|
||||||
sorted_results = sorted(
|
sorted_results = sorted(
|
||||||
zip(scores, flat_items), key=lambda x: x[0], reverse=True
|
zip(scores, flat_items, strict=False),
|
||||||
|
key=lambda x: x[0],
|
||||||
|
reverse=True,
|
||||||
)
|
)
|
||||||
# max pooling
|
# max pooling
|
||||||
seen: set[tuple[tuple[str, ...], str]] = set()
|
seen: set[tuple[tuple[str, ...], str]] = set()
|
||||||
@@ -452,7 +454,7 @@ class InMemoryStore(BaseStore):
|
|||||||
f"Number of embeddings ({len(embeddings)}) does not"
|
f"Number of embeddings ({len(embeddings)}) does not"
|
||||||
f" match number of indices ({len(indices)})"
|
f" match number of indices ({len(indices)})"
|
||||||
)
|
)
|
||||||
for embedding, (ns, key, path) in zip(embeddings, indices):
|
for embedding, (ns, key, path) in zip(embeddings, indices, strict=False):
|
||||||
self._vectors[ns][key][path] = embedding
|
self._vectors[ns][key][path] = embedding
|
||||||
|
|
||||||
def _handle_list_namespaces(self, op: ListNamespacesOp) -> list[tuple[str, ...]]:
|
def _handle_list_namespaces(self, op: ListNamespacesOp) -> list[tuple[str, ...]]:
|
||||||
@@ -511,7 +513,7 @@ def _cosine_similarity(X: list[float], Y: list[list[float]]) -> list[float]:
|
|||||||
|
|
||||||
similarities = []
|
similarities = []
|
||||||
for y in Y:
|
for y in Y:
|
||||||
dot_product = sum(a * b for a, b in zip(X, y))
|
dot_product = sum(a * b for a, b in zip(X, y, strict=False))
|
||||||
norm1 = sum(a * a for a in X) ** 0.5
|
norm1 = sum(a * a for a in X) ** 0.5
|
||||||
norm2 = sum(a * a for a in y) ** 0.5
|
norm2 = sum(a * a for a in y) ** 0.5
|
||||||
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
similarity = dot_product / (norm1 * norm2) if norm1 > 0 and norm2 > 0 else 0.0
|
||||||
@@ -529,14 +531,14 @@ def _does_match(match_condition: MatchCondition, key: tuple[str, ...]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if match_type == "prefix":
|
if match_type == "prefix":
|
||||||
for k_elem, p_elem in zip(key, path):
|
for k_elem, p_elem in zip(key, path, strict=False):
|
||||||
if p_elem == "*":
|
if p_elem == "*":
|
||||||
continue # Wildcard matches any element
|
continue # Wildcard matches any element
|
||||||
if k_elem != p_elem:
|
if k_elem != p_elem:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
elif match_type == "suffix":
|
elif match_type == "suffix":
|
||||||
for k_elem, p_elem in zip(reversed(key), reversed(path)):
|
for k_elem, p_elem in zip(reversed(key), reversed(path), strict=False):
|
||||||
if p_elem == "*":
|
if p_elem == "*":
|
||||||
continue # Wildcard matches any element
|
continue # Wildcard matches any element
|
||||||
if k_elem != p_elem:
|
if k_elem != p_elem:
|
||||||
@@ -563,7 +565,10 @@ def _compare_values(item_value: Any, filter_value: Any) -> bool:
|
|||||||
return (
|
return (
|
||||||
isinstance(item_value, (list, tuple))
|
isinstance(item_value, (list, tuple))
|
||||||
and len(item_value) == len(filter_value)
|
and len(item_value) == len(filter_value)
|
||||||
and all(_compare_values(iv, fv) for iv, fv in zip(item_value, filter_value))
|
and all(
|
||||||
|
_compare_values(iv, fv)
|
||||||
|
for iv, fv in zip(item_value, filter_value, strict=False)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return item_value == filter_value
|
return item_value == filter_value
|
||||||
|
|||||||
@@ -4,36 +4,42 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "langgraph-checkpoint"
|
name = "langgraph-checkpoint"
|
||||||
version = "2.1.1"
|
version = "3.0.1"
|
||||||
description = "Library with base interfaces for LangGraph checkpoint savers."
|
description = "Library with base interfaces for LangGraph checkpoint savers."
|
||||||
authors = []
|
authors = []
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
license-files = ['LICENSE']
|
license-files = ['LICENSE']
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langchain-core>=0.2.38",
|
"langchain-core>=0.2.38",
|
||||||
"ormsgpack>=1.10.0",
|
"ormsgpack>=1.12.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Repository = "https://www.github.com/langchain-ai/langgraph"
|
Repository = "https://www.github.com/langchain-ai/langgraph"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
test = [
|
||||||
"ruff",
|
|
||||||
"codespell",
|
|
||||||
"pytest",
|
"pytest",
|
||||||
"pytest-asyncio",
|
"pytest-asyncio",
|
||||||
"pytest-mock",
|
"pytest-mock",
|
||||||
"pytest-watcher",
|
"pytest-watcher",
|
||||||
"mypy",
|
|
||||||
"dataclasses-json",
|
"dataclasses-json",
|
||||||
"numpy",
|
"numpy",
|
||||||
"pandas",
|
"pandas",
|
||||||
"pandas-stubs>=2.2.2.240807",
|
"pandas-stubs>=2.2.2.240807",
|
||||||
"redis",
|
"redis",
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
"ruff",
|
||||||
|
"codespell",
|
||||||
|
"mypy",
|
||||||
|
]
|
||||||
|
dev = [
|
||||||
|
{include-group = "test"},
|
||||||
|
{include-group = "lint"},
|
||||||
|
]
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
[tool.hatch.build.targets.wheel]
|
||||||
include = ["langgraph"]
|
include = ["langgraph"]
|
||||||
@@ -49,8 +55,10 @@ lint.select = [
|
|||||||
"UP", # pyupgrade
|
"UP", # pyupgrade
|
||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"I", # isort
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
]
|
]
|
||||||
lint.ignore = ["E501", "B008"]
|
lint.ignore = ["E501", "B008"]
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
[tool.pytest-watcher]
|
[tool.pytest-watcher]
|
||||||
now = true
|
now = true
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@@ -19,6 +20,7 @@ from pydantic.v1 import BaseModel as BaseModelV1
|
|||||||
from pydantic.v1 import SecretStr as SecretStrV1
|
from pydantic.v1 import SecretStr as SecretStrV1
|
||||||
|
|
||||||
from langgraph.checkpoint.serde.jsonplus import (
|
from langgraph.checkpoint.serde.jsonplus import (
|
||||||
|
InvalidModuleError,
|
||||||
JsonPlusSerializer,
|
JsonPlusSerializer,
|
||||||
_msgpack_ext_hook_to_json,
|
_msgpack_ext_hook_to_json,
|
||||||
)
|
)
|
||||||
@@ -60,22 +62,15 @@ class MyDataclass:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info < (3, 10):
|
@dataclasses.dataclass(slots=True)
|
||||||
|
class MyDataclassWSlots:
|
||||||
|
foo: str
|
||||||
|
bar: int
|
||||||
|
inner: InnerDataclass
|
||||||
|
|
||||||
class MyDataclassWSlots(MyDataclass):
|
def something(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
@dataclasses.dataclass(slots=True)
|
|
||||||
class MyDataclassWSlots:
|
|
||||||
foo: str
|
|
||||||
bar: int
|
|
||||||
inner: InnerDataclass
|
|
||||||
|
|
||||||
def something(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MyEnum(Enum):
|
class MyEnum(Enum):
|
||||||
FOO = "foo"
|
FOO = "foo"
|
||||||
@@ -115,11 +110,7 @@ def test_serde_jsonplus() -> None:
|
|||||||
"my_dataclass": MyDataclass("foo", 1, InnerDataclass("hello")),
|
"my_dataclass": MyDataclass("foo", 1, InnerDataclass("hello")),
|
||||||
"my_enum": MyEnum.FOO,
|
"my_enum": MyEnum.FOO,
|
||||||
"my_pydantic": MyPydantic(foo="foo", bar=1, inner=InnerPydantic(hello="hello")),
|
"my_pydantic": MyPydantic(foo="foo", bar=1, inner=InnerPydantic(hello="hello")),
|
||||||
"my_pydantic_v1": MyPydanticV1(
|
|
||||||
foo="foo", bar=1, inner=InnerPydanticV1(hello="hello")
|
|
||||||
),
|
|
||||||
"my_secret_str": SecretStr("meow"),
|
"my_secret_str": SecretStr("meow"),
|
||||||
"my_secret_str_v1": SecretStrV1("meow"),
|
|
||||||
"person": Person(name="foo"),
|
"person": Person(name="foo"),
|
||||||
"a_bool": True,
|
"a_bool": True,
|
||||||
"a_none": None,
|
"a_none": None,
|
||||||
@@ -141,6 +132,12 @@ def test_serde_jsonplus() -> None:
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sys.version_info < (3, 14):
|
||||||
|
to_serialize["my_pydantic_v1"] = MyPydanticV1(
|
||||||
|
foo="foo", bar=1, inner=InnerPydanticV1(hello="hello")
|
||||||
|
)
|
||||||
|
to_serialize["my_secret_str_v1"] = SecretStrV1("meow")
|
||||||
|
|
||||||
serde = JsonPlusSerializer()
|
serde = JsonPlusSerializer()
|
||||||
|
|
||||||
dumped = serde.dumps_typed(to_serialize)
|
dumped = serde.dumps_typed(to_serialize)
|
||||||
@@ -152,23 +149,22 @@ def test_serde_jsonplus() -> None:
|
|||||||
assert serde.loads_typed(serde.dumps_typed(value)) == value
|
assert serde.loads_typed(serde.dumps_typed(value)) == value
|
||||||
|
|
||||||
surrogates = [
|
surrogates = [
|
||||||
"Hello\ud83d\ude00",
|
"Hello??",
|
||||||
"Python\ud83d\udc0d",
|
"Python??",
|
||||||
"Surrogate\ud834\udd1e",
|
"Surrogate??",
|
||||||
"Example\ud83c\udf89",
|
"Example??",
|
||||||
"String\ud83c\udfa7",
|
"String??",
|
||||||
"With\ud83c\udf08",
|
"With??",
|
||||||
"Surrogates\ud83d\ude0e",
|
"Surrogates??",
|
||||||
"Embedded\ud83d\udcbb",
|
"Embedded??",
|
||||||
"In\ud83c\udf0e",
|
"In??",
|
||||||
"The\ud83d\udcd6",
|
"The??",
|
||||||
"Text\ud83d\udcac",
|
"Text??",
|
||||||
"收花🙄·到",
|
"收花🙄·到",
|
||||||
]
|
]
|
||||||
|
serde = JsonPlusSerializer(pickle_fallback=False)
|
||||||
|
|
||||||
assert serde.loads_typed(serde.dumps_typed(surrogates)) == [
|
assert serde.loads_typed(serde.dumps_typed(surrogates)) == surrogates
|
||||||
v.encode("utf-8", "ignore").decode() for v in surrogates
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_serde_jsonplus_json_mode() -> None:
|
def test_serde_jsonplus_json_mode() -> None:
|
||||||
@@ -197,11 +193,7 @@ def test_serde_jsonplus_json_mode() -> None:
|
|||||||
"my_dataclass": MyDataclass("foo", 1, InnerDataclass("hello")),
|
"my_dataclass": MyDataclass("foo", 1, InnerDataclass("hello")),
|
||||||
"my_enum": MyEnum.FOO,
|
"my_enum": MyEnum.FOO,
|
||||||
"my_pydantic": MyPydantic(foo="foo", bar=1, inner=InnerPydantic(hello="hello")),
|
"my_pydantic": MyPydantic(foo="foo", bar=1, inner=InnerPydantic(hello="hello")),
|
||||||
"my_pydantic_v1": MyPydanticV1(
|
|
||||||
foo="foo", bar=1, inner=InnerPydanticV1(hello="hello")
|
|
||||||
),
|
|
||||||
"my_secret_str": SecretStr("meow"),
|
"my_secret_str": SecretStr("meow"),
|
||||||
"my_secret_str_v1": SecretStrV1("meow"),
|
|
||||||
"person": Person(name="foo"),
|
"person": Person(name="foo"),
|
||||||
"a_bool": True,
|
"a_bool": True,
|
||||||
"a_none": None,
|
"a_none": None,
|
||||||
@@ -223,13 +215,20 @@ def test_serde_jsonplus_json_mode() -> None:
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sys.version_info < (3, 14):
|
||||||
|
to_serialize["my_pydantic_v1"] = MyPydanticV1(
|
||||||
|
foo="foo", bar=1, inner=InnerPydanticV1(hello="hello")
|
||||||
|
)
|
||||||
|
to_serialize["my_secret_str_v1"] = SecretStrV1("meow")
|
||||||
|
|
||||||
serde = JsonPlusSerializer(__unpack_ext_hook__=_msgpack_ext_hook_to_json)
|
serde = JsonPlusSerializer(__unpack_ext_hook__=_msgpack_ext_hook_to_json)
|
||||||
|
|
||||||
dumped = serde.dumps_typed(to_serialize)
|
dumped = serde.dumps_typed(to_serialize)
|
||||||
|
|
||||||
assert dumped[0] == "msgpack"
|
assert dumped[0] == "msgpack"
|
||||||
result = serde.loads_typed(dumped)
|
result = serde.loads_typed(dumped)
|
||||||
assert result == {
|
|
||||||
|
expected_result = {
|
||||||
"path": ["foo", "bar"],
|
"path": ["foo", "bar"],
|
||||||
"re": ["foo", 48],
|
"re": ["foo", 48],
|
||||||
"decimal": "1.10101",
|
"decimal": "1.10101",
|
||||||
@@ -253,9 +252,7 @@ def test_serde_jsonplus_json_mode() -> None:
|
|||||||
"my_dataclass": {"foo": "foo", "bar": 1, "inner": {"hello": "hello"}},
|
"my_dataclass": {"foo": "foo", "bar": 1, "inner": {"hello": "hello"}},
|
||||||
"my_enum": "foo",
|
"my_enum": "foo",
|
||||||
"my_pydantic": {"foo": "foo", "bar": 1, "inner": {"hello": "hello"}},
|
"my_pydantic": {"foo": "foo", "bar": 1, "inner": {"hello": "hello"}},
|
||||||
"my_pydantic_v1": {"foo": "foo", "bar": 1, "inner": {"hello": "hello"}},
|
|
||||||
"my_secret_str": "meow",
|
"my_secret_str": "meow",
|
||||||
"my_secret_str_v1": "meow",
|
|
||||||
"person": {"name": "foo"},
|
"person": {"name": "foo"},
|
||||||
"a_bool": True,
|
"a_bool": True,
|
||||||
"a_none": None,
|
"a_none": None,
|
||||||
@@ -277,6 +274,16 @@ def test_serde_jsonplus_json_mode() -> None:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sys.version_info < (3, 14):
|
||||||
|
expected_result["my_pydantic_v1"] = {
|
||||||
|
"foo": "foo",
|
||||||
|
"bar": 1,
|
||||||
|
"inner": {"hello": "hello"},
|
||||||
|
}
|
||||||
|
expected_result["my_secret_str_v1"] = "meow"
|
||||||
|
|
||||||
|
assert result == expected_result
|
||||||
|
|
||||||
|
|
||||||
def test_serde_jsonplus_bytes() -> None:
|
def test_serde_jsonplus_bytes() -> None:
|
||||||
serde = JsonPlusSerializer()
|
serde = JsonPlusSerializer()
|
||||||
@@ -288,6 +295,20 @@ def test_serde_jsonplus_bytes() -> None:
|
|||||||
assert serde.loads_typed(dumped) == some_bytes
|
assert serde.loads_typed(dumped) == some_bytes
|
||||||
|
|
||||||
|
|
||||||
|
def test_deserde_invalid_module() -> None:
|
||||||
|
serde = JsonPlusSerializer()
|
||||||
|
load = {
|
||||||
|
"lc": 2,
|
||||||
|
"type": "constructor",
|
||||||
|
"id": ["pprint", "pprint"],
|
||||||
|
"kwargs": {"object": "HELLO"},
|
||||||
|
}
|
||||||
|
with pytest.raises(InvalidModuleError):
|
||||||
|
serde._revive_lc2(load)
|
||||||
|
serde = JsonPlusSerializer(allowed_json_modules=[("pprint", "pprint")])
|
||||||
|
serde.loads_typed(("json", json.dumps(load).encode("utf-8")))
|
||||||
|
|
||||||
|
|
||||||
def test_serde_jsonplus_bytearray() -> None:
|
def test_serde_jsonplus_bytearray() -> None:
|
||||||
serde = JsonPlusSerializer()
|
serde = JsonPlusSerializer()
|
||||||
|
|
||||||
@@ -364,7 +385,12 @@ def test_serde_jsonplus_numpy_array_json_hook(arr: np.ndarray) -> None:
|
|||||||
"str_col": ["a", None, "c"],
|
"str_col": ["a", None, "c"],
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
pd.DataFrame({"cat_col": pd.Categorical(["a", "b", "a", "c"])}),
|
pytest.param(
|
||||||
|
pd.DataFrame({"cat_col": pd.Categorical(["a", "b", "a", "c"])}),
|
||||||
|
marks=pytest.mark.skipif(
|
||||||
|
sys.version_info >= (3, 14), reason="NotImplementedError on Python 3.14"
|
||||||
|
),
|
||||||
|
),
|
||||||
pd.DataFrame(
|
pd.DataFrame(
|
||||||
{
|
{
|
||||||
"int8": pd.array([1, 2, 3], dtype="int8"),
|
"int8": pd.array([1, 2, 3], dtype="int8"),
|
||||||
@@ -392,11 +418,25 @@ def test_serde_jsonplus_numpy_array_json_hook(arr: np.ndarray) -> None:
|
|||||||
"col3": np.random.rand(1000),
|
"col3": np.random.rand(1000),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
pd.DataFrame(
|
pytest.param(
|
||||||
{"tz_datetime": pd.date_range("2024-01-01", periods=3, freq="D", tz="UTC")}
|
pd.DataFrame(
|
||||||
|
{
|
||||||
|
"tz_datetime": pd.date_range(
|
||||||
|
"2024-01-01", periods=3, freq="D", tz="UTC"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
marks=pytest.mark.skipif(
|
||||||
|
sys.version_info >= (3, 14), reason="NotImplementedError on Python 3.14"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
pd.DataFrame({"timedelta": pd.to_timedelta([1, 2, 3], unit="D")}),
|
pd.DataFrame({"timedelta": pd.to_timedelta([1, 2, 3], unit="D")}),
|
||||||
pd.DataFrame({"period": pd.period_range("2024-01", periods=3, freq="M")}),
|
pytest.param(
|
||||||
|
pd.DataFrame({"period": pd.period_range("2024-01", periods=3, freq="M")}),
|
||||||
|
marks=pytest.mark.skipif(
|
||||||
|
sys.version_info >= (3, 14), reason="NotImplementedError on Python 3.14"
|
||||||
|
),
|
||||||
|
),
|
||||||
pd.DataFrame({"interval": pd.interval_range(start=0, end=3, periods=3)}),
|
pd.DataFrame({"interval": pd.interval_range(start=0, end=3, periods=3)}),
|
||||||
pd.DataFrame({"unicode": ["Hello 🌍", "Python 🐍", "Data 📊"]}),
|
pd.DataFrame({"unicode": ["Hello 🌍", "Python 🐍", "Data 📊"]}),
|
||||||
pd.DataFrame({"mixed": [1, "string", [1, 2, 3], {"key": "value"}]}),
|
pd.DataFrame({"mixed": [1, "string", [1, 2, 3], {"key": "value"}]}),
|
||||||
@@ -433,7 +473,12 @@ def test_serde_jsonplus_pandas_dataframe(df: pd.DataFrame) -> None:
|
|||||||
pd.Series([1, 2, None]),
|
pd.Series([1, 2, None]),
|
||||||
pd.Series([1.1, None, 3.3]),
|
pd.Series([1.1, None, 3.3]),
|
||||||
pd.Series(["a", None, "c"]),
|
pd.Series(["a", None, "c"]),
|
||||||
pd.Series(pd.Categorical(["a", "b", "a", "c"])),
|
pytest.param(
|
||||||
|
pd.Series(pd.Categorical(["a", "b", "a", "c"])),
|
||||||
|
marks=pytest.mark.skipif(
|
||||||
|
sys.version_info >= (3, 14), reason="NotImplementedError on Python 3.14"
|
||||||
|
),
|
||||||
|
),
|
||||||
pd.Series([1, 2, 3], dtype="int8"),
|
pd.Series([1, 2, 3], dtype="int8"),
|
||||||
pd.Series([10, 20, 30], dtype="int16"),
|
pd.Series([10, 20, 30], dtype="int16"),
|
||||||
pd.Series([100, 200, 300], dtype="int32"),
|
pd.Series([100, 200, 300], dtype="int32"),
|
||||||
|
|||||||
@@ -845,7 +845,7 @@ async def test_async_batched_vector_search_concurrent(
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
for results, (query, filter_) in zip(all_results, search_queries):
|
for results, (query, filter_) in zip(all_results, search_queries, strict=False):
|
||||||
assert len(results) > 0, f"No results for query '{query}' with filter {filter_}"
|
assert len(results) > 0, f"No results for query '{query}' with filter {filter_}"
|
||||||
|
|
||||||
for result in results:
|
for result in results:
|
||||||
|
|||||||
Generated
+569
-619
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,12 @@
|
|||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from typing import Annotated, Literal, TypedDict
|
from typing import Annotated, Literal, TypedDict
|
||||||
|
|
||||||
from langchain_community.tools.tavily_search import TavilySearchResults
|
|
||||||
from langchain_core.messages import BaseMessage
|
from langchain_core.messages import BaseMessage
|
||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
from langgraph.graph import END, StateGraph, add_messages
|
from langgraph.graph import END, StateGraph, add_messages
|
||||||
from langgraph.prebuilt import ToolNode
|
from langgraph.prebuilt import ToolNode
|
||||||
|
|
||||||
tools = [TavilySearchResults(max_results=1)]
|
tools = []
|
||||||
|
|
||||||
model_oai = ChatOpenAI(temperature=0)
|
model_oai = ChatOpenAI(temperature=0)
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ description = "Test for prerelease stuff"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langgraph==0.6.0"
|
"langgraph==1.0.2"
|
||||||
]
|
]
|
||||||
@@ -5,5 +5,5 @@ description = "Test for prerelease stuff"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langchain-openai==0.3.0"
|
"langchain-openai==1.0.1"
|
||||||
]
|
]
|
||||||
@@ -6,9 +6,9 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langchain-openai==1.0.0a2",
|
"langchain-openai==1.0.0a2",
|
||||||
"langgraph==1.0.0a2",
|
"langchain-anthropic==1.0.0a5",
|
||||||
"langchain_community>=0.3.0",
|
"langgraph==1.0.2"
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
prerelease = "allow"
|
prerelease = "allow"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
from typing import Annotated, Optional
|
from typing import Annotated
|
||||||
|
|
||||||
from langchain_community.retrievers import WikipediaRetriever
|
from langchain_community.retrievers import WikipediaRetriever
|
||||||
from langchain_community.tools.tavily_search import TavilySearchResults
|
from langchain_community.tools.tavily_search import TavilySearchResults
|
||||||
@@ -51,7 +51,7 @@ class Subsection(BaseModel):
|
|||||||
class Section(BaseModel):
|
class Section(BaseModel):
|
||||||
section_title: str = Field(..., title="Title of the section")
|
section_title: str = Field(..., title="Title of the section")
|
||||||
description: str = Field(..., title="Content of the section")
|
description: str = Field(..., title="Content of the section")
|
||||||
subsections: Optional[list[Subsection]] = Field(
|
subsections: list[Subsection] | None = Field(
|
||||||
default=None,
|
default=None,
|
||||||
title="Titles and descriptions for each subsection of the Wikipedia page.",
|
title="Titles and descriptions for each subsection of the Wikipedia page.",
|
||||||
)
|
)
|
||||||
@@ -201,8 +201,8 @@ def update_editor(editor, new_editor):
|
|||||||
|
|
||||||
class InterviewState(TypedDict):
|
class InterviewState(TypedDict):
|
||||||
messages: Annotated[list[AnyMessage], add_messages]
|
messages: Annotated[list[AnyMessage], add_messages]
|
||||||
references: Annotated[Optional[dict], update_references]
|
references: Annotated[dict | None, update_references]
|
||||||
editor: Annotated[Optional[Editor], update_editor]
|
editor: Annotated[Editor | None, update_editor]
|
||||||
|
|
||||||
|
|
||||||
gen_qn_prompt = ChatPromptTemplate.from_messages(
|
gen_qn_prompt = ChatPromptTemplate.from_messages(
|
||||||
@@ -321,7 +321,7 @@ async def search_engine(query: str):
|
|||||||
|
|
||||||
async def gen_answer(
|
async def gen_answer(
|
||||||
state: InterviewState,
|
state: InterviewState,
|
||||||
config: Optional[RunnableConfig] = None,
|
config: RunnableConfig | None = None,
|
||||||
name: str = "Subject_Matter_Expert",
|
name: str = "Subject_Matter_Expert",
|
||||||
max_str_len: int = 15000,
|
max_str_len: int = 15000,
|
||||||
):
|
):
|
||||||
@@ -437,7 +437,7 @@ class SubSection(BaseModel):
|
|||||||
class WikiSection(BaseModel):
|
class WikiSection(BaseModel):
|
||||||
section_title: str = Field(..., title="Title of the section")
|
section_title: str = Field(..., title="Title of the section")
|
||||||
content: str = Field(..., title="Full content of the section")
|
content: str = Field(..., title="Full content of the section")
|
||||||
subsections: Optional[list[Subsection]] = Field(
|
subsections: list[Subsection] | None = Field(
|
||||||
default=None,
|
default=None,
|
||||||
title="Titles and descriptions for each subsection of the Wikipedia page.",
|
title="Titles and descriptions for each subsection of the Wikipedia page.",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ name = "langgraph-examples"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = ""
|
description = ""
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langgraph-cli",
|
"langgraph-cli",
|
||||||
"langgraph-sdk",
|
"langgraph-sdk",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
import msgspec
|
import msgspec
|
||||||
|
|
||||||
from langgraph_cli.config import (
|
from langgraph_cli.schemas import (
|
||||||
AuthConfig,
|
AuthConfig,
|
||||||
CheckpointerConfig,
|
CheckpointerConfig,
|
||||||
Config,
|
Config,
|
||||||
@@ -22,6 +22,7 @@ from langgraph_cli.config import (
|
|||||||
HttpConfig,
|
HttpConfig,
|
||||||
IndexConfig,
|
IndexConfig,
|
||||||
SecurityConfig,
|
SecurityConfig,
|
||||||
|
SerdeConfig,
|
||||||
StoreConfig,
|
StoreConfig,
|
||||||
ThreadTTLConfig,
|
ThreadTTLConfig,
|
||||||
TTLConfig,
|
TTLConfig,
|
||||||
@@ -112,6 +113,7 @@ def add_descriptions_to_schema(schema, cls):
|
|||||||
CorsConfig,
|
CorsConfig,
|
||||||
ThreadTTLConfig,
|
ThreadTTLConfig,
|
||||||
CheckpointerConfig,
|
CheckpointerConfig,
|
||||||
|
SerdeConfig,
|
||||||
TTLConfig,
|
TTLConfig,
|
||||||
ConfigurableHeaderConfig,
|
ConfigurableHeaderConfig,
|
||||||
]:
|
]:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.4.2"
|
__version__ = "0.4.7"
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import os
|
|||||||
import pathlib
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from collections.abc import Sequence
|
from collections.abc import Callable, Sequence
|
||||||
from typing import Callable, Optional
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import click.exceptions
|
import click.exceptions
|
||||||
@@ -200,23 +199,23 @@ def cli():
|
|||||||
@log_command
|
@log_command
|
||||||
def up(
|
def up(
|
||||||
config: pathlib.Path,
|
config: pathlib.Path,
|
||||||
docker_compose: Optional[pathlib.Path],
|
docker_compose: pathlib.Path | None,
|
||||||
port: int,
|
port: int,
|
||||||
recreate: bool,
|
recreate: bool,
|
||||||
pull: bool,
|
pull: bool,
|
||||||
watch: bool,
|
watch: bool,
|
||||||
wait: bool,
|
wait: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
debugger_port: Optional[int],
|
debugger_port: int | None,
|
||||||
debugger_base_url: Optional[str],
|
debugger_base_url: str | None,
|
||||||
postgres_uri: Optional[str],
|
postgres_uri: str | None,
|
||||||
api_version: Optional[str],
|
api_version: str | None,
|
||||||
image: Optional[str],
|
image: str | None,
|
||||||
base_image: Optional[str],
|
base_image: str | None,
|
||||||
):
|
):
|
||||||
click.secho("Starting LangGraph API server...", fg="green")
|
click.secho("Starting LangGraph API server...", fg="green")
|
||||||
click.secho(
|
click.secho(
|
||||||
"""For local dev, requires env var LANGSMITH_API_KEY with access to LangGraph Platform.
|
"""For local dev, requires env var LANGSMITH_API_KEY with access to LangSmith Deployment.
|
||||||
For production use, requires a license key in env var LANGGRAPH_CLOUD_LICENSE_KEY.""",
|
For production use, requires a license key in env var LANGGRAPH_CLOUD_LICENSE_KEY.""",
|
||||||
)
|
)
|
||||||
with Runner() as runner, Progress(message="Pulling...") as set:
|
with Runner() as runner, Progress(message="Pulling...") as set:
|
||||||
@@ -298,13 +297,13 @@ def _build(
|
|||||||
set: Callable[[str], None],
|
set: Callable[[str], None],
|
||||||
config: pathlib.Path,
|
config: pathlib.Path,
|
||||||
config_json: dict,
|
config_json: dict,
|
||||||
base_image: Optional[str],
|
base_image: str | None,
|
||||||
api_version: Optional[str],
|
api_version: str | None,
|
||||||
pull: bool,
|
pull: bool,
|
||||||
tag: str,
|
tag: str,
|
||||||
passthrough: Sequence[str] = (),
|
passthrough: Sequence[str] = (),
|
||||||
install_command: Optional[str] = None,
|
install_command: str | None = None,
|
||||||
build_command: Optional[str] = None,
|
build_command: str | None = None,
|
||||||
):
|
):
|
||||||
# pull latest images
|
# pull latest images
|
||||||
if pull:
|
if pull:
|
||||||
@@ -403,12 +402,12 @@ def _build(
|
|||||||
def build(
|
def build(
|
||||||
config: pathlib.Path,
|
config: pathlib.Path,
|
||||||
docker_build_args: Sequence[str],
|
docker_build_args: Sequence[str],
|
||||||
base_image: Optional[str],
|
base_image: str | None,
|
||||||
api_version: Optional[str],
|
api_version: str | None,
|
||||||
pull: bool,
|
pull: bool,
|
||||||
tag: str,
|
tag: str,
|
||||||
install_command: Optional[str],
|
install_command: str | None,
|
||||||
build_command: Optional[str],
|
build_command: str | None,
|
||||||
):
|
):
|
||||||
with Runner() as runner, Progress(message="Pulling...") as set:
|
with Runner() as runner, Progress(message="Pulling...") as set:
|
||||||
if shutil.which("docker") is None:
|
if shutil.which("docker") is None:
|
||||||
@@ -512,8 +511,8 @@ def dockerfile(
|
|||||||
save_path: str,
|
save_path: str,
|
||||||
config: pathlib.Path,
|
config: pathlib.Path,
|
||||||
add_docker_compose: bool,
|
add_docker_compose: bool,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
save_path = pathlib.Path(save_path).absolute()
|
save_path = pathlib.Path(save_path).absolute()
|
||||||
secho(f"🔍 Validating configuration at path: {config}", fg="yellow")
|
secho(f"🔍 Validating configuration at path: {config}", fg="yellow")
|
||||||
@@ -584,7 +583,7 @@ def dockerfile(
|
|||||||
"\n",
|
"\n",
|
||||||
"# LANGSMITH_API_KEY=your-api-key",
|
"# LANGSMITH_API_KEY=your-api-key",
|
||||||
"\n",
|
"\n",
|
||||||
"# Or if you have a LangGraph Platform license key, "
|
"# Or if you have a LangSmith Deployment license key, "
|
||||||
"then uncomment the following line: ",
|
"then uncomment the following line: ",
|
||||||
"\n",
|
"\n",
|
||||||
"# LANGGRAPH_CLOUD_LICENSE_KEY=your-license-key",
|
"# LANGGRAPH_CLOUD_LICENSE_KEY=your-license-key",
|
||||||
@@ -688,11 +687,11 @@ def dev(
|
|||||||
port: int,
|
port: int,
|
||||||
no_reload: bool,
|
no_reload: bool,
|
||||||
config: str,
|
config: str,
|
||||||
n_jobs_per_worker: Optional[int],
|
n_jobs_per_worker: int | None,
|
||||||
no_browser: bool,
|
no_browser: bool,
|
||||||
debug_port: Optional[int],
|
debug_port: int | None,
|
||||||
wait_for_client: bool,
|
wait_for_client: bool,
|
||||||
studio_url: Optional[str],
|
studio_url: str | None,
|
||||||
allow_blocking: bool,
|
allow_blocking: bool,
|
||||||
tunnel: bool,
|
tunnel: bool,
|
||||||
server_log_level: str,
|
server_log_level: str,
|
||||||
@@ -776,7 +775,7 @@ def dev(
|
|||||||
)
|
)
|
||||||
@cli.command("new", help="🌱 Create a new LangGraph project from a template.")
|
@cli.command("new", help="🌱 Create a new LangGraph project from a template.")
|
||||||
@log_command
|
@log_command
|
||||||
def new(path: Optional[str], template: Optional[str]) -> None:
|
def new(path: str | None, template: str | None) -> None:
|
||||||
"""Create a new LangGraph project from a template."""
|
"""Create a new LangGraph project from a template."""
|
||||||
return create_new(path, template)
|
return create_new(path, template)
|
||||||
|
|
||||||
@@ -786,17 +785,17 @@ def prepare_args_and_stdin(
|
|||||||
capabilities: DockerCapabilities,
|
capabilities: DockerCapabilities,
|
||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
config: Config,
|
config: Config,
|
||||||
docker_compose: Optional[pathlib.Path],
|
docker_compose: pathlib.Path | None,
|
||||||
port: int,
|
port: int,
|
||||||
watch: bool,
|
watch: bool,
|
||||||
debugger_port: Optional[int] = None,
|
debugger_port: int | None = None,
|
||||||
debugger_base_url: Optional[str] = None,
|
debugger_base_url: str | None = None,
|
||||||
postgres_uri: Optional[str] = None,
|
postgres_uri: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
# Like "my-tag" (if you already built it locally)
|
# Like "my-tag" (if you already built it locally)
|
||||||
image: Optional[str] = None,
|
image: str | None = None,
|
||||||
# Like "langchain/langgraphjs-api" or "langchain/langgraph-api
|
# Like "langchain/langgraphjs-api" or "langchain/langgraph-api
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
) -> tuple[list[str], str]:
|
) -> tuple[list[str], str]:
|
||||||
assert config_path.exists(), f"Config file not found: {config_path}"
|
assert config_path.exists(), f"Config file not found: {config_path}"
|
||||||
# prepare args
|
# prepare args
|
||||||
@@ -835,17 +834,17 @@ def prepare(
|
|||||||
*,
|
*,
|
||||||
capabilities: DockerCapabilities,
|
capabilities: DockerCapabilities,
|
||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
docker_compose: Optional[pathlib.Path],
|
docker_compose: pathlib.Path | None,
|
||||||
port: int,
|
port: int,
|
||||||
pull: bool,
|
pull: bool,
|
||||||
watch: bool,
|
watch: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
debugger_port: Optional[int] = None,
|
debugger_port: int | None = None,
|
||||||
debugger_base_url: Optional[str] = None,
|
debugger_base_url: str | None = None,
|
||||||
postgres_uri: Optional[str] = None,
|
postgres_uri: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
image: Optional[str] = None,
|
image: str | None = None,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
) -> tuple[list[str], str]:
|
) -> tuple[list[str], str]:
|
||||||
"""Prepare the arguments and stdin for running the LangGraph API server."""
|
"""Prepare the arguments and stdin for running the LangGraph API server."""
|
||||||
config_json = langgraph_cli.config.validate_config_file(config_path)
|
config_json = langgraph_cli.config.validate_config_file(config_path)
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import pathlib
|
|||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import Any, Literal, NamedTuple, Optional, TypedDict, Union
|
from typing import Literal, NamedTuple
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
|
from langgraph_cli.schemas import Config, Distros
|
||||||
|
|
||||||
MIN_NODE_VERSION = "20"
|
MIN_NODE_VERSION = "20"
|
||||||
DEFAULT_NODE_VERSION = "20"
|
DEFAULT_NODE_VERSION = "20"
|
||||||
|
|
||||||
@@ -17,510 +19,12 @@ DEFAULT_PYTHON_VERSION = "3.11"
|
|||||||
DEFAULT_IMAGE_DISTRO = "debian"
|
DEFAULT_IMAGE_DISTRO = "debian"
|
||||||
|
|
||||||
|
|
||||||
Distros = Literal["debian", "wolfi", "bullseye", "bookworm"]
|
|
||||||
MiddlewareOrders = Literal["auth_first", "middleware_first"]
|
|
||||||
|
|
||||||
|
|
||||||
class TTLConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for TTL (time-to-live) behavior in the store."""
|
|
||||||
|
|
||||||
refresh_on_read: bool
|
|
||||||
"""Default behavior for refreshing TTLs on read operations (GET and SEARCH).
|
|
||||||
|
|
||||||
If True, TTLs will be refreshed on read operations (get/search) by default.
|
|
||||||
This can be overridden per-operation by explicitly setting refresh_ttl.
|
|
||||||
Defaults to True if not configured.
|
|
||||||
"""
|
|
||||||
default_ttl: Optional[float]
|
|
||||||
"""Optional. Default TTL (time-to-live) in minutes for new items.
|
|
||||||
|
|
||||||
If provided, all new items will have this TTL unless explicitly overridden.
|
|
||||||
If omitted, items will have no TTL by default.
|
|
||||||
"""
|
|
||||||
sweep_interval_minutes: Optional[int]
|
|
||||||
"""Optional. Interval in minutes between TTL sweep iterations.
|
|
||||||
|
|
||||||
If provided, the store will periodically delete expired items based on the TTL.
|
|
||||||
If omitted, no automatic sweeping will occur.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class IndexConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for indexing documents for semantic search in the store.
|
|
||||||
|
|
||||||
This governs how text is converted into embeddings and stored for vector-based lookups.
|
|
||||||
"""
|
|
||||||
|
|
||||||
dims: int
|
|
||||||
"""Required. Dimensionality of the embedding vectors you will store.
|
|
||||||
|
|
||||||
Must match the output dimension of your selected embedding model or custom embed function.
|
|
||||||
If mismatched, you will likely encounter shape/size errors when inserting or querying vectors.
|
|
||||||
|
|
||||||
Common embedding model output dimensions:
|
|
||||||
- openai:text-embedding-3-large: 3072
|
|
||||||
- openai:text-embedding-3-small: 1536
|
|
||||||
- openai:text-embedding-ada-002: 1536
|
|
||||||
- cohere:embed-english-v3.0: 1024
|
|
||||||
- cohere:embed-english-light-v3.0: 384
|
|
||||||
- cohere:embed-multilingual-v3.0: 1024
|
|
||||||
- cohere:embed-multilingual-light-v3.0: 384
|
|
||||||
"""
|
|
||||||
|
|
||||||
embed: str
|
|
||||||
"""Required. Identifier or reference to the embedding model or a custom embedding function.
|
|
||||||
|
|
||||||
The format can vary:
|
|
||||||
- "<provider>:<model_name>" for recognized providers (e.g., "openai:text-embedding-3-large")
|
|
||||||
- "path/to/module.py:function_name" for your own local embedding function
|
|
||||||
- "my_custom_embed" if it's a known alias in your system
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- "openai:text-embedding-3-large"
|
|
||||||
- "cohere:embed-multilingual-v3.0"
|
|
||||||
- "src/app.py:embeddings"
|
|
||||||
|
|
||||||
Note: Must return embeddings of dimension `dims`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
fields: Optional[list[str]]
|
|
||||||
"""Optional. List of JSON fields to extract before generating embeddings.
|
|
||||||
|
|
||||||
Defaults to ["$"], which means the entire JSON object is embedded as one piece of text.
|
|
||||||
If you provide multiple fields (e.g. ["title", "content"]), each is extracted and embedded separately,
|
|
||||||
often saving token usage if you only care about certain parts of the data.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
fields=["title", "abstract", "author.biography"]
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class StoreConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for the built-in long-term memory store.
|
|
||||||
|
|
||||||
This store can optionally perform semantic search. If you omit `index`,
|
|
||||||
the store will just handle traditional (non-embedded) data without vector lookups.
|
|
||||||
"""
|
|
||||||
|
|
||||||
index: Optional[IndexConfig]
|
|
||||||
"""Optional. Defines the vector-based semantic search configuration.
|
|
||||||
|
|
||||||
If provided, the store will:
|
|
||||||
- Generate embeddings according to `index.embed`
|
|
||||||
- Enforce the embedding dimension given by `index.dims`
|
|
||||||
- Embed only specified JSON fields (if any) from `index.fields`
|
|
||||||
|
|
||||||
If omitted, no vector index is initialized.
|
|
||||||
"""
|
|
||||||
|
|
||||||
ttl: Optional[TTLConfig]
|
|
||||||
"""Optional. Defines the TTL (time-to-live) behavior configuration.
|
|
||||||
|
|
||||||
If provided, the store will apply TTL settings according to the configuration.
|
|
||||||
If omitted, no TTL behavior is configured.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadTTLConfig(TypedDict, total=False):
|
|
||||||
"""Configure a default TTL for checkpointed data within threads."""
|
|
||||||
|
|
||||||
strategy: Literal["delete"]
|
|
||||||
"""Strategy to use for deleting checkpointed data.
|
|
||||||
|
|
||||||
Choices:
|
|
||||||
- "delete": Delete all checkpoints for a thread after TTL expires.
|
|
||||||
"""
|
|
||||||
default_ttl: Optional[float]
|
|
||||||
"""Default TTL (time-to-live) in minutes for checkpointed data."""
|
|
||||||
sweep_interval_minutes: Optional[int]
|
|
||||||
"""Interval in minutes between sweep iterations.
|
|
||||||
If omitted, a default interval will be used (typically ~ 5 minutes)."""
|
|
||||||
|
|
||||||
|
|
||||||
class CheckpointerConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for the built-in checkpointer, which handles checkpointing of state.
|
|
||||||
|
|
||||||
If omitted, no checkpointer is set up (the object store will still be present, however).
|
|
||||||
"""
|
|
||||||
|
|
||||||
ttl: Optional[ThreadTTLConfig]
|
|
||||||
"""Optional. Defines the TTL (time-to-live) behavior configuration.
|
|
||||||
|
|
||||||
If provided, the checkpointer will apply TTL settings according to the configuration.
|
|
||||||
If omitted, no TTL behavior is configured.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class SecurityConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for OpenAPI security definitions and requirements.
|
|
||||||
|
|
||||||
Useful for specifying global or path-level authentication and authorization flows
|
|
||||||
(e.g., OAuth2, API key headers, etc.).
|
|
||||||
"""
|
|
||||||
|
|
||||||
securitySchemes: dict[str, dict[str, Any]]
|
|
||||||
"""Required. Dict describing each security scheme recognized by your OpenAPI spec.
|
|
||||||
|
|
||||||
Keys are scheme names (e.g. "OAuth2", "ApiKeyAuth") and values are their definitions.
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"OAuth2": {
|
|
||||||
"type": "oauth2",
|
|
||||||
"flows": {
|
|
||||||
"password": {
|
|
||||||
"tokenUrl": "/token",
|
|
||||||
"scopes": {"read": "Read data", "write": "Write data"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
security: list[dict[str, list[str]]]
|
|
||||||
"""Optional. Global security requirements across all endpoints.
|
|
||||||
|
|
||||||
Each element in the list maps a security scheme (e.g. "OAuth2") to a list of scopes (e.g. ["read", "write"]).
|
|
||||||
Example:
|
|
||||||
[
|
|
||||||
{"OAuth2": ["read", "write"]},
|
|
||||||
{"ApiKeyAuth": []}
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
# path => {method => security}
|
|
||||||
paths: dict[str, dict[str, list[dict[str, list[str]]]]]
|
|
||||||
"""Optional. Path-specific security overrides.
|
|
||||||
|
|
||||||
Keys are path templates (e.g., "/items/{item_id}"), mapping to:
|
|
||||||
- Keys that are HTTP methods (e.g., "GET", "POST"),
|
|
||||||
- Values are lists of security definitions (just like `security`) for that method.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"/private_data": {
|
|
||||||
"GET": [{"OAuth2": ["read"]}],
|
|
||||||
"POST": [{"OAuth2": ["write"]}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class AuthConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for custom authentication logic and how it integrates into the OpenAPI spec."""
|
|
||||||
|
|
||||||
path: str
|
|
||||||
"""Required. Path to an instance of the Auth() class that implements custom authentication.
|
|
||||||
|
|
||||||
Format: "path/to/file.py:my_auth"
|
|
||||||
"""
|
|
||||||
disable_studio_auth: bool
|
|
||||||
"""Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.
|
|
||||||
|
|
||||||
Defaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header
|
|
||||||
value is a valid API key for the deployment's workspace. If True, all requests will go through your custom
|
|
||||||
authentication logic, regardless of origin of the request.
|
|
||||||
"""
|
|
||||||
openapi: SecurityConfig
|
|
||||||
"""Required. Detailed security configuration that merges into your deployment's OpenAPI spec.
|
|
||||||
|
|
||||||
Example (OAuth2):
|
|
||||||
{
|
|
||||||
"securitySchemes": {
|
|
||||||
"OAuth2": {
|
|
||||||
"type": "oauth2",
|
|
||||||
"flows": {
|
|
||||||
"password": {
|
|
||||||
"tokenUrl": "/token",
|
|
||||||
"scopes": {"me": "Read user info", "items": "Manage items"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{"OAuth2": ["me"]}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class CorsConfig(TypedDict, total=False):
|
|
||||||
"""Specifies Cross-Origin Resource Sharing (CORS) rules for your server.
|
|
||||||
|
|
||||||
If omitted, defaults are typically very restrictive (often no cross-origin requests).
|
|
||||||
Configure carefully if you want to allow usage from browsers hosted on other domains.
|
|
||||||
"""
|
|
||||||
|
|
||||||
allow_origins: list[str]
|
|
||||||
"""Optional. List of allowed origins (e.g., "https://example.com").
|
|
||||||
|
|
||||||
Default is often an empty list (no external origins).
|
|
||||||
Use "*" only if you trust all origins, as that bypasses most restrictions.
|
|
||||||
"""
|
|
||||||
allow_methods: list[str]
|
|
||||||
"""Optional. HTTP methods permitted for cross-origin requests (e.g. ["GET", "POST"]).
|
|
||||||
|
|
||||||
Default might be ["GET", "POST", "OPTIONS"] depending on your server framework.
|
|
||||||
"""
|
|
||||||
allow_headers: list[str]
|
|
||||||
"""Optional. HTTP headers that can be used in cross-origin requests (e.g. ["Content-Type", "Authorization"])."""
|
|
||||||
allow_credentials: bool
|
|
||||||
"""Optional. If True, cross-origin requests can include credentials (cookies, auth headers).
|
|
||||||
|
|
||||||
Default False to avoid accidentally exposing secured endpoints to untrusted sites.
|
|
||||||
"""
|
|
||||||
allow_origin_regex: str
|
|
||||||
"""Optional. A regex pattern for matching allowed origins, used if you have dynamic subdomains.
|
|
||||||
|
|
||||||
Example: "^https://.*\\.mycompany\\.com$"
|
|
||||||
"""
|
|
||||||
expose_headers: list[str]
|
|
||||||
"""Optional. List of headers that browsers are allowed to read from the response in cross-origin contexts."""
|
|
||||||
max_age: int
|
|
||||||
"""Optional. How many seconds the browser may cache preflight responses.
|
|
||||||
|
|
||||||
Default might be 600 (10 minutes). Larger values reduce preflight requests but can cause stale configurations.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigurableHeaderConfig(TypedDict):
|
|
||||||
"""Customize which headers to include as configurable values in your runs.
|
|
||||||
|
|
||||||
By default, omits x-api-key, x-tenant-id, and x-service-key.
|
|
||||||
|
|
||||||
Exclusions (if provided) take precedence.
|
|
||||||
|
|
||||||
Each value can be a raw string with an optional wildcard.
|
|
||||||
"""
|
|
||||||
|
|
||||||
includes: Optional[list[str]]
|
|
||||||
"""Headers to include (if not also matches against an 'exludes' pattern.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- 'user-agent'
|
|
||||||
- 'x-configurable-*'
|
|
||||||
"""
|
|
||||||
excludes: Optional[list[str]]
|
|
||||||
"""Headers to exclude. Applied before the 'includes' checks.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- 'x-api-key'
|
|
||||||
- '*key*'
|
|
||||||
- '*token*'
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class HttpConfig(TypedDict, total=False):
|
|
||||||
"""Configuration for the built-in HTTP server that powers your deployment's routes and endpoints."""
|
|
||||||
|
|
||||||
app: str
|
|
||||||
"""Optional. Import path to a custom Starlette/FastAPI application to mount.
|
|
||||||
|
|
||||||
Format: "path/to/module.py:app_var"
|
|
||||||
If provided, it can override or extend the default routes.
|
|
||||||
"""
|
|
||||||
disable_assistants: bool
|
|
||||||
"""Optional. If True, /assistants routes are removed from the server.
|
|
||||||
|
|
||||||
Default is False (meaning /assistants is enabled).
|
|
||||||
"""
|
|
||||||
disable_threads: bool
|
|
||||||
"""Optional. If True, /threads routes are removed.
|
|
||||||
|
|
||||||
Default is False.
|
|
||||||
"""
|
|
||||||
disable_runs: bool
|
|
||||||
"""Optional. If True, /runs routes are removed.
|
|
||||||
|
|
||||||
Default is False.
|
|
||||||
"""
|
|
||||||
disable_store: bool
|
|
||||||
"""Optional. If True, /store routes are removed, disabling direct store interactions via HTTP.
|
|
||||||
|
|
||||||
Default is False.
|
|
||||||
"""
|
|
||||||
disable_mcp: bool
|
|
||||||
"""Optional. If True, /mcp routes are removed, disabling the MCP server.
|
|
||||||
|
|
||||||
Default is False.
|
|
||||||
"""
|
|
||||||
disable_meta: bool
|
|
||||||
"""Optional. Remove meta endpoints.
|
|
||||||
|
|
||||||
Set to True to disable the following endpoints: /openapi.json, /info, /metrics, /docs.
|
|
||||||
This will also make the /ok endpoint skip any DB or other checks, always returning {"ok": True}.
|
|
||||||
|
|
||||||
Default is False.
|
|
||||||
"""
|
|
||||||
cors: Optional[CorsConfig]
|
|
||||||
"""Optional. Defines CORS restrictions. If omitted, no special rules are set and
|
|
||||||
cross-origin behavior depends on default server settings.
|
|
||||||
"""
|
|
||||||
configurable_headers: Optional[ConfigurableHeaderConfig]
|
|
||||||
"""Optional. Defines how headers are treated for a run's configuration.
|
|
||||||
|
|
||||||
You can include or exclude headers as configurable values to condition your
|
|
||||||
agent's behavior or permissions on a request's headers."""
|
|
||||||
logging_headers: Optional[ConfigurableHeaderConfig]
|
|
||||||
"""Optional. Defines which headers are excluded from logging."""
|
|
||||||
middleware_order: Optional[MiddlewareOrders]
|
|
||||||
"""Optional. Defines the order in which to apply server customizations.
|
|
||||||
|
|
||||||
Choices:
|
|
||||||
- "auth_first": Authentication hooks (custom or default) are evaluated
|
|
||||||
before custom middleware.
|
|
||||||
- "middleware_first": Custom middleware is evaluated
|
|
||||||
before authentication hooks (custom or default).
|
|
||||||
|
|
||||||
Default is `middleware_first`.
|
|
||||||
"""
|
|
||||||
enable_custom_route_auth: bool
|
|
||||||
"""Optional. If True, authentication is enabled for custom routes,
|
|
||||||
not just the routes that are protected by default.
|
|
||||||
(Routes protected by default include /assistants, /threads, and /runs).
|
|
||||||
|
|
||||||
Default is False. This flag only affects authentication behavior
|
|
||||||
if `app` is provided and contains custom routes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class Config(TypedDict, total=False):
|
|
||||||
"""Top-level config for langgraph-cli or similar deployment tooling."""
|
|
||||||
|
|
||||||
python_version: str
|
|
||||||
"""Optional. Python version in 'major.minor' format (e.g. '3.11').
|
|
||||||
Must be at least 3.11 or greater for this deployment to function properly.
|
|
||||||
"""
|
|
||||||
|
|
||||||
node_version: Optional[str]
|
|
||||||
"""Optional. Node.js version as a major version (e.g. '20'), if your deployment needs Node.
|
|
||||||
Must be >= 20 if provided.
|
|
||||||
"""
|
|
||||||
|
|
||||||
api_version: Optional[str]
|
|
||||||
"""Optional. Which semantic version of the LangGraph API server to use.
|
|
||||||
|
|
||||||
Defaults to latest. Check the
|
|
||||||
[changelog](https://docs.langchain.com/langgraph-platform/langgraph-server-changelog)
|
|
||||||
for more information."""
|
|
||||||
|
|
||||||
_INTERNAL_docker_tag: Optional[str]
|
|
||||||
"""Optional. Internal use only.
|
|
||||||
"""
|
|
||||||
|
|
||||||
base_image: Optional[str]
|
|
||||||
"""Optional. Base image to use for the LangGraph API server.
|
|
||||||
|
|
||||||
Defaults to langchain/langgraph-api or langchain/langgraphjs-api."""
|
|
||||||
|
|
||||||
image_distro: Optional[Distros]
|
|
||||||
"""Optional. Linux distribution for the base image.
|
|
||||||
|
|
||||||
Must be one of 'wolfi', 'debian', 'bullseye', or 'bookworm'.
|
|
||||||
If omitted, defaults to 'debian' ('latest').
|
|
||||||
"""
|
|
||||||
|
|
||||||
pip_config_file: Optional[str]
|
|
||||||
"""Optional. Path to a pip config file (e.g., "/etc/pip.conf" or "pip.ini") for controlling
|
|
||||||
package installation (custom indices, credentials, etc.).
|
|
||||||
|
|
||||||
Only relevant if Python dependencies are installed via pip. If omitted, default pip settings are used.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pip_installer: Optional[str]
|
|
||||||
"""Optional. Python package installer to use ('auto', 'pip', 'uv').
|
|
||||||
|
|
||||||
- 'auto' (default): Use uv for supported base images, otherwise pip
|
|
||||||
- 'pip': Force use of pip regardless of base image support
|
|
||||||
- 'uv': Force use of uv (will fail if base image doesn't support it)
|
|
||||||
"""
|
|
||||||
|
|
||||||
dockerfile_lines: list[str]
|
|
||||||
"""Optional. Additional Docker instructions that will be appended to your base Dockerfile.
|
|
||||||
|
|
||||||
Useful for installing OS packages, setting environment variables, etc.
|
|
||||||
Example:
|
|
||||||
dockerfile_lines=[
|
|
||||||
"RUN apt-get update && apt-get install -y libmagic-dev",
|
|
||||||
"ENV MY_CUSTOM_VAR=hello_world"
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
|
|
||||||
dependencies: list[str]
|
|
||||||
"""List of Python dependencies to install, either from PyPI or local paths.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- "." or "./src" if you have a local Python package
|
|
||||||
- str (aka "anthropic") for a PyPI package
|
|
||||||
- "git+https://github.com/org/repo.git@main" for a Git-based package
|
|
||||||
Defaults to an empty list, meaning no additional packages installed beyond your base environment.
|
|
||||||
"""
|
|
||||||
|
|
||||||
graphs: dict[str, str]
|
|
||||||
"""Optional. Named definitions of graphs, each pointing to a Python object.
|
|
||||||
|
|
||||||
|
|
||||||
Graphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context
|
|
||||||
managers that accept a single configuration argument (of type RunnableConfig) and return a pregel object
|
|
||||||
(instance of Stategraph, etc.).
|
|
||||||
|
|
||||||
Keys are graph names, values are "path/to/file.py:object_name".
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"mygraph": "graphs/my_graph.py:graph_definition",
|
|
||||||
"anothergraph": "graphs/another.py:get_graph"
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
env: Union[dict[str, str], str]
|
|
||||||
"""Optional. Environment variables to set for your deployment.
|
|
||||||
|
|
||||||
- If given as a dict, keys are variable names and values are their values.
|
|
||||||
- If given as a string, it must be a path to a file containing lines in KEY=VALUE format.
|
|
||||||
|
|
||||||
Example as a dict:
|
|
||||||
env={"API_TOKEN": "abc123", "DEBUG": "true"}
|
|
||||||
Example as a file path:
|
|
||||||
env=".env"
|
|
||||||
"""
|
|
||||||
|
|
||||||
store: Optional[StoreConfig]
|
|
||||||
"""Optional. Configuration for the built-in long-term memory store, including semantic search indexing.
|
|
||||||
|
|
||||||
If omitted, no vector index is set up (the object store will still be present, however).
|
|
||||||
"""
|
|
||||||
|
|
||||||
checkpointer: Optional[CheckpointerConfig]
|
|
||||||
"""Optional. Configuration for the built-in checkpointer, which handles checkpointing of state.
|
|
||||||
|
|
||||||
If omitted, no checkpointer is set up (the object store will still be present, however).
|
|
||||||
"""
|
|
||||||
|
|
||||||
auth: Optional[AuthConfig]
|
|
||||||
"""Optional. Custom authentication config, including the path to your Python auth logic and
|
|
||||||
the OpenAPI security definitions it uses.
|
|
||||||
"""
|
|
||||||
|
|
||||||
http: Optional[HttpConfig]
|
|
||||||
"""Optional. Configuration for the built-in HTTP server, controlling which custom routes are exposed
|
|
||||||
and how cross-origin requests are handled.
|
|
||||||
"""
|
|
||||||
|
|
||||||
ui: Optional[dict[str, str]]
|
|
||||||
"""Optional. Named definitions of UI components emitted by the agent, each pointing to a JS/TS file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
keep_pkg_tools: Optional[Union[bool, list[str]]]
|
|
||||||
"""Optional. Control whether to retain Python packaging tools in the final image.
|
|
||||||
|
|
||||||
Allowed tools are: "pip", "setuptools", "wheel".
|
|
||||||
You can also set to true to include all packaging tools.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
_BUILD_TOOLS = ("pip", "setuptools", "wheel")
|
_BUILD_TOOLS = ("pip", "setuptools", "wheel")
|
||||||
|
|
||||||
|
|
||||||
def _get_pip_cleanup_lines(
|
def _get_pip_cleanup_lines(
|
||||||
install_cmd: str,
|
install_cmd: str,
|
||||||
to_uninstall: Optional[tuple[str]],
|
to_uninstall: tuple[str] | None,
|
||||||
pip_installer: Literal["uv", "pip"],
|
pip_installer: Literal["uv", "pip"],
|
||||||
) -> str:
|
) -> str:
|
||||||
commands = [
|
commands = [
|
||||||
@@ -586,7 +90,7 @@ def _parse_node_version(version_str: str) -> int:
|
|||||||
) from None
|
) from None
|
||||||
|
|
||||||
|
|
||||||
def _is_node_graph(spec: Union[str, dict]) -> bool:
|
def _is_node_graph(spec: str | dict) -> bool:
|
||||||
"""Check if a graph is a Node.js graph based on the file extension."""
|
"""Check if a graph is a Node.js graph based on the file extension."""
|
||||||
if isinstance(spec, dict):
|
if isinstance(spec, dict):
|
||||||
spec = spec.get("path")
|
spec = spec.get("path")
|
||||||
@@ -846,7 +350,7 @@ class LocalDeps(NamedTuple):
|
|||||||
real_pkgs: dict[pathlib.Path, tuple[str, str]]
|
real_pkgs: dict[pathlib.Path, tuple[str, str]]
|
||||||
faux_pkgs: dict[pathlib.Path, tuple[str, str]]
|
faux_pkgs: dict[pathlib.Path, tuple[str, str]]
|
||||||
# if . is in dependencies, use it as working_dir
|
# if . is in dependencies, use it as working_dir
|
||||||
working_dir: Optional[str] = None
|
working_dir: str | None = None
|
||||||
# if there are local dependencies in parent directories, use additional_contexts
|
# if there are local dependencies in parent directories, use additional_contexts
|
||||||
additional_contexts: list[pathlib.Path] = None
|
additional_contexts: list[pathlib.Path] = None
|
||||||
|
|
||||||
@@ -882,7 +386,7 @@ def _assemble_local_deps(config_path: pathlib.Path, config: Config) -> LocalDeps
|
|||||||
pip_reqs = []
|
pip_reqs = []
|
||||||
real_pkgs = {}
|
real_pkgs = {}
|
||||||
faux_pkgs = {}
|
faux_pkgs = {}
|
||||||
working_dir: Optional[str] = None
|
working_dir: str | None = None
|
||||||
additional_contexts: list[pathlib.Path] = []
|
additional_contexts: list[pathlib.Path] = []
|
||||||
|
|
||||||
for local_dep in config["dependencies"]:
|
for local_dep in config["dependencies"]:
|
||||||
@@ -1265,7 +769,7 @@ def python_config_to_docker(
|
|||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
config: Config,
|
config: Config,
|
||||||
base_image: str,
|
base_image: str,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
) -> tuple[str, dict[str, str]]:
|
) -> tuple[str, dict[str, str]]:
|
||||||
"""Generate a Dockerfile from the configuration."""
|
"""Generate a Dockerfile from the configuration."""
|
||||||
pip_installer = config.get("pip_installer", "auto")
|
pip_installer = config.get("pip_installer", "auto")
|
||||||
@@ -1422,35 +926,51 @@ ADD {relpath} /deps/{name}
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
image_str = docker_tag(config, base_image, api_version)
|
image_str = docker_tag(config, base_image, api_version)
|
||||||
docker_file_contents = [
|
|
||||||
f"FROM {image_str}",
|
# Prepare docker file contents
|
||||||
"",
|
docker_file_contents = []
|
||||||
os.linesep.join(config["dockerfile_lines"]),
|
|
||||||
"",
|
# Add syntax directive if we have additional contexts (requires BuildKit frontend.contexts capability)
|
||||||
installs,
|
if local_deps.additional_contexts:
|
||||||
"",
|
docker_file_contents.extend(
|
||||||
"# -- Installing all local dependencies --",
|
[
|
||||||
f"""RUN for dep in /deps/*; do \
|
"# syntax=docker/dockerfile:1.4",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add main dockerfile content
|
||||||
|
docker_file_contents.extend(
|
||||||
|
[
|
||||||
|
f"FROM {image_str}",
|
||||||
|
"",
|
||||||
|
os.linesep.join(config["dockerfile_lines"]),
|
||||||
|
"",
|
||||||
|
installs,
|
||||||
|
"",
|
||||||
|
"# -- Installing all local dependencies --",
|
||||||
|
f"""RUN for dep in /deps/*; do \
|
||||||
echo "Installing $dep"; \
|
echo "Installing $dep"; \
|
||||||
if [ -d "$dep" ]; then \
|
if [ -d "$dep" ]; then \
|
||||||
echo "Installing $dep"; \
|
echo "Installing $dep"; \
|
||||||
(cd "$dep" && {global_reqs_pip_install} .); \
|
(cd "$dep" && {global_reqs_pip_install} -e .); \
|
||||||
fi; \
|
fi; \
|
||||||
done""",
|
done""",
|
||||||
"# -- End of local dependencies install --",
|
"# -- End of local dependencies install --",
|
||||||
os.linesep.join(env_vars),
|
os.linesep.join(env_vars),
|
||||||
"",
|
"",
|
||||||
js_inst_str,
|
js_inst_str,
|
||||||
"",
|
"",
|
||||||
# Add pip cleanup after all installations are complete
|
# Add pip cleanup after all installations are complete
|
||||||
_get_pip_cleanup_lines(
|
_get_pip_cleanup_lines(
|
||||||
install_cmd=install_cmd,
|
install_cmd=install_cmd,
|
||||||
to_uninstall=build_tools_to_uninstall,
|
to_uninstall=build_tools_to_uninstall,
|
||||||
pip_installer=pip_installer,
|
pip_installer=pip_installer,
|
||||||
),
|
),
|
||||||
"",
|
"",
|
||||||
f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "",
|
f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "",
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
additional_contexts: dict[str, str] = {}
|
additional_contexts: dict[str, str] = {}
|
||||||
for p in local_deps.additional_contexts:
|
for p in local_deps.additional_contexts:
|
||||||
@@ -1469,10 +989,10 @@ def node_config_to_docker(
|
|||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
config: Config,
|
config: Config,
|
||||||
base_image: str,
|
base_image: str,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
install_command: Optional[str] = None,
|
install_command: str | None = None,
|
||||||
build_command: Optional[str] = None,
|
build_command: str | None = None,
|
||||||
build_context: Optional[str] = None,
|
build_context: str | None = None,
|
||||||
) -> tuple[str, dict[str, str]]:
|
) -> tuple[str, dict[str, str]]:
|
||||||
# Calculate paths for monorepo support
|
# Calculate paths for monorepo support
|
||||||
if build_context:
|
if build_context:
|
||||||
@@ -1562,8 +1082,8 @@ def default_base_image(config: Config) -> str:
|
|||||||
|
|
||||||
def docker_tag(
|
def docker_tag(
|
||||||
config: Config,
|
config: Config,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
api_version = api_version or config.get("api_version")
|
api_version = api_version or config.get("api_version")
|
||||||
base_image = base_image or default_base_image(config)
|
base_image = base_image or default_base_image(config)
|
||||||
@@ -1612,11 +1132,11 @@ def _calculate_relative_workdir(config_path: pathlib.Path, build_context: str) -
|
|||||||
def config_to_docker(
|
def config_to_docker(
|
||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
config: Config,
|
config: Config,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
install_command: Optional[str] = None,
|
install_command: str | None = None,
|
||||||
build_command: Optional[str] = None,
|
build_command: str | None = None,
|
||||||
build_context: Optional[str] = None,
|
build_context: str | None = None,
|
||||||
) -> tuple[str, dict[str, str]]:
|
) -> tuple[str, dict[str, str]]:
|
||||||
base_image = base_image or default_base_image(config)
|
base_image = base_image or default_base_image(config)
|
||||||
|
|
||||||
@@ -1637,9 +1157,9 @@ def config_to_docker(
|
|||||||
def config_to_compose(
|
def config_to_compose(
|
||||||
config_path: pathlib.Path,
|
config_path: pathlib.Path,
|
||||||
config: Config,
|
config: Config,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
image: Optional[str] = None,
|
image: str | None = None,
|
||||||
watch: bool = False,
|
watch: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
base_image = base_image or default_base_image(config)
|
base_image = base_image or default_base_image(config)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
from typing import Literal, NamedTuple, Optional
|
from typing import Literal, NamedTuple
|
||||||
|
|
||||||
import click.exceptions
|
import click.exceptions
|
||||||
|
|
||||||
@@ -90,9 +90,7 @@ def check_capabilities(runner) -> DockerCapabilities:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def debugger_compose(
|
def debugger_compose(*, port: int | None = None, base_url: str | None = None) -> dict:
|
||||||
*, port: Optional[int] = None, base_url: Optional[str] = None
|
|
||||||
) -> dict:
|
|
||||||
if port is None:
|
if port is None:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@@ -141,16 +139,16 @@ def compose_as_dict(
|
|||||||
capabilities: DockerCapabilities,
|
capabilities: DockerCapabilities,
|
||||||
*,
|
*,
|
||||||
port: int,
|
port: int,
|
||||||
debugger_port: Optional[int] = None,
|
debugger_port: int | None = None,
|
||||||
debugger_base_url: Optional[str] = None,
|
debugger_base_url: str | None = None,
|
||||||
# postgres://user:password@host:port/database?option=value
|
# postgres://user:password@host:port/database?option=value
|
||||||
postgres_uri: Optional[str] = None,
|
postgres_uri: str | None = None,
|
||||||
# If you are running against an already-built image, you can pass it here
|
# If you are running against an already-built image, you can pass it here
|
||||||
image: Optional[str] = None,
|
image: str | None = None,
|
||||||
# Base image to use for the LangGraph API server
|
# Base image to use for the LangGraph API server
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
# API version of the base image
|
# API version of the base image
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Create a docker compose file as a dictionary in YML style."""
|
"""Create a docker compose file as a dictionary in YML style."""
|
||||||
if postgres_uri is None:
|
if postgres_uri is None:
|
||||||
@@ -250,13 +248,13 @@ def compose(
|
|||||||
capabilities: DockerCapabilities,
|
capabilities: DockerCapabilities,
|
||||||
*,
|
*,
|
||||||
port: int,
|
port: int,
|
||||||
debugger_port: Optional[int] = None,
|
debugger_port: int | None = None,
|
||||||
debugger_base_url: Optional[str] = None,
|
debugger_base_url: str | None = None,
|
||||||
# postgres://user:password@host:port/database?option=value
|
# postgres://user:password@host:port/database?option=value
|
||||||
postgres_uri: Optional[str] = None,
|
postgres_uri: str | None = None,
|
||||||
image: Optional[str] = None,
|
image: str | None = None,
|
||||||
base_image: Optional[str] = None,
|
base_image: str | None = None,
|
||||||
api_version: Optional[str] = None,
|
api_version: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Create a docker compose file as a string."""
|
"""Create a docker compose file as a string."""
|
||||||
compose_content = compose_as_dict(
|
compose_content = compose_as_dict(
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
|
from collections.abc import Callable
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Callable, Optional, cast
|
from typing import cast
|
||||||
|
|
||||||
import click.exceptions
|
import click.exceptions
|
||||||
|
|
||||||
@@ -30,12 +31,12 @@ def Runner():
|
|||||||
async def subp_exec(
|
async def subp_exec(
|
||||||
cmd: str,
|
cmd: str,
|
||||||
*args: str,
|
*args: str,
|
||||||
input: Optional[str] = None,
|
input: str | None = None,
|
||||||
wait: Optional[float] = None,
|
wait: float | None = None,
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
collect: bool = False,
|
collect: bool = False,
|
||||||
on_stdout: Optional[Callable[[str], Optional[bool]]] = None,
|
on_stdout: Callable[[str], bool | None] | None = None,
|
||||||
) -> tuple[Optional[str], Optional[str]]:
|
) -> tuple[str | None, str | None]:
|
||||||
if verbose:
|
if verbose:
|
||||||
cmd_str = f"+ {cmd} {' '.join(map(str, args))}"
|
cmd_str = f"+ {cmd} {' '.join(map(str, args))}"
|
||||||
if input:
|
if input:
|
||||||
@@ -126,8 +127,8 @@ async def monitor_stream(
|
|||||||
stream: asyncio.StreamReader,
|
stream: asyncio.StreamReader,
|
||||||
collect: bool = False,
|
collect: bool = False,
|
||||||
display: bool = False,
|
display: bool = False,
|
||||||
on_line: Optional[Callable[[str], Optional[bool]]] = None,
|
on_line: Callable[[str], bool | None] | None = None,
|
||||||
) -> Optional[bytearray]:
|
) -> bytearray | None:
|
||||||
if collect:
|
if collect:
|
||||||
ba = bytearray()
|
ba = bytearray()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from typing import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
|
|
||||||
class Progress:
|
class Progress:
|
||||||
|
|||||||
@@ -0,0 +1,558 @@
|
|||||||
|
from typing import Any, Literal, TypedDict
|
||||||
|
|
||||||
|
Distros = Literal["debian", "wolfi", "bullseye", "bookworm"]
|
||||||
|
MiddlewareOrders = Literal["auth_first", "middleware_first"]
|
||||||
|
|
||||||
|
|
||||||
|
class TTLConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for TTL (time-to-live) behavior in the store."""
|
||||||
|
|
||||||
|
refresh_on_read: bool
|
||||||
|
"""Default behavior for refreshing TTLs on read operations (`GET` and `SEARCH`).
|
||||||
|
|
||||||
|
If `True`, TTLs will be refreshed on read operations (get/search) by default.
|
||||||
|
This can be overridden per-operation by explicitly setting `refresh_ttl`.
|
||||||
|
Defaults to `True` if not configured.
|
||||||
|
"""
|
||||||
|
default_ttl: float | None
|
||||||
|
"""Optional. Default TTL (time-to-live) in minutes for new items.
|
||||||
|
|
||||||
|
If provided, all new items will have this TTL unless explicitly overridden.
|
||||||
|
If omitted, items will have no TTL by default.
|
||||||
|
"""
|
||||||
|
sweep_interval_minutes: int | None
|
||||||
|
"""Optional. Interval in minutes between TTL sweep iterations.
|
||||||
|
|
||||||
|
If provided, the store will periodically delete expired items based on the TTL.
|
||||||
|
If omitted, no automatic sweeping will occur.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class IndexConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for indexing documents for semantic search in the store.
|
||||||
|
|
||||||
|
This governs how text is converted into embeddings and stored for vector-based lookups.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dims: int
|
||||||
|
"""Required. Dimensionality of the embedding vectors you will store.
|
||||||
|
|
||||||
|
Must match the output dimension of your selected embedding model or custom embed function.
|
||||||
|
If mismatched, you will likely encounter shape/size errors when inserting or querying vectors.
|
||||||
|
|
||||||
|
Common embedding model output dimensions:
|
||||||
|
- openai:text-embedding-3-large: 3072
|
||||||
|
- openai:text-embedding-3-small: 1536
|
||||||
|
- openai:text-embedding-ada-002: 1536
|
||||||
|
- cohere:embed-english-v3.0: 1024
|
||||||
|
- cohere:embed-english-light-v3.0: 384
|
||||||
|
- cohere:embed-multilingual-v3.0: 1024
|
||||||
|
- cohere:embed-multilingual-light-v3.0: 384
|
||||||
|
"""
|
||||||
|
|
||||||
|
embed: str
|
||||||
|
"""Required. Identifier or reference to the embedding model or a custom embedding function.
|
||||||
|
|
||||||
|
The format can vary:
|
||||||
|
- "<provider>:<model_name>" for recognized providers (e.g., "openai:text-embedding-3-large")
|
||||||
|
- "path/to/module.py:function_name" for your own local embedding function
|
||||||
|
- "my_custom_embed" if it's a known alias in your system
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "openai:text-embedding-3-large"
|
||||||
|
- "cohere:embed-multilingual-v3.0"
|
||||||
|
- "src/app.py:embeddings"
|
||||||
|
|
||||||
|
Note: Must return embeddings of dimension `dims`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
fields: list[str] | None
|
||||||
|
"""Optional. List of JSON fields to extract before generating embeddings.
|
||||||
|
|
||||||
|
Defaults to ["$"], which means the entire JSON object is embedded as one piece of text.
|
||||||
|
If you provide multiple fields (e.g. ["title", "content"]), each is extracted and embedded separately,
|
||||||
|
often saving token usage if you only care about certain parts of the data.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
fields=["title", "abstract", "author.biography"]
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class StoreConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for the built-in long-term memory store.
|
||||||
|
|
||||||
|
This store can optionally perform semantic search. If you omit `index`,
|
||||||
|
the store will just handle traditional (non-embedded) data without vector lookups.
|
||||||
|
"""
|
||||||
|
|
||||||
|
index: IndexConfig | None
|
||||||
|
"""Optional. Defines the vector-based semantic search configuration.
|
||||||
|
|
||||||
|
If provided, the store will:
|
||||||
|
- Generate embeddings according to `index.embed`
|
||||||
|
- Enforce the embedding dimension given by `index.dims`
|
||||||
|
- Embed only specified JSON fields (if any) from `index.fields`
|
||||||
|
|
||||||
|
If omitted, no vector index is initialized.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ttl: TTLConfig | None
|
||||||
|
"""Optional. Defines the TTL (time-to-live) behavior configuration.
|
||||||
|
|
||||||
|
If provided, the store will apply TTL settings according to the configuration.
|
||||||
|
If omitted, no TTL behavior is configured.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadTTLConfig(TypedDict, total=False):
|
||||||
|
"""Configure a default TTL for checkpointed data within threads."""
|
||||||
|
|
||||||
|
strategy: Literal["delete"]
|
||||||
|
"""Strategy to use for deleting checkpointed data.
|
||||||
|
|
||||||
|
Choices:
|
||||||
|
- "delete": Delete all checkpoints for a thread after TTL expires.
|
||||||
|
"""
|
||||||
|
default_ttl: float | None
|
||||||
|
"""Default TTL (time-to-live) in minutes for checkpointed data."""
|
||||||
|
sweep_interval_minutes: int | None
|
||||||
|
"""Interval in minutes between sweep iterations.
|
||||||
|
If omitted, a default interval will be used (typically ~ 5 minutes)."""
|
||||||
|
|
||||||
|
|
||||||
|
class SerdeConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for the built-in serde, which handles checkpointing of state.
|
||||||
|
|
||||||
|
If omitted, no serde is set up (the object store will still be present, however)."""
|
||||||
|
|
||||||
|
allowed_json_modules: list[list[str]] | bool | None
|
||||||
|
"""Optional. List of allowed python modules to de-serialize custom objects from.
|
||||||
|
|
||||||
|
If provided, only the specified modules will be allowed to be deserialized.
|
||||||
|
If omitted, no modules are allowed, and the object returned will simply be a json object OR
|
||||||
|
a deserialized langchain object.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{...
|
||||||
|
"serde": {
|
||||||
|
"allowed_json_modules": [
|
||||||
|
["my_agent", "my_file", "SomeType"],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
If you set this to True, any module will be allowed to be deserialized.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{...
|
||||||
|
"serde": {
|
||||||
|
"allowed_json_modules": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
pickle_fallback: bool
|
||||||
|
"""Optional. Whether to allow pickling as a fallback for deserialization.
|
||||||
|
|
||||||
|
If True, pickling will be allowed as a fallback for deserialization.
|
||||||
|
If False, pickling will not be allowed as a fallback for deserialization.
|
||||||
|
Defaults to True if not configured."""
|
||||||
|
|
||||||
|
|
||||||
|
class CheckpointerConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for the built-in checkpointer, which handles checkpointing of state.
|
||||||
|
|
||||||
|
If omitted, no checkpointer is set up (the object store will still be present, however).
|
||||||
|
"""
|
||||||
|
|
||||||
|
ttl: ThreadTTLConfig | None
|
||||||
|
"""Optional. Defines the TTL (time-to-live) behavior configuration.
|
||||||
|
|
||||||
|
If provided, the checkpointer will apply TTL settings according to the configuration.
|
||||||
|
If omitted, no TTL behavior is configured.
|
||||||
|
"""
|
||||||
|
serde: SerdeConfig | None
|
||||||
|
"""Optional. Defines the serde configuration.
|
||||||
|
|
||||||
|
If provided, the checkpointer will apply serde settings according to the configuration.
|
||||||
|
If omitted, no serde behavior is configured.
|
||||||
|
|
||||||
|
This configuration requires server version 0.5 or later to take effect.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for OpenAPI security definitions and requirements.
|
||||||
|
|
||||||
|
Useful for specifying global or path-level authentication and authorization flows
|
||||||
|
(e.g., OAuth2, API key headers, etc.).
|
||||||
|
"""
|
||||||
|
|
||||||
|
securitySchemes: dict[str, dict[str, Any]]
|
||||||
|
"""Describe each security scheme recognized by your OpenAPI spec.
|
||||||
|
|
||||||
|
Keys are scheme names (e.g. "OAuth2", "ApiKeyAuth") and values are their definitions.
|
||||||
|
Example:
|
||||||
|
{
|
||||||
|
"OAuth2": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"password": {
|
||||||
|
"tokenUrl": "/token",
|
||||||
|
"scopes": {"read": "Read data", "write": "Write data"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
security: list[dict[str, list[str]]]
|
||||||
|
"""Global security requirements across all endpoints.
|
||||||
|
|
||||||
|
Each element in the list maps a security scheme (e.g. "OAuth2") to a list of scopes (e.g. ["read", "write"]).
|
||||||
|
Example:
|
||||||
|
[
|
||||||
|
{"OAuth2": ["read", "write"]},
|
||||||
|
{"ApiKeyAuth": []}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# path => {method => security}
|
||||||
|
paths: dict[str, dict[str, list[dict[str, list[str]]]]]
|
||||||
|
"""Path-specific security overrides.
|
||||||
|
|
||||||
|
Keys are path templates (e.g., "/items/{item_id}"), mapping to:
|
||||||
|
- Keys that are HTTP methods (e.g., "GET", "POST"),
|
||||||
|
- Values are lists of security definitions (just like `security`) for that method.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{
|
||||||
|
"/private_data": {
|
||||||
|
"GET": [{"OAuth2": ["read"]}],
|
||||||
|
"POST": [{"OAuth2": ["write"]}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class AuthConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for custom authentication logic and how it integrates into the OpenAPI spec."""
|
||||||
|
|
||||||
|
path: str
|
||||||
|
"""Required. Path to an instance of the Auth() class that implements custom authentication.
|
||||||
|
|
||||||
|
Format: "path/to/file.py:my_auth"
|
||||||
|
"""
|
||||||
|
disable_studio_auth: bool
|
||||||
|
"""Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.
|
||||||
|
|
||||||
|
Defaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header
|
||||||
|
value is a valid API key for the deployment's workspace. If `True`, all requests will go through your custom
|
||||||
|
authentication logic, regardless of origin of the request.
|
||||||
|
"""
|
||||||
|
openapi: SecurityConfig
|
||||||
|
"""The security configuration to include in your server's OpenAPI spec.
|
||||||
|
|
||||||
|
Example (OAuth2):
|
||||||
|
{
|
||||||
|
"securitySchemes": {
|
||||||
|
"OAuth2": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"flows": {
|
||||||
|
"password": {
|
||||||
|
"tokenUrl": "/token",
|
||||||
|
"scopes": {"me": "Read user info", "items": "Manage items"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{"OAuth2": ["me"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class CorsConfig(TypedDict, total=False):
|
||||||
|
"""Specifies Cross-Origin Resource Sharing (CORS) rules for your server.
|
||||||
|
|
||||||
|
If omitted, defaults are typically very restrictive (often no cross-origin requests).
|
||||||
|
Configure carefully if you want to allow usage from browsers hosted on other domains.
|
||||||
|
"""
|
||||||
|
|
||||||
|
allow_origins: list[str]
|
||||||
|
"""Optional. List of allowed origins (e.g., "https://example.com").
|
||||||
|
|
||||||
|
Default is often an empty list (no external origins).
|
||||||
|
Use "*" only if you trust all origins, as that bypasses most restrictions.
|
||||||
|
"""
|
||||||
|
allow_methods: list[str]
|
||||||
|
"""Optional. HTTP methods permitted for cross-origin requests (e.g. ["GET", "POST"]).
|
||||||
|
|
||||||
|
Default might be ["GET", "POST", "OPTIONS"] depending on your server framework.
|
||||||
|
"""
|
||||||
|
allow_headers: list[str]
|
||||||
|
"""Optional. HTTP headers that can be used in cross-origin requests (e.g. ["Content-Type", "Authorization"])."""
|
||||||
|
allow_credentials: bool
|
||||||
|
"""Optional. If `True`, cross-origin requests can include credentials (cookies, auth headers).
|
||||||
|
|
||||||
|
Default False to avoid accidentally exposing secured endpoints to untrusted sites.
|
||||||
|
"""
|
||||||
|
allow_origin_regex: str
|
||||||
|
"""Optional. A regex pattern for matching allowed origins, used if you have dynamic subdomains.
|
||||||
|
|
||||||
|
Example: "^https://.*\\.mycompany\\.com$"
|
||||||
|
"""
|
||||||
|
expose_headers: list[str]
|
||||||
|
"""Optional. List of headers that browsers are allowed to read from the response in cross-origin contexts."""
|
||||||
|
max_age: int
|
||||||
|
"""Optional. How many seconds the browser may cache preflight responses.
|
||||||
|
|
||||||
|
Default might be 600 (10 minutes). Larger values reduce preflight requests but can cause stale configurations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurableHeaderConfig(TypedDict):
|
||||||
|
"""Customize which headers to include as configurable values in your runs.
|
||||||
|
|
||||||
|
By default, omits x-api-key, x-tenant-id, and x-service-key.
|
||||||
|
|
||||||
|
Exclusions (if provided) take precedence.
|
||||||
|
|
||||||
|
Each value can be a raw string with an optional wildcard.
|
||||||
|
"""
|
||||||
|
|
||||||
|
includes: list[str] | None
|
||||||
|
"""Headers to include (if not also matches against an 'exludes' pattern.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- 'user-agent'
|
||||||
|
- 'x-configurable-*'
|
||||||
|
"""
|
||||||
|
excludes: list[str] | None
|
||||||
|
"""Headers to exclude. Applied before the 'includes' checks.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- 'x-api-key'
|
||||||
|
- '*key*'
|
||||||
|
- '*token*'
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class HttpConfig(TypedDict, total=False):
|
||||||
|
"""Configuration for the built-in HTTP server that powers your deployment's routes and endpoints."""
|
||||||
|
|
||||||
|
app: str
|
||||||
|
"""Optional. Import path to a custom Starlette/FastAPI application to mount.
|
||||||
|
|
||||||
|
Format: "path/to/module.py:app_var"
|
||||||
|
If provided, it can override or extend the default routes.
|
||||||
|
"""
|
||||||
|
disable_assistants: bool
|
||||||
|
"""Optional. If `True`, /assistants routes are removed from the server.
|
||||||
|
|
||||||
|
Default is False (meaning /assistants is enabled).
|
||||||
|
"""
|
||||||
|
disable_threads: bool
|
||||||
|
"""Optional. If `True`, /threads routes are removed.
|
||||||
|
|
||||||
|
Default is False.
|
||||||
|
"""
|
||||||
|
disable_runs: bool
|
||||||
|
"""Optional. If `True`, /runs routes are removed.
|
||||||
|
|
||||||
|
Default is False.
|
||||||
|
"""
|
||||||
|
disable_store: bool
|
||||||
|
"""Optional. If `True`, /store routes are removed, disabling direct store interactions via HTTP.
|
||||||
|
|
||||||
|
Default is False.
|
||||||
|
"""
|
||||||
|
disable_mcp: bool
|
||||||
|
"""Optional. If `True`, /mcp routes are removed, disabling the MCP server.
|
||||||
|
|
||||||
|
Default is False.
|
||||||
|
"""
|
||||||
|
disable_meta: bool
|
||||||
|
"""Optional. Remove meta endpoints.
|
||||||
|
|
||||||
|
Set to True to disable the following endpoints: /openapi.json, /info, /metrics, /docs.
|
||||||
|
This will also make the /ok endpoint skip any DB or other checks, always returning {"ok": True}.
|
||||||
|
|
||||||
|
Default is False.
|
||||||
|
"""
|
||||||
|
cors: CorsConfig | None
|
||||||
|
"""Optional. Defines CORS restrictions. If omitted, no special rules are set and
|
||||||
|
cross-origin behavior depends on default server settings.
|
||||||
|
"""
|
||||||
|
configurable_headers: ConfigurableHeaderConfig | None
|
||||||
|
"""Optional. Defines how headers are treated for a run's configuration.
|
||||||
|
|
||||||
|
You can include or exclude headers as configurable values to condition your
|
||||||
|
agent's behavior or permissions on a request's headers."""
|
||||||
|
logging_headers: ConfigurableHeaderConfig | None
|
||||||
|
"""Optional. Defines which headers are excluded from logging."""
|
||||||
|
middleware_order: MiddlewareOrders | None
|
||||||
|
"""Optional. Defines the order in which to apply server customizations.
|
||||||
|
|
||||||
|
Choices:
|
||||||
|
- "auth_first": Authentication hooks (custom or default) are evaluated
|
||||||
|
before custom middleware.
|
||||||
|
- "middleware_first": Custom middleware is evaluated
|
||||||
|
before authentication hooks (custom or default).
|
||||||
|
|
||||||
|
Default is `middleware_first`.
|
||||||
|
"""
|
||||||
|
enable_custom_route_auth: bool
|
||||||
|
"""Optional. If `True`, authentication is enabled for custom routes,
|
||||||
|
not just the routes that are protected by default.
|
||||||
|
(Routes protected by default include /assistants, /threads, and /runs).
|
||||||
|
|
||||||
|
Default is False. This flag only affects authentication behavior
|
||||||
|
if `app` is provided and contains custom routes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Config(TypedDict, total=False):
|
||||||
|
"""Top-level config for langgraph-cli or similar deployment tooling."""
|
||||||
|
|
||||||
|
python_version: str
|
||||||
|
"""Optional. Python version in 'major.minor' format (e.g. '3.11').
|
||||||
|
Must be at least 3.11 or greater for this deployment to function properly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
node_version: str | None
|
||||||
|
"""Optional. Node.js version as a major version (e.g. '20'), if your deployment needs Node.
|
||||||
|
Must be >= 20 if provided.
|
||||||
|
"""
|
||||||
|
|
||||||
|
api_version: str | None
|
||||||
|
"""Optional. Which semantic version of the LangGraph API server to use.
|
||||||
|
|
||||||
|
Defaults to latest. Check the
|
||||||
|
[changelog](https://docs.langchain.com/langgraph-platform/langgraph-server-changelog)
|
||||||
|
for more information."""
|
||||||
|
|
||||||
|
_INTERNAL_docker_tag: str | None
|
||||||
|
"""Optional. Internal use only.
|
||||||
|
"""
|
||||||
|
|
||||||
|
base_image: str | None
|
||||||
|
"""Optional. Base image to use for the LangGraph API server.
|
||||||
|
|
||||||
|
Defaults to langchain/langgraph-api or langchain/langgraphjs-api."""
|
||||||
|
|
||||||
|
image_distro: Distros | None
|
||||||
|
"""Optional. Linux distribution for the base image.
|
||||||
|
|
||||||
|
Must be one of 'wolfi', 'debian', 'bullseye', or 'bookworm'.
|
||||||
|
If omitted, defaults to 'debian' ('latest').
|
||||||
|
"""
|
||||||
|
|
||||||
|
pip_config_file: str | None
|
||||||
|
"""Optional. Path to a pip config file (e.g., "/etc/pip.conf" or "pip.ini") for controlling
|
||||||
|
package installation (custom indices, credentials, etc.).
|
||||||
|
|
||||||
|
Only relevant if Python dependencies are installed via pip. If omitted, default pip settings are used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pip_installer: str | None
|
||||||
|
"""Optional. Python package installer to use ('auto', 'pip', 'uv').
|
||||||
|
|
||||||
|
- 'auto' (default): Use uv for supported base images, otherwise pip
|
||||||
|
- 'pip': Force use of pip regardless of base image support
|
||||||
|
- 'uv': Force use of uv (will fail if base image doesn't support it)
|
||||||
|
"""
|
||||||
|
|
||||||
|
dockerfile_lines: list[str]
|
||||||
|
"""Optional. Additional Docker instructions that will be appended to your base Dockerfile.
|
||||||
|
|
||||||
|
Useful for installing OS packages, setting environment variables, etc.
|
||||||
|
Example:
|
||||||
|
dockerfile_lines=[
|
||||||
|
"RUN apt-get update && apt-get install -y libmagic-dev",
|
||||||
|
"ENV MY_CUSTOM_VAR=hello_world"
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
|
||||||
|
dependencies: list[str]
|
||||||
|
"""List of Python dependencies to install, either from PyPI or local paths.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "." or "./src" if you have a local Python package
|
||||||
|
- str (aka "anthropic") for a PyPI package
|
||||||
|
- "git+https://github.com/org/repo.git@main" for a Git-based package
|
||||||
|
Defaults to an empty list, meaning no additional packages installed beyond your base environment.
|
||||||
|
"""
|
||||||
|
|
||||||
|
graphs: dict[str, str]
|
||||||
|
"""Optional. Named definitions of graphs, each pointing to a Python object.
|
||||||
|
|
||||||
|
|
||||||
|
Graphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context
|
||||||
|
managers that accept a single configuration argument (of type RunnableConfig) and return a pregel object
|
||||||
|
(instance of Stategraph, etc.).
|
||||||
|
|
||||||
|
Keys are graph names, values are "path/to/file.py:object_name".
|
||||||
|
Example:
|
||||||
|
{
|
||||||
|
"mygraph": "graphs/my_graph.py:graph_definition",
|
||||||
|
"anothergraph": "graphs/another.py:get_graph"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
env: dict[str, str] | str
|
||||||
|
"""Optional. Environment variables to set for your deployment.
|
||||||
|
|
||||||
|
- If given as a dict, keys are variable names and values are their values.
|
||||||
|
- If given as a string, it must be a path to a file containing lines in KEY=VALUE format.
|
||||||
|
|
||||||
|
Example as a dict:
|
||||||
|
env={"API_TOKEN": "abc123", "DEBUG": "true"}
|
||||||
|
Example as a file path:
|
||||||
|
env=".env"
|
||||||
|
"""
|
||||||
|
|
||||||
|
store: StoreConfig | None
|
||||||
|
"""Optional. Configuration for the built-in long-term memory store, including semantic search indexing.
|
||||||
|
|
||||||
|
If omitted, no vector index is set up (the object store will still be present, however).
|
||||||
|
"""
|
||||||
|
|
||||||
|
checkpointer: CheckpointerConfig | None
|
||||||
|
"""Optional. Configuration for the built-in checkpointer, which handles checkpointing of state.
|
||||||
|
|
||||||
|
If omitted, no checkpointer is set up (the object store will still be present, however).
|
||||||
|
"""
|
||||||
|
|
||||||
|
auth: AuthConfig | None
|
||||||
|
"""Optional. Custom authentication config, including the path to your Python auth logic and
|
||||||
|
the OpenAPI security definitions it uses.
|
||||||
|
"""
|
||||||
|
|
||||||
|
http: HttpConfig | None
|
||||||
|
"""Optional. Configuration for the built-in HTTP server, controlling which custom routes are exposed
|
||||||
|
and how cross-origin requests are handled.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ui: dict[str, str] | None
|
||||||
|
"""Optional. Named definitions of UI components emitted by the agent, each pointing to a JS/TS file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
keep_pkg_tools: bool | list[str] | None
|
||||||
|
"""Optional. Control whether to retain Python packaging tools in the final image.
|
||||||
|
|
||||||
|
Allowed tools are: "pip", "setuptools", "wheel".
|
||||||
|
You can also set to true to include all packaging tools.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Config",
|
||||||
|
"StoreConfig",
|
||||||
|
"CheckpointerConfig",
|
||||||
|
"AuthConfig",
|
||||||
|
"HttpConfig",
|
||||||
|
"MiddlewareOrders",
|
||||||
|
"Distros",
|
||||||
|
"TTLConfig",
|
||||||
|
"IndexConfig",
|
||||||
|
]
|
||||||
@@ -2,7 +2,6 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional
|
|
||||||
from urllib import error, request
|
from urllib import error, request
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ def _choose_template() -> str:
|
|||||||
click.secho(f" - {template_info['description']}", fg="white")
|
click.secho(f" - {template_info['description']}", fg="white")
|
||||||
|
|
||||||
# Get the template choice from the user, defaulting to the first template if blank
|
# Get the template choice from the user, defaulting to the first template if blank
|
||||||
template_choice: Optional[int] = click.prompt(
|
template_choice: int | None = click.prompt(
|
||||||
"Enter the number of your template choice (default is 1)",
|
"Enter the number of your template choice (default is 1)",
|
||||||
type=int,
|
type=int,
|
||||||
default=1,
|
default=1,
|
||||||
@@ -131,7 +130,7 @@ def _download_repo_with_requests(repo_url: str, path: str) -> None:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def _get_template_url(template_name: str) -> Optional[str]:
|
def _get_template_url(template_name: str) -> str | None:
|
||||||
"""
|
"""
|
||||||
Retrieves the template URL based on the provided template name.
|
Retrieves the template URL based on the provided template name.
|
||||||
|
|
||||||
@@ -162,7 +161,7 @@ def _get_template_url(template_name: str) -> Optional[str]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def create_new(path: Optional[str], template: Optional[str]) -> None:
|
def create_new(path: str | None, template: str | None) -> None:
|
||||||
"""Create a new LangGraph project at the specified PATH using the chosen TEMPLATE.
|
"""Create a new LangGraph project at the specified PATH using the chosen TEMPLATE.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
+14
-6
@@ -7,7 +7,7 @@ name = "langgraph-cli"
|
|||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
description = "CLI for interacting with LangGraph API"
|
description = "CLI for interacting with LangGraph API"
|
||||||
authors = []
|
authors = []
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
license-files = ['LICENSE']
|
license-files = ['LICENSE']
|
||||||
@@ -19,7 +19,7 @@ dependencies = [
|
|||||||
path = "langgraph_cli/__init__.py"
|
path = "langgraph_cli/__init__.py"
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
inmem = [
|
inmem = [
|
||||||
"langgraph-api>=0.3,<0.5.0 ; python_version >= '3.11'",
|
"langgraph-api>=0.4,<0.6.0 ; python_version >= '3.11'",
|
||||||
"langgraph-runtime-inmem>=0.7 ; python_version >= '3.11'",
|
"langgraph-runtime-inmem>=0.7 ; python_version >= '3.11'",
|
||||||
"python-dotenv>=0.8.0",
|
"python-dotenv>=0.8.0",
|
||||||
]
|
]
|
||||||
@@ -31,16 +31,22 @@ Repository = "https://www.github.com/langchain-ai/langgraph"
|
|||||||
langgraph = "langgraph_cli.cli:cli"
|
langgraph = "langgraph_cli.cli:cli"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
test = [
|
||||||
"ruff",
|
|
||||||
"codespell",
|
|
||||||
"pytest",
|
"pytest",
|
||||||
"pytest-asyncio",
|
"pytest-asyncio",
|
||||||
"pytest-mock",
|
"pytest-mock",
|
||||||
"pytest-watch",
|
"pytest-watch",
|
||||||
"mypy",
|
|
||||||
"msgspec",
|
"msgspec",
|
||||||
]
|
]
|
||||||
|
lint = [
|
||||||
|
"ruff",
|
||||||
|
"codespell",
|
||||||
|
"mypy",
|
||||||
|
]
|
||||||
|
dev = [
|
||||||
|
{include-group = "test"},
|
||||||
|
{include-group = "lint"},
|
||||||
|
]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
default-groups = ['dev']
|
default-groups = ['dev']
|
||||||
@@ -59,5 +65,7 @@ lint.select = [
|
|||||||
"UP", # pyupgrade
|
"UP", # pyupgrade
|
||||||
"B", # flake8-bugbear
|
"B", # flake8-bugbear
|
||||||
"I", # isort
|
"I", # isort
|
||||||
|
"UP", # pyupgrade
|
||||||
]
|
]
|
||||||
lint.ignore = ["E501", "B008"]
|
lint.ignore = ["E501", "B008"]
|
||||||
|
target-version = "py310"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ authors = [
|
|||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
requires-python = ">=3.11,<4.0"
|
requires-python = ">=3.11,<4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"langgraph>=0.6.0,<0.7.0",
|
"langgraph>=0.6.0,<2",
|
||||||
"langchain-core>=0.2.14",
|
"langchain-core>=0.2.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -407,11 +407,11 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"disable_studio_auth": {
|
"disable_studio_auth": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.\n\nDefaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header\nvalue is a valid API key for the deployment's workspace. If True, all requests will go through your custom\nauthentication logic, regardless of origin of the request.\n"
|
"description": "Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.\n\nDefaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header\nvalue is a valid API key for the deployment's workspace. If `True`, all requests will go through your custom\nauthentication logic, regardless of origin of the request.\n"
|
||||||
},
|
},
|
||||||
"openapi": {
|
"openapi": {
|
||||||
"$ref": "#/$defs/SecurityConfig",
|
"$ref": "#/$defs/SecurityConfig",
|
||||||
"description": "Required. Detailed security configuration that merges into your deployment's OpenAPI spec.\n\n{\n}\n}\n}\n},\n]\n}\n"
|
"description": "The security configuration to include in your server's OpenAPI spec.\n\n{\n}\n}\n}\n},\n]\n}\n"
|
||||||
},
|
},
|
||||||
"path": {
|
"path": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -442,7 +442,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": "Optional. Path-specific security overrides.\n\n- Keys that are HTTP methods (e.g., \"GET\", \"POST\"),\n- Values are lists of security definitions (just like `security`) for that method.\n"
|
"description": "Path-specific security overrides.\n\n- Keys that are HTTP methods (e.g., \"GET\", \"POST\"),\n- Values are lists of security definitions (just like `security`) for that method.\n"
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -455,14 +455,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": "Optional. Global security requirements across all endpoints.\n\nEach element in the list maps a security scheme (e.g. \"OAuth2\") to a list of scopes (e.g. [\"read\", \"write\"])."
|
"description": "Global security requirements across all endpoints.\n\nEach element in the list maps a security scheme (e.g. \"OAuth2\") to a list of scopes (e.g. [\"read\", \"write\"])."
|
||||||
},
|
},
|
||||||
"securitySchemes": {
|
"securitySchemes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"description": "Required. Dict describing each security scheme recognized by your OpenAPI spec.\n\nKeys are scheme names (e.g. \"OAuth2\", \"ApiKeyAuth\") and values are their definitions."
|
"description": "Describe each security scheme recognized by your OpenAPI spec.\n\nKeys are scheme names (e.g. \"OAuth2\", \"ApiKeyAuth\") and values are their definitions."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
@@ -472,6 +472,17 @@
|
|||||||
"description": "Configuration for the built-in checkpointer, which handles checkpointing of state.\n\nIf omitted, no checkpointer is set up (the object store will still be present, however).",
|
"description": "Configuration for the built-in checkpointer, which handles checkpointing of state.\n\nIf omitted, no checkpointer is set up (the object store will still be present, however).",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"serde": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/SerdeConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Optional. Defines the serde configuration.\n\nIf provided, the checkpointer will apply serde settings according to the configuration.\nIf omitted, no serde behavior is configured.\n\nThis configuration requires server version 0.5 or later to take effect.\n"
|
||||||
|
},
|
||||||
"ttl": {
|
"ttl": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
@@ -486,6 +497,38 @@
|
|||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
},
|
},
|
||||||
|
"SerdeConfig": {
|
||||||
|
"title": "SerdeConfig",
|
||||||
|
"description": "Configuration for the built-in serde, which handles checkpointing of state.\n\nIf omitted, no serde is set up (the object store will still be present, however).",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"allowed_json_modules": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Optional. List of allowed python modules to de-serialize custom objects from.\n\nIf provided, only the specified modules will be allowed to be deserialized.\nIf omitted, no modules are allowed, and the object returned will simply be a json object OR\na deserialized langchain object.\n"
|
||||||
|
},
|
||||||
|
"pickle_fallback": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Optional. Whether to allow pickling as a fallback for deserialization.\n\nIf True, pickling will be allowed as a fallback for deserialization.\nIf False, pickling will not be allowed as a fallback for deserialization.\nDefaults to True if not configured."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
"ThreadTTLConfig": {
|
"ThreadTTLConfig": {
|
||||||
"title": "ThreadTTLConfig",
|
"title": "ThreadTTLConfig",
|
||||||
"description": "Configure a default TTL for checkpointed data within threads.",
|
"description": "Configure a default TTL for checkpointed data within threads.",
|
||||||
@@ -555,11 +598,11 @@
|
|||||||
},
|
},
|
||||||
"disable_assistants": {
|
"disable_assistants": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /assistants routes are removed from the server.\n\nDefault is False (meaning /assistants is enabled).\n"
|
"description": "Optional. If `True`, /assistants routes are removed from the server.\n\nDefault is False (meaning /assistants is enabled).\n"
|
||||||
},
|
},
|
||||||
"disable_mcp": {
|
"disable_mcp": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /mcp routes are removed, disabling the MCP server.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /mcp routes are removed, disabling the MCP server.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_meta": {
|
"disable_meta": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -567,19 +610,19 @@
|
|||||||
},
|
},
|
||||||
"disable_runs": {
|
"disable_runs": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /runs routes are removed.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /runs routes are removed.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_store": {
|
"disable_store": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /store routes are removed, disabling direct store interactions via HTTP.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /store routes are removed, disabling direct store interactions via HTTP.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_threads": {
|
"disable_threads": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /threads routes are removed.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /threads routes are removed.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"enable_custom_route_auth": {
|
"enable_custom_route_auth": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, authentication is enabled for custom routes,\nnot just the routes that are protected by default.\n(Routes protected by default include /assistants, /threads, and /runs).\n\nDefault is False. This flag only affects authentication behavior\nif `app` is provided and contains custom routes.\n"
|
"description": "Optional. If `True`, authentication is enabled for custom routes,\nnot just the routes that are protected by default.\n(Routes protected by default include /assistants, /threads, and /runs).\n\nDefault is False. This flag only affects authentication behavior\nif `app` is provided and contains custom routes.\n"
|
||||||
},
|
},
|
||||||
"logging_headers": {
|
"logging_headers": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@@ -655,7 +698,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow_credentials": {
|
"allow_credentials": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, cross-origin requests can include credentials (cookies, auth headers).\n\nDefault False to avoid accidentally exposing secured endpoints to untrusted sites.\n"
|
"description": "Optional. If `True`, cross-origin requests can include credentials (cookies, auth headers).\n\nDefault False to avoid accidentally exposing secured endpoints to untrusted sites.\n"
|
||||||
},
|
},
|
||||||
"allow_headers": {
|
"allow_headers": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -774,7 +817,7 @@
|
|||||||
},
|
},
|
||||||
"refresh_on_read": {
|
"refresh_on_read": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Default behavior for refreshing TTLs on read operations (GET and SEARCH).\n\nIf True, TTLs will be refreshed on read operations (get/search) by default.\nThis can be overridden per-operation by explicitly setting refresh_ttl.\nDefaults to True if not configured.\n"
|
"description": "Default behavior for refreshing TTLs on read operations (`GET` and `SEARCH`).\n\nIf `True`, TTLs will be refreshed on read operations (get/search) by default.\nThis can be overridden per-operation by explicitly setting `refresh_ttl`.\nDefaults to `True` if not configured.\n"
|
||||||
},
|
},
|
||||||
"sweep_interval_minutes": {
|
"sweep_interval_minutes": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|||||||
@@ -407,11 +407,11 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"disable_studio_auth": {
|
"disable_studio_auth": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.\n\nDefaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header\nvalue is a valid API key for the deployment's workspace. If True, all requests will go through your custom\nauthentication logic, regardless of origin of the request.\n"
|
"description": "Optional. Whether to disable LangSmith API-key authentication for requests originating the Studio.\n\nDefaults to False, meaning that if a particular header is set, the server will verify the `x-api-key` header\nvalue is a valid API key for the deployment's workspace. If `True`, all requests will go through your custom\nauthentication logic, regardless of origin of the request.\n"
|
||||||
},
|
},
|
||||||
"openapi": {
|
"openapi": {
|
||||||
"$ref": "#/$defs/SecurityConfig",
|
"$ref": "#/$defs/SecurityConfig",
|
||||||
"description": "Required. Detailed security configuration that merges into your deployment's OpenAPI spec.\n\n{\n}\n}\n}\n},\n]\n}\n"
|
"description": "The security configuration to include in your server's OpenAPI spec.\n\n{\n}\n}\n}\n},\n]\n}\n"
|
||||||
},
|
},
|
||||||
"path": {
|
"path": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -442,7 +442,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": "Optional. Path-specific security overrides.\n\n- Keys that are HTTP methods (e.g., \"GET\", \"POST\"),\n- Values are lists of security definitions (just like `security`) for that method.\n"
|
"description": "Path-specific security overrides.\n\n- Keys that are HTTP methods (e.g., \"GET\", \"POST\"),\n- Values are lists of security definitions (just like `security`) for that method.\n"
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -455,14 +455,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": "Optional. Global security requirements across all endpoints.\n\nEach element in the list maps a security scheme (e.g. \"OAuth2\") to a list of scopes (e.g. [\"read\", \"write\"])."
|
"description": "Global security requirements across all endpoints.\n\nEach element in the list maps a security scheme (e.g. \"OAuth2\") to a list of scopes (e.g. [\"read\", \"write\"])."
|
||||||
},
|
},
|
||||||
"securitySchemes": {
|
"securitySchemes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"description": "Required. Dict describing each security scheme recognized by your OpenAPI spec.\n\nKeys are scheme names (e.g. \"OAuth2\", \"ApiKeyAuth\") and values are their definitions."
|
"description": "Describe each security scheme recognized by your OpenAPI spec.\n\nKeys are scheme names (e.g. \"OAuth2\", \"ApiKeyAuth\") and values are their definitions."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
@@ -472,6 +472,17 @@
|
|||||||
"description": "Configuration for the built-in checkpointer, which handles checkpointing of state.\n\nIf omitted, no checkpointer is set up (the object store will still be present, however).",
|
"description": "Configuration for the built-in checkpointer, which handles checkpointing of state.\n\nIf omitted, no checkpointer is set up (the object store will still be present, however).",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"serde": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/SerdeConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Optional. Defines the serde configuration.\n\nIf provided, the checkpointer will apply serde settings according to the configuration.\nIf omitted, no serde behavior is configured.\n\nThis configuration requires server version 0.5 or later to take effect.\n"
|
||||||
|
},
|
||||||
"ttl": {
|
"ttl": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
@@ -486,6 +497,38 @@
|
|||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
},
|
},
|
||||||
|
"SerdeConfig": {
|
||||||
|
"title": "SerdeConfig",
|
||||||
|
"description": "Configuration for the built-in serde, which handles checkpointing of state.\n\nIf omitted, no serde is set up (the object store will still be present, however).",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"allowed_json_modules": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Optional. List of allowed python modules to de-serialize custom objects from.\n\nIf provided, only the specified modules will be allowed to be deserialized.\nIf omitted, no modules are allowed, and the object returned will simply be a json object OR\na deserialized langchain object.\n"
|
||||||
|
},
|
||||||
|
"pickle_fallback": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Optional. Whether to allow pickling as a fallback for deserialization.\n\nIf True, pickling will be allowed as a fallback for deserialization.\nIf False, pickling will not be allowed as a fallback for deserialization.\nDefaults to True if not configured."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
"ThreadTTLConfig": {
|
"ThreadTTLConfig": {
|
||||||
"title": "ThreadTTLConfig",
|
"title": "ThreadTTLConfig",
|
||||||
"description": "Configure a default TTL for checkpointed data within threads.",
|
"description": "Configure a default TTL for checkpointed data within threads.",
|
||||||
@@ -555,11 +598,11 @@
|
|||||||
},
|
},
|
||||||
"disable_assistants": {
|
"disable_assistants": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /assistants routes are removed from the server.\n\nDefault is False (meaning /assistants is enabled).\n"
|
"description": "Optional. If `True`, /assistants routes are removed from the server.\n\nDefault is False (meaning /assistants is enabled).\n"
|
||||||
},
|
},
|
||||||
"disable_mcp": {
|
"disable_mcp": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /mcp routes are removed, disabling the MCP server.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /mcp routes are removed, disabling the MCP server.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_meta": {
|
"disable_meta": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -567,19 +610,19 @@
|
|||||||
},
|
},
|
||||||
"disable_runs": {
|
"disable_runs": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /runs routes are removed.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /runs routes are removed.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_store": {
|
"disable_store": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /store routes are removed, disabling direct store interactions via HTTP.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /store routes are removed, disabling direct store interactions via HTTP.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"disable_threads": {
|
"disable_threads": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, /threads routes are removed.\n\nDefault is False.\n"
|
"description": "Optional. If `True`, /threads routes are removed.\n\nDefault is False.\n"
|
||||||
},
|
},
|
||||||
"enable_custom_route_auth": {
|
"enable_custom_route_auth": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, authentication is enabled for custom routes,\nnot just the routes that are protected by default.\n(Routes protected by default include /assistants, /threads, and /runs).\n\nDefault is False. This flag only affects authentication behavior\nif `app` is provided and contains custom routes.\n"
|
"description": "Optional. If `True`, authentication is enabled for custom routes,\nnot just the routes that are protected by default.\n(Routes protected by default include /assistants, /threads, and /runs).\n\nDefault is False. This flag only affects authentication behavior\nif `app` is provided and contains custom routes.\n"
|
||||||
},
|
},
|
||||||
"logging_headers": {
|
"logging_headers": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@@ -655,7 +698,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"allow_credentials": {
|
"allow_credentials": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Optional. If True, cross-origin requests can include credentials (cookies, auth headers).\n\nDefault False to avoid accidentally exposing secured endpoints to untrusted sites.\n"
|
"description": "Optional. If `True`, cross-origin requests can include credentials (cookies, auth headers).\n\nDefault False to avoid accidentally exposing secured endpoints to untrusted sites.\n"
|
||||||
},
|
},
|
||||||
"allow_headers": {
|
"allow_headers": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -774,7 +817,7 @@
|
|||||||
},
|
},
|
||||||
"refresh_on_read": {
|
"refresh_on_read": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Default behavior for refreshing TTLs on read operations (GET and SEARCH).\n\nIf True, TTLs will be refreshed on read operations (get/search) by default.\nThis can be overridden per-operation by explicitly setting refresh_ttl.\nDefaults to True if not configured.\n"
|
"description": "Default behavior for refreshing TTLs on read operations (`GET` and `SEARCH`).\n\nIf `True`, TTLs will be refreshed on read operations (get/search) by default.\nThis can be overridden per-operation by explicitly setting `refresh_ttl`.\nDefaults to `True` if not configured.\n"
|
||||||
},
|
},
|
||||||
"sweep_interval_minutes": {
|
"sweep_interval_minutes": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ services:
|
|||||||
additional_contexts:
|
additional_contexts:
|
||||||
- cli_1: {str(pathlib.Path(__file__).parent.parent.parent.parent.absolute())}
|
- cli_1: {str(pathlib.Path(__file__).parent.parent.parent.parent.absolute())}
|
||||||
dockerfile_inline: |
|
dockerfile_inline: |
|
||||||
|
# syntax=docker/dockerfile:1.4
|
||||||
FROM langchain/langgraph-api:3.11
|
FROM langchain/langgraph-api:3.11
|
||||||
# -- Adding local package . --
|
# -- Adding local package . --
|
||||||
ADD . /deps/cli
|
ADD . /deps/cli
|
||||||
@@ -149,7 +150,7 @@ services:
|
|||||||
COPY --from=cli_1 . /deps/cli_1
|
COPY --from=cli_1 . /deps/cli_1
|
||||||
# -- End of local package ../../.. --
|
# -- End of local package ../../.. --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ def test_config_to_docker_simple():
|
|||||||
"langchain/langgraph-api",
|
"langchain/langgraph-api",
|
||||||
)
|
)
|
||||||
expected_docker_stdin = f"""\
|
expected_docker_stdin = f"""\
|
||||||
|
# syntax=docker/dockerfile:1.4
|
||||||
FROM langchain/langgraph-api:3.11
|
FROM langchain/langgraph-api:3.11
|
||||||
# -- Installing local requirements --
|
# -- Installing local requirements --
|
||||||
COPY --from=outer-requirements.txt requirements.txt /deps/outer-graphs_reqs_a/graphs_reqs_a/requirements.txt
|
COPY --from=outer-requirements.txt requirements.txt /deps/outer-graphs_reqs_a/graphs_reqs_a/requirements.txt
|
||||||
@@ -456,7 +457,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency graphs_reqs_a --
|
# -- End of non-package dependency graphs_reqs_a --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGGRAPH_HTTP='{{"app": "/deps/examples/my_app.py:app"}}'
|
ENV LANGGRAPH_HTTP='{{"app": "/deps/examples/my_app.py:app"}}'
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
@@ -482,6 +483,7 @@ def test_config_to_docker_outside_path():
|
|||||||
)
|
)
|
||||||
expected_docker_stdin = (
|
expected_docker_stdin = (
|
||||||
"""\
|
"""\
|
||||||
|
# syntax=docker/dockerfile:1.4
|
||||||
FROM langchain/langgraph-api:3.11
|
FROM langchain/langgraph-api:3.11
|
||||||
# -- Adding non-package dependency unit_tests --
|
# -- Adding non-package dependency unit_tests --
|
||||||
ADD . /deps/outer-unit_tests/unit_tests
|
ADD . /deps/outer-unit_tests/unit_tests
|
||||||
@@ -512,7 +514,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency tests --
|
# -- End of non-package dependency tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}'
|
ENV LANGSERVE_GRAPHS='{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}'
|
||||||
"""
|
"""
|
||||||
@@ -559,7 +561,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}'
|
ENV LANGSERVE_GRAPHS='{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}'
|
||||||
"""
|
"""
|
||||||
@@ -621,7 +623,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency graphs --
|
# -- End of non-package dependency graphs --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-graphs/src/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-graphs/src/agent.py:graph"}}'
|
||||||
{FORMATTED_CLEANUP_LINES}\
|
{FORMATTED_CLEANUP_LINES}\
|
||||||
@@ -657,7 +659,7 @@ dependencies = ["langchain"]"""
|
|||||||
ADD . /deps/unit_tests
|
ADD . /deps/unit_tests
|
||||||
# -- End of local package . --
|
# -- End of local package . --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{"agent": "/deps/unit_tests/graphs/agent.py:graph"}'
|
ENV LANGSERVE_GRAPHS='{"agent": "/deps/unit_tests/graphs/agent.py:graph"}'
|
||||||
"""
|
"""
|
||||||
@@ -705,7 +707,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency graphs --
|
# -- End of non-package dependency graphs --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-graphs/src/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-graphs/src/agent.py:graph"}}'
|
||||||
{FORMATTED_CLEANUP_LINES}"""
|
{FORMATTED_CLEANUP_LINES}"""
|
||||||
@@ -713,7 +715,7 @@ ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-graphs/src/agent.py:graph"}}'
|
|||||||
assert additional_contexts == {}
|
assert additional_contexts == {}
|
||||||
|
|
||||||
|
|
||||||
# node.js build used for LangGraph Platform
|
# node.js build used for LangSmith Deployment
|
||||||
def test_config_to_docker_nodejs():
|
def test_config_to_docker_nodejs():
|
||||||
graphs = {"agent": "./graphs/agent.js:graph"}
|
graphs = {"agent": "./graphs/agent.js:graph"}
|
||||||
actual_docker_stdin, additional_contexts = config_to_docker(
|
actual_docker_stdin, additional_contexts = config_to_docker(
|
||||||
@@ -811,7 +813,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGGRAPH_UI='{{"agent": "./graphs/agent.ui.jsx"}}'
|
ENV LANGGRAPH_UI='{{"agent": "./graphs/agent.ui.jsx"}}'
|
||||||
ENV LANGGRAPH_UI_CONFIG='{{"shared": ["nuqs"]}}'
|
ENV LANGGRAPH_UI_CONFIG='{{"shared": ["nuqs"]}}'
|
||||||
@@ -857,7 +859,7 @@ RUN set -ex && \\
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"python": "/deps/outer-unit_tests/unit_tests/multiplatform/python.py:graph", "js": "/deps/outer-unit_tests/unit_tests/multiplatform/js.mts:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"python": "/deps/outer-unit_tests/unit_tests/multiplatform/python.py:graph", "js": "/deps/outer-unit_tests/unit_tests/multiplatform/js.mts:graph"}}'
|
||||||
# -- Installing JS dependencies --
|
# -- Installing JS dependencies --
|
||||||
@@ -998,7 +1000,7 @@ def test_config_to_compose_simple_config():
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
@@ -1039,7 +1041,7 @@ def test_config_to_compose_env_vars():
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
@@ -1084,7 +1086,7 @@ def test_config_to_compose_env_file():
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
@@ -1122,7 +1124,7 @@ def test_config_to_compose_watch():
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
@@ -1169,7 +1171,7 @@ def test_config_to_compose_end_to_end():
|
|||||||
done
|
done
|
||||||
# -- End of non-package dependency unit_tests --
|
# -- End of non-package dependency unit_tests --
|
||||||
# -- Installing all local dependencies --
|
# -- Installing all local dependencies --
|
||||||
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt .); fi; done
|
RUN for dep in /deps/*; do echo "Installing $dep"; if [ -d "$dep" ]; then echo "Installing $dep"; (cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .); fi; done
|
||||||
# -- End of local dependencies install --
|
# -- End of local dependencies install --
|
||||||
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
ENV LANGSERVE_GRAPHS='{{"agent": "/deps/outer-unit_tests/unit_tests/agent.py:graph"}}'
|
||||||
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")}
|
||||||
|
|||||||
Generated
+842
-765
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,10 @@
|
|||||||
"Bash(sed:*)",
|
"Bash(sed:*)",
|
||||||
"Bash(awk:*)",
|
"Bash(awk:*)",
|
||||||
"Bash(uv run mypy:*)",
|
"Bash(uv run mypy:*)",
|
||||||
"Bash(uv run:*)"
|
"Bash(uv run:*)",
|
||||||
|
"Bash(make test:*)",
|
||||||
|
"Bash(make test_parallel:*)"
|
||||||
],
|
],
|
||||||
"deny": []
|
"deny": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ test:
|
|||||||
test_parallel:
|
test_parallel:
|
||||||
make start-services &&\
|
make start-services &&\
|
||||||
make start-dev-server &&\
|
make start-dev-server &&\
|
||||||
uv run pytest -n auto --dist worksteal $(TEST) --lf --snapshot-update; \
|
uv run pytest -n auto --dist worksteal $(TEST) -vv --lf; \
|
||||||
EXIT_CODE=$$?; \
|
EXIT_CODE=$$?; \
|
||||||
make stop-services; \
|
make stop-services; \
|
||||||
make stop-dev-server; \
|
make stop-dev-server; \
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ LangGraph provides low-level supporting infrastructure for *any* long-running, s
|
|||||||
While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. To improve your LLM application development, pair LangGraph with:
|
While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. To improve your LLM application development, pair LangGraph with:
|
||||||
|
|
||||||
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
- [LangSmith](http://www.langchain.com/langsmith) — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
||||||
- [LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
- [LangSmith Deployment](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||||
- [LangChain](https://python.langchain.com/docs/introduction/) – Provides integrations and composable components to streamline LLM application development.
|
- [LangChain](https://docs.langchain.com/oss/python/langchain/overview) – Provides integrations and composable components to streamline LLM application development.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
> Looking for the JS version of LangGraph? See the [JS repo](https://github.com/langchain-ai/langgraphjs) and the [JS docs](https://langchain-ai.github.io/langgraphjs/).
|
||||||
@@ -81,4 +81,4 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
|
|||||||
|
|
||||||
## Acknowledgements
|
## 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.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import operator
|
|||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from random import choice
|
from random import choice
|
||||||
from typing import Annotated, Optional
|
from typing import Annotated
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
raise TypeError("primary_issue_medium must be a string")
|
raise TypeError("primary_issue_medium must be a string")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
autoresponse: Annotated[Optional[dict], lambda _, y: y] = Field(
|
autoresponse: Annotated[dict | None, lambda _, y: y] = Field(
|
||||||
default=None
|
default=None
|
||||||
) # Always overwrite
|
) # Always overwrite
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
raise TypeError("issue must be a dict or None")
|
raise TypeError("issue must be a dict or None")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
relevant_rules: Optional[list[dict]] = Field(default=None)
|
relevant_rules: list[dict] | None = Field(default=None)
|
||||||
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
||||||
|
|
||||||
@field_validator("relevant_rules", mode="after")
|
@field_validator("relevant_rules", mode="after")
|
||||||
@@ -94,7 +94,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
)
|
)
|
||||||
return v
|
return v
|
||||||
|
|
||||||
memory_docs: Optional[list[dict]] = Field(default=None)
|
memory_docs: list[dict] | None = Field(default=None)
|
||||||
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
||||||
|
|
||||||
@field_validator("memory_docs", mode="after")
|
@field_validator("memory_docs", mode="after")
|
||||||
@@ -145,7 +145,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
raise TypeError("responses must be a list of dicts with str keys")
|
raise TypeError("responses must be a list of dicts with str keys")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
user_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x] = (
|
user_info: Annotated[dict | None, lambda x, y: y if y is not None else x] = (
|
||||||
Field(default=None)
|
Field(default=None)
|
||||||
)
|
)
|
||||||
"""The current user state (by email)."""
|
"""The current user state (by email)."""
|
||||||
@@ -157,7 +157,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
raise TypeError("user_info must be a dict or None")
|
raise TypeError("user_info must be a dict or None")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
crm_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x] = (
|
crm_info: Annotated[dict | None, lambda x, y: y if y is not None else x] = (
|
||||||
Field(default=None)
|
Field(default=None)
|
||||||
)
|
)
|
||||||
"""The CRM information for organization the current user is from."""
|
"""The CRM information for organization the current user is from."""
|
||||||
@@ -170,7 +170,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
email_thread_id: Annotated[
|
email_thread_id: Annotated[
|
||||||
Optional[str], lambda x, y: y if y is not None else x
|
str | None, lambda x, y: y if y is not None else x
|
||||||
] = Field(default=None)
|
] = Field(default=None)
|
||||||
"""The current email thread ID."""
|
"""The current email thread ID."""
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ def pydantic_state(n: int) -> StateGraph:
|
|||||||
raise TypeError("slack_participants must be a dict with str keys")
|
raise TypeError("slack_participants must be a dict with str keys")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
bot_id: Optional[str] = Field(default=None)
|
bot_id: str | None = Field(default=None)
|
||||||
"""The ID of the bot user in the slack channel."""
|
"""The ID of the bot user in the slack channel."""
|
||||||
|
|
||||||
@field_validator("bot_id", mode="after")
|
@field_validator("bot_id", mode="after")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from langchain_core.callbacks import CallbackManagerForLLMRun
|
from langchain_core.callbacks import CallbackManagerForLLMRun
|
||||||
@@ -14,7 +14,7 @@ from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
|||||||
from langgraph.pregel import Pregel
|
from langgraph.pregel import Pregel
|
||||||
|
|
||||||
|
|
||||||
def react_agent(n_tools: int, checkpointer: Optional[BaseCheckpointSaver]) -> Pregel:
|
def react_agent(n_tools: int, checkpointer: BaseCheckpointSaver | None) -> Pregel:
|
||||||
class FakeFunctionChatModel(FakeMessagesListChatModel):
|
class FakeFunctionChatModel(FakeMessagesListChatModel):
|
||||||
def bind_tools(self, functions: list):
|
def bind_tools(self, functions: list):
|
||||||
return self
|
return self
|
||||||
@@ -22,8 +22,8 @@ def react_agent(n_tools: int, checkpointer: Optional[BaseCheckpointSaver]) -> Pr
|
|||||||
def _generate(
|
def _generate(
|
||||||
self,
|
self,
|
||||||
messages: list[BaseMessage],
|
messages: list[BaseMessage],
|
||||||
stop: Optional[list[str]] = None,
|
stop: list[str] | None = None,
|
||||||
run_manager: Optional[CallbackManagerForLLMRun] = None,
|
run_manager: CallbackManagerForLLMRun | None = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> ChatResult:
|
) -> ChatResult:
|
||||||
response = self.responses[self.i].copy()
|
response = self.responses[self.i].copy()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import operator
|
|||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from random import choice
|
from random import choice
|
||||||
from typing import Annotated, Optional
|
from typing import Annotated
|
||||||
|
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
@@ -16,28 +16,26 @@ def wide_dict(n: int) -> StateGraph:
|
|||||||
trigger_events: Annotated[list, operator.add]
|
trigger_events: Annotated[list, operator.add]
|
||||||
"""The external events that are converted by the graph."""
|
"""The external events that are converted by the graph."""
|
||||||
primary_issue_medium: Annotated[str, lambda x, y: y or x]
|
primary_issue_medium: Annotated[str, lambda x, y: y or x]
|
||||||
autoresponse: Annotated[Optional[dict], lambda _, y: y] # Always overwrite
|
autoresponse: Annotated[dict | None, lambda _, y: y] # Always overwrite
|
||||||
issue: Annotated[dict | None, lambda x, y: y if y else x]
|
issue: Annotated[dict | None, lambda x, y: y if y else x]
|
||||||
relevant_rules: Optional[list[dict]]
|
relevant_rules: list[dict] | None
|
||||||
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
||||||
memory_docs: Optional[list[dict]]
|
memory_docs: list[dict] | None
|
||||||
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
||||||
categorizations: Annotated[list[dict], operator.add]
|
categorizations: Annotated[list[dict], operator.add]
|
||||||
"""The issue categorizations auto-generated by the AI."""
|
"""The issue categorizations auto-generated by the AI."""
|
||||||
responses: Annotated[list[dict], operator.add]
|
responses: Annotated[list[dict], operator.add]
|
||||||
"""The draft responses recommended by the AI."""
|
"""The draft responses recommended by the AI."""
|
||||||
|
|
||||||
user_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x]
|
user_info: Annotated[dict | None, lambda x, y: y if y is not None else x]
|
||||||
"""The current user state (by email)."""
|
"""The current user state (by email)."""
|
||||||
crm_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x]
|
crm_info: Annotated[dict | None, lambda x, y: y if y is not None else x]
|
||||||
"""The CRM information for organization the current user is from."""
|
"""The CRM information for organization the current user is from."""
|
||||||
email_thread_id: Annotated[
|
email_thread_id: Annotated[str | None, lambda x, y: y if y is not None else x]
|
||||||
Optional[str], lambda x, y: y if y is not None else x
|
|
||||||
]
|
|
||||||
"""The current email thread ID."""
|
"""The current email thread ID."""
|
||||||
slack_participants: Annotated[dict, operator.or_]
|
slack_participants: Annotated[dict, operator.or_]
|
||||||
"""The growing list of current slack participants."""
|
"""The growing list of current slack participants."""
|
||||||
bot_id: Optional[str]
|
bot_id: str | None
|
||||||
"""The ID of the bot user in the slack channel."""
|
"""The ID of the bot user in the slack channel."""
|
||||||
notified_assignees: Annotated[dict, operator.or_]
|
notified_assignees: Annotated[dict, operator.or_]
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from collections.abc import Sequence
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from random import choice
|
from random import choice
|
||||||
from typing import Annotated, Optional
|
from typing import Annotated
|
||||||
|
|
||||||
from langgraph.constants import END, START
|
from langgraph.constants import END, START
|
||||||
from langgraph.graph.state import StateGraph
|
from langgraph.graph.state import StateGraph
|
||||||
@@ -18,13 +18,13 @@ def wide_state(n: int) -> StateGraph:
|
|||||||
primary_issue_medium: Annotated[str, lambda x, y: y or x] = field(
|
primary_issue_medium: Annotated[str, lambda x, y: y or x] = field(
|
||||||
default="email"
|
default="email"
|
||||||
)
|
)
|
||||||
autoresponse: Annotated[Optional[dict], lambda _, y: y] = field(
|
autoresponse: Annotated[dict | None, lambda _, y: y] = field(
|
||||||
default=None
|
default=None
|
||||||
) # Always overwrite
|
) # Always overwrite
|
||||||
issue: Annotated[dict | None, lambda x, y: y if y else x] = field(default=None)
|
issue: Annotated[dict | None, lambda x, y: y if y else x] = field(default=None)
|
||||||
relevant_rules: Optional[list[dict]] = field(default=None)
|
relevant_rules: list[dict] | None = field(default=None)
|
||||||
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
"""SOPs fetched from the rulebook that are relevant to the current conversation."""
|
||||||
memory_docs: Optional[list[dict]] = field(default=None)
|
memory_docs: list[dict] | None = field(default=None)
|
||||||
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
"""Memory docs fetched from the memory service that are relevant to the current conversation."""
|
||||||
categorizations: Annotated[list[dict], operator.add] = field(
|
categorizations: Annotated[list[dict], operator.add] = field(
|
||||||
default_factory=list
|
default_factory=list
|
||||||
@@ -33,21 +33,21 @@ def wide_state(n: int) -> StateGraph:
|
|||||||
responses: Annotated[list[dict], operator.add] = field(default_factory=list)
|
responses: Annotated[list[dict], operator.add] = field(default_factory=list)
|
||||||
"""The draft responses recommended by the AI."""
|
"""The draft responses recommended by the AI."""
|
||||||
|
|
||||||
user_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x] = (
|
user_info: Annotated[dict | None, lambda x, y: y if y is not None else x] = (
|
||||||
field(default=None)
|
field(default=None)
|
||||||
)
|
)
|
||||||
"""The current user state (by email)."""
|
"""The current user state (by email)."""
|
||||||
crm_info: Annotated[Optional[dict], lambda x, y: y if y is not None else x] = (
|
crm_info: Annotated[dict | None, lambda x, y: y if y is not None else x] = (
|
||||||
field(default=None)
|
field(default=None)
|
||||||
)
|
)
|
||||||
"""The CRM information for organization the current user is from."""
|
"""The CRM information for organization the current user is from."""
|
||||||
email_thread_id: Annotated[
|
email_thread_id: Annotated[
|
||||||
Optional[str], lambda x, y: y if y is not None else x
|
str | None, lambda x, y: y if y is not None else x
|
||||||
] = field(default=None)
|
] = field(default=None)
|
||||||
"""The current email thread ID."""
|
"""The current email thread ID."""
|
||||||
slack_participants: Annotated[dict, operator.or_] = field(default_factory=dict)
|
slack_participants: Annotated[dict, operator.or_] = field(default_factory=dict)
|
||||||
"""The growing list of current slack participants."""
|
"""The growing list of current slack participants."""
|
||||||
bot_id: Optional[str] = field(default=None)
|
bot_id: str | None = field(default=None)
|
||||||
"""The ID of the bot user in the slack channel."""
|
"""The ID of the bot user in the slack channel."""
|
||||||
notified_assignees: Annotated[dict, operator.or_] = field(default_factory=dict)
|
notified_assignees: Annotated[dict, operator.or_] = field(default_factory=dict)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import ChainMap
|
from collections import ChainMap
|
||||||
from collections.abc import Sequence
|
from collections.abc import Mapping, Sequence
|
||||||
from os import getenv
|
from os import getenv
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
@@ -162,14 +162,10 @@ def patch_config(
|
|||||||
Args:
|
Args:
|
||||||
config: The config to patch.
|
config: The config to patch.
|
||||||
callbacks: The callbacks to set.
|
callbacks: The callbacks to set.
|
||||||
Defaults to None.
|
|
||||||
recursion_limit: The recursion limit to set.
|
recursion_limit: The recursion limit to set.
|
||||||
Defaults to None.
|
|
||||||
max_concurrency: The max number of concurrent steps to run, which also applies to parallelized steps.
|
max_concurrency: The max number of concurrent steps to run, which also applies to parallelized steps.
|
||||||
Defaults to None.
|
run_name: The run name to set.
|
||||||
run_name: The run name to set. Defaults to None.
|
|
||||||
configurable: The configurable to set.
|
configurable: The configurable to set.
|
||||||
Defaults to None.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
RunnableConfig: The patched config.
|
RunnableConfig: The patched config.
|
||||||
@@ -312,11 +308,22 @@ def ensure_config(*configs: RunnableConfig | None) -> RunnableConfig:
|
|||||||
for k, v in config.items():
|
for k, v in config.items():
|
||||||
if _is_not_empty(v) and k not in CONFIG_KEYS:
|
if _is_not_empty(v) and k not in CONFIG_KEYS:
|
||||||
empty[CONF][k] = v
|
empty[CONF][k] = v
|
||||||
|
_empty_metadata = empty["metadata"]
|
||||||
for key, value in empty[CONF].items():
|
for key, value in empty[CONF].items():
|
||||||
if (
|
if _exclude_as_metadata(key, value, _empty_metadata):
|
||||||
not key.startswith("__")
|
continue
|
||||||
and isinstance(value, (str, int, float, bool))
|
_empty_metadata[key] = value
|
||||||
and key not in empty["metadata"]
|
|
||||||
):
|
|
||||||
empty["metadata"][key] = value
|
|
||||||
return empty
|
return empty
|
||||||
|
|
||||||
|
|
||||||
|
_OMIT = ("key", "token", "secret", "password", "auth")
|
||||||
|
|
||||||
|
|
||||||
|
def _exclude_as_metadata(key: str, value: Any, metadata: Mapping[str, Any]) -> bool:
|
||||||
|
key_lower = key.casefold()
|
||||||
|
return (
|
||||||
|
key.startswith("__")
|
||||||
|
or not isinstance(value, (str, int, float, bool))
|
||||||
|
or key in metadata
|
||||||
|
or any(substr in key_lower for substr in _OMIT)
|
||||||
|
)
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ CONF = cast(Literal["configurable"], sys.intern("configurable"))
|
|||||||
# key for the configurable dict in RunnableConfig
|
# key for the configurable dict in RunnableConfig
|
||||||
NULL_TASK_ID = sys.intern("00000000-0000-0000-0000-000000000000")
|
NULL_TASK_ID = sys.intern("00000000-0000-0000-0000-000000000000")
|
||||||
# the task_id to use for writes that are not associated with a task
|
# the task_id to use for writes that are not associated with a task
|
||||||
|
OVERWRITE = sys.intern("__overwrite__")
|
||||||
|
# dict key for the overwrite value, used as `{'__overwrite__': value}`
|
||||||
|
|
||||||
# redefined to avoid circular import with langgraph.constants
|
# redefined to avoid circular import with langgraph.constants
|
||||||
_TAG_HIDDEN = sys.intern("langsmith:hidden")
|
_TAG_HIDDEN = sys.intern("langsmith:hidden")
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dataclasses
|
|||||||
import types
|
import types
|
||||||
import weakref
|
import weakref
|
||||||
from collections.abc import Generator, Sequence
|
from collections.abc import Generator, Sequence
|
||||||
from typing import Annotated, Any, Optional, Union, get_type_hints
|
from typing import Annotated, Any, Optional, Union, get_origin, get_type_hints
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing_extensions import NotRequired, ReadOnly, Required, get_origin
|
from typing_extensions import NotRequired, ReadOnly, Required
|
||||||
|
|
||||||
from langgraph._internal._typing import MISSING
|
from langgraph._internal._typing import MISSING
|
||||||
|
|
||||||
@@ -15,6 +15,12 @@ from langgraph._internal._typing import MISSING
|
|||||||
def _is_optional_type(type_: Any) -> bool:
|
def _is_optional_type(type_: Any) -> bool:
|
||||||
"""Check if a type is Optional."""
|
"""Check if a type is Optional."""
|
||||||
|
|
||||||
|
# Handle new union syntax (PEP 604): str | None
|
||||||
|
if isinstance(type_, types.UnionType):
|
||||||
|
return any(
|
||||||
|
arg is type(None) or _is_optional_type(arg) for arg in type_.__args__
|
||||||
|
)
|
||||||
|
|
||||||
if hasattr(type_, "__origin__") and hasattr(type_, "__args__"):
|
if hasattr(type_, "__origin__") and hasattr(type_, "__args__"):
|
||||||
origin = get_origin(type_)
|
origin = get_origin(type_)
|
||||||
if origin is Optional:
|
if origin is Optional:
|
||||||
@@ -195,6 +201,10 @@ def get_cached_annotated_keys(obj: type[Any]) -> tuple[str, ...]:
|
|||||||
keys: list[str] = []
|
keys: list[str] = []
|
||||||
for base in reversed(obj.__mro__):
|
for base in reversed(obj.__mro__):
|
||||||
ann = base.__dict__.get("__annotations__")
|
ann = base.__dict__.get("__annotations__")
|
||||||
|
# In Python 3.14+, Pydantic models use descriptors for __annotations__
|
||||||
|
# so we need to fall back to getattr if __dict__.get returns None
|
||||||
|
if ann is None:
|
||||||
|
ann = getattr(base, "__annotations__", None)
|
||||||
if ann is None or isinstance(ann, types.GetSetDescriptorType):
|
if ann is None or isinstance(ann, types.GetSetDescriptorType):
|
||||||
continue
|
continue
|
||||||
keys.extend(ann.keys())
|
keys.extend(ann.keys())
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user