langgraph-api 0.5.35__tar.gz → 0.6.25__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.5.35 → langgraph_api-0.6.25}/Makefile +2 -2
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/PKG-INFO +6 -5
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/Makefile +37 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/README.md +2 -2
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/capacity_k6.js +3 -1
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/capacity_runner.mjs +68 -14
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/clean.js +7 -6
- langgraph_api-0.6.25/benchmark/continuous/README.md +38 -0
- langgraph_api-0.6.25/benchmark/continuous/pyproject.toml +13 -0
- langgraph_api-0.6.25/benchmark/continuous/runner.py +699 -0
- langgraph_api-0.6.25/benchmark/continuous/uv.lock +228 -0
- langgraph_api-0.6.25/benchmark/mixed_workload_k6.js +290 -0
- langgraph_api-0.6.25/benchmark/mixed_workload_runner.mjs +171 -0
- langgraph_api-0.6.25/benchmark/reporting/slack_slowest_runs.py +244 -0
- langgraph_api-0.6.25/benchmark/reporting/slack_summary.py +311 -0
- langgraph_api-0.6.25/benchmark/run_local.sh +27 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/update-revision.js +0 -5
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/constraints.txt +4 -3
- langgraph_api-0.6.25/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/__init__.py +72 -26
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/assistants.py +16 -11
- langgraph_api-0.6.25/langgraph_api/api/encryption_middleware.py +626 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/meta.py +9 -2
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/runs.py +76 -120
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/store.py +19 -2
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/threads.py +81 -9
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/custom.py +22 -12
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/cli.py +4 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/config/__init__.py +43 -2
- langgraph_api-0.6.25/langgraph_api/config/_parse.py +58 -0
- langgraph_api-0.6.25/langgraph_api/config/schemas.py +429 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/cron_scheduler.py +3 -5
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/encryption/__init__.py +5 -1
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/encryption/custom.py +20 -34
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/graph.py +129 -56
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/client.py +111 -1
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/__init__.py +6 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/checkpointer_pb2.py +63 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/checkpointer_pb2.pyi +99 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/checkpointer_pb2_grpc.py +329 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/core_api_pb2.py +206 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/core_api_pb2.pyi +117 -232
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/core_api_pb2_grpc.py +93 -48
- langgraph_api-0.6.25/langgraph_api/grpc/generated/engine_common_pb2.py +217 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/engine_common_pb2.pyi +50 -19
- langgraph_api-0.6.25/langgraph_api/grpc/generated/enum_control_signal_pb2.py +37 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/enum_control_signal_pb2.pyi +16 -0
- langgraph_api-0.6.25/langgraph_api/grpc/generated/enum_control_signal_pb2_grpc.py +24 -0
- langgraph_api-0.6.25/langgraph_api/grpc/ops/__init__.py +320 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/ops/assistants.py +9 -7
- langgraph_api-0.6.25/langgraph_api/grpc/ops/runs.py +487 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/ops/threads.py +113 -16
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/package.json +18 -18
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/yarn.lock +330 -298
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/metadata.py +14 -3
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/models/run.py +30 -13
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/queue_entrypoint.py +14 -22
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/schema.py +62 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/self_hosted_metrics.py +25 -1
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/server.py +18 -18
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/store.py +25 -16
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/stream.py +1 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/thread_ttl.py +27 -12
- langgraph_api-0.6.25/langgraph_api/timing/__init__.py +25 -0
- langgraph_api-0.6.25/langgraph_api/timing/profiler.py +200 -0
- langgraph_api-0.6.25/langgraph_api/timing/timer.py +318 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/__init__.py +11 -3
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/validation.py +3 -0
- langgraph_api-0.6.25/langgraph_api/webhook.py +163 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/worker.py +24 -25
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/__init__.py +1 -0
- langgraph_api-0.6.25/langgraph_runtime/routes.py +11 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/openapi.json +120 -6
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/pyproject.toml +9 -5
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/uv.lock +216 -168
- langgraph_api-0.5.35/langgraph_api/__init__.py +0 -1
- langgraph_api-0.5.35/langgraph_api/api/encryption_middleware.py +0 -403
- langgraph_api-0.5.35/langgraph_api/config/_parse.py +0 -39
- langgraph_api-0.5.35/langgraph_api/config/schemas.py +0 -245
- langgraph_api-0.5.35/langgraph_api/grpc/generated/core_api_pb2.py +0 -285
- langgraph_api-0.5.35/langgraph_api/grpc/generated/engine_common_pb2.py +0 -211
- langgraph_api-0.5.35/langgraph_api/grpc/ops/__init__.py +0 -181
- langgraph_api-0.5.35/langgraph_api/webhook.py +0 -52
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/.gitignore +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/LICENSE +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/README.md +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/.gitignore +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/assistant.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/benchmark-runner.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/benchmarks.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/stream_write.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/thread.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/benchmark-runners/wait_write.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/burst.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/capacity_urls.mjs +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/graphs.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/package.json +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/ramp.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/benchmark/weather.js +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/forbidden.txt +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/healthcheck.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/mcp.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/command.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/executor_entrypoint.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/feature_flags.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/config_conversion.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_durability_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/errors_pb2.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/errors_pb2.pyi +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/grpc/generated/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/http.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/route.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/state.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/logging.json +0 -0
- {langgraph_api-0.5.35 → langgraph_api-0.6.25}/scripts/create_license.py +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Environment variables
|
|
4
4
|
FF_USE_CORE_API ?= false
|
|
5
|
-
LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "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", "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"}'
|
|
5
|
+
LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "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", "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"}'
|
|
6
6
|
LANGSERVE_GRAPHS_AUTH = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "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", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci"}'
|
|
7
7
|
|
|
8
8
|
# Go server management
|
|
@@ -66,7 +66,7 @@ LANGGRAPH_ENCRYPTION ?=
|
|
|
66
66
|
|
|
67
67
|
test-license-oss:
|
|
68
68
|
@if [ "$(FF_USE_CORE_API)" = "true" ]; then \
|
|
69
|
-
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ FF_USE_CORE_API=true uv run pytest -m
|
|
69
|
+
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ FF_USE_CORE_API=true uv run pytest -m sqlite_grpc -v $(TEST); \
|
|
70
70
|
else \
|
|
71
71
|
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run pytest -v $(TEST); \
|
|
72
72
|
fi
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.25
|
|
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
|
|
7
7
|
Requires-Python: >=3.11
|
|
8
8
|
Requires-Dist: cloudpickle>=3.0.0
|
|
9
|
-
Requires-Dist: cryptography<
|
|
9
|
+
Requires-Dist: cryptography<47.0,>=42.0.0
|
|
10
|
+
Requires-Dist: grpcio-health-checking<2.0.0,>=1.75.0
|
|
10
11
|
Requires-Dist: grpcio-tools==1.75.1
|
|
11
12
|
Requires-Dist: grpcio<2.0.0,>=1.75.0
|
|
12
13
|
Requires-Dist: httpx>=0.25.0
|
|
13
14
|
Requires-Dist: jsonschema-rs<0.30,>=0.20.0
|
|
14
15
|
Requires-Dist: langchain-core>=0.3.64
|
|
15
|
-
Requires-Dist: langgraph-checkpoint<
|
|
16
|
-
Requires-Dist: langgraph-runtime-inmem<0.
|
|
17
|
-
Requires-Dist: langgraph-sdk>=0.
|
|
16
|
+
Requires-Dist: langgraph-checkpoint<5,>=3.0.1
|
|
17
|
+
Requires-Dist: langgraph-runtime-inmem<0.23.0,>=0.22.0
|
|
18
|
+
Requires-Dist: langgraph-sdk>=0.3.0
|
|
18
19
|
Requires-Dist: langgraph<2,>=0.4.10
|
|
19
20
|
Requires-Dist: langsmith>=0.3.45
|
|
20
21
|
Requires-Dist: opentelemetry-api>=1.37.0
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Benchmark commands
|
|
2
2
|
BASE_URL ?= https://benchmark-dr-s-2799835ad04b501a95044223ae72ced7.staging.langgraph.app
|
|
3
|
+
SLOWEST_N ?= 2
|
|
3
4
|
RAMP_START ?= 40
|
|
4
5
|
RAMP_END ?= 1000
|
|
5
6
|
RAMP_MULTIPLIER ?= 2
|
|
@@ -23,6 +24,7 @@ benchmark-capacity:
|
|
|
23
24
|
rm -f capacity_summary_t*.json capacity_raw_t*.json capacity_histogram_*.json
|
|
24
25
|
npm install
|
|
25
26
|
BASE_URL=$(BASE_URL) \
|
|
27
|
+
SLOWEST_N=$(SLOWEST_N) \
|
|
26
28
|
RAMP_START=$(RAMP_START) \
|
|
27
29
|
RAMP_END=$(RAMP_END) \
|
|
28
30
|
RAMP_MULTIPLIER=$(RAMP_MULTIPLIER) \
|
|
@@ -50,3 +52,38 @@ benchmark-clean:
|
|
|
50
52
|
|
|
51
53
|
benchmark-clean-charts:
|
|
52
54
|
rm -f *_chart_*.png
|
|
55
|
+
|
|
56
|
+
# Mixed workload benchmark - tests quick runs competing with long runs
|
|
57
|
+
QUICK_VUS ?= 250
|
|
58
|
+
QUICK_ITERATIONS ?= 1000
|
|
59
|
+
QUICK_STEPS ?= 5
|
|
60
|
+
QUICK_DATA_SIZE ?= 100
|
|
61
|
+
QUICK_MAX_WAIT_SECONDS ?= 120
|
|
62
|
+
QUICK_POLL_INTERVAL ?= 2
|
|
63
|
+
LONG_VUS ?= 5
|
|
64
|
+
LONG_ITERATIONS ?= 10
|
|
65
|
+
LONG_STEPS ?= 50
|
|
66
|
+
LONG_DELAY ?= 1
|
|
67
|
+
LONG_DATA_SIZE ?= 10000
|
|
68
|
+
LONG_MAX_WAIT_SECONDS ?= 200
|
|
69
|
+
LONG_POLL_INTERVAL ?= 5
|
|
70
|
+
|
|
71
|
+
benchmark-mixed:
|
|
72
|
+
rm -f mixed_workload_*.json
|
|
73
|
+
npm install
|
|
74
|
+
BASE_URL=$(BASE_URL) \
|
|
75
|
+
SLOWEST_N=$(SLOWEST_N) \
|
|
76
|
+
QUICK_VUS=$(QUICK_VUS) \
|
|
77
|
+
QUICK_ITERATIONS=$(QUICK_ITERATIONS) \
|
|
78
|
+
QUICK_STEPS=$(QUICK_STEPS) \
|
|
79
|
+
QUICK_DATA_SIZE=$(QUICK_DATA_SIZE) \
|
|
80
|
+
QUICK_MAX_WAIT_SECONDS=$(QUICK_MAX_WAIT_SECONDS) \
|
|
81
|
+
QUICK_POLL_INTERVAL=$(QUICK_POLL_INTERVAL) \
|
|
82
|
+
LONG_VUS=$(LONG_VUS) \
|
|
83
|
+
LONG_ITERATIONS=$(LONG_ITERATIONS) \
|
|
84
|
+
LONG_STEPS=$(LONG_STEPS) \
|
|
85
|
+
LONG_DELAY=$(LONG_DELAY) \
|
|
86
|
+
LONG_DATA_SIZE=$(LONG_DATA_SIZE) \
|
|
87
|
+
LONG_MAX_WAIT_SECONDS=$(LONG_MAX_WAIT_SECONDS) \
|
|
88
|
+
LONG_POLL_INTERVAL=$(LONG_POLL_INTERVAL) \
|
|
89
|
+
node mixed_workload_runner.mjs
|
|
@@ -7,7 +7,7 @@ K6 is a modern load testing tool that allows you to test the performance and rel
|
|
|
7
7
|
### Available Tests
|
|
8
8
|
|
|
9
9
|
There are two modes of testing available:
|
|
10
|
-
1. `Burst` - Kick off a burst of /run/wait requests.
|
|
10
|
+
1. `Burst` - Kick off a burst of /run/wait requests.
|
|
11
11
|
Available Params:
|
|
12
12
|
BURST_SIZE - How many requests to run. Default: 100
|
|
13
13
|
2. `Ramp` - Scale up the number of /run/wait requests and then plateau.
|
|
@@ -71,4 +71,4 @@ Charts can be created from the run locally using the `make benchmark-charts` com
|
|
|
71
71
|
|
|
72
72
|
- [K6 Documentation](https://k6.io/docs/)
|
|
73
73
|
- [K6 JavaScript API](https://k6.io/docs/javascript-api/)
|
|
74
|
-
- [Performance Testing Best Practices](https://k6.io/docs/testing-guides/)
|
|
74
|
+
- [Performance Testing Best Practices](https://k6.io/docs/testing-guides/)
|
|
@@ -13,6 +13,7 @@ const successfulRuns = new Counter('successful_runs');
|
|
|
13
13
|
const failedRuns = new Counter('failed_runs');
|
|
14
14
|
const capacitySuccessRate = new Rate('capacity_success_rate');
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
// Env
|
|
17
18
|
const BASE_URL = __ENV.BASE_URL;
|
|
18
19
|
const LANGSMITH_API_KEY = __ENV.LANGSMITH_API_KEY;
|
|
@@ -59,6 +60,7 @@ function buildPayload() {
|
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
|
|
62
64
|
export default function () {
|
|
63
65
|
// one-shot per iteration: create → wait → poll status once
|
|
64
66
|
const payload = buildPayload();
|
|
@@ -130,7 +132,7 @@ export default function () {
|
|
|
130
132
|
}
|
|
131
133
|
const durMs = new Date(run.updated_at).getTime() - createdAt;
|
|
132
134
|
if (!Number.isNaN(durMs) && durMs >= 0) {
|
|
133
|
-
runDuration.add(durMs);
|
|
135
|
+
runDuration.add(durMs, { runId, threadId });
|
|
134
136
|
}
|
|
135
137
|
const pickupDurMs = new Date(t.values.start_time).getTime() - new Date(run.created_at).getTime();
|
|
136
138
|
if (!Number.isNaN(pickupDurMs) && pickupDurMs >= 0) {
|
|
@@ -75,16 +75,24 @@ async function cleanThreads() {
|
|
|
75
75
|
let totalDeleted = 0;
|
|
76
76
|
// Loop until no more threads
|
|
77
77
|
while (true) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
let threads;
|
|
79
|
+
try {
|
|
80
|
+
const res = await fetch(searchUrl, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: hdrs,
|
|
83
|
+
// Only request thread_id to minimize response size
|
|
84
|
+
body: JSON.stringify({ limit: 1000, select: ['thread_id'] }),
|
|
85
|
+
});
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
console.error(`Cleanup search failed: ${res.status} ${res.statusText}`);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
threads = await res.json();
|
|
91
|
+
} catch (e) {
|
|
92
|
+
// Response too large or other error - skip cleanup
|
|
93
|
+
console.error(`Cleanup search error: ${e?.message || e}`);
|
|
85
94
|
break;
|
|
86
95
|
}
|
|
87
|
-
const threads = await res.json();
|
|
88
96
|
if (!Array.isArray(threads) || threads.length === 0) break;
|
|
89
97
|
for (const t of threads) {
|
|
90
98
|
try {
|
|
@@ -104,6 +112,8 @@ async function cleanThreads() {
|
|
|
104
112
|
console.log(`Cleanup completed. Deleted ~${totalDeleted} threads.`);
|
|
105
113
|
}
|
|
106
114
|
|
|
115
|
+
const SLOWEST_N = envInt('SLOWEST_N', 2);
|
|
116
|
+
|
|
107
117
|
function runK6(target) {
|
|
108
118
|
const env = {
|
|
109
119
|
...process.env,
|
|
@@ -138,7 +148,13 @@ function loadSummaryForTarget(target) {
|
|
|
138
148
|
}
|
|
139
149
|
const latest = files[files.length - 1];
|
|
140
150
|
const content = readFileSync(join(process.cwd(), latest), 'utf-8');
|
|
141
|
-
return JSON.parse(content);
|
|
151
|
+
return { filename: latest, data: JSON.parse(content) };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function updateSummaryWithSlowestRuns(summaryFilename, summaryData, slowestRuns) {
|
|
155
|
+
summaryData.slowestRuns = slowestRuns;
|
|
156
|
+
writeFileSync(join(process.cwd(), summaryFilename), JSON.stringify(summaryData, null, 2));
|
|
157
|
+
console.log(`Updated ${summaryFilename} with ${slowestRuns.length} slowest runs`);
|
|
142
158
|
}
|
|
143
159
|
|
|
144
160
|
async function main() {
|
|
@@ -155,14 +171,18 @@ async function main() {
|
|
|
155
171
|
let stageTimestamp = null;
|
|
156
172
|
let runDurationHistogram = null;
|
|
157
173
|
let histogramSampleCount = 0;
|
|
174
|
+
let slowestRuns = [];
|
|
175
|
+
let rawOut = null;
|
|
158
176
|
|
|
159
177
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
178
|
+
const result = runK6(currentTarget);
|
|
179
|
+
rawOut = result.rawOut;
|
|
180
|
+
stageTimestamp = result.ts;
|
|
162
181
|
try {
|
|
163
|
-
const histogramResult = await generateHistogramsForStage(rawOut);
|
|
182
|
+
const histogramResult = await generateHistogramsForStage(result.rawOut);
|
|
164
183
|
runDurationHistogram = histogramResult?.runDurationHistogramSeconds ?? null;
|
|
165
184
|
histogramSampleCount = histogramResult?.sampleCount ?? 0;
|
|
185
|
+
slowestRuns = histogramResult?.slowestRuns ?? [];
|
|
166
186
|
} catch (e) {
|
|
167
187
|
console.error(`Failed to generate histograms for N=${currentTarget}:`, e?.message || e);
|
|
168
188
|
}
|
|
@@ -171,9 +191,17 @@ async function main() {
|
|
|
171
191
|
// Treat as failure for this step
|
|
172
192
|
}
|
|
173
193
|
|
|
194
|
+
let summaryFilename = null;
|
|
174
195
|
let summary = null;
|
|
175
196
|
try {
|
|
176
|
-
|
|
197
|
+
const result = loadSummaryForTarget(currentTarget);
|
|
198
|
+
summaryFilename = result.filename;
|
|
199
|
+
summary = result.data;
|
|
200
|
+
|
|
201
|
+
// Update summary with slowest runs extracted from raw JSON
|
|
202
|
+
if (slowestRuns.length > 0) {
|
|
203
|
+
updateSummaryWithSlowestRuns(summaryFilename, summary, slowestRuns);
|
|
204
|
+
}
|
|
177
205
|
} catch (e) {
|
|
178
206
|
console.error(`Failed to read summary for N=${currentTarget}:`, e?.message || e);
|
|
179
207
|
}
|
|
@@ -190,7 +218,7 @@ async function main() {
|
|
|
190
218
|
console.log(`Step N=${currentTarget} summary incomplete`);
|
|
191
219
|
}
|
|
192
220
|
|
|
193
|
-
const effectiveTimestamp = summary?.timestamp ?? stageTimestamp ?? slugifyTimestamp();
|
|
221
|
+
const effectiveTimestamp = summary?.timestamp ?? stageTimestamp ?? slugifyTimestamp(null);
|
|
194
222
|
|
|
195
223
|
if (Array.isArray(runDurationHistogram) && runDurationHistogram.length > 0) {
|
|
196
224
|
const histogramLog = {
|
|
@@ -279,6 +307,7 @@ function buildHistogramBuckets(valuesSeconds, bucketCount = 12) {
|
|
|
279
307
|
}
|
|
280
308
|
|
|
281
309
|
// Build and save histogram charts for one stage from raw K6 JSON
|
|
310
|
+
// Also extracts slowest runs from run_duration metric tags
|
|
282
311
|
async function generateHistogramsForStage(rawFile) {
|
|
283
312
|
// Parse streaming JSONL from k6 --out json
|
|
284
313
|
const metrics = {
|
|
@@ -288,6 +317,8 @@ async function generateHistogramsForStage(rawFile) {
|
|
|
288
317
|
run_insertion_duration: [],
|
|
289
318
|
run_oss_duration: [],
|
|
290
319
|
};
|
|
320
|
+
// Collect run_duration entries with tags for slowest runs
|
|
321
|
+
const runDurationWithTags = [];
|
|
291
322
|
|
|
292
323
|
await new Promise((resolve, reject) => {
|
|
293
324
|
const rl = readline.createInterface({ input: createReadStream(join(process.cwd(), rawFile), { encoding: 'utf-8' }), crlfDelay: Infinity });
|
|
@@ -300,6 +331,18 @@ async function generateHistogramsForStage(rawFile) {
|
|
|
300
331
|
const v = entry?.data?.value;
|
|
301
332
|
if (Number.isFinite(v)) metrics[name].push(v);
|
|
302
333
|
}
|
|
334
|
+
// Capture run_duration entries with runId/threadId tags
|
|
335
|
+
if (name === 'run_duration') {
|
|
336
|
+
const tags = entry?.data?.tags;
|
|
337
|
+
const v = entry?.data?.value;
|
|
338
|
+
if (tags?.runId && tags?.threadId && Number.isFinite(v)) {
|
|
339
|
+
runDurationWithTags.push({
|
|
340
|
+
durationMs: v,
|
|
341
|
+
runId: tags.runId,
|
|
342
|
+
threadId: tags.threadId,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
303
346
|
}
|
|
304
347
|
} catch (_) {
|
|
305
348
|
// ignore parse errors
|
|
@@ -309,9 +352,20 @@ async function generateHistogramsForStage(rawFile) {
|
|
|
309
352
|
rl.on('error', reject);
|
|
310
353
|
});
|
|
311
354
|
|
|
355
|
+
// Get slowest N runs
|
|
356
|
+
const slowestRuns = runDurationWithTags
|
|
357
|
+
.sort((a, b) => b.durationMs - a.durationMs)
|
|
358
|
+
.slice(0, SLOWEST_N)
|
|
359
|
+
.map((r) => ({
|
|
360
|
+
durationSeconds: r.durationMs / 1000,
|
|
361
|
+
runId: r.runId,
|
|
362
|
+
threadId: r.threadId,
|
|
363
|
+
}));
|
|
364
|
+
|
|
312
365
|
const runDurationSeconds = metrics.run_duration.map((v) => v / 1000);
|
|
313
366
|
return {
|
|
314
367
|
runDurationHistogramSeconds: buildHistogramBuckets(runDurationSeconds),
|
|
315
368
|
sampleCount: runDurationSeconds.length,
|
|
369
|
+
slowestRuns,
|
|
316
370
|
};
|
|
317
371
|
}
|
|
@@ -28,7 +28,7 @@ async function cleanAssistants() {
|
|
|
28
28
|
let totalDeleted = 0;
|
|
29
29
|
|
|
30
30
|
console.log('Starting assistant cleanup...');
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
while (true) {
|
|
33
33
|
// Get the next page of assistants
|
|
34
34
|
console.log('Searching for assistants...');
|
|
@@ -48,7 +48,7 @@ async function cleanAssistants() {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const assistants = await searchResponse.json();
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
// If no assistants found, we're done
|
|
53
53
|
if (!assistants || assistants.length === 0) {
|
|
54
54
|
console.log('No more assistants found.');
|
|
@@ -93,7 +93,7 @@ async function cleanThreads() {
|
|
|
93
93
|
let totalDeleted = 0;
|
|
94
94
|
|
|
95
95
|
console.log('Starting thread cleanup...');
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
while (true) {
|
|
98
98
|
// Get the next page of threads
|
|
99
99
|
console.log('Searching for threads...');
|
|
@@ -101,7 +101,8 @@ async function cleanThreads() {
|
|
|
101
101
|
method: 'POST',
|
|
102
102
|
headers,
|
|
103
103
|
body: JSON.stringify({
|
|
104
|
-
limit: 1000
|
|
104
|
+
limit: 1000,
|
|
105
|
+
select: ['thread_id']
|
|
105
106
|
})
|
|
106
107
|
});
|
|
107
108
|
|
|
@@ -110,7 +111,7 @@ async function cleanThreads() {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
const threads = await searchResponse.json();
|
|
113
|
-
|
|
114
|
+
|
|
114
115
|
// If no threads found, we're done
|
|
115
116
|
if (!threads || threads.length === 0) {
|
|
116
117
|
console.log('No more threads found.');
|
|
@@ -147,4 +148,4 @@ async function cleanThreads() {
|
|
|
147
148
|
clean().catch(error => {
|
|
148
149
|
console.error('Unhandled error:', error.message);
|
|
149
150
|
process.exit(1);
|
|
150
|
-
});
|
|
151
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Continuous Load Test
|
|
2
|
+
|
|
3
|
+
Maintains a target pool of streaming threads to exercise long-running HTTP SSE streams.
|
|
4
|
+
|
|
5
|
+
## Local Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
uv sync
|
|
10
|
+
|
|
11
|
+
# Set environment variables
|
|
12
|
+
export LANGSMITH_API_KEY=your-langsmith-key
|
|
13
|
+
export DD_API_KEY=your-datadog-key
|
|
14
|
+
|
|
15
|
+
# Run with defaults (1000 threads)
|
|
16
|
+
uv run python runner.py
|
|
17
|
+
|
|
18
|
+
# Or with custom options
|
|
19
|
+
# use --raw-sse flag to send without SDK (which would mask retries etc)
|
|
20
|
+
uv run python runner.py \
|
|
21
|
+
--base-url https://your-deployment.langgraph.app \
|
|
22
|
+
--assistant-id long_running \
|
|
23
|
+
--num-threads 1000
|
|
24
|
+
--raw-sse
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Metrics
|
|
28
|
+
|
|
29
|
+
Metrics are shipped to Datadog every 60 seconds. Per-run metrics are sent once when each run completes:
|
|
30
|
+
|
|
31
|
+
- `langsmith_deployment.continuous.threads.active` - Active streaming threads (gauge)
|
|
32
|
+
- `langsmith_deployment.continuous.threads.failed` - Failed threads (gauge)
|
|
33
|
+
- `langsmith_deployment.continuous.events` - SSE events received per run (count)
|
|
34
|
+
- `langsmith_deployment.continuous.failures` - Connection failures per run (count)
|
|
35
|
+
- `langsmith_deployment.continuous.threads.faults.dropped_chunks` - Dropped messages per run (count)
|
|
36
|
+
- `langsmith_deployment.continuous.threads.faults.out_of_order_runs` - Runs with out-of-order messages (count)
|
|
37
|
+
- `langsmith_deployment.continuous.threads.faults.malformed_chunks` - Malformed chunks per run (count)
|
|
38
|
+
- `langsmith_deployment.continuous.threads.latency` - End-to-end latency per message in seconds (distribution)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "langgraph-continuous-test"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Continuous stress test for Agent Server"
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"langgraph-sdk>=0.2.10",
|
|
8
|
+
"click>=8.0.0",
|
|
9
|
+
"structlog>=24.1.0",
|
|
10
|
+
"datadog-api-client>=2.0.0",
|
|
11
|
+
"python-dateutil>=2.8.0",
|
|
12
|
+
"httpx>=0.27.0",
|
|
13
|
+
]
|