langgraph-api 0.12.0.dev9__tar.gz → 0.12.0.dev11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/Makefile +1 -1
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/PKG-INFO +2 -2
- langgraph_api-0.12.0.dev11/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/_adapter.py +26 -1
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/service.py +49 -8
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/state_normalizers.py +8 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/feature_flags.py +10 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/checkpointer.py +14 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/checkpointer.py +115 -21
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/checkpoint.py +95 -6
- langgraph_api-0.12.0.dev11/langgraph_grpc_common/conversion/struct.py +60 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/value.py +11 -1
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.py +13 -3
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +113 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +47 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +24 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/serde.py +36 -4
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/pyproject.toml +1 -1
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/uv.lock +53 -67
- langgraph_api-0.12.0.dev9/langgraph_api/__init__.py +0 -1
- langgraph_api-0.12.0.dev9/langgraph_grpc_common/conversion/struct.py +0 -27
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/.gitignore +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/LICENSE +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/README.md +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/.gitignore +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/Makefile +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/README.md +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/assistant.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmarks.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/log-failure.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/meta_workload.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/stream_write.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/thread.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/types.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/wait_write.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_dd_report.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_k6.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_runner.mjs +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_slack_report.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_urls.mjs +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/clean-cli.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/clean.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/README.md +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/pyproject.toml +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/runner.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/uv.lock +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/graphs.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/mixed_workload_k6.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/mixed_workload_runner.mjs +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/package.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/ramp.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/slack_slowest_runs.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/slack_summary.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/run_local.sh +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/staircase.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/staircase_step_k6.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/tsconfig.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/update-revision.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/weather.js +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/constraints.txt +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/custom_store.sql +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/forbidden.txt +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/hatch_build.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/healthcheck.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph-cloud-debugging-20260210132856.zip +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/protocol.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_factory_utils.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/event_streaming.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_constants.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_handlers.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_models.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_routes.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_sanitizers.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/errors.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cache.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/command.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/_parse.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/schemas.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/aes_json.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/custom.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/middleware.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/shared.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/capabilities.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/constants.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/event_normalizers.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/namespace.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/session.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/types.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/client.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/assistants.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/cache.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/crons.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/runs.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/threads.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/server.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/encryption.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/package.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/yarn.lock +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/exceptions.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/policy.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/transport.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metrics_collector.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metrics_otlp.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/ensure_store.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/otel_context.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/queue_entrypoint.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/release_tags.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/route.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/self_hosted_metrics.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/server.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/state.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/store.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/stream_v2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/profiler.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/timer.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/extract.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/network.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/worker.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/_compat.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/config.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/durability.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/routes.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/logging.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/openapi.json +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/build_wheel.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/create_license.py +0 -0
- {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/run_a2a_tck.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.PHONY: build release lint format test test_watch start start-inmem start-inmem-license-oss start start-js-server build-go-server start-go-server stop-go-server check-version check-base-imports test-a2a-tck test-a2a-tck-mandatory start-test-a2a-tck start-test-a2a-tck-mandatory start-test-a2a-tck-watch test-mcp-conformance start-test-mcp-conformance list-mcp-scenarios test-auth-read-only-assistant
|
|
2
2
|
|
|
3
3
|
# Environment variables
|
|
4
|
-
LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "message_type_test": "./tests/graphs/message_type_test.py:graph", "remote_subgraph_parent": "./tests/graphs/remote_subgraph_parent.py:graph", "simple_remote": "./tests/graphs/simple_remote.py:graph", "nested_subgraphs": "./tests/graphs/nested_subgraphs.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "max_concurrency_graph": "./tests/graphs/max_concurrency_graph.py:graph", "unserializable_subgraph": "./tests/graphs/unserializable_subgraph.py:graph", "agent_interrupt_text": "./tests/graphs/agent_interrupt_text.py:graph", "agent_echo_stream": "./tests/graphs/agent_echo_stream.py:graph", "agent_tool_stream": "./tests/graphs/agent_tool_stream.py:graph", "runtime_graph": "./tests/graphs/runtime_graph.py:graph", "tool_call_chunk_stream": "./tests/graphs/tool_call_chunk_stream.py:graph", "ui_tool_call_stream": "./tests/graphs/ui_tool_call_stream.py:graph", "agent_metrics_stream": "./tests/graphs/agent_metrics_stream.py:graph", "agent_multimodal_stream": "./tests/graphs/agent_multimodal_stream.py:graph", "agent_bedtime_story": "./tests/graphs/agent_bedtime_story.py:graph", "delta_channel": "./tests/graphs/delta_channel.py:graph", "delta_channel_freq": "./tests/graphs/delta_channel_freq.py:graph", "delta_channel_files": "./tests/graphs/delta_channel_files.py:graph", "delta_channel_files_freq": "./tests/graphs/delta_channel_files_freq.py:graph", "delta_channel_legacy": "./tests/graphs/delta_channel_migration.py:graph_legacy", "delta_channel_delta": "./tests/graphs/delta_channel_migration.py:graph_delta", "delta_channel_messages_freq": "./tests/graphs/delta_channel_messages.py:graph_freq", "delta_channel_messages": "./tests/graphs/delta_channel_messages.py:graph", "delta_channel_messages_legacy": "./tests/graphs/delta_channel_messages.py:graph_legacy", "delta_channel_messages_remove": "./tests/graphs/delta_channel_messages.py:graph_remove", "delta_channel_messages_update": "./tests/graphs/delta_channel_messages.py:graph_update", "delta_channel_messages_delta": "./tests/graphs/delta_channel_messages.py:graph_delta"}'
|
|
4
|
+
LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "message_type_test": "./tests/graphs/message_type_test.py:graph", "remote_subgraph_parent": "./tests/graphs/remote_subgraph_parent.py:graph", "simple_remote": "./tests/graphs/simple_remote.py:graph", "nested_subgraphs": "./tests/graphs/nested_subgraphs.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "max_concurrency_graph": "./tests/graphs/max_concurrency_graph.py:graph", "unserializable_subgraph": "./tests/graphs/unserializable_subgraph.py:graph", "agent_interrupt_text": "./tests/graphs/agent_interrupt_text.py:graph", "agent_echo_stream": "./tests/graphs/agent_echo_stream.py:graph", "agent_tool_stream": "./tests/graphs/agent_tool_stream.py:graph", "runtime_graph": "./tests/graphs/runtime_graph.py:graph", "tool_call_chunk_stream": "./tests/graphs/tool_call_chunk_stream.py:graph", "ui_tool_call_stream": "./tests/graphs/ui_tool_call_stream.py:graph", "agent_metrics_stream": "./tests/graphs/agent_metrics_stream.py:graph", "agent_multimodal_stream": "./tests/graphs/agent_multimodal_stream.py:graph", "agent_bedtime_story": "./tests/graphs/agent_bedtime_story.py:graph", "delta_channel": "./tests/graphs/delta_channel.py:graph", "delta_channel_freq": "./tests/graphs/delta_channel_freq.py:graph", "delta_channel_files": "./tests/graphs/delta_channel_files.py:graph", "delta_channel_files_freq": "./tests/graphs/delta_channel_files_freq.py:graph", "delta_channel_legacy": "./tests/graphs/delta_channel_migration.py:graph_legacy", "delta_channel_delta": "./tests/graphs/delta_channel_migration.py:graph_delta", "delta_channel_delta_filter": "./tests/graphs/delta_channel_migration.py:graph_delta_filter", "delta_channel_messages_freq": "./tests/graphs/delta_channel_messages.py:graph_freq", "delta_channel_messages": "./tests/graphs/delta_channel_messages.py:graph", "delta_channel_messages_legacy": "./tests/graphs/delta_channel_messages.py:graph_legacy", "delta_channel_messages_remove": "./tests/graphs/delta_channel_messages.py:graph_remove", "delta_channel_messages_update": "./tests/graphs/delta_channel_messages.py:graph_update", "delta_channel_messages_delta": "./tests/graphs/delta_channel_messages.py:graph_delta"}'
|
|
5
5
|
LANGSERVE_GRAPHS_AUTH = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "runtime_graph": "./tests/graphs/runtime_graph.py:graph"}'
|
|
6
6
|
|
|
7
7
|
# Go server management
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.12.0.
|
|
3
|
+
Version: 0.12.0.dev11
|
|
4
4
|
Author-email: Will Fu-Hinthorn <will@langchain.dev>, Josh Rogers <josh@langchain.dev>, Parker Rule <parker@langchain.dev>
|
|
5
5
|
License: Elastic-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -16,7 +16,7 @@ Requires-Dist: jsonschema-rs<0.45,>=0.20.0
|
|
|
16
16
|
Requires-Dist: langchain-core>=0.3.64
|
|
17
17
|
Requires-Dist: langchain-protocol<0.1,>=0.0.18
|
|
18
18
|
Requires-Dist: langgraph-checkpoint<5,>=3.0.1
|
|
19
|
-
Requires-Dist: langgraph-runtime-inmem<0.
|
|
19
|
+
Requires-Dist: langgraph-runtime-inmem<0.33.0.dev0,>=0.32.0.dev0
|
|
20
20
|
Requires-Dist: langgraph-sdk>=0.3.5
|
|
21
21
|
Requires-Dist: langgraph<2,>=0.4.10
|
|
22
22
|
Requires-Dist: langsmith[otel]>=0.6.3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.12.0.dev11"
|
{langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/_adapter.py
RENAMED
|
@@ -24,6 +24,14 @@ from langgraph_grpc_common.checkpointer import GrpcCheckpointer
|
|
|
24
24
|
from langgraph_api import config, timing
|
|
25
25
|
from langgraph_api.asyncio import as_asynccontextmanager
|
|
26
26
|
from langgraph_api.grpc.client import get_shared_client
|
|
27
|
+
|
|
28
|
+
# Used as the per-instance serializer for ``GrpcCheckpointer`` below so
|
|
29
|
+
# checkpoint payloads honour the same ``USE_PICKLE_FALLBACK`` /
|
|
30
|
+
# encryption / ``allowed_json_modules`` policy as the in-process Python
|
|
31
|
+
# ``Checkpointer``. Scoped to checkpointer RPCs only (via the contextvar
|
|
32
|
+
# in ``langgraph_grpc_common.serde``) so non-checkpointer gRPC ops keep
|
|
33
|
+
# using the safer ``JsonPlusSerializer`` default.
|
|
34
|
+
from langgraph_api.serde import Serializer as _ApiSerializer
|
|
27
35
|
from langgraph_api.timing import profiled_import
|
|
28
36
|
from langgraph_api.utils.config import run_in_executor
|
|
29
37
|
|
|
@@ -320,7 +328,24 @@ async def get_checkpointer(
|
|
|
320
328
|
):
|
|
321
329
|
return cast(
|
|
322
330
|
"FullCheckpointerProtocol",
|
|
323
|
-
GrpcCheckpointer(
|
|
331
|
+
GrpcCheckpointer(
|
|
332
|
+
get_stub=_get_shared_checkpointer_stub,
|
|
333
|
+
serializer=_ApiSerializer(),
|
|
334
|
+
),
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
from langgraph_api.feature_flags import ( # noqa: PLC0415
|
|
338
|
+
IS_POSTGRES_BACKEND,
|
|
339
|
+
PREFER_GRPC_CHECKPOINTER,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
if IS_POSTGRES_BACKEND and PREFER_GRPC_CHECKPOINTER:
|
|
343
|
+
return cast(
|
|
344
|
+
"FullCheckpointerProtocol",
|
|
345
|
+
GrpcCheckpointer(
|
|
346
|
+
get_stub=_get_shared_checkpointer_stub,
|
|
347
|
+
serializer=_ApiSerializer(),
|
|
348
|
+
),
|
|
324
349
|
)
|
|
325
350
|
|
|
326
351
|
from langgraph_runtime.checkpoint import Checkpointer # noqa: PLC0415
|
{langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/service.py
RENAMED
|
@@ -21,6 +21,7 @@ from __future__ import annotations
|
|
|
21
21
|
import asyncio
|
|
22
22
|
import contextlib
|
|
23
23
|
import inspect
|
|
24
|
+
import time
|
|
24
25
|
from collections.abc import Awaitable, Callable
|
|
25
26
|
from typing import Any, cast, get_args
|
|
26
27
|
from uuid import UUID, uuid4
|
|
@@ -124,6 +125,12 @@ def _multitask_strategy_from_run_start(params: dict[str, Any]) -> str:
|
|
|
124
125
|
EventSink = Callable[[dict[str, Any]], Awaitable[None] | None]
|
|
125
126
|
|
|
126
127
|
|
|
128
|
+
# ``set_joint_status`` commits interrupts after the stream event; gRPC can lag.
|
|
129
|
+
_IN_FLIGHT_THREAD_STATUS = "busy"
|
|
130
|
+
_INTERRUPT_SETTLE_TIMEOUT_SECONDS = 5.0
|
|
131
|
+
_INTERRUPT_SETTLE_POLL_INTERVAL_SECONDS = 0.05
|
|
132
|
+
|
|
133
|
+
|
|
127
134
|
# Protocol v2 commands this server implements. Anything outside this
|
|
128
135
|
# set returns ``unknown_command`` up front from ``handle_command`` so
|
|
129
136
|
# pre-session dispatch does not mislabel typos (or removed methods
|
|
@@ -593,13 +600,11 @@ class ThreadRunManager:
|
|
|
593
600
|
# this HTTP request (the stateless ``POST /commands`` transport) its
|
|
594
601
|
# source task hasn't had a chance to emit ``input.requested`` yet —
|
|
595
602
|
# ``_pending_interrupts`` is still empty. In that case, fall back to
|
|
596
|
-
# the thread-state check so we
|
|
597
|
-
#
|
|
598
|
-
# in-memory check and skips the DB round-trip.
|
|
603
|
+
# the thread-state check (``_collect_settled_interrupt_ids``) so we
|
|
604
|
+
# don't reject legitimate resumes with a fresh handle.
|
|
599
605
|
#
|
|
600
606
|
# The thread-state fallback is fetched at most once per batch and
|
|
601
|
-
# cached in ``thread_state_ids
|
|
602
|
-
# the session would otherwise issue N identical ``State.get`` calls.
|
|
607
|
+
# cached in ``thread_state_ids``.
|
|
603
608
|
thread_state_ids: set[str] | None = None
|
|
604
609
|
thread_state_fetched = False
|
|
605
610
|
for interrupt_id, claimed_namespace, _ in entries:
|
|
@@ -623,7 +628,7 @@ class ThreadRunManager:
|
|
|
623
628
|
# only, so trust the client-claimed namespace and validate by
|
|
624
629
|
# existence (the id is a namespace hash, so that's sufficient).
|
|
625
630
|
if not thread_state_fetched:
|
|
626
|
-
thread_state_ids = await self.
|
|
631
|
+
thread_state_ids = await self._collect_settled_interrupt_ids()
|
|
627
632
|
thread_state_fetched = True
|
|
628
633
|
# Fail open when the lookup is unavailable (``None``): only reject
|
|
629
634
|
# when a definitive id set was read and lacks the target. The
|
|
@@ -669,6 +674,7 @@ class ThreadRunManager:
|
|
|
669
674
|
{
|
|
670
675
|
"assistant_id": assistant_id,
|
|
671
676
|
"input": resume_input,
|
|
677
|
+
"force_resume": True,
|
|
672
678
|
"update": params.get("update"),
|
|
673
679
|
"goto": params.get("goto"),
|
|
674
680
|
"config": params.get("config"),
|
|
@@ -732,7 +738,8 @@ class ThreadRunManager:
|
|
|
732
738
|
has_interrupts = await self._has_pending_interrupts()
|
|
733
739
|
|
|
734
740
|
is_resume = params.get("input") is not None and (
|
|
735
|
-
(
|
|
741
|
+
params.get("force_resume")
|
|
742
|
+
or (current_run is not None and current_status == "interrupted")
|
|
736
743
|
or has_interrupts
|
|
737
744
|
)
|
|
738
745
|
|
|
@@ -1108,6 +1115,40 @@ class ThreadRunManager:
|
|
|
1108
1115
|
found.add(entry_id)
|
|
1109
1116
|
return found
|
|
1110
1117
|
|
|
1118
|
+
async def _fetch_thread_status(self) -> str | None:
|
|
1119
|
+
"""Return durable thread status, or ``None`` if unreadable."""
|
|
1120
|
+
from langgraph_runtime.database import connect # noqa: PLC0415
|
|
1121
|
+
|
|
1122
|
+
try:
|
|
1123
|
+
async with connect() as conn:
|
|
1124
|
+
result = await self._threads.get(conn, self._thread_id)
|
|
1125
|
+
thread = await anext(result) if hasattr(result, "__anext__") else result
|
|
1126
|
+
except Exception:
|
|
1127
|
+
return None
|
|
1128
|
+
status = thread.get("status") if _is_record(thread) else None
|
|
1129
|
+
return status if isinstance(status, str) else None
|
|
1130
|
+
|
|
1131
|
+
async def _collect_settled_interrupt_ids(self) -> set[str] | None:
|
|
1132
|
+
"""Persisted interrupt ids, polling while the thread is still ``busy``."""
|
|
1133
|
+
ids = await self._collect_persisted_interrupt_ids()
|
|
1134
|
+
if ids is None:
|
|
1135
|
+
return None
|
|
1136
|
+
if ids:
|
|
1137
|
+
return ids
|
|
1138
|
+
deadline = time.monotonic() + _INTERRUPT_SETTLE_TIMEOUT_SECONDS
|
|
1139
|
+
while True:
|
|
1140
|
+
status = await self._fetch_thread_status()
|
|
1141
|
+
if status != _IN_FLIGHT_THREAD_STATUS:
|
|
1142
|
+
return await self._collect_persisted_interrupt_ids()
|
|
1143
|
+
if time.monotonic() >= deadline:
|
|
1144
|
+
return set()
|
|
1145
|
+
await asyncio.sleep(_INTERRUPT_SETTLE_POLL_INTERVAL_SECONDS)
|
|
1146
|
+
ids = await self._collect_persisted_interrupt_ids()
|
|
1147
|
+
if ids is None:
|
|
1148
|
+
return None
|
|
1149
|
+
if ids:
|
|
1150
|
+
return ids
|
|
1151
|
+
|
|
1111
1152
|
async def _has_pending_interrupts(self) -> bool:
|
|
1112
1153
|
# Prefer the session's in-memory pending interrupts (populated the
|
|
1113
1154
|
# instant ``input.requested`` surfaces) to skip a DB round-trip;
|
|
@@ -1116,7 +1157,7 @@ class ThreadRunManager:
|
|
|
1116
1157
|
# the ``current_status == "interrupted"`` signal for resume-vs-start.
|
|
1117
1158
|
if self._session is not None and self._session._pending_interrupts:
|
|
1118
1159
|
return True
|
|
1119
|
-
found = await self.
|
|
1160
|
+
found = await self._collect_settled_interrupt_ids()
|
|
1120
1161
|
return bool(found)
|
|
1121
1162
|
|
|
1122
1163
|
# ------------------------------------------------------------------
|
|
@@ -320,6 +320,14 @@ def _normalize_state_message(value: dict[str, Any]) -> dict[str, Any]:
|
|
|
320
320
|
if msg_type in ("ai", "human") and isinstance(value.get("example"), bool):
|
|
321
321
|
message["example"] = value["example"]
|
|
322
322
|
|
|
323
|
+
# Preserve ``response_metadata`` when present. It is a first-class protocol
|
|
324
|
+
# message field, and HITL flows rely on it: an interrupt's card is carried
|
|
325
|
+
# on ``AIMessage.response_metadata`` (e.g. ``{"cards": ...}``) and the
|
|
326
|
+
# frontend pushes that message into state via ``respond(decision, update)``.
|
|
327
|
+
# We only forward a non-empty record to keep the common (empty) case minimal.
|
|
328
|
+
if _is_record(value.get("response_metadata")) and value["response_metadata"]:
|
|
329
|
+
message["response_metadata"] = value["response_metadata"]
|
|
330
|
+
|
|
323
331
|
if msg_type == "tool":
|
|
324
332
|
if isinstance(value.get("tool_call_id"), str):
|
|
325
333
|
message["tool_call_id"] = value["tool_call_id"]
|
|
@@ -35,6 +35,16 @@ FF_V2_EVENT_STREAMING = os.getenv("FF_V2_EVENT_STREAMING", "true").lower() in (
|
|
|
35
35
|
"yes",
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
+
# When true on the postgres runtime, use ``GrpcCheckpointer``.
|
|
39
|
+
# Inmem edition is unaffected (``IS_POSTGRES_BACKEND`` is false there).
|
|
40
|
+
# Custom checkpointer (``backend=custom`` in ``LANGGRAPH_CHECKPOINTER``) and
|
|
41
|
+
# Mongo (``backend=mongo``) is also unaffected.
|
|
42
|
+
PREFER_GRPC_CHECKPOINTER = os.getenv("PREFER_GRPC_CHECKPOINTER", "false").lower() in (
|
|
43
|
+
"true",
|
|
44
|
+
"1",
|
|
45
|
+
"yes",
|
|
46
|
+
)
|
|
47
|
+
|
|
38
48
|
# In langgraph <= 1.0.3, we automatically subscribed to updates stream events to surface interrupts. In langgraph 1.0.4 we include interrupts in values events (which we are automatically subscribed to), so we no longer need to implicitly subscribe to updates stream events
|
|
39
49
|
# Strip prerelease suffixes (e.g. "0a5" -> 0) so versions like 1.2.0a5 still
|
|
40
50
|
# parse correctly; fall back to (0, 0, 0) only if no leading digits at all.
|
|
@@ -242,3 +242,17 @@ class CheckpointerServicerImpl(CheckpointerServicer):
|
|
|
242
242
|
context.set_code(grpc.StatusCode.INTERNAL)
|
|
243
243
|
context.set_details(f"Checkpointer Prune failed: {e}")
|
|
244
244
|
raise
|
|
245
|
+
|
|
246
|
+
async def GetDeltaChannelHistory(
|
|
247
|
+
self,
|
|
248
|
+
request: checkpointer_pb2.GetDeltaChannelHistoryRequest,
|
|
249
|
+
context: grpc_aio.ServicerContext,
|
|
250
|
+
) -> checkpointer_pb2.GetDeltaChannelHistoryResponse:
|
|
251
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
252
|
+
context.set_details(
|
|
253
|
+
"GetDeltaChannelHistory is not implemented by the Python "
|
|
254
|
+
"checkpointer servicer"
|
|
255
|
+
)
|
|
256
|
+
raise NotImplementedError(
|
|
257
|
+
"GetDeltaChannelHistory not implemented by the Python checkpointer servicer"
|
|
258
|
+
)
|
{langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/checkpointer.py
RENAMED
|
@@ -8,10 +8,14 @@ from collections.abc import (
|
|
|
8
8
|
Callable,
|
|
9
9
|
Coroutine,
|
|
10
10
|
Iterator,
|
|
11
|
+
Mapping,
|
|
11
12
|
Sequence,
|
|
12
13
|
)
|
|
14
|
+
from contextlib import AbstractContextManager, nullcontext
|
|
13
15
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
|
14
16
|
|
|
17
|
+
import grpc
|
|
18
|
+
import grpc.aio
|
|
15
19
|
from langgraph.checkpoint.base import (
|
|
16
20
|
BaseCheckpointSaver,
|
|
17
21
|
ChannelVersions,
|
|
@@ -20,6 +24,7 @@ from langgraph.checkpoint.base import (
|
|
|
20
24
|
CheckpointTuple,
|
|
21
25
|
)
|
|
22
26
|
|
|
27
|
+
from langgraph_grpc_common import serde as _grpc_serde
|
|
23
28
|
from langgraph_grpc_common.conversion import checkpoint as ckpt_conv
|
|
24
29
|
from langgraph_grpc_common.conversion.config import (
|
|
25
30
|
config_from_proto,
|
|
@@ -30,6 +35,7 @@ from langgraph_grpc_common.proto import checkpointer_pb2
|
|
|
30
35
|
|
|
31
36
|
if TYPE_CHECKING:
|
|
32
37
|
from langchain_core.runnables import RunnableConfig
|
|
38
|
+
from langgraph.checkpoint.serde.base import SerializerProtocol
|
|
33
39
|
|
|
34
40
|
from langgraph_grpc_common.proto.checkpointer_pb2_grpc import CheckpointerStub
|
|
35
41
|
|
|
@@ -49,17 +55,43 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
49
55
|
get_stub: StubProvider,
|
|
50
56
|
retry: RetryFn | None = None,
|
|
51
57
|
retry_context_prefix: str | None = None,
|
|
58
|
+
serializer: SerializerProtocol | None = None,
|
|
52
59
|
) -> None:
|
|
60
|
+
"""Construct a gRPC checkpointer client.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
get_stub: Async factory returning the ``CheckpointerStub`` to
|
|
64
|
+
use for the next RPC. Called per-call so the caller can
|
|
65
|
+
pool / refresh connections.
|
|
66
|
+
retry: Optional retry wrapper. When provided, every RPC is
|
|
67
|
+
dispatched through ``retry(func, context)``.
|
|
68
|
+
retry_context_prefix: Label included in ``retry``'s context
|
|
69
|
+
string. Defaults to the concrete class name.
|
|
70
|
+
serializer: Optional ``SerializerProtocol`` to use for
|
|
71
|
+
payload (de)serialization on *this* checkpointer
|
|
72
|
+
instance only. Scoped via a :class:`~contextvars.ContextVar`
|
|
73
|
+
so unrelated gRPC ops sharing
|
|
74
|
+
``langgraph_grpc_common.conversion.*`` keep using the
|
|
75
|
+
process-wide default
|
|
76
|
+
"""
|
|
53
77
|
super().__init__(serde=None)
|
|
54
78
|
self._get_stub = get_stub
|
|
55
79
|
self._retry = retry
|
|
56
80
|
self._retry_context_prefix = retry_context_prefix or type(self).__name__
|
|
81
|
+
self._serializer = serializer
|
|
57
82
|
self.latest_iter = None
|
|
58
83
|
try:
|
|
59
84
|
self._loop: asyncio.AbstractEventLoop | None = asyncio.get_running_loop()
|
|
60
85
|
except RuntimeError:
|
|
61
86
|
self._loop = None
|
|
62
87
|
|
|
88
|
+
def _scoped(self) -> AbstractContextManager[None]:
|
|
89
|
+
"""Bind ``self._serializer`` for the duration of a conversion call.
|
|
90
|
+
"""
|
|
91
|
+
if self._serializer is None:
|
|
92
|
+
return nullcontext()
|
|
93
|
+
return _grpc_serde.use_serializer(self._serializer)
|
|
94
|
+
|
|
63
95
|
@property
|
|
64
96
|
def loop(self) -> asyncio.AbstractEventLoop:
|
|
65
97
|
if self._loop is None:
|
|
@@ -94,13 +126,15 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
94
126
|
return None
|
|
95
127
|
|
|
96
128
|
async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
|
|
97
|
-
|
|
129
|
+
with self._scoped():
|
|
130
|
+
request = checkpointer_pb2.GetTupleRequest(config=config_to_proto(config))
|
|
98
131
|
|
|
99
132
|
async def _request() -> CheckpointTuple | None:
|
|
100
133
|
response = await (await self._stub()).GetTuple(request)
|
|
101
134
|
if not response.HasField("checkpoint_tuple"):
|
|
102
135
|
return None
|
|
103
|
-
|
|
136
|
+
with self._scoped():
|
|
137
|
+
return ckpt_conv.checkpoint_tuple_from_proto(response.checkpoint_tuple)
|
|
104
138
|
|
|
105
139
|
return await self._call("aget_tuple", _request)
|
|
106
140
|
|
|
@@ -128,16 +162,18 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
128
162
|
metadata: CheckpointMetadata,
|
|
129
163
|
new_versions: ChannelVersions,
|
|
130
164
|
) -> RunnableConfig:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
165
|
+
with self._scoped():
|
|
166
|
+
request = checkpointer_pb2.PutRequest(
|
|
167
|
+
config=config_to_proto(config),
|
|
168
|
+
checkpoint=ckpt_conv.checkpoint_to_proto(checkpoint),
|
|
169
|
+
metadata=ckpt_conv.checkpoint_metadata_to_proto(metadata),
|
|
170
|
+
new_versions={k: str(v) for k, v in new_versions.items()},
|
|
171
|
+
)
|
|
137
172
|
|
|
138
173
|
async def _request() -> RunnableConfig:
|
|
139
174
|
response = await (await self._stub()).Put(request)
|
|
140
|
-
|
|
175
|
+
with self._scoped():
|
|
176
|
+
next_config = config_from_proto(response.next_config)
|
|
141
177
|
if next_config is None:
|
|
142
178
|
raise ValueError("Unexpected None value for next_config")
|
|
143
179
|
return next_config
|
|
@@ -160,12 +196,13 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
160
196
|
task_id: str,
|
|
161
197
|
task_path: str = "",
|
|
162
198
|
) -> None:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
199
|
+
with self._scoped():
|
|
200
|
+
request = checkpointer_pb2.PutWritesRequest(
|
|
201
|
+
config=config_to_proto(config),
|
|
202
|
+
writes=ckpt_conv.writes_to_proto(writes),
|
|
203
|
+
task_id=task_id,
|
|
204
|
+
task_path=task_path,
|
|
205
|
+
)
|
|
169
206
|
|
|
170
207
|
async def _request() -> None:
|
|
171
208
|
await (await self._stub()).PutWrites(request)
|
|
@@ -212,11 +249,12 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
212
249
|
before: RunnableConfig | None = None,
|
|
213
250
|
limit: int | None = None,
|
|
214
251
|
) -> AsyncIterator[CheckpointTuple]:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
252
|
+
with self._scoped():
|
|
253
|
+
request = checkpointer_pb2.ListRequest(
|
|
254
|
+
config=config_to_proto(config) if config is not None else None,
|
|
255
|
+
filter_json=convert_dict_to_json_bytes(filter) or b"",
|
|
256
|
+
before=config_to_proto(before) if before is not None else None,
|
|
257
|
+
)
|
|
220
258
|
if limit is not None:
|
|
221
259
|
request.limit = limit
|
|
222
260
|
|
|
@@ -225,7 +263,11 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
225
263
|
|
|
226
264
|
response = await self._call("alist", _request)
|
|
227
265
|
for proto_tuple in response.checkpoint_tuples:
|
|
228
|
-
|
|
266
|
+
# Bind inside the loop body so the override does not leak
|
|
267
|
+
# across ``yield`` into the consumer's frame.
|
|
268
|
+
with self._scoped():
|
|
269
|
+
tup = ckpt_conv.checkpoint_tuple_from_proto(proto_tuple)
|
|
270
|
+
if tup is not None:
|
|
229
271
|
yield tup
|
|
230
272
|
|
|
231
273
|
def delete_thread(self, thread_id: str) -> None:
|
|
@@ -298,3 +340,55 @@ class GrpcCheckpointer(BaseCheckpointSaver):
|
|
|
298
340
|
next_v = current_v + 1
|
|
299
341
|
next_h = random.random()
|
|
300
342
|
return f"{next_v:032}.{next_h:.16f}"
|
|
343
|
+
|
|
344
|
+
def get_delta_channel_history(
|
|
345
|
+
self,
|
|
346
|
+
*,
|
|
347
|
+
config: RunnableConfig,
|
|
348
|
+
channels: Sequence[str],
|
|
349
|
+
) -> Mapping[str, dict[str, Any]]:
|
|
350
|
+
"""Synchronous wrapper for ``aget_delta_channel_history``.
|
|
351
|
+
|
|
352
|
+
langgraph >= 1.2 calls the async variant from the loop, but the
|
|
353
|
+
BaseCheckpointSaver protocol expects sync wrappers to exist.
|
|
354
|
+
"""
|
|
355
|
+
return self._run_sync(
|
|
356
|
+
self.aget_delta_channel_history(config=config, channels=channels)
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
async def aget_delta_channel_history(
|
|
360
|
+
self,
|
|
361
|
+
*,
|
|
362
|
+
config: RunnableConfig,
|
|
363
|
+
channels: Sequence[str],
|
|
364
|
+
) -> Mapping[str, dict[str, Any]]:
|
|
365
|
+
if not channels:
|
|
366
|
+
return {}
|
|
367
|
+
configurable = config.get("configurable", {}) if config else {}
|
|
368
|
+
request = checkpointer_pb2.GetDeltaChannelHistoryRequest(
|
|
369
|
+
thread_id=configurable.get("thread_id", "") or "",
|
|
370
|
+
checkpoint_ns=configurable.get("checkpoint_ns", "") or "",
|
|
371
|
+
# Empty checkpoint_id => server resolves the latest checkpoint.
|
|
372
|
+
checkpoint_id=configurable.get("checkpoint_id", "") or "",
|
|
373
|
+
channels=list(channels),
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
async def _request() -> checkpointer_pb2.GetDeltaChannelHistoryResponse:
|
|
377
|
+
return await (await self._stub()).GetDeltaChannelHistory(request)
|
|
378
|
+
|
|
379
|
+
try:
|
|
380
|
+
response = await self._call("aget_delta_channel_history", _request)
|
|
381
|
+
except grpc.aio.AioRpcError as e:
|
|
382
|
+
if e.code() == grpc.StatusCode.UNIMPLEMENTED:
|
|
383
|
+
# The backend has no native fast path for delta-channel
|
|
384
|
+
# reconstruction (e.g. the Go mongo/sqlite checkpointers).
|
|
385
|
+
# Fall back to BaseCheckpointSaver's parent-chain walk, which
|
|
386
|
+
# drives aget_tuple (-> gRPC GetTuple) per ancestor. langgraph
|
|
387
|
+
# calls this method unguarded, so we must degrade gracefully
|
|
388
|
+
# rather than raise.
|
|
389
|
+
return await super().aget_delta_channel_history(
|
|
390
|
+
config=config, channels=channels
|
|
391
|
+
)
|
|
392
|
+
raise
|
|
393
|
+
with self._scoped():
|
|
394
|
+
return ckpt_conv.delta_channel_history_from_proto(response.entries)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import Mapping
|
|
1
2
|
from collections.abc import Sequence as SequenceType
|
|
2
3
|
from typing import Any, Literal, cast
|
|
3
4
|
|
|
@@ -16,7 +17,7 @@ from langgraph_grpc_common.conversion.config import (
|
|
|
16
17
|
)
|
|
17
18
|
from langgraph_grpc_common.conversion.struct import dict_from_raw_map, raw_map_from_dict
|
|
18
19
|
from langgraph_grpc_common.conversion.value import (
|
|
19
|
-
|
|
20
|
+
base_value_to_proto,
|
|
20
21
|
send_to_proto,
|
|
21
22
|
value_from_proto,
|
|
22
23
|
value_to_proto,
|
|
@@ -86,11 +87,7 @@ def checkpoint_to_proto(checkpoint: Checkpoint) -> engine_common_pb2.Checkpoint:
|
|
|
86
87
|
)
|
|
87
88
|
)
|
|
88
89
|
else:
|
|
89
|
-
checkpoint_proto.channel_values[k].CopyFrom(
|
|
90
|
-
engine_common_pb2.ChannelValue(
|
|
91
|
-
serialized_value=any_to_serialized_value(v)
|
|
92
|
-
)
|
|
93
|
-
)
|
|
90
|
+
checkpoint_proto.channel_values[k].CopyFrom(base_value_to_proto(v))
|
|
94
91
|
|
|
95
92
|
return checkpoint_proto
|
|
96
93
|
|
|
@@ -241,3 +238,95 @@ def prune_strategy_to_proto(
|
|
|
241
238
|
case "delete_all":
|
|
242
239
|
return checkpointer_pb2.PruneRequest.PruneStrategy.DELETE_ALL
|
|
243
240
|
raise ValueError("Unknown prune strategy: " + strategy)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
# ---------------------------------------------------------------------------
|
|
244
|
+
# DeltaChannelHistory conversion
|
|
245
|
+
# ---------------------------------------------------------------------------
|
|
246
|
+
#
|
|
247
|
+
# ``DeltaChannelHistory`` is a TypedDict from langgraph >= 1.2:
|
|
248
|
+
#
|
|
249
|
+
# class DeltaChannelHistory(TypedDict, total=False):
|
|
250
|
+
# seed: Any # optional snapshot value
|
|
251
|
+
# writes: list[PendingWrite] # (task_id, channel, value) tuples
|
|
252
|
+
#
|
|
253
|
+
# These helpers serialize/deserialize that shape to/from the wire-format
|
|
254
|
+
# ``DeltaChannelHistoryEntry`` proto.
|
|
255
|
+
#
|
|
256
|
+
# We accept and return plain ``dict[str, dict]`` rather than importing
|
|
257
|
+
# the ``DeltaChannelHistory`` TypedDict — langgraph treats the TypedDict
|
|
258
|
+
# structurally, so any dict with the right keys is accepted by the
|
|
259
|
+
# consumer (langgraph's ``DeltaChannel.replay_writes``).
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def delta_channel_history_entry_to_proto(
|
|
263
|
+
entry: Mapping[str, Any],
|
|
264
|
+
*,
|
|
265
|
+
channel: str,
|
|
266
|
+
) -> checkpointer_pb2.DeltaChannelHistoryEntry:
|
|
267
|
+
"""Encode one channel's ``DeltaChannelHistory`` dict as proto.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
entry: Mapping with optional ``seed`` and optional ``writes``.
|
|
271
|
+
``writes`` is a sequence of ``(task_id, channel, value)`` tuples
|
|
272
|
+
(langgraph's ``PendingWrite``).
|
|
273
|
+
channel: The channel name this entry corresponds to. We pass it to
|
|
274
|
+
``value_to_proto`` so the TASKS channel special-cases the
|
|
275
|
+
seed/write conversion if it ever appears here.
|
|
276
|
+
"""
|
|
277
|
+
pb_entry = checkpointer_pb2.DeltaChannelHistoryEntry()
|
|
278
|
+
if "seed" in entry:
|
|
279
|
+
pb_entry.seed.CopyFrom(value_to_proto(channel, entry["seed"]))
|
|
280
|
+
for write in entry.get("writes", ()) or ():
|
|
281
|
+
task_id, write_channel, write_value = write
|
|
282
|
+
pb_entry.writes.append(
|
|
283
|
+
engine_common_pb2.PendingWrite(
|
|
284
|
+
task_id=str(task_id),
|
|
285
|
+
channel=str(write_channel),
|
|
286
|
+
value=value_to_proto(write_channel, write_value),
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
return pb_entry
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def delta_channel_history_to_proto(
|
|
293
|
+
history: Mapping[str, Mapping[str, Any]],
|
|
294
|
+
) -> dict[str, checkpointer_pb2.DeltaChannelHistoryEntry]:
|
|
295
|
+
"""Encode the full per-channel mapping for the response proto."""
|
|
296
|
+
return {
|
|
297
|
+
ch: delta_channel_history_entry_to_proto(entry, channel=ch)
|
|
298
|
+
for ch, entry in history.items()
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def delta_channel_history_entry_from_proto(
|
|
303
|
+
entry: checkpointer_pb2.DeltaChannelHistoryEntry,
|
|
304
|
+
) -> dict[str, Any]:
|
|
305
|
+
"""Decode one channel's proto entry to a ``DeltaChannelHistory`` dict.
|
|
306
|
+
|
|
307
|
+
The ``seed`` key is omitted from the result when the proto has no
|
|
308
|
+
seed set — matches the Python source's "absence means MISSING"
|
|
309
|
+
contract (see ``_assemble_delta_history`` in
|
|
310
|
+
``storage_postgres/langgraph_runtime_postgres/checkpoint.py``).
|
|
311
|
+
"""
|
|
312
|
+
out: dict[str, Any] = {
|
|
313
|
+
"writes": [
|
|
314
|
+
(write.task_id, write.channel, value_from_proto(write.value))
|
|
315
|
+
for write in entry.writes
|
|
316
|
+
],
|
|
317
|
+
}
|
|
318
|
+
if entry.HasField("seed"):
|
|
319
|
+
out["seed"] = value_from_proto(entry.seed)
|
|
320
|
+
return out
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def delta_channel_history_from_proto(
|
|
324
|
+
entries: Mapping[str, checkpointer_pb2.DeltaChannelHistoryEntry],
|
|
325
|
+
) -> dict[str, dict[str, Any]]:
|
|
326
|
+
"""Decode the full per-channel response proto map."""
|
|
327
|
+
return {
|
|
328
|
+
ch: delta_channel_history_entry_from_proto(entry)
|
|
329
|
+
for ch, entry in entries.items()
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from collections.abc import Mapping
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import orjson
|
|
6
|
+
from google.protobuf import struct_pb2
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def struct_from_dict(d: Mapping[str, Any]) -> struct_pb2.Struct:
|
|
10
|
+
s = struct_pb2.Struct()
|
|
11
|
+
s.update(d)
|
|
12
|
+
return s
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _default_serializer(obj: Any) -> Any:
|
|
16
|
+
if hasattr(obj, "dict") and callable(obj.dict):
|
|
17
|
+
return obj.dict()
|
|
18
|
+
if hasattr(obj, "__dict__"):
|
|
19
|
+
return obj.__dict__
|
|
20
|
+
raise TypeError(f"Type is not JSON serializable: {type(obj).__name__}")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_SURROGATE_RE = re.compile(r"[\ud800-\udfff]")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _replace_surrogates(o: Any) -> Any:
|
|
27
|
+
"""Recursively replace lone-surrogate codepoints (orjson rejects them).
|
|
28
|
+
|
|
29
|
+
Mirrors ``_sanitise`` in ``langgraph_grpc_common.serde`` so metadata
|
|
30
|
+
encode falls back gracefully instead of raising. Without this,
|
|
31
|
+
fixtures that intentionally embed surrogates (e.g.
|
|
32
|
+
``test_thread_copy``'s ``"surrogate"`` field on
|
|
33
|
+
``langgraph==0.4.10`` which mirrors input into metadata) crash the
|
|
34
|
+
whole put.
|
|
35
|
+
"""
|
|
36
|
+
if isinstance(o, str):
|
|
37
|
+
return _SURROGATE_RE.sub("?", o) if _SURROGATE_RE.search(o) else o
|
|
38
|
+
if isinstance(o, Mapping):
|
|
39
|
+
return {_replace_surrogates(k): _replace_surrogates(v) for k, v in o.items()}
|
|
40
|
+
if isinstance(o, (list, tuple, set)):
|
|
41
|
+
return type(o)(_replace_surrogates(x) for x in o)
|
|
42
|
+
return o
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def raw_map_from_dict(d: Mapping[str, Any]) -> Mapping[str, bytes]:
|
|
46
|
+
out: dict[str, bytes] = {}
|
|
47
|
+
for k, v in d.items():
|
|
48
|
+
try:
|
|
49
|
+
out[k] = orjson.dumps(v, default=_default_serializer)
|
|
50
|
+
except (TypeError, ValueError):
|
|
51
|
+
# orjson rejects e.g. lone surrogates and a few other oddities
|
|
52
|
+
# that the in-process Python ``Checkpointer.aput`` happily
|
|
53
|
+
# stores via its own serde. Sanitize and retry rather than
|
|
54
|
+
# failing the entire put.
|
|
55
|
+
out[k] = orjson.dumps(_replace_surrogates(v), default=_default_serializer)
|
|
56
|
+
return out
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def dict_from_raw_map(m: Mapping[str, bytes]) -> dict[str, Any]:
|
|
60
|
+
return {k: orjson.loads(v) for k, v in m.items()}
|