langgraph-api 0.13.4__tar.gz → 0.14.0__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.13.4 → langgraph_api-0.14.0}/Makefile +21 -19
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/PKG-INFO +3 -3
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/Makefile +8 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/README.md +79 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/benchmark-runner.ts +1 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/benchmark_profiles.ts +20 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/benchmarks.ts +3 -0
- langgraph_api-0.14.0/benchmark/benchmark-runners/classify-error.test.js +116 -0
- langgraph_api-0.14.0/benchmark/benchmark-runners/classify-error.ts +86 -0
- langgraph_api-0.14.0/benchmark/benchmark-runners/delta-turns-lib.test.js +169 -0
- langgraph_api-0.14.0/benchmark/benchmark-runners/delta-turns-lib.ts +102 -0
- langgraph_api-0.14.0/benchmark/benchmark-runners/delta_turns.ts +169 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/log-failure.ts +33 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/stream_write.ts +18 -13
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/threads_search_metadata.ts +45 -22
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/wait_write.ts +19 -12
- langgraph_api-0.14.0/benchmark/capacity-ci.js +658 -0
- langgraph_api-0.14.0/benchmark/capacity-ci.test.js +138 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/clean.js +61 -21
- langgraph_api-0.14.0/benchmark/daily-report.js +263 -0
- langgraph_api-0.14.0/benchmark/daily-report.test.js +242 -0
- langgraph_api-0.14.0/benchmark/host-v2.js +297 -0
- langgraph_api-0.14.0/benchmark/host-v2.test.js +108 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/package.json +4 -2
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/ramp.js +87 -24
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/staircase.py +152 -17
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/staircase_step_k6.js +77 -4
- langgraph_api-0.14.0/benchmark/update-revision.js +20 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/yarn.lock +17 -16
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/constraints.txt +1 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/healthcheck.py +1 -1
- langgraph_api-0.14.0/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/_checkpointer/_adapter.py +13 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/__init__.py +5 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/runs.py +3 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/store.py +7 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/custom.py +43 -7
- langgraph_api-0.14.0/langgraph_api/beacon_data_plane_jwt_auth.py +71 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/config/__init__.py +16 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/config/schemas.py +17 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/custom.py +33 -3
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/middleware.py +17 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/feature_flags.py +0 -6
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/servicers/encryption.py +122 -23
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/client.mts +20 -7
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/package.json +3 -2
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/remote.py +30 -8
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/yarn.lock +13 -18
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/metrics_otlp.py +1 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/queue_entrypoint.py +7 -6
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/release_tags.py +17 -16
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/schema.py +5 -5
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/self_hosted_logs.py +52 -23
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/server.py +5 -3
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/checkpointer.py +21 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/checkpoint.py +1 -2
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/value.py +1 -2
- langgraph_api-0.14.0/langgraph_grpc_common/proto/checkpointer_pb2.py +87 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +56 -2
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/encryption_pb2.py +11 -7
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/encryption_pb2.pyi +61 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +88 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +24 -0
- langgraph_api-0.14.0/langgraph_grpc_common/proto/store_pb2.py +86 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/store_pb2.pyi +27 -1
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/store.py +20 -3
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/pyproject.toml +3 -3
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/uv.lock +56 -56
- langgraph_api-0.13.4/benchmark/update-revision.js +0 -137
- langgraph_api-0.13.4/langgraph_api/__init__.py +0 -1
- langgraph_api-0.13.4/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -79
- langgraph_api-0.13.4/langgraph_grpc_common/proto/store_pb2.py +0 -82
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/.gitignore +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/LICENSE +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/README.md +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/.gitignore +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/assistant.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/meta_workload.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/store.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/thread.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/types.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/clean-cli.js +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/continuous/README.md +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/continuous/pyproject.toml +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/continuous/runner.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/continuous/uv.lock +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/graphs.js +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/tsconfig.json +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/weather.js +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/custom_store.sql +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/forbidden.txt +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/hatch_build.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph-cloud-debugging-20260210132856.zip +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/_checkpointer/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/_checkpointer/protocol.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/_factory_utils.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/event_streaming.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/_constants.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/_handlers.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/_models.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/_routes.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/mcp/_sanitizers.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/errors.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/cache.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/command.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/config/_parse.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/aes_json.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/encryption/shared.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/capabilities.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/constants.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/event_normalizers.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/namespace.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/service.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/session.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/state_normalizers.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/event_streaming/types.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/client.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/assistants.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/cache.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/crons.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/runs.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/ops/threads.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/server.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/servicers/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/http.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/.yarnclean +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/lc_security/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/lc_security/exceptions.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/lc_security/policy.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/lc_security/transport.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/metrics_collector.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/middleware/ensure_store.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/otel_context.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/route.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/self_hosted_metrics.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/state.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/store.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/stream_v2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/timing/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/timing/profiler.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/timing/timer.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/tracing_session.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/extract.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/network.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_api/worker.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/_compat.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/config.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/durability.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/store.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/conversion/struct.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_grpc_common/serde.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/routes.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/logging.json +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/openapi.json +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/scripts/build_wheel.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/scripts/create_license.py +0 -0
- {langgraph_api-0.13.4 → langgraph_api-0.14.0}/scripts/run_a2a_tck.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
.PHONY: build release lint format test test_watch start start-inmem start-inmem-license-oss start
|
|
1
|
+
.PHONY: build release lint format test test_watch start start-inmem start-inmem-license-oss start 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_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", "store_e2e_async": "./tests/graphs/store_e2e.py:graph_async", "store_e2e_sync": "./tests/graphs/store_e2e.py:graph_sync"}'
|
|
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", "benchmark_delta": "./tests/graphs/benchmark.py:graph_delta", "benchmark_delta_freq": "./tests/graphs/benchmark.py:graph_delta_freq", "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", "store_e2e_async": "./tests/graphs/store_e2e.py:graph_async", "store_e2e_sync": "./tests/graphs/store_e2e.py:graph_sync"}'
|
|
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
|
|
@@ -48,6 +48,7 @@ BG_JOB_TIMEOUT_SECS ?= 86400
|
|
|
48
48
|
BG_JOB_ISOLATED_LOOPS ?= false
|
|
49
49
|
CRON_SCHEDULER_SLEEP_TIME ?= 0
|
|
50
50
|
RELOAD_ARGS ?= --reload --reload-dir langgraph_api --reload-dir ../runtime_inmem
|
|
51
|
+
LANGGRAPH_AUTH_LANGSMITH ?= {"path": "tests/graphs/jwt_auth.py:auth", "allow_langsmith_api_keys": true}
|
|
51
52
|
|
|
52
53
|
ifdef CI
|
|
53
54
|
RELOAD_ARGS :=
|
|
@@ -166,6 +167,14 @@ test-auth-fastapi-jwt--after-custom-middleware--custom-route-auth:
|
|
|
166
167
|
test-auth-watch:
|
|
167
168
|
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_AUTH='{"path": "./tests/graphs/fastapi_jwt_auth.py:auth"}' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run ptw . -- -x -vv --ff --capture=no $(AUTH_TEST)
|
|
168
169
|
|
|
170
|
+
test-auth-langsmith-api-keys:
|
|
171
|
+
LANGGRAPH_RUNTIME_EDITION=inmem \
|
|
172
|
+
LANGGRAPH_AUTH='$(LANGGRAPH_AUTH_LANGSMITH)' \
|
|
173
|
+
REDIS_URI=_FAKE \
|
|
174
|
+
DATABASE_URI=:memory: \
|
|
175
|
+
MIGRATIONS_PATH=__inmem__ \
|
|
176
|
+
uv run pytest -v tests/integration_tests/test_langsmith_parallel_auth.py
|
|
177
|
+
|
|
169
178
|
# dev commands
|
|
170
179
|
LANGGRAPH_DISABLE_FILE_PERSISTENCE ?= true
|
|
171
180
|
LANGSMITH_TRACING ?= false
|
|
@@ -223,6 +232,8 @@ start-encrypt:
|
|
|
223
232
|
--no-access-log
|
|
224
233
|
|
|
225
234
|
|
|
235
|
+
LANGGRAPH_AUTH ?= {"path": "tests/graphs/jwt_auth.py:auth"}
|
|
236
|
+
|
|
226
237
|
start-auth-jwt:
|
|
227
238
|
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_HTTP='$(HTTP_CONFIG)' \
|
|
228
239
|
LANGGRAPH_AES_KEY='$(LANGGRAPH_AES_KEY)' \
|
|
@@ -230,7 +241,7 @@ start-auth-jwt:
|
|
|
230
241
|
LANGSERVE_GRAPHS=$(LANGSERVE_GRAPHS_AUTH) \
|
|
231
242
|
LANGGRAPH_STORE='$(STORE_CONFIG)' \
|
|
232
243
|
LANGGRAPH_CHECKPOINTER='$(CHECKPOINTER_CONFIG)' \
|
|
233
|
-
LANGGRAPH_AUTH='
|
|
244
|
+
LANGGRAPH_AUTH='$(LANGGRAPH_AUTH)' \
|
|
234
245
|
LANGSMITH_LANGGRAPH_API_VARIANT=test \
|
|
235
246
|
REDIS_URI=fake \
|
|
236
247
|
DATABASE_URI=:memory: \
|
|
@@ -258,6 +269,13 @@ start-auth-fastapi-jwt:
|
|
|
258
269
|
$(RELOAD_ARGS) \
|
|
259
270
|
--no-access-log
|
|
260
271
|
|
|
272
|
+
start-auth-langsmith-api-keys:
|
|
273
|
+
LANGGRAPH_AUTH_TYPE=langsmith \
|
|
274
|
+
LANGSMITH_AUTH_ENDPOINT=http://localhost:9124 \
|
|
275
|
+
LANGSMITH_TENANT_ID=8a1f2c4e-5b6d-4f70-9a3b-2c1d0e4f5a6b \
|
|
276
|
+
$(MAKE) start-auth-jwt \
|
|
277
|
+
LANGGRAPH_AUTH='$(LANGGRAPH_AUTH_LANGSMITH)'
|
|
278
|
+
|
|
261
279
|
define RUN_FASTAPI_JWT_MW_ORDERING
|
|
262
280
|
LANGGRAPH_RUNTIME_EDITION=inmem \
|
|
263
281
|
LANGGRAPH_HTTP='{"app": "./tests/graphs/fastapi_jwt_middleware_ordering.py:app", "middleware_order": "$(1)", "enable_custom_route_auth": $(2)}' \
|
|
@@ -292,22 +310,6 @@ start-auth-fastapi-jwt--after-custom-middleware--custom-route-auth:
|
|
|
292
310
|
$(call RUN_FASTAPI_JWT_MW_ORDERING,middleware_first,true)
|
|
293
311
|
|
|
294
312
|
|
|
295
|
-
start-js-server:
|
|
296
|
-
@echo "Building and starting Go gRPC server..."
|
|
297
|
-
$(MAKE) build-go-server
|
|
298
|
-
$(MAKE) start-go-server
|
|
299
|
-
@trap '$(MAKE) -C $(CURDIR) stop-go-server' INT TERM EXIT; \
|
|
300
|
-
echo "Installing JS server dependencies..."; \
|
|
301
|
-
cd ../public-api-server-js && yarn install; \
|
|
302
|
-
echo "Building JS server..."; \
|
|
303
|
-
cd ../public-api-server-js && yarn run build; \
|
|
304
|
-
echo "Starting JS server on port 9123..."; \
|
|
305
|
-
cd ../public-api-server-js && \
|
|
306
|
-
LANGSERVE_GRAPHS=$(LANGSERVE_GRAPHS_ALL) \
|
|
307
|
-
LANGGRAPH_CONFIG='{"agent": {"configurable": {"model_name": "openai"}}}' \
|
|
308
|
-
FF_USE_JS_API=true \
|
|
309
|
-
PORT=9123 yarn start
|
|
310
|
-
|
|
311
313
|
VERSION_KIND ?= patch
|
|
312
314
|
|
|
313
315
|
bump-version:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.0
|
|
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,8 +16,8 @@ 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.
|
|
20
|
-
Requires-Dist: langgraph-sdk>=0.
|
|
19
|
+
Requires-Dist: langgraph-runtime-inmem<0.35.0.dev0,>=0.34.0.dev0
|
|
20
|
+
Requires-Dist: langgraph-sdk>=0.4.4
|
|
21
21
|
Requires-Dist: langgraph<2,>=0.4.10
|
|
22
22
|
Requires-Dist: langsmith[otel]>=0.6.3
|
|
23
23
|
Requires-Dist: opentelemetry-api>=0.0.1
|
|
@@ -19,6 +19,14 @@ benchmark-new-revision:
|
|
|
19
19
|
benchmark-staircase:
|
|
20
20
|
python staircase.py
|
|
21
21
|
|
|
22
|
+
benchmark-capacity-ci:
|
|
23
|
+
npm install
|
|
24
|
+
node capacity-ci.js
|
|
25
|
+
|
|
26
|
+
benchmark-capacity-matrix:
|
|
27
|
+
npm install
|
|
28
|
+
node capacity-ci.js --all-deployments
|
|
29
|
+
|
|
22
30
|
benchmark-staircase-reset:
|
|
23
31
|
python ../../scripts/reset_deployment.py -a $(BENCHMARK_APP_NAME) -n $(BENCHMARK_NAMESPACE) -db $(BENCHMARK_DB_INSTANCE)
|
|
24
32
|
python staircase.py
|
|
@@ -25,6 +25,14 @@ This directory contains k6 + Python/Node benchmark tooling for LangGraph API.
|
|
|
25
25
|
- `make benchmark-reset` - Cleans benchmark server state via `clean-cli.js`.
|
|
26
26
|
- `make benchmark-new-revision` - Triggers a new benchmark deployment revision.
|
|
27
27
|
|
|
28
|
+
- `make benchmark-capacity-ci` - Runs the daily capacity matrix for one deployment (`DEPLOYMENT` env). Uses `staircase.py` per cell (default 200–2000 VUs, step 100). Config lives in `capacity-ci.js`.
|
|
29
|
+
- **Example:**
|
|
30
|
+
- `DEPLOYMENT=daily-cap-benchmark-dedicated make benchmark-capacity-ci`
|
|
31
|
+
|
|
32
|
+
- `make benchmark-capacity-matrix` - Runs the full local capacity matrix for all deployments in `capacity-ci.js` (sequential).
|
|
33
|
+
|
|
34
|
+
Host API calls use [`host-v2.js`](host-v2.js) (v2 revisions + resource-tiers). [`update-revision.js`](update-revision.js) uses the same module.
|
|
35
|
+
|
|
28
36
|
## Benchmark runner types (`BENCHMARK_TYPE`)
|
|
29
37
|
|
|
30
38
|
The runner contains the actual logic each virtual user will execute during the benchmark and steps to validate the logic worked correctly. Options are:
|
|
@@ -39,6 +47,7 @@ The runner contains the actual logic each virtual user will execute during the b
|
|
|
39
47
|
- `threads_search_metadata` - Validates thread metadata search/filter behavior.
|
|
40
48
|
- `store` - Writes, reads, validates, and deletes a Store item with a configurable payload size.
|
|
41
49
|
- `meta_workload` (randomly delegates to one of the others)
|
|
50
|
+
- `delta_turns` - Keeps one thread per VU and adds a turn to it every iteration, so latency can be read against thread depth. Built for the delta-channel cells; see below.
|
|
42
51
|
|
|
43
52
|
## Profiles (`BENCHMARK_PROFILE`)
|
|
44
53
|
|
|
@@ -50,6 +59,7 @@ Profiles are quick ways to configure the benchmark graph for any run depending o
|
|
|
50
59
|
- `stateless-parallel-medium` - Stateless high-fanout profile with medium checkpoint payloads.
|
|
51
60
|
- `parallel-small` - Stateful high-fanout profile with small checkpoint payloads.
|
|
52
61
|
- `parallel-medium` - Stateful high-fanout profile with medium checkpoint payloads.
|
|
62
|
+
- `delta-turns` - Cheap turns for the delta-channel cells, so a VU reaches the depth where a `snapshot_frequency` of 1000 fires.
|
|
53
63
|
|
|
54
64
|
Each profile defines:
|
|
55
65
|
|
|
@@ -105,6 +115,53 @@ make benchmark-charts
|
|
|
105
115
|
make benchmark-clean
|
|
106
116
|
```
|
|
107
117
|
|
|
118
|
+
## Delta-channel cells
|
|
119
|
+
|
|
120
|
+
A `DeltaChannel` stores changes rather than the value, and rebuilds the value on read
|
|
121
|
+
by replaying them. That moves cost from write to read, and the read cost grows with
|
|
122
|
+
thread depth. `delta_turns` measures it: one thread per VU, one turn per iteration,
|
|
123
|
+
`turn_duration` tagged by depth bucket.
|
|
124
|
+
|
|
125
|
+
Run the cells one at a time and compare `turn_duration` by depth. Both sides get slower
|
|
126
|
+
with depth for different reasons, the control by re-writing a growing value and delta by
|
|
127
|
+
replaying more writes, so the deliverable is which curve is worse and where they cross.
|
|
128
|
+
|
|
129
|
+
| Cell | Env |
|
|
130
|
+
|---|---|
|
|
131
|
+
| control | `GRAPH_ID=benchmark EXPECT_DELTA=false` |
|
|
132
|
+
| delta, snapshot every 1000 | `GRAPH_ID=benchmark_delta` |
|
|
133
|
+
| delta, snapshot every 50 | `GRAPH_ID=benchmark_delta_freq` |
|
|
134
|
+
| migration | `GRAPH_ID=benchmark_delta MIGRATE_FROM_GRAPH_ID=benchmark MIGRATE_AFTER=200` |
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
BASE_URL=... BENCHMARK_TYPE=delta_turns BENCHMARK_PROFILE=delta-turns \
|
|
138
|
+
GRAPH_ID=benchmark_delta LOAD_SIZE=25 LEVELS=1 PLATEAU_DURATION=300 \
|
|
139
|
+
P95_RUN_DURATION=... AVERAGE_RUN_DURATION=... k6 run --system-tags='[]' ramp.js
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Knobs beyond the common ones:
|
|
143
|
+
|
|
144
|
+
- `GRAPH_ID` - graph under test (any runner; defaults to `benchmark`).
|
|
145
|
+
- `EXPECT_DELTA` - whether `GRAPH_ID` is delta-backed. Default `true`.
|
|
146
|
+
- `MIGRATE_FROM_GRAPH_ID` / `MIGRATE_AFTER` - run the first N turns on another graph, then
|
|
147
|
+
switch on the same thread.
|
|
148
|
+
- `VERIFY_EVERY` - cold re-read cadence in turns. Default 50, `0` disables.
|
|
149
|
+
- `DEPTH_BUCKET` - width of a depth bucket. Default 100.
|
|
150
|
+
|
|
151
|
+
Two things to know before reading any result:
|
|
152
|
+
|
|
153
|
+
- **Run at low `LOAD_SIZE`.** Depth and load fight each other: saturate the deployment and
|
|
154
|
+
turn time measures queueing, not reconstruction. Verify the control curve is flat before
|
|
155
|
+
trusting the delta one.
|
|
156
|
+
- **`successful_runs` will fail its threshold.** The count is derived from a duration table
|
|
157
|
+
that assumes the existing workload. Pass `P95_RUN_DURATION` and `AVERAGE_RUN_DURATION`,
|
|
158
|
+
and treat these cells as report-only until the numbers settle.
|
|
159
|
+
|
|
160
|
+
The runner fails a turn rather than reporting a false pass when delta is not actually on:
|
|
161
|
+
the `DeltaChannel` import is version-guarded, and its stub degrades to a plain channel.
|
|
162
|
+
Storage savings, the reason the feature exists, are not measured here; that needs a query
|
|
163
|
+
against the deployment database, which CI cannot reach.
|
|
164
|
+
|
|
108
165
|
## Outputs
|
|
109
166
|
|
|
110
167
|
- Ramp:
|
|
@@ -113,11 +170,32 @@ make benchmark-clean
|
|
|
113
170
|
- `summary_<timestamp>.json`
|
|
114
171
|
- `*_chart_*.png` (when chart generation is run)
|
|
115
172
|
- Staircase:
|
|
116
|
-
- `staircase_summary.json`
|
|
173
|
+
- `staircase_summary.json` (or `SUMMARY_PATH` when set by capacity CI)
|
|
174
|
+
- `staircase_summary_<deployment>_<tier>_<runner>.json` (capacity matrix)
|
|
117
175
|
|
|
118
176
|
## CI workflows
|
|
119
177
|
|
|
120
178
|
- Daily ramp benchmark: `.github/workflows/benchmark.yml`
|
|
179
|
+
- Daily capacity matrix: `.github/workflows/benchmark-capacity-matrix.yml`
|
|
180
|
+
|
|
181
|
+
### Capacity matrix setup
|
|
182
|
+
|
|
183
|
+
1. Create staging deployments `daily-cap-benchmark-dedicated` and `daily-cap-benchmark-serverless`.
|
|
184
|
+
2. Fill in `deploymentId` and `baseUrl` in `CAPACITY_DEPLOYMENTS` at the top of [`capacity-ci.js`](capacity-ci.js).
|
|
185
|
+
3. Scheduled run: two parallel CI jobs (one per deployment), aggregate job posts Slack summary.
|
|
186
|
+
|
|
187
|
+
Local commands:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Single deployment (9 cells: 3 tiers × 3 runners)
|
|
191
|
+
DEPLOYMENT=daily-cap-benchmark-dedicated make benchmark-capacity-ci
|
|
192
|
+
|
|
193
|
+
# All deployments sequentially (18 cells)
|
|
194
|
+
make benchmark-capacity-matrix
|
|
195
|
+
|
|
196
|
+
# Aggregate downloaded CI artifacts
|
|
197
|
+
node capacity-ci.js --aggregate --summaries-dir ./artifacts --slack
|
|
198
|
+
```
|
|
121
199
|
|
|
122
200
|
## References
|
|
123
201
|
|
{langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/benchmark-runner.ts
RENAMED
|
@@ -3,6 +3,7 @@ import type { BenchmarkResult, BenchmarkGraphOptions } from './types.js';
|
|
|
3
3
|
export interface ErrorMetrics {
|
|
4
4
|
server_errors: { add(n: number): void };
|
|
5
5
|
timeout_errors: { add(n: number): void };
|
|
6
|
+
connection_errors?: { add(n: number): void };
|
|
6
7
|
api_errors?: { add(n: number): void };
|
|
7
8
|
missing_message_errors?: { add(n: number): void };
|
|
8
9
|
other_errors: { add(n: number): void };
|
{langgraph_api-0.13.4 → langgraph_api-0.14.0}/benchmark/benchmark-runners/benchmark_profiles.ts
RENAMED
|
@@ -68,6 +68,26 @@ export const BENCHMARK_PROFILES: Record<string, BenchmarkProfile> = {
|
|
|
68
68
|
burst_size: 0,
|
|
69
69
|
},
|
|
70
70
|
},
|
|
71
|
+
// Delta-channel cells: cheap turns, so a VU reaches the depth where a
|
|
72
|
+
// snapshot_frequency of 1000 finally fires. Run these at a low LOAD_SIZE;
|
|
73
|
+
// saturation turns the measurement into queue time.
|
|
74
|
+
'delta-turns': {
|
|
75
|
+
resumable: false,
|
|
76
|
+
runMode: 'stateful',
|
|
77
|
+
context: {
|
|
78
|
+
delay: 0,
|
|
79
|
+
delay_jitter_ratio: 0,
|
|
80
|
+
expand: 1,
|
|
81
|
+
steps: 1,
|
|
82
|
+
checkpoint_size: 256,
|
|
83
|
+
llm_enabled: false,
|
|
84
|
+
stream_size: 0,
|
|
85
|
+
chunk_size: 1,
|
|
86
|
+
burst_mode: false,
|
|
87
|
+
burst_probability: 0,
|
|
88
|
+
burst_size: 0,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
71
91
|
'streaming-long': {
|
|
72
92
|
resumable: true,
|
|
73
93
|
runMode: 'stateful',
|
|
@@ -8,6 +8,7 @@ import { ThreadRunsMetadataSearch } from './thread_runs_metadata_search.js';
|
|
|
8
8
|
import { ThreadsSearchMetadata } from './threads_search_metadata.js';
|
|
9
9
|
import { Store } from './store.js';
|
|
10
10
|
import { MetaWorkload } from './meta_workload.js';
|
|
11
|
+
import { DeltaTurns } from './delta_turns.js';
|
|
11
12
|
import type { BenchmarkRunner } from './benchmark-runner.js';
|
|
12
13
|
|
|
13
14
|
export class Benchmarks {
|
|
@@ -33,6 +34,8 @@ export class Benchmarks {
|
|
|
33
34
|
return Store;
|
|
34
35
|
case MetaWorkload.toString():
|
|
35
36
|
return MetaWorkload;
|
|
37
|
+
case DeltaTurns.toString():
|
|
38
|
+
return DeltaTurns;
|
|
36
39
|
default:
|
|
37
40
|
throw new Error(`Unknown benchmark type: ${type}`);
|
|
38
41
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
// Compiled output: the source is TypeScript, and `npm test` runs after
|
|
4
|
+
// `npm run build` both locally and in CI.
|
|
5
|
+
import { classifyError, recordError } from './dist/classify-error.js';
|
|
6
|
+
|
|
7
|
+
test('5xx is a server error', () => {
|
|
8
|
+
assert.equal(classifyError({ response: { status: 500 } }), 'server');
|
|
9
|
+
assert.equal(classifyError({ response: { status: 503 } }), 'server');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('408 and timeout error strings are timeouts', () => {
|
|
13
|
+
assert.equal(classifyError({ response: { status: 408 } }), 'timeout');
|
|
14
|
+
assert.equal(
|
|
15
|
+
classifyError({ response: { status: 0, error: 'request timeout' } }),
|
|
16
|
+
'timeout'
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// The bucket that had never once been written to. A refused connection has no
|
|
21
|
+
// HTTP status, so every runner used to file it under something else.
|
|
22
|
+
test('an unreachable deployment is a connection error', () => {
|
|
23
|
+
assert.equal(
|
|
24
|
+
classifyError({ response: { status: 0, error: 'dial: connection refused' } }),
|
|
25
|
+
'connection'
|
|
26
|
+
);
|
|
27
|
+
assert.equal(classifyError({ response: { status: 0 } }), 'connection');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('connection beats the runner-specific fallbacks', () => {
|
|
31
|
+
// Before this classifier, stream_write reported exactly this case as
|
|
32
|
+
// missing_message and wait_write as other.
|
|
33
|
+
const unreachable = { status: 0, error: 'dial: connection refused' };
|
|
34
|
+
assert.equal(
|
|
35
|
+
classifyError({ response: unreachable, missingMessage: true }),
|
|
36
|
+
'connection'
|
|
37
|
+
);
|
|
38
|
+
assert.equal(
|
|
39
|
+
classifyError({ response: unreachable, hasApiError: true }),
|
|
40
|
+
'connection'
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('a 200 that came back wrong falls to the runner-specific buckets', () => {
|
|
45
|
+
const ok = { status: 200 };
|
|
46
|
+
assert.equal(classifyError({ response: ok, hasApiError: true }), 'api');
|
|
47
|
+
assert.equal(classifyError({ response: ok, missingMessage: true }), 'missing_message');
|
|
48
|
+
assert.equal(classifyError({ response: ok }), 'other');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('4xx that is not 408 is not mistaken for anything else', () => {
|
|
52
|
+
assert.equal(classifyError({ response: { status: 422 } }), 'other');
|
|
53
|
+
assert.equal(classifyError({ response: { status: 404 } }), 'other');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('a missing response is not reported as unreachable', () => {
|
|
57
|
+
// No response object at all means the runner never got that far; that is not
|
|
58
|
+
// evidence about the network, so it must not claim `connection`.
|
|
59
|
+
assert.equal(classifyError({}), 'other');
|
|
60
|
+
assert.equal(classifyError({ response: null, missingMessage: true }), 'missing_message');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// classifyError picks the bucket; recordError is what actually increments a
|
|
64
|
+
// counter, and it was previously untested. A mutation that unwired
|
|
65
|
+
// connection_errors passed the whole suite.
|
|
66
|
+
function spyMetrics(omit = []) {
|
|
67
|
+
const names = [
|
|
68
|
+
'server_errors',
|
|
69
|
+
'timeout_errors',
|
|
70
|
+
'connection_errors',
|
|
71
|
+
'api_errors',
|
|
72
|
+
'missing_message_errors',
|
|
73
|
+
'other_errors',
|
|
74
|
+
];
|
|
75
|
+
const counts = {};
|
|
76
|
+
const metrics = {};
|
|
77
|
+
for (const name of names) {
|
|
78
|
+
counts[name] = 0;
|
|
79
|
+
if (!omit.includes(name)) metrics[name] = { add: (n) => (counts[name] += n) };
|
|
80
|
+
}
|
|
81
|
+
return { metrics, counts };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
test('recordError increments the counter the bucket names', async (t) => {
|
|
85
|
+
const cases = [
|
|
86
|
+
['server', 'server_errors'],
|
|
87
|
+
['timeout', 'timeout_errors'],
|
|
88
|
+
['connection', 'connection_errors'],
|
|
89
|
+
['api', 'api_errors'],
|
|
90
|
+
['missing_message', 'missing_message_errors'],
|
|
91
|
+
['other', 'other_errors'],
|
|
92
|
+
];
|
|
93
|
+
for (const [bucket, counter] of cases) {
|
|
94
|
+
await t.test(`${bucket} -> ${counter}`, () => {
|
|
95
|
+
const { metrics, counts } = spyMetrics();
|
|
96
|
+
recordError(bucket, metrics);
|
|
97
|
+
assert.equal(counts[counter], 1, `${bucket} did not increment ${counter}`);
|
|
98
|
+
const strays = Object.entries(counts).filter(([k, v]) => k !== counter && v !== 0);
|
|
99
|
+
assert.deepEqual(strays, [], `${bucket} also incremented ${strays.map(([k]) => k)}`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('recordError falls back to other_errors for counters the entrypoint omits', () => {
|
|
105
|
+
// Preserves what the runners open-coded for api_errors and
|
|
106
|
+
// missing_message_errors, and covers older entrypoints without connection.
|
|
107
|
+
for (const [bucket, counter] of [
|
|
108
|
+
['connection', 'connection_errors'],
|
|
109
|
+
['api', 'api_errors'],
|
|
110
|
+
['missing_message', 'missing_message_errors'],
|
|
111
|
+
]) {
|
|
112
|
+
const { metrics, counts } = spyMetrics([counter]);
|
|
113
|
+
recordError(bucket, metrics);
|
|
114
|
+
assert.equal(counts.other_errors, 1, `${bucket} did not fall back to other_errors`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ErrorMetrics } from './benchmark-runner.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Which error counter a failed run belongs in.
|
|
5
|
+
*
|
|
6
|
+
* `wait_write` and `stream_write` each grew their own copy of this ladder, and
|
|
7
|
+
* both had the same hole: neither could ever produce `connection`. That bucket
|
|
8
|
+
* is declared in ramp.js and staircase_step_k6.js, wired into the metrics map,
|
|
9
|
+
* and printed in every report - but no runner has ever written to it, so it has
|
|
10
|
+
* read 0 in all 32 scheduled runs on record. A refused connection has no HTTP
|
|
11
|
+
* status, so it fell through to `missing_message` (stream) or `other` (wait):
|
|
12
|
+
* "the server answered but left something out" when the truth was "the server
|
|
13
|
+
* never answered".
|
|
14
|
+
*/
|
|
15
|
+
export type ErrorBucket =
|
|
16
|
+
| 'connection'
|
|
17
|
+
| 'timeout'
|
|
18
|
+
| 'server'
|
|
19
|
+
| 'api'
|
|
20
|
+
| 'missing_message'
|
|
21
|
+
| 'other';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Only the two fields the ladder reads. Structurally satisfied by both k6's
|
|
25
|
+
* RefinedResponse and our normalized HttpResponse, so runners can pass either
|
|
26
|
+
* without converting.
|
|
27
|
+
*/
|
|
28
|
+
export interface ClassifiableResponse {
|
|
29
|
+
status?: number;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ClassifyInput {
|
|
34
|
+
/** The response the run hinges on, if there was one. */
|
|
35
|
+
response?: ClassifiableResponse | null;
|
|
36
|
+
/** Runner-specific: the response body carried an `__error__` key. */
|
|
37
|
+
hasApiError?: boolean;
|
|
38
|
+
/** Runner-specific: the expected message/counter never arrived. */
|
|
39
|
+
missingMessage?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** k6 reports a status of 0 when no HTTP response was received at all. */
|
|
43
|
+
function isUnreachable(response?: ClassifiableResponse | null): boolean {
|
|
44
|
+
if (response == null) return false;
|
|
45
|
+
const status = response.status;
|
|
46
|
+
if (status != null && status > 0) return false;
|
|
47
|
+
return status === 0 || (response.error ?? '') !== '';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isTimeout(response?: ClassifiableResponse | null): boolean {
|
|
51
|
+
if (response?.status === 408) return true;
|
|
52
|
+
return (response?.error ?? '').includes('timeout');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Order matters: a timeout is reported by k6 as an error string on a status-0
|
|
57
|
+
* response, so it has to be tested before the general unreachable case.
|
|
58
|
+
*/
|
|
59
|
+
export function classifyError(input: ClassifyInput): ErrorBucket {
|
|
60
|
+
const { response, hasApiError, missingMessage } = input;
|
|
61
|
+
const status = response?.status;
|
|
62
|
+
|
|
63
|
+
if (status != null && status >= 500) return 'server';
|
|
64
|
+
if (isTimeout(response)) return 'timeout';
|
|
65
|
+
if (isUnreachable(response)) return 'connection';
|
|
66
|
+
if (hasApiError) return 'api';
|
|
67
|
+
if (missingMessage) return 'missing_message';
|
|
68
|
+
return 'other';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Add one to the counter for `bucket`, falling back to `other_errors` when the
|
|
73
|
+
* entrypoint did not supply that counter. Preserves the behaviour the runners
|
|
74
|
+
* open-coded for `api_errors` and `missing_message_errors`.
|
|
75
|
+
*/
|
|
76
|
+
export function recordError(bucket: ErrorBucket, errorMetrics: ErrorMetrics): void {
|
|
77
|
+
const counters: Record<ErrorBucket, { add(n: number): void } | undefined> = {
|
|
78
|
+
server: errorMetrics.server_errors,
|
|
79
|
+
timeout: errorMetrics.timeout_errors,
|
|
80
|
+
connection: errorMetrics.connection_errors,
|
|
81
|
+
api: errorMetrics.api_errors,
|
|
82
|
+
missing_message: errorMetrics.missing_message_errors,
|
|
83
|
+
other: errorMetrics.other_errors,
|
|
84
|
+
};
|
|
85
|
+
(counters[bucket] ?? errorMetrics.other_errors).add(1);
|
|
86
|
+
}
|