langgraph-api 0.18.0.dev13__tar.gz → 0.18.0.dev14__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.18.0.dev13 → langgraph_api-0.18.0.dev14}/Makefile +4 -1
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/PKG-INFO +2 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/constraints.txt +1 -1
- langgraph_api-0.18.0.dev14/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_elicitation.py +318 -5
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_forms.py +5 -1
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/runs.py +31 -14
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/threads.py +3 -3
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/asyncio.py +11 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/cli.py +8 -1
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/config/__init__.py +11 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/config/schemas.py +12 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/session.py +10 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/executor/__main__.py +9 -4
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/assistants.py +3 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/runs.py +168 -1
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/threads.py +19 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/client.mts +9 -6
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/package.json +2 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/yarn.lock +110 -110
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/metrics_collector.py +24 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/metrics_otlp.py +33 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/models/run.py +2 -3
- langgraph_api-0.18.0.dev14/langgraph_api/priority_settings.py +237 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/queue_entrypoint.py +2 -9
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/schema.py +26 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/self_hosted_metrics.py +83 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/stream.py +9 -1
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/__init__.py +4 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/webhook.py +16 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/worker.py +16 -0
- langgraph_api-0.18.0.dev14/langgraph_grpc_common/proto/core_api_pb2.py +296 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/core_api_pb2.pyi +117 -6
- langgraph_api-0.18.0.dev14/langgraph_grpc_common/proto/orchestrator_pb2.py +52 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/orchestrator_pb2.pyi +24 -3
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.py +4 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.pyi +12 -6
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/openapi.json +62 -4
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/pyproject.toml +6 -2
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/uv.lock +8 -8
- langgraph_api-0.18.0.dev13/langgraph_api/__init__.py +0 -1
- langgraph_api-0.18.0.dev13/langgraph_grpc_common/proto/core_api_pb2.py +0 -292
- langgraph_api-0.18.0.dev13/langgraph_grpc_common/proto/orchestrator_pb2.py +0 -50
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/.gitignore +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/LICENSE +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/README.md +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/.gitignore +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/Makefile +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/README.md +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/REPORTS.md +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/assistant.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/benchmarks.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/classify-error.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/classify-error.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/delta-turns-lib.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/delta-turns-lib.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/delta_turns.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/interrupt_resume.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/log-failure.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/meta_workload.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/store.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/stream_write.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/thread.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/types.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/benchmark-runners/wait_write.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/capacity-ci.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/capacity-ci.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/clean-cli.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/clean.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/continuous/README.md +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/continuous/pyproject.toml +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/continuous/runner.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/continuous/uv.lock +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/cpu-probe.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/daily-report.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/daily-report.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/delta-report.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/delta-report.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/graphs.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/history.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/history.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/host-v2.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/host-v2.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/multer.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/package.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/ramp.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/runner-descriptions.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/server-metrics.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/server-metrics.test.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/slack.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/staircase.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/staircase_step_k6.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/tsconfig.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/update-revision.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/weather.js +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/benchmark/yarn.lock +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/custom_store.sql +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/forbidden.txt +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/hatch_build.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/healthcheck.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph-cloud-debugging-20260210132856.zip +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/_checkpointer/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/_checkpointer/_adapter.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/_checkpointer/protocol.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/_factory_utils.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui_schemas/README.md +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui_schemas/client_capabilities.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui_schemas/client_data_model.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui_schemas/client_to_server.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/a2ui_schemas/server_to_client.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/event_streaming.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_call_thread.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_calls.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_constants.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_digest.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_origins.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_outcome.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_pauses.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_request_state.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_routes.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_sanitizers.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_sdk.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_server.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_tools.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/errors.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/beacon_data_plane_jwt_auth.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/cache.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/command.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/config/_parse.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/drain.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/aes_json.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/custom.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/middleware.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/encryption/shared.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/capabilities.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/constants.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/event_normalizers.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/namespace.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/service.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/state_normalizers.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/event_streaming/types.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/executor/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/feature_flags.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/client.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/cache.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/ops/crons.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/server.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/servicers/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/grpc/servicers/encryption.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/http.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/.yarnclean +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/auth-mutations.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/lc_security/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/lc_security/exceptions.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/lc_security/policy.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/lc_security/transport.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/middleware/ensure_store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/operator_routes.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/otel_context.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/release_tags.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/route.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/server.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/state.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/stream_v2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/timing/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/timing/profiler.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/timing/startup.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/timing/timer.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/tracing_session.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/extract.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/network.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/worker_runtime.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/checkpointer.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/_compat.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/config.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/durability.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/struct.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/conversion/value.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/store_pb2.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/serde.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_grpc_common/store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/encryption.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/routes.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/logging.json +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/scripts/build_wheel.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/scripts/create_license.py +0 -0
- {langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/scripts/run_a2a_tck.py +0 -0
|
@@ -108,9 +108,11 @@ endif
|
|
|
108
108
|
|
|
109
109
|
REVISION ?= $(shell git rev-parse --short HEAD)
|
|
110
110
|
LANGGRAPH_ENCRYPTION ?=
|
|
111
|
+
# The servers' priority callback, off by default; tests/graphs/custom_priority.py to test it.
|
|
112
|
+
LANGGRAPH_PRIORITY ?=
|
|
111
113
|
|
|
112
114
|
test-license-oss:
|
|
113
|
-
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_CHECKPOINTER='$(CHECKPOINTER_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run pytest -v $(PYTEST_ROOT_ARGS) $(XDIST_ARGS) $(TEST)
|
|
115
|
+
LANGGRAPH_PRIORITY='$(LANGGRAPH_PRIORITY)' LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_CHECKPOINTER='$(CHECKPOINTER_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run pytest -v $(PYTEST_ROOT_ARGS) $(XDIST_ARGS) $(TEST)
|
|
114
116
|
|
|
115
117
|
test-watch-oss:
|
|
116
118
|
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run --no-sync ptw . -- -x -vv --ff --capture=no $(TEST)
|
|
@@ -200,6 +202,7 @@ LANGSMITH_TRACING ?= false
|
|
|
200
202
|
start:
|
|
201
203
|
LANGGRAPH_DISABLE_FILE_PERSISTENCE=$(LANGGRAPH_DISABLE_FILE_PERSISTENCE) \
|
|
202
204
|
LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' \
|
|
205
|
+
LANGGRAPH_PRIORITY='$(LANGGRAPH_PRIORITY)' \
|
|
203
206
|
LANGGRAPH_HTTP='$(HTTP_CONFIG)' \
|
|
204
207
|
LANGGRAPH_RUNTIME_EDITION=inmem \
|
|
205
208
|
LANGGRAPH_AES_KEY='$(LANGGRAPH_AES_KEY)' \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.18.0.
|
|
3
|
+
Version: 0.18.0.dev14
|
|
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
|
|
@@ -13,7 +13,7 @@ Requires-Dist: grpcio-tools==1.81.1
|
|
|
13
13
|
Requires-Dist: grpcio<1.82.0,>=1.81.0
|
|
14
14
|
Requires-Dist: httptools>=0.5.0; platform_system != 'Windows'
|
|
15
15
|
Requires-Dist: httpx>=0.25.0
|
|
16
|
-
Requires-Dist: jsonschema-rs<0.45,>=0.
|
|
16
|
+
Requires-Dist: jsonschema-rs<0.45,>=0.35.0
|
|
17
17
|
Requires-Dist: langchain-core>=0.3.64
|
|
18
18
|
Requires-Dist: langchain-protocol<0.1,>=0.0.18
|
|
19
19
|
Requires-Dist: langgraph-checkpoint<5,>=3.0.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.18.0.dev14"
|
{langgraph_api-0.18.0.dev13 → langgraph_api-0.18.0.dev14}/langgraph_api/api/mcp/_elicitation.py
RENAMED
|
@@ -3,18 +3,20 @@ from __future__ import annotations
|
|
|
3
3
|
import re
|
|
4
4
|
from collections import Counter
|
|
5
5
|
from contextlib import contextmanager
|
|
6
|
-
from dataclasses import dataclass, replace
|
|
7
|
-
from typing import TYPE_CHECKING, Literal, Protocol
|
|
6
|
+
from dataclasses import dataclass, field, replace
|
|
7
|
+
from typing import TYPE_CHECKING, Literal, NoReturn, Protocol, TypeGuard
|
|
8
8
|
from urllib.parse import urlsplit
|
|
9
9
|
|
|
10
|
+
import jsonschema_rs
|
|
10
11
|
import mcp_types as types
|
|
11
12
|
import orjson
|
|
13
|
+
import structlog
|
|
12
14
|
from mcp.shared.exceptions import MCPError
|
|
13
15
|
from pydantic import TypeAdapter, ValidationError
|
|
14
16
|
|
|
15
17
|
from langgraph_api.api.mcp._constants import UNASKABLE_INPUT_MESSAGE
|
|
16
18
|
from langgraph_api.api.mcp._digest import digest
|
|
17
|
-
from langgraph_api.api.mcp._forms import FormSchema, UnsupportedSchema
|
|
19
|
+
from langgraph_api.api.mcp._forms import FormSchema, FormTooLarge, UnsupportedSchema
|
|
18
20
|
from langgraph_api.api.mcp._origins import LOOPBACK_HOSTS
|
|
19
21
|
from langgraph_api.api.mcp._outcome import Failed
|
|
20
22
|
|
|
@@ -24,6 +26,9 @@ if TYPE_CHECKING:
|
|
|
24
26
|
from pydantic import JsonValue
|
|
25
27
|
|
|
26
28
|
from langgraph_api.schema import Interrupt
|
|
29
|
+
from langgraph_api.validation import SchemaValidator
|
|
30
|
+
|
|
31
|
+
logger = structlog.stdlib.get_logger(__name__)
|
|
27
32
|
|
|
28
33
|
TEXT_ANSWER: dict[str, JsonValue] = {"type": "string"}
|
|
29
34
|
ELICIT_PARAMS: TypeAdapter[types.ElicitRequestParams] = TypeAdapter(
|
|
@@ -39,6 +44,25 @@ Refusal = Literal["decline", "cancel"]
|
|
|
39
44
|
Mode = Literal["form", "url"]
|
|
40
45
|
ENDED: dict[Refusal, str] = {"decline": "declined", "cancel": "cancelled"}
|
|
41
46
|
Results = dict[str, types.ElicitResult]
|
|
47
|
+
DECISION_TITLES: dict[str, str] = {
|
|
48
|
+
"approve": "Approve",
|
|
49
|
+
"edit": "Edit the arguments",
|
|
50
|
+
"reject": "Reject",
|
|
51
|
+
"respond": "Answer for the tool",
|
|
52
|
+
}
|
|
53
|
+
MESSAGE_DECISIONS = frozenset({"reject", "respond"})
|
|
54
|
+
REVIEW_MESSAGE: dict[str, JsonValue] = {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"title": "Message",
|
|
57
|
+
"description": "Why you reject the call, or the answer to send in its place",
|
|
58
|
+
}
|
|
59
|
+
REVIEW_ARGS: dict[str, JsonValue] = {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"title": "Arguments",
|
|
62
|
+
"description": "The arguments to run the tool with, as a JSON object",
|
|
63
|
+
}
|
|
64
|
+
DECISION_TYPE_PATH: list[str | int] = ["type"]
|
|
65
|
+
ANY_DECISION = jsonschema_rs.validator_for({})
|
|
42
66
|
|
|
43
67
|
|
|
44
68
|
class UnaskableInterrupt(ValueError):
|
|
@@ -199,6 +223,163 @@ class RelayedRequests:
|
|
|
199
223
|
}
|
|
200
224
|
|
|
201
225
|
|
|
226
|
+
@dataclass(frozen=True, slots=True)
|
|
227
|
+
class ReviewDialect:
|
|
228
|
+
allowed_decisions: str
|
|
229
|
+
edited_action: str
|
|
230
|
+
|
|
231
|
+
def decisions_of(self, config: JsonValue) -> JsonValue:
|
|
232
|
+
return config.get(self.allowed_decisions) if isinstance(config, dict) else None
|
|
233
|
+
|
|
234
|
+
def edit(self, name: str, args: dict[str, JsonValue]) -> dict[str, JsonValue]:
|
|
235
|
+
return {"type": "edit", self.edited_action: {"name": name, "args": args}}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
SNAKE_CASE = ReviewDialect("allowed_decisions", "edited_action")
|
|
239
|
+
CAMEL_CASE = ReviewDialect("allowedDecisions", "editedAction")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass(slots=True)
|
|
243
|
+
class ReviewKeys:
|
|
244
|
+
asked: Counter[str] = field(default_factory=Counter)
|
|
245
|
+
|
|
246
|
+
def next(self, *action: JsonValue) -> str:
|
|
247
|
+
reviewed = digest(*action)
|
|
248
|
+
self.asked[reviewed] += 1
|
|
249
|
+
return f"review-{reviewed}.{self.asked[reviewed]}"
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@dataclass(frozen=True, slots=True)
|
|
253
|
+
class ReviewedAction:
|
|
254
|
+
name: str
|
|
255
|
+
decisions: tuple[str, ...]
|
|
256
|
+
question: FormQuestion
|
|
257
|
+
dialect: ReviewDialect
|
|
258
|
+
|
|
259
|
+
@classmethod
|
|
260
|
+
def of(
|
|
261
|
+
cls,
|
|
262
|
+
request: JsonValue,
|
|
263
|
+
decisions: JsonValue,
|
|
264
|
+
dialect: ReviewDialect,
|
|
265
|
+
*,
|
|
266
|
+
keys: ReviewKeys,
|
|
267
|
+
) -> ReviewedAction:
|
|
268
|
+
match request:
|
|
269
|
+
case {
|
|
270
|
+
"name": str() as name,
|
|
271
|
+
"args": dict() as args,
|
|
272
|
+
**rest,
|
|
273
|
+
} if _are_decisions(decisions):
|
|
274
|
+
allowed = tuple(dict.fromkeys(decisions))
|
|
275
|
+
message = _text(rest.get("description")) or f"Run {name}?"
|
|
276
|
+
key = keys.next(name, args, message, allowed)
|
|
277
|
+
question = FormQuestion(key, message, _review_form(args, allowed))
|
|
278
|
+
return cls(name, allowed, question, dialect)
|
|
279
|
+
case _:
|
|
280
|
+
raise UnaskableInterrupt(
|
|
281
|
+
"A review needs a tool name, its arguments and its decisions"
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
def refusal(self, results: Results) -> EndCall | None:
|
|
285
|
+
match results[self.question.key].action:
|
|
286
|
+
case "cancel":
|
|
287
|
+
return EndCall("cancel")
|
|
288
|
+
case "decline" if "reject" not in self.decisions:
|
|
289
|
+
return EndCall("decline")
|
|
290
|
+
case _:
|
|
291
|
+
return None
|
|
292
|
+
|
|
293
|
+
def decision(self, results: Results) -> dict[str, JsonValue]:
|
|
294
|
+
result = results[self.question.key]
|
|
295
|
+
if result.action == "decline":
|
|
296
|
+
return {"type": "reject"}
|
|
297
|
+
return _decision(self.name, self.question.answer(result), self.dialect)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@dataclass(frozen=True, slots=True)
|
|
301
|
+
class ReviewPrompt:
|
|
302
|
+
actions: tuple[ReviewedAction, ...]
|
|
303
|
+
|
|
304
|
+
@classmethod
|
|
305
|
+
def of(
|
|
306
|
+
cls,
|
|
307
|
+
requests: Sequence[JsonValue],
|
|
308
|
+
configs: Sequence[JsonValue],
|
|
309
|
+
dialect: ReviewDialect,
|
|
310
|
+
*,
|
|
311
|
+
keys: ReviewKeys,
|
|
312
|
+
) -> ReviewPrompt:
|
|
313
|
+
if len(requests) != len(configs):
|
|
314
|
+
raise UnaskableInterrupt("A review needs one review config per action")
|
|
315
|
+
return cls(
|
|
316
|
+
tuple(
|
|
317
|
+
ReviewedAction.of(
|
|
318
|
+
request, dialect.decisions_of(config), dialect, keys=keys
|
|
319
|
+
)
|
|
320
|
+
for request, config in zip(requests, configs, strict=True)
|
|
321
|
+
)
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def questions(self) -> tuple[FormQuestion, ...]:
|
|
326
|
+
return tuple(action.question for action in self.actions)
|
|
327
|
+
|
|
328
|
+
def scoped(self, scope: str) -> ReviewPrompt:
|
|
329
|
+
return self
|
|
330
|
+
|
|
331
|
+
def refusal(self, results: Results) -> EndCall | None:
|
|
332
|
+
for action in self.actions:
|
|
333
|
+
if (refusal := action.refusal(results)) is not None:
|
|
334
|
+
return refusal
|
|
335
|
+
return None
|
|
336
|
+
|
|
337
|
+
def resume_value(self, results: Results) -> JsonValue:
|
|
338
|
+
return {"decisions": [action.decision(results) for action in self.actions]}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@dataclass(frozen=True, slots=True)
|
|
342
|
+
class DecisionSchema:
|
|
343
|
+
schema: JsonValue
|
|
344
|
+
|
|
345
|
+
def checked(self, decision: dict[str, JsonValue]) -> dict[str, JsonValue]:
|
|
346
|
+
validator = _decision_validator(self.schema)
|
|
347
|
+
try:
|
|
348
|
+
validator.validate(decision)
|
|
349
|
+
except jsonschema_rs.ValidationError as error:
|
|
350
|
+
raise InvalidAnswer(
|
|
351
|
+
f"The decision does not fit the tool: {_reason(error)}"
|
|
352
|
+
) from None
|
|
353
|
+
return decision
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
@dataclass(frozen=True, slots=True)
|
|
357
|
+
class ToolApprovalPrompt:
|
|
358
|
+
action: ReviewedAction
|
|
359
|
+
schema: DecisionSchema
|
|
360
|
+
|
|
361
|
+
@classmethod
|
|
362
|
+
def of(
|
|
363
|
+
cls, approval: JsonValue, schema: JsonValue, *, keys: ReviewKeys
|
|
364
|
+
) -> ToolApprovalPrompt:
|
|
365
|
+
decisions = _approval_decisions(schema)
|
|
366
|
+
action = ReviewedAction.of(approval, decisions, SNAKE_CASE, keys=keys)
|
|
367
|
+
return cls(action, DecisionSchema(schema))
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
def questions(self) -> tuple[FormQuestion]:
|
|
371
|
+
return (self.action.question,)
|
|
372
|
+
|
|
373
|
+
def scoped(self, scope: str) -> ToolApprovalPrompt:
|
|
374
|
+
return self
|
|
375
|
+
|
|
376
|
+
def refusal(self, results: Results) -> EndCall | None:
|
|
377
|
+
return self.action.refusal(results)
|
|
378
|
+
|
|
379
|
+
def resume_value(self, results: Results) -> JsonValue:
|
|
380
|
+
return self.schema.checked(self.action.decision(results))
|
|
381
|
+
|
|
382
|
+
|
|
202
383
|
@dataclass(frozen=True, slots=True)
|
|
203
384
|
class Round:
|
|
204
385
|
prompts: Mapping[str, Prompt]
|
|
@@ -206,8 +387,10 @@ class Round:
|
|
|
206
387
|
|
|
207
388
|
@classmethod
|
|
208
389
|
def of(cls, interrupts: Sequence[Interrupt]) -> Round:
|
|
390
|
+
keys = ReviewKeys()
|
|
209
391
|
prompts = {
|
|
210
|
-
_interrupt_id(interrupt): _prompt(interrupt)
|
|
392
|
+
_interrupt_id(interrupt): _prompt(interrupt, keys)
|
|
393
|
+
for interrupt in interrupts
|
|
211
394
|
}
|
|
212
395
|
if len(prompts) > 1:
|
|
213
396
|
scopes = _scopes(interrupts)
|
|
@@ -260,7 +443,7 @@ class Round:
|
|
|
260
443
|
return Resume(resumed)
|
|
261
444
|
|
|
262
445
|
|
|
263
|
-
def _prompt(interrupt: Interrupt) -> Prompt:
|
|
446
|
+
def _prompt(interrupt: Interrupt, keys: ReviewKeys) -> Prompt:
|
|
264
447
|
match interrupt["value"]:
|
|
265
448
|
case {"type": "mcp_elicitation", "requests": [_, *_] as listed}:
|
|
266
449
|
return RelayedRequests(tuple(map(_listed_question, listed)))
|
|
@@ -270,6 +453,19 @@ def _prompt(interrupt: Interrupt) -> Prompt:
|
|
|
270
453
|
)
|
|
271
454
|
case {"type": "mcp_elicitation"}:
|
|
272
455
|
raise UnaskableInterrupt("An mcp_elicitation interrupt needs a request")
|
|
456
|
+
case {"type": "tool_approval"} as approval:
|
|
457
|
+
schema = interrupt.get("response_schema")
|
|
458
|
+
return ToolApprovalPrompt.of(approval, schema, keys=keys)
|
|
459
|
+
case {
|
|
460
|
+
"action_requests": [_, *_] as requests,
|
|
461
|
+
"review_configs": list() as configs,
|
|
462
|
+
}:
|
|
463
|
+
return ReviewPrompt.of(requests, configs, SNAKE_CASE, keys=keys)
|
|
464
|
+
case {
|
|
465
|
+
"actionRequests": [_, *_] as requests,
|
|
466
|
+
"reviewConfigs": list() as configs,
|
|
467
|
+
}:
|
|
468
|
+
return ReviewPrompt.of(requests, configs, CAMEL_CASE, keys=keys)
|
|
273
469
|
case _:
|
|
274
470
|
return AnswerPrompt.of(interrupt)
|
|
275
471
|
|
|
@@ -314,6 +510,123 @@ def _elicit_params(request: JsonValue) -> types.ElicitRequestParams | None:
|
|
|
314
510
|
return None
|
|
315
511
|
|
|
316
512
|
|
|
513
|
+
def _are_decisions(values: JsonValue) -> TypeGuard[list[str]]:
|
|
514
|
+
return (
|
|
515
|
+
isinstance(values, list)
|
|
516
|
+
and bool(values)
|
|
517
|
+
and all(isinstance(value, str) and value in DECISION_TITLES for value in values)
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _approval_decisions(schema: JsonValue) -> JsonValue:
|
|
522
|
+
match schema:
|
|
523
|
+
case {"discriminator": {"mapping": dict() as mapping}}:
|
|
524
|
+
return list(mapping)
|
|
525
|
+
case {"oneOf": [*branches]} | {"anyOf": [*branches]}:
|
|
526
|
+
return [_decision_type(branch) for branch in branches]
|
|
527
|
+
case _:
|
|
528
|
+
return [_decision_type(schema)]
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def _decision_type(branch: JsonValue) -> JsonValue:
|
|
532
|
+
match branch:
|
|
533
|
+
case {"properties": {"type": {"const": str() as decision}}}:
|
|
534
|
+
return decision
|
|
535
|
+
case _:
|
|
536
|
+
return None
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def _decision_validator(schema: JsonValue) -> SchemaValidator:
|
|
540
|
+
try:
|
|
541
|
+
return jsonschema_rs.validator_for(
|
|
542
|
+
schema, retriever=_never_fetch, validate_formats=False
|
|
543
|
+
)
|
|
544
|
+
except jsonschema_rs.ValidationError as error:
|
|
545
|
+
logger.warning(
|
|
546
|
+
"A tool approval's response_schema does not compile, "
|
|
547
|
+
"so this answer is not checked",
|
|
548
|
+
error=error.message,
|
|
549
|
+
)
|
|
550
|
+
return ANY_DECISION
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def _never_fetch(uri: str) -> NoReturn:
|
|
554
|
+
raise ValueError(f"The server never fetches {uri}")
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def _reason(error: jsonschema_rs.ValidationError) -> str:
|
|
558
|
+
match error.kind:
|
|
559
|
+
case (
|
|
560
|
+
jsonschema_rs.ValidationErrorKind.OneOfNotValid(context=branches)
|
|
561
|
+
| jsonschema_rs.ValidationErrorKind.AnyOf(context=branches)
|
|
562
|
+
):
|
|
563
|
+
for errors in branches:
|
|
564
|
+
if not _rejects_the_type(errors):
|
|
565
|
+
return errors[0].message
|
|
566
|
+
return error.message
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def _rejects_the_type(errors: list[jsonschema_rs.ValidationError]) -> bool:
|
|
570
|
+
return any(error.instance_path == DECISION_TYPE_PATH for error in errors)
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def _review_form(args: dict[str, JsonValue], decisions: tuple[str, ...]) -> FormSchema:
|
|
574
|
+
with _unaskable_schemas():
|
|
575
|
+
try:
|
|
576
|
+
return FormSchema.of(_review_schema(args, decisions))
|
|
577
|
+
except FormTooLarge:
|
|
578
|
+
uneditable = tuple(decision for decision in decisions if decision != "edit")
|
|
579
|
+
if not uneditable:
|
|
580
|
+
raise
|
|
581
|
+
return FormSchema.of(_review_schema(args, uneditable))
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
def _review_schema(
|
|
585
|
+
args: dict[str, JsonValue], decisions: tuple[str, ...]
|
|
586
|
+
) -> dict[str, JsonValue]:
|
|
587
|
+
choices = [
|
|
588
|
+
{"const": decision, "title": DECISION_TITLES[decision]}
|
|
589
|
+
for decision in decisions
|
|
590
|
+
]
|
|
591
|
+
fields: dict[str, JsonValue] = {
|
|
592
|
+
"decision": {"type": "string", "title": "Decision", "oneOf": choices}
|
|
593
|
+
}
|
|
594
|
+
if MESSAGE_DECISIONS.intersection(decisions):
|
|
595
|
+
fields["message"] = REVIEW_MESSAGE
|
|
596
|
+
if "edit" in decisions:
|
|
597
|
+
fields["args"] = {**REVIEW_ARGS, "default": orjson.dumps(args).decode()}
|
|
598
|
+
return {"type": "object", "properties": fields, "required": ["decision"]}
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
def _decision(
|
|
602
|
+
name: str, answer: JsonValue, dialect: ReviewDialect
|
|
603
|
+
) -> dict[str, JsonValue]:
|
|
604
|
+
match answer:
|
|
605
|
+
case {"decision": "approve"}:
|
|
606
|
+
return {"type": "approve"}
|
|
607
|
+
case {"decision": "reject", **rest}:
|
|
608
|
+
reason = _text(rest.get("message"))
|
|
609
|
+
return (
|
|
610
|
+
{"type": "reject", "message": reason} if reason else {"type": "reject"}
|
|
611
|
+
)
|
|
612
|
+
case {"decision": "respond", "message": str() as message} if _text(message):
|
|
613
|
+
return {"type": "respond", "message": message}
|
|
614
|
+
case {"decision": "edit", "args": str() as args}:
|
|
615
|
+
return dialect.edit(name, _json_object(args))
|
|
616
|
+
case _:
|
|
617
|
+
raise InvalidAnswer("A decision needs its message or its arguments")
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
def _json_object(text: str) -> dict[str, JsonValue]:
|
|
621
|
+
try:
|
|
622
|
+
value = orjson.loads(text)
|
|
623
|
+
except orjson.JSONDecodeError:
|
|
624
|
+
value = None
|
|
625
|
+
if not isinstance(value, dict):
|
|
626
|
+
raise InvalidAnswer("Edited arguments must be a JSON object")
|
|
627
|
+
return value
|
|
628
|
+
|
|
629
|
+
|
|
317
630
|
def _safe_url(url: str) -> str:
|
|
318
631
|
try:
|
|
319
632
|
parsed = urlsplit(url)
|
|
@@ -37,6 +37,10 @@ class UnsupportedSchema(ValueError):
|
|
|
37
37
|
pass
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
class FormTooLarge(UnsupportedSchema):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
40
44
|
@dataclass(frozen=True, slots=True)
|
|
41
45
|
class Definitions:
|
|
42
46
|
schemas: Mapping[str, JsonValue]
|
|
@@ -71,7 +75,7 @@ class FormSize:
|
|
|
71
75
|
def plus(self, value: JsonValue) -> Self:
|
|
72
76
|
encoded = _encoded(value)
|
|
73
77
|
if encoded is None or self.used + len(encoded) > MAX_FORM_BYTES:
|
|
74
|
-
raise
|
|
78
|
+
raise FormTooLarge(f"A form can't be over {MAX_FORM_BYTES} bytes")
|
|
75
79
|
return replace(self, used=self.used + len(encoded))
|
|
76
80
|
|
|
77
81
|
|
|
@@ -40,7 +40,7 @@ from langgraph_api.validation import (
|
|
|
40
40
|
RunsCancel,
|
|
41
41
|
ThreadCronCreate,
|
|
42
42
|
)
|
|
43
|
-
from langgraph_api.webhook import
|
|
43
|
+
from langgraph_api.webhook import validate_or_drop_webhook
|
|
44
44
|
from langgraph_runtime.database import connect
|
|
45
45
|
from langgraph_runtime.retry import retry_db
|
|
46
46
|
|
|
@@ -294,7 +294,9 @@ async def create_stateless_run(request: ApiRequest):
|
|
|
294
294
|
)
|
|
295
295
|
return ApiResponse(
|
|
296
296
|
run,
|
|
297
|
-
headers={
|
|
297
|
+
headers={
|
|
298
|
+
"Content-Location": f"/threads/{run['thread_id']}/runs/{run['run_id']}"
|
|
299
|
+
},
|
|
298
300
|
)
|
|
299
301
|
|
|
300
302
|
|
|
@@ -415,8 +417,8 @@ async def stream_run_stateless(
|
|
|
415
417
|
return EventSourceResponse(
|
|
416
418
|
body(),
|
|
417
419
|
headers={
|
|
418
|
-
"Location": f"/runs/{run['run_id']}/stream",
|
|
419
|
-
"Content-Location": f"/runs/{run['run_id']}",
|
|
420
|
+
"Location": f"/threads/{run['thread_id']}/runs/{run['run_id']}/stream",
|
|
421
|
+
"Content-Location": f"/threads/{run['thread_id']}/runs/{run['run_id']}",
|
|
420
422
|
},
|
|
421
423
|
on_close=lambda: sub.__aexit__(None, None, None),
|
|
422
424
|
)
|
|
@@ -598,11 +600,15 @@ async def join_run(request: ApiRequest):
|
|
|
598
600
|
fallback=_thread_values_fallback(thread_id),
|
|
599
601
|
)
|
|
600
602
|
|
|
603
|
+
# Clients reconnect to Location as-is, so it keeps the request's query.
|
|
604
|
+
query = f"?{request.url.query}" if request.url.query else ""
|
|
605
|
+
location = f"/threads/{thread_id}/runs/{run_id}/join{query}"
|
|
606
|
+
|
|
601
607
|
return StreamingResponse(
|
|
602
608
|
body(),
|
|
603
609
|
media_type="application/json",
|
|
604
610
|
headers={
|
|
605
|
-
"Location":
|
|
611
|
+
"Location": location,
|
|
606
612
|
"Content-Location": f"/threads/{thread_id}/runs/{run_id}",
|
|
607
613
|
},
|
|
608
614
|
)
|
|
@@ -618,8 +624,11 @@ async def join_run_stream(request: ApiRequest):
|
|
|
618
624
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
619
625
|
validate_uuid(run_id, "Invalid run ID: must be a UUID")
|
|
620
626
|
|
|
621
|
-
|
|
622
|
-
|
|
627
|
+
stream_mode = [
|
|
628
|
+
mode
|
|
629
|
+
for value in request.query_params.getlist("stream_mode")
|
|
630
|
+
for mode in parse_stream_mode_param(value)
|
|
631
|
+
]
|
|
623
632
|
|
|
624
633
|
last_event_id = request.headers.get("last-event-id") or None
|
|
625
634
|
|
|
@@ -639,10 +648,14 @@ async def join_run_stream(request: ApiRequest):
|
|
|
639
648
|
# Clean up the stream handler
|
|
640
649
|
await sub.__aexit__(None, None, None)
|
|
641
650
|
|
|
651
|
+
# Clients reconnect to Location as-is, so it keeps the request's query.
|
|
652
|
+
query = f"?{request.url.query}" if request.url.query else ""
|
|
653
|
+
location = f"/threads/{thread_id}/runs/{run_id}/stream{query}"
|
|
654
|
+
|
|
642
655
|
return EventSourceResponse(
|
|
643
656
|
body(),
|
|
644
657
|
headers={
|
|
645
|
-
"Location":
|
|
658
|
+
"Location": location,
|
|
646
659
|
"Content-Location": f"/threads/{thread_id}/runs/{run_id}",
|
|
647
660
|
},
|
|
648
661
|
)
|
|
@@ -766,8 +779,7 @@ async def delete_run(request: ApiRequest):
|
|
|
766
779
|
async def create_cron(request: ApiRequest):
|
|
767
780
|
"""Create a cron with new thread."""
|
|
768
781
|
payload = await request.json(CronCreate)
|
|
769
|
-
|
|
770
|
-
await validate_webhook_url_or_raise(str(webhook))
|
|
782
|
+
await validate_or_drop_webhook(payload)
|
|
771
783
|
_validate_assistant_id(payload.get("assistant_id"))
|
|
772
784
|
timezone = validate_timezone(payload.get("timezone"))
|
|
773
785
|
|
|
@@ -798,8 +810,7 @@ async def create_thread_cron(request: ApiRequest):
|
|
|
798
810
|
thread_id = request.path_params["thread_id"]
|
|
799
811
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
800
812
|
payload = await request.json(ThreadCronCreate)
|
|
801
|
-
|
|
802
|
-
await validate_webhook_url_or_raise(str(webhook))
|
|
813
|
+
await validate_or_drop_webhook(payload)
|
|
803
814
|
_validate_assistant_id(payload.get("assistant_id"))
|
|
804
815
|
timezone = validate_timezone(payload.get("timezone"))
|
|
805
816
|
|
|
@@ -842,8 +853,14 @@ async def patch_cron(request: ApiRequest):
|
|
|
842
853
|
raise HTTPException(status_code=400, detail="Request body cannot be empty")
|
|
843
854
|
timezone = validate_timezone(payload.get("timezone"))
|
|
844
855
|
|
|
845
|
-
|
|
846
|
-
|
|
856
|
+
await validate_or_drop_webhook(payload)
|
|
857
|
+
# The body was non-empty above, so it is empty here only when its sole field
|
|
858
|
+
# was a webhook dropped because webhooks are disabled.
|
|
859
|
+
if not payload:
|
|
860
|
+
raise HTTPException(
|
|
861
|
+
status_code=422,
|
|
862
|
+
detail="Webhooks are disabled on this server, so `webhook` can't be updated",
|
|
863
|
+
)
|
|
847
864
|
|
|
848
865
|
# An explicit `end_time: null` clears the end time; an absent key leaves it unchanged.
|
|
849
866
|
clear_end_time = "end_time" in payload and payload["end_time"] is None
|
|
@@ -585,9 +585,9 @@ async def join_thread_stream(request: ApiRequest):
|
|
|
585
585
|
"""Join a thread stream."""
|
|
586
586
|
thread_id = request.path_params["thread_id"]
|
|
587
587
|
validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
|
|
588
|
-
last_event_id =
|
|
589
|
-
|
|
590
|
-
|
|
588
|
+
last_event_id = validate_stream_id(
|
|
589
|
+
request.headers.get("last-event-id") or None,
|
|
590
|
+
"Invalid last-event-id: must be a valid Redis stream ID",
|
|
591
591
|
)
|
|
592
592
|
|
|
593
593
|
# The SDKs send ``stream_mode``: once per mode, or as one JSON array from
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import concurrent.futures
|
|
3
|
+
import sys
|
|
3
4
|
from collections.abc import AsyncIterator, Coroutine, Generator
|
|
4
5
|
from contextlib import (
|
|
5
6
|
AbstractAsyncContextManager,
|
|
@@ -13,6 +14,11 @@ from typing import Any, Generic, TypeVar
|
|
|
13
14
|
import structlog
|
|
14
15
|
import uvicorn
|
|
15
16
|
|
|
17
|
+
if sys.platform == "win32":
|
|
18
|
+
_MAIN_LOOP_FACTORY = None
|
|
19
|
+
else:
|
|
20
|
+
from uvloop import new_event_loop as _MAIN_LOOP_FACTORY
|
|
21
|
+
|
|
16
22
|
T = TypeVar("T")
|
|
17
23
|
|
|
18
24
|
logger = structlog.stdlib.get_logger(__name__)
|
|
@@ -50,6 +56,11 @@ def get_event_loop() -> asyncio.AbstractEventLoop:
|
|
|
50
56
|
return _MAIN_LOOP
|
|
51
57
|
|
|
52
58
|
|
|
59
|
+
def run_main_loop(main: Coroutine[object, object, T]) -> T:
|
|
60
|
+
with asyncio.Runner(loop_factory=_MAIN_LOOP_FACTORY) as runner:
|
|
61
|
+
return runner.run(main)
|
|
62
|
+
|
|
63
|
+
|
|
53
64
|
async def sleep_if_not_done(delay: float, done: asyncio.Event) -> None:
|
|
54
65
|
with suppress(TimeoutError):
|
|
55
66
|
await asyncio.wait_for(done.wait(), delay)
|
|
@@ -19,7 +19,12 @@ from typing import Literal
|
|
|
19
19
|
if typing.TYPE_CHECKING:
|
|
20
20
|
from packaging.version import Version
|
|
21
21
|
|
|
22
|
-
from langgraph_api.config import
|
|
22
|
+
from langgraph_api.config import (
|
|
23
|
+
AuthConfig,
|
|
24
|
+
HttpConfig,
|
|
25
|
+
PriorityConfig,
|
|
26
|
+
StoreConfig,
|
|
27
|
+
)
|
|
23
28
|
|
|
24
29
|
logging.basicConfig(level=logging.INFO)
|
|
25
30
|
logger = logging.getLogger(__name__)
|
|
@@ -184,6 +189,7 @@ def run_server(
|
|
|
184
189
|
reload_excludes: Sequence[str] | None = None,
|
|
185
190
|
store: typing.Optional["StoreConfig"] = None,
|
|
186
191
|
auth: typing.Optional["AuthConfig"] = None,
|
|
192
|
+
priority: typing.Optional["PriorityConfig"] = None,
|
|
187
193
|
http: typing.Optional["HttpConfig"] = None,
|
|
188
194
|
ui: dict | None = None,
|
|
189
195
|
webhooks: dict | None = None,
|
|
@@ -270,6 +276,7 @@ def run_server(
|
|
|
270
276
|
LANGSERVE_GRAPHS=json.dumps(graphs) if graphs else None,
|
|
271
277
|
LANGSMITH_LANGGRAPH_API_VARIANT="local_dev",
|
|
272
278
|
LANGGRAPH_AUTH=json.dumps(auth) if auth else None,
|
|
279
|
+
LANGGRAPH_PRIORITY=json.dumps(priority) if priority else None,
|
|
273
280
|
LANGGRAPH_HTTP=json.dumps(http) if http else None,
|
|
274
281
|
LANGGRAPH_UI=json.dumps(ui) if ui else None,
|
|
275
282
|
LANGGRAPH_WEBHOOKS=json.dumps(webhooks) if webhooks else None,
|
|
@@ -18,6 +18,7 @@ from langgraph_api.config.schemas import (
|
|
|
18
18
|
CorsConfig,
|
|
19
19
|
EncryptionConfig,
|
|
20
20
|
HttpConfig,
|
|
21
|
+
PriorityConfig,
|
|
21
22
|
SerdeConfig,
|
|
22
23
|
StoreConfig,
|
|
23
24
|
ThreadTTLConfig,
|
|
@@ -611,6 +612,14 @@ LANGGRAPH_AUTH = env(
|
|
|
611
612
|
LANGGRAPH_ENCRYPTION = env(
|
|
612
613
|
"LANGGRAPH_ENCRYPTION", cast=_parse.parse_schema(EncryptionConfig), default=None
|
|
613
614
|
)
|
|
615
|
+
# Not in public docs: populated by langgraph.json config, not set as env var directly
|
|
616
|
+
LANGGRAPH_PRIORITY = env(
|
|
617
|
+
"LANGGRAPH_PRIORITY", cast=_parse.parse_schema(PriorityConfig), default=None
|
|
618
|
+
)
|
|
619
|
+
# Whether the deployment has a priority callback, the one source of run priority levels.
|
|
620
|
+
# Per-level queue stats and metric labels are reported only then, so a deployment without
|
|
621
|
+
# one keeps its metrics as they were.
|
|
622
|
+
PRIORITY_CALLBACK_CONFIGURED = bool(LANGGRAPH_PRIORITY)
|
|
614
623
|
# Not in public docs: set by SaaS control plane, not user-configurable
|
|
615
624
|
LANGSMITH_TENANT_ID = env("LANGSMITH_TENANT_ID", cast=str, default=None)
|
|
616
625
|
LANGSMITH_HOST_PROJECT_ID = env("LANGSMITH_HOST_PROJECT_ID", cast=str, default=None)
|
|
@@ -882,6 +891,7 @@ __all__ = [
|
|
|
882
891
|
"LANGGRAPH_METRICS_ENDPOINT",
|
|
883
892
|
"LANGGRAPH_METRICS_EXPORT_INTERVAL_MS",
|
|
884
893
|
"LANGGRAPH_POSTGRES_EXTENSIONS",
|
|
894
|
+
"LANGGRAPH_PRIORITY",
|
|
885
895
|
"LANGSMITH_API_KEY",
|
|
886
896
|
"LANGSMITH_AUTH_ENDPOINT",
|
|
887
897
|
"LANGSMITH_AUTH_VERIFY_TENANT_ID",
|
|
@@ -900,6 +910,7 @@ __all__ = [
|
|
|
900
910
|
"N_JOBS_PER_WORKER",
|
|
901
911
|
"OTEL_ENABLED",
|
|
902
912
|
"POSTGRES_POOL_MAX_SIZE",
|
|
913
|
+
"PRIORITY_CALLBACK_CONFIGURED",
|
|
903
914
|
"PYTHON_GRPC_BIND_HOST",
|
|
904
915
|
"PYTHON_GRPC_SERVER_ENABLED",
|
|
905
916
|
"PYTHON_GRPC_SERVER_PORT",
|