langgraph-api 0.17.0.dev3__tar.gz → 0.17.0.dev4__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.17.0.dev3 → langgraph_api-0.17.0.dev4}/LICENSE +1 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/Makefile +9 -5
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/PKG-INFO +2 -2
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/README.md +9 -11
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/REPORTS.md +35 -47
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/delta-turns-lib.test.js +33 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/delta-turns-lib.ts +41 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/delta_turns.ts +47 -20
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/capacity-ci.js +7 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/capacity-ci.test.js +22 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/clean.js +0 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/continuous/uv.lock +3 -3
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/daily-report.js +9 -2
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/daily-report.test.js +16 -2
- langgraph_api-0.17.0.dev4/benchmark/delta-report.js +384 -0
- langgraph_api-0.17.0.dev4/benchmark/delta-report.test.js +185 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/history.js +36 -12
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/history.test.js +25 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/multer.test.js +2 -2
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/package.json +13 -3
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/ramp.js +5 -6
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/slack.js +2 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/update-revision.js +4 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/yarn.lock +154 -209
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/custom_store.sql +0 -0
- langgraph_api-0.17.0.dev4/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/threads.py +2 -7
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/cache.py +86 -26
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/config/__init__.py +45 -5
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/config/schemas.py +12 -12
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/cron_scheduler.py +16 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/feature_flags.py +35 -4
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/crons.py +3 -2
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/runs.py +3 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/threads.py +44 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/package.json +1 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/yarn.lock +7 -7
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/models/run.py +4 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/schema.py +3 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/store.py +7 -6
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/cache.py +22 -10
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +1 -1
- langgraph_api-0.17.0.dev4/langgraph_grpc_common/proto/core_api_pb2.py +286 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/core_api_pb2.pyi +163 -2
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +47 -3
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +15 -3
- langgraph_api-0.17.0.dev4/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/openapi.json +8 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/pyproject.toml +1 -1
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/uv.lock +7 -7
- langgraph_api-0.17.0.dev3/benchmark/delta-report.js +0 -583
- langgraph_api-0.17.0.dev3/benchmark/delta-report.test.js +0 -222
- langgraph_api-0.17.0.dev3/langgraph_api/__init__.py +0 -1
- langgraph_api-0.17.0.dev3/langgraph_api/event_streaming/__init__.py +0 -1
- langgraph_api-0.17.0.dev3/langgraph_grpc_common/proto/core_api_pb2.py +0 -274
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/.gitignore +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/README.md +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/.gitignore +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/Makefile +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/assistant.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/benchmarks.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/classify-error.test.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/classify-error.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/interrupt_resume.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/log-failure.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/meta_workload.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/store.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/stream_write.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/thread.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/types.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/wait_write.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/clean-cli.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/continuous/README.md +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/continuous/pyproject.toml +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/continuous/runner.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/graphs.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/host-v2.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/host-v2.test.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/runner-descriptions.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/server-metrics.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/server-metrics.test.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/staircase.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/staircase_step_k6.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/tsconfig.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/weather.js +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/constraints.txt +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/forbidden.txt +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/hatch_build.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/healthcheck.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph-cloud-debugging-20260210132856.zip +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/_checkpointer/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/_checkpointer/_adapter.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/_checkpointer/protocol.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/_factory_utils.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui_schemas/README.md +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui_schemas/client_capabilities.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui_schemas/client_data_model.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui_schemas/client_to_server.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/a2ui_schemas/server_to_client.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/event_streaming.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/_constants.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/_handlers.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/_models.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/_routes.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/mcp/_sanitizers.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/meta.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/errors.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/beacon_data_plane_jwt_auth.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/command.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/config/_parse.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/aes_json.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/custom.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/middleware.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/encryption/shared.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.17.0.dev3/langgraph_api/grpc → langgraph_api-0.17.0.dev4/langgraph_api/event_streaming}/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/capabilities.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/constants.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/event_normalizers.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/namespace.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/service.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/session.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/state_normalizers.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/event_streaming/types.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.17.0.dev3/langgraph_api/js → langgraph_api-0.17.0.dev4/langgraph_api/grpc}/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/client.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/assistants.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/ops/cache.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/server.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/servicers/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/grpc/servicers/encryption.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/http.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/.yarnclean +0 -0
- {langgraph_api-0.17.0.dev3/langgraph_api/middleware → langgraph_api-0.17.0.dev4/langgraph_api/js}/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/auth-mutations.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/lc_security/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/lc_security/exceptions.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/lc_security/policy.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/lc_security/transport.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/metrics_collector.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/metrics_otlp.py +0 -0
- {langgraph_api-0.17.0.dev3/langgraph_api/models → langgraph_api-0.17.0.dev4/langgraph_api/middleware}/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/middleware/ensure_store.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.17.0.dev3/langgraph_license → langgraph_api-0.17.0.dev4/langgraph_api/models}/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/otel_context.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/queue_entrypoint.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/release_tags.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/route.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/runner/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/runner/__main__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/self_hosted_metrics.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/server.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/state.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/stream_v2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/timing/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/timing/profiler.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/timing/timer.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/tracing_session.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/extract.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/network.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/worker.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_api/worker_runtime.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/checkpointer.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/_compat.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/config.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/durability.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/store.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/struct.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/conversion/value.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/runner_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/runner_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/runner_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/runner_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/store_pb2.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/serde.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_grpc_common/store.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/encryption.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/routes.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/logging.json +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/scripts/build_wheel.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/scripts/create_license.py +0 -0
- {langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/scripts/run_a2a_tck.py +0 -0
|
@@ -38,6 +38,10 @@ check-base-imports:
|
|
|
38
38
|
# test commands
|
|
39
39
|
|
|
40
40
|
TEST ?= tests/ ../runtime_inmem/tests/
|
|
41
|
+
# Pin rootdir/config to this package. TEST includes ../runtime_inmem/tests/,
|
|
42
|
+
# and in the monorepo that climbs past api/ to the root pyproject.toml which
|
|
43
|
+
# has no [tool.pytest] — dropping pythonpath (e.g. apply_prerelease_version).
|
|
44
|
+
PYTEST_ROOT_ARGS := --rootdir=. -c pyproject.toml
|
|
41
45
|
PYTEST_WORKERS ?= 0
|
|
42
46
|
AUTH_TEST ?= "tests/integration_tests/test_custom_auth.py"
|
|
43
47
|
LANGGRAPH_HTTP ?= {"disable_mcp": false, "disable_a2a": false}
|
|
@@ -105,7 +109,7 @@ REVISION ?= $(shell git rev-parse --short HEAD)
|
|
|
105
109
|
LANGGRAPH_ENCRYPTION ?=
|
|
106
110
|
|
|
107
111
|
test-license-oss:
|
|
108
|
-
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_CHECKPOINTER='$(CHECKPOINTER_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run pytest -v $(XDIST_ARGS) $(TEST)
|
|
112
|
+
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_STORE='$(STORE_CONFIG)' LANGGRAPH_CHECKPOINTER='$(CHECKPOINTER_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run pytest -v $(PYTEST_ROOT_ARGS) $(XDIST_ARGS) $(TEST)
|
|
109
113
|
|
|
110
114
|
test-watch-oss:
|
|
111
115
|
LANGGRAPH_RUNTIME_EDITION=inmem LANGGRAPH_WEBHOOKS='$(LANGGRAPH_WEBHOOKS)' LANGGRAPH_HTTP='$(HTTP_CONFIG)' LANGGRAPH_ENCRYPTION='$(LANGGRAPH_ENCRYPTION)' REDIS_URI=_FAKE DATABASE_URI=:memory: MIGRATIONS_PATH=__inmem__ uv run --no-sync ptw . -- -x -vv --ff --capture=no $(TEST)
|
|
@@ -113,13 +117,13 @@ test-watch-oss:
|
|
|
113
117
|
test: test-license-oss
|
|
114
118
|
test-watch: test-watch-oss
|
|
115
119
|
unit-test:
|
|
116
|
-
LANGGRAPH_RUNTIME_EDITION="inmem" DATABASE_URI="test" REDIS_URI="test" uv run pytest tests/unit_tests
|
|
120
|
+
LANGGRAPH_RUNTIME_EDITION="inmem" DATABASE_URI="test" REDIS_URI="test" uv run pytest $(PYTEST_ROOT_ARGS) tests/unit_tests
|
|
117
121
|
|
|
118
122
|
unit-test-watch:
|
|
119
123
|
LANGGRAPH_RUNTIME_EDITION="inmem" DATABASE_URI="test" REDIS_URI="test" uv run ptw . -- -x -vv --ff --capture=no tests/unit_tests
|
|
120
124
|
|
|
121
125
|
test-auth:
|
|
122
|
-
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 pytest -v $(XDIST_ARGS) $(AUTH_TEST)
|
|
126
|
+
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 pytest -v $(PYTEST_ROOT_ARGS) $(XDIST_ARGS) $(AUTH_TEST)
|
|
123
127
|
|
|
124
128
|
test-with-server:
|
|
125
129
|
@bash -euo pipefail -c '$(MAKE) $(START_TARGET) LANGGRAPH_HTTP='\''$(LANGGRAPH_HTTP)'\'' & \
|
|
@@ -146,7 +150,7 @@ define FASTAPI_JWT_AUTH_TEST
|
|
|
146
150
|
DATABASE_URI=:memory: \
|
|
147
151
|
MIGRATIONS_PATH=__inmem__ \
|
|
148
152
|
LANGGRAPH_HTTP='{"app": "./tests/graphs/fastapi_jwt_middleware_ordering.py:app", "middleware_order": "$(1)", "enable_custom_route_auth": $(2)}' \
|
|
149
|
-
uv run pytest -v $(AUTH_TEST)
|
|
153
|
+
uv run pytest -v $(PYTEST_ROOT_ARGS) $(AUTH_TEST)
|
|
150
154
|
endef
|
|
151
155
|
|
|
152
156
|
test-auth-fastapi-jwt--before-custom-middleware--no-custom-route-auth:
|
|
@@ -171,7 +175,7 @@ test-auth-langsmith-api-keys:
|
|
|
171
175
|
REDIS_URI=_FAKE \
|
|
172
176
|
DATABASE_URI=:memory: \
|
|
173
177
|
MIGRATIONS_PATH=__inmem__ \
|
|
174
|
-
uv run pytest -v tests/integration_tests/test_langsmith_parallel_auth.py
|
|
178
|
+
uv run pytest -v $(PYTEST_ROOT_ARGS) tests/integration_tests/test_langsmith_parallel_auth.py
|
|
175
179
|
|
|
176
180
|
# dev commands
|
|
177
181
|
LANGGRAPH_DISABLE_FILE_PERSISTENCE ?= true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.17.0.
|
|
3
|
+
Version: 0.17.0.dev4
|
|
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
|
|
@@ -28,7 +28,7 @@ Requires-Dist: opentelemetry-sdk>=0.0.1
|
|
|
28
28
|
Requires-Dist: orjson>=3.9.7
|
|
29
29
|
Requires-Dist: prometheus-client>=0.0.1
|
|
30
30
|
Requires-Dist: protobuf<7.0.0,>=6.32.1
|
|
31
|
-
Requires-Dist: pyjwt>=2.
|
|
31
|
+
Requires-Dist: pyjwt>=2.15.0
|
|
32
32
|
Requires-Dist: sse-starlette<4.0.0,>=2.1.3
|
|
33
33
|
Requires-Dist: starlette>=1.3.1
|
|
34
34
|
Requires-Dist: structlog<26,>=24.1.0
|
|
@@ -129,13 +129,11 @@ by replaying them. That moves cost from write to read, and the read cost grows w
|
|
|
129
129
|
thread depth. `delta_turns` measures it: one thread per VU, one turn per iteration,
|
|
130
130
|
`turn_duration` tagged by depth bucket.
|
|
131
131
|
|
|
132
|
-
`benchmark-delta.yml` runs
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
with depth for different reasons, the control by re-writing a growing value and delta by
|
|
138
|
-
replaying more writes, so the deliverable is which curve is worse and where they cross.
|
|
132
|
+
`benchmark-delta.yml` runs two cells nightly in one k6 run (`DELTA_CELLS`): every VU turns a
|
|
133
|
+
plain-channel thread and a `benchmark_delta_messages` thread (a message list, snapshot every 50,
|
|
134
|
+
the deepagents setting) in rotation, `ITERATIONS` fixed so both reach 1,400 turns.
|
|
135
|
+
`delta-report.js` posts write, read and storage at the last turn and puts the by-depth tables
|
|
136
|
+
in the thread; `REPORTS.md` explains the post. The cells below stay available for manual runs.
|
|
139
137
|
|
|
140
138
|
| Cell | Env |
|
|
141
139
|
|---|---|
|
|
@@ -143,7 +141,7 @@ replaying more writes, so the deliverable is which curve is worse and where they
|
|
|
143
141
|
| delta, snapshot every 1000 | `GRAPH_ID=benchmark_delta` |
|
|
144
142
|
| delta, snapshot every 50 | `GRAPH_ID=benchmark_delta_freq` |
|
|
145
143
|
| delta, snapshot every 500 | `GRAPH_ID=benchmark_delta_500` |
|
|
146
|
-
| delta on a message list | `GRAPH_ID=benchmark_delta_messages PAYLOAD=messages` |
|
|
144
|
+
| delta on a message list, snapshot every 50 | `GRAPH_ID=benchmark_delta_messages PAYLOAD=messages` |
|
|
147
145
|
| migration | `GRAPH_ID=benchmark_delta MIGRATE_FROM_GRAPH_ID=benchmark MIGRATE_AFTER=200` |
|
|
148
146
|
|
|
149
147
|
```bash
|
|
@@ -190,9 +188,9 @@ be compared on the bytes they occupy, which is what the feature exists to reduce
|
|
|
190
188
|
|
|
191
189
|
## CI workflows
|
|
192
190
|
|
|
193
|
-
- Daily ramp benchmark: `.github/workflows/benchmark.yml`
|
|
194
|
-
- Daily capacity matrix: `.github/workflows/benchmark-capacity-matrix.yml`
|
|
195
|
-
- Daily delta-channel cells: `.github/workflows/benchmark-delta.yml`, reported by `delta-report.js`
|
|
191
|
+
- Daily ramp benchmark: `.github/workflows/langgraph-api-benchmark.yml`
|
|
192
|
+
- Daily capacity matrix: `.github/workflows/langgraph-api-benchmark-capacity-matrix.yml`
|
|
193
|
+
- Daily delta-channel cells: `.github/workflows/langgraph-api-benchmark-delta.yml`, reported by `delta-report.js`
|
|
196
194
|
|
|
197
195
|
The staging deployments build their graphs from
|
|
198
196
|
[langgraph-server-benchmarks](https://github.com/langchain-ai/langgraph-server-benchmarks), not
|
|
@@ -16,8 +16,8 @@ in the same channel is separate and not covered here.
|
|
|
16
16
|
- **Failed / Errors / Regressed / Bottlenecks** lines only appear when there is
|
|
17
17
|
something to say, worst first.
|
|
18
18
|
- **Regressed / Improved.** A figure is flagged only when it leaves its own
|
|
19
|
-
usual range over the recent nights: the 9 before tonight for the daily
|
|
20
|
-
reports, the last 7 for capacity
|
|
19
|
+
usual range over the recent nights: the 9 before tonight for the daily and
|
|
20
|
+
delta reports, the last 7 for capacity, where ▲ better and ▼ worse also
|
|
21
21
|
mark the cell in the table. The usual range is half the spread
|
|
22
22
|
between the best and worst of those nights, and never less than 10%, so a
|
|
23
23
|
series that swings 40% night to night is not flagged for moving 15%.
|
|
@@ -101,8 +101,10 @@ model", the way real traffic arrives), and raises it every 60 s: dedicated by
|
|
|
101
101
|
|
|
102
102
|
**The table.** Each cell is the highest request rate the tier held for two
|
|
103
103
|
steps while staying on target: at least 99% success, p50 at most 3 s, p95 at
|
|
104
|
-
most 10 s. `
|
|
105
|
-
|
|
104
|
+
most 10 s. `70+` means the tier passed the last step, so its real ceiling is
|
|
105
|
+
higher than the test goes. `0` means no step met the target, `ERR` means the cell crashed,
|
|
106
|
+
`-` means it never ran. A crashed cell's error is on the `Why:` line, once per
|
|
107
|
+
distinct error.
|
|
106
108
|
|
|
107
109
|
**Bottlenecks.** A component (queue, api, database, redis) running at or over
|
|
108
110
|
95% of its CPU request during the steps the tier passed. That is what stops
|
|
@@ -120,9 +122,9 @@ that failed. Last, the request rate actually served at the top step.
|
|
|
120
122
|
|
|
121
123
|
## Delta channel
|
|
122
124
|
|
|
123
|
-
**Question it answers:**
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
**Question it answers:** on a long thread, does `DeltaChannel` at the
|
|
126
|
+
deepagents setting (a message list, snapshot every 50 turns) save faster and
|
|
127
|
+
store less than a plain channel, without making reads slower?
|
|
126
128
|
|
|
127
129
|
**Background.** A plain channel saves the whole value at every checkpoint. A
|
|
128
130
|
`DeltaChannel` saves only what changed, plus a full snapshot every N turns,
|
|
@@ -130,46 +132,32 @@ and rebuilds the value on read by replaying the changes since the last
|
|
|
130
132
|
snapshot. That moves cost from write to read, and read cost grows with the
|
|
131
133
|
distance to the last snapshot.
|
|
132
134
|
|
|
133
|
-
**How it runs.**
|
|
134
|
-
|
|
135
|
-
1
|
|
136
|
-
(`
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
**Pass bar.** Request errors under 1% and success over 99% per cell. Two
|
|
161
|
-
correctness checks turn the dot yellow on any failure: at turn 2 each cell
|
|
162
|
-
confirms delta is on (or off, for the control), because a too-old langgraph
|
|
163
|
-
silently degrades a `DeltaChannel` to a plain one; and every cold read is
|
|
164
|
-
compared with what the run returned.
|
|
165
|
-
|
|
166
|
-
**Thread.** Per-cell turn and failure counts against past nights; the plain
|
|
167
|
-
channel and delta-at-50 as two stacked tables every 250 turns, with the
|
|
168
|
-
deepest turn each cell reached; and the snapshot-frequency sweep, whose
|
|
169
|
-
columns are the snapshot interval (50, 500, 1000). The sweep shows read,
|
|
170
|
-
write and storage at the turn before and at each snapshot, where read peaks
|
|
171
|
-
and resets, plus the write at the row's own turn: snapshots land on those
|
|
172
|
-
turns, so it is the full-value write the median hides.
|
|
135
|
+
**How it runs.** One k6 run of 20 users. Each user owns two threads, one plain
|
|
136
|
+
(`base`) and one delta, and takes a turn on each in rotation until both reach
|
|
137
|
+
1,400 turns, so the two are always measured at the same depth seconds apart.
|
|
138
|
+
A turn (`POST /runs/wait`) appends one 1 KB chat message of varied text; text
|
|
139
|
+
repeated every turn would compress away in Postgres and make storage measure
|
|
140
|
+
row overhead. Each user also does a cold state read (`GET /threads/{id}/state`)
|
|
141
|
+
once every 50 turns, at its own offset in that interval, so the reads cover
|
|
142
|
+
the whole climb between two snapshots instead of the moment right after one.
|
|
143
|
+
Storage (`GET /threads/{id}/storage`) is read at turns 350, 700, 1050 and 1400.
|
|
144
|
+
|
|
145
|
+
**The table.** Both setups at turn 1400: `write` is the median checkpoint
|
|
146
|
+
save, timed by the worker between the graph's two steps; `read` is the median
|
|
147
|
+
cold read, timed to the server's first byte; `MB` is the thread's storage.
|
|
148
|
+
Lower is better for all three. `last 10` is the delta value over tonight and
|
|
149
|
+
the nine nights before it. A metric outside its usual range over five or more
|
|
150
|
+
nights gets a ⚠️ line above the table.
|
|
151
|
+
|
|
152
|
+
**Pass bar.** Request errors under 1% and success over 99%. Two correctness
|
|
153
|
+
checks turn the dot yellow on any failure: at turn 2 each thread confirms
|
|
154
|
+
delta is on (or off, for `base`), because a too-old langgraph silently
|
|
155
|
+
degrades a `DeltaChannel` to a plain one; and every cold read is compared with
|
|
156
|
+
what the run returned.
|
|
157
|
+
|
|
158
|
+
**Thread.** Write, read and MB at turns 350, 700, 1050 and 1400, with `gain`:
|
|
159
|
+
how many times better delta is (`same` within 15%, below `1.0x` when delta is
|
|
160
|
+
worse). Then the run's size, failures and correctness checks.
|
|
173
161
|
|
|
174
162
|
## Changing a report
|
|
175
163
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import test from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import {
|
|
4
|
+
parseCells,
|
|
4
5
|
planTurn,
|
|
6
|
+
readOffset,
|
|
5
7
|
deltaGuardFailure,
|
|
6
8
|
digestDrift,
|
|
7
9
|
stateDrift,
|
|
@@ -15,6 +17,8 @@ const BASE = {
|
|
|
15
17
|
migrateAfter: 0,
|
|
16
18
|
expectDelta: true,
|
|
17
19
|
verifyEvery: 50,
|
|
20
|
+
readOffset: 0,
|
|
21
|
+
storageEvery: 0,
|
|
18
22
|
bucketSize: 100,
|
|
19
23
|
};
|
|
20
24
|
|
|
@@ -180,3 +184,32 @@ test('a missing digest on either side is reported, not passed', () => {
|
|
|
180
184
|
assert.equal(digestDrift('', 'a'.repeat(64)), 'run_digest_missing');
|
|
181
185
|
assert.equal(digestDrift('a'.repeat(64), null), 'cold_digest_missing');
|
|
182
186
|
});
|
|
187
|
+
|
|
188
|
+
test('cold reads spread across the snapshot interval instead of all landing on it', () => {
|
|
189
|
+
const offsets = Array.from({ length: 20 }, (_, i) => readOffset(i + 1, 20, 50));
|
|
190
|
+
assert.equal(offsets[0], 0);
|
|
191
|
+
assert.equal(offsets.at(-1), 47);
|
|
192
|
+
assert.equal(new Set(offsets).size, 20, 'every VU reads at its own point');
|
|
193
|
+
assert.equal(planTurn(47, { ...BASE, readOffset: 3 }).verify, true);
|
|
194
|
+
assert.equal(planTurn(50, { ...BASE, readOffset: 3 }).verify, false);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('storage is read on the cold-read turn of each bucket that ends a table row', () => {
|
|
198
|
+
const options = { ...BASE, bucketSize: 50, readOffset: 10, storageEvery: 350 };
|
|
199
|
+
assert.equal(planTurn(340, options).storage, true, 'bucket 301-350 ends on 350');
|
|
200
|
+
assert.equal(planTurn(290, options).storage, false, 'a cold read, but bucket 251-300 is not a row');
|
|
201
|
+
assert.equal(planTurn(341, options).storage, false, 'not a cold-read turn');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('without a storage interval, storage is read on every cold read', () => {
|
|
205
|
+
assert.equal(planTurn(50, { ...BASE, storageEvery: 0 }).storage, true);
|
|
206
|
+
assert.equal(planTurn(51, { ...BASE, storageEvery: 0 }).storage, false);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test('cells parse from name:graph:expectDelta', () => {
|
|
210
|
+
assert.deepEqual(parseCells('control:benchmark:false, delta_50:benchmark_delta_messages:true'), [
|
|
211
|
+
{ name: 'control', graphId: 'benchmark', expectDelta: false },
|
|
212
|
+
{ name: 'delta_50', graphId: 'benchmark_delta_messages', expectDelta: true },
|
|
213
|
+
]);
|
|
214
|
+
assert.deepEqual(parseCells(''), []);
|
|
215
|
+
});
|
|
@@ -9,9 +9,20 @@ export interface DeltaTurnsOptions {
|
|
|
9
9
|
expectDelta: boolean;
|
|
10
10
|
/** Cold re-read cadence, in turns. 0 disables. */
|
|
11
11
|
verifyEvery: number;
|
|
12
|
+
/** Shifts this VU's cold reads off the multiples of `verifyEvery`; see readOffset. */
|
|
13
|
+
readOffset: number;
|
|
14
|
+
/** Storage is read on the cold-read turn of every bucket ending on a multiple of this. 0 reads it on every cold read. */
|
|
15
|
+
storageEvery: number;
|
|
12
16
|
bucketSize: number;
|
|
13
17
|
}
|
|
14
18
|
|
|
19
|
+
/** One setup the VU turns in rotation, on a thread of its own. */
|
|
20
|
+
export interface DeltaCell {
|
|
21
|
+
name: string;
|
|
22
|
+
graphId: string;
|
|
23
|
+
expectDelta: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
export interface TurnPlan {
|
|
16
27
|
graphId: string;
|
|
17
28
|
/** Cumulative on a reused thread, so turn N asks for N. */
|
|
@@ -19,6 +30,7 @@ export interface TurnPlan {
|
|
|
19
30
|
expectDelta: boolean;
|
|
20
31
|
guard: boolean;
|
|
21
32
|
verify: boolean;
|
|
33
|
+
storage: boolean;
|
|
22
34
|
depthBucket: string;
|
|
23
35
|
}
|
|
24
36
|
|
|
@@ -32,16 +44,40 @@ export function unusableCheckpointSize(checkpointSize: number | undefined): bool
|
|
|
32
44
|
export function planTurn(turn: number, options: DeltaTurnsOptions): TurnPlan {
|
|
33
45
|
const migrating = options.migrateFromGraphId !== '' && options.migrateAfter > 0;
|
|
34
46
|
const beforeSwitch = migrating && turn <= options.migrateAfter;
|
|
47
|
+
const verify = options.verifyEvery > 0 && (turn + options.readOffset) % options.verifyEvery === 0;
|
|
35
48
|
return {
|
|
36
49
|
graphId: beforeSwitch ? options.migrateFromGraphId : options.graphId,
|
|
37
50
|
steps: turn,
|
|
38
51
|
expectDelta: beforeSwitch ? false : options.expectDelta,
|
|
39
52
|
guard: isGuardTurn(turn, options, migrating),
|
|
40
|
-
verify
|
|
53
|
+
verify,
|
|
54
|
+
storage: verify && (options.storageEvery <= 0 || bucketEnd(turn, options.bucketSize) % options.storageEvery === 0),
|
|
41
55
|
depthBucket: depthBucket(turn, options.bucketSize),
|
|
42
56
|
};
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
/** `name:graph:expectDelta`, comma-separated. */
|
|
60
|
+
export function parseCells(spec: string): DeltaCell[] {
|
|
61
|
+
return spec
|
|
62
|
+
.split(',')
|
|
63
|
+
.map((part) => part.trim())
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.map((part) => {
|
|
66
|
+
const [name, graphId, expectDelta] = part.split(':');
|
|
67
|
+
return { name, graphId, expectDelta: expectDelta === 'true' };
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A delta snapshot lands on every multiple of its frequency, so reading every
|
|
73
|
+
* VU on those turns only ever measures the read right after one. Spreading the
|
|
74
|
+
* VUs across the interval samples the whole climb between snapshots.
|
|
75
|
+
*/
|
|
76
|
+
export function readOffset(vu: number, vus: number, verifyEvery: number): number {
|
|
77
|
+
if (verifyEvery <= 0 || vus <= 0) return 0;
|
|
78
|
+
return Math.floor(((vu - 1) * verifyEvery) / vus) % verifyEvery;
|
|
79
|
+
}
|
|
80
|
+
|
|
45
81
|
/**
|
|
46
82
|
* Turn 1 has no counters yet, and on a snapshot point Pregel drops the counters
|
|
47
83
|
* entry, so its absence there is correct rather than a fallback.
|
|
@@ -51,6 +87,10 @@ function isGuardTurn(turn: number, options: DeltaTurnsOptions, migrating: boolea
|
|
|
51
87
|
return migrating && turn === options.migrateAfter + 2;
|
|
52
88
|
}
|
|
53
89
|
|
|
90
|
+
function bucketEnd(turn: number, bucketSize: number): number {
|
|
91
|
+
return bucketSize <= 0 ? turn : Math.ceil(turn / bucketSize) * bucketSize;
|
|
92
|
+
}
|
|
93
|
+
|
|
54
94
|
function depthBucket(turn: number, bucketSize: number): string {
|
|
55
95
|
if (bucketSize <= 0) return String(turn);
|
|
56
96
|
const floor = Math.floor((turn - 1) / bucketSize) * bucketSize;
|
{langgraph_api-0.17.0.dev3 → langgraph_api-0.17.0.dev4}/benchmark/benchmark-runners/delta_turns.ts
RENAMED
|
@@ -13,9 +13,11 @@ import {
|
|
|
13
13
|
planTurn,
|
|
14
14
|
deltaGuardFailure,
|
|
15
15
|
digestDrift,
|
|
16
|
+
parseCells,
|
|
17
|
+
readOffset,
|
|
16
18
|
unusableCheckpointSize,
|
|
17
19
|
} from './delta-turns-lib.js';
|
|
18
|
-
import type { DeltaTurnsOptions, TurnPlan } from './delta-turns-lib.js';
|
|
20
|
+
import type { DeltaCell, DeltaTurnsOptions, TurnPlan } from './delta-turns-lib.js';
|
|
19
21
|
|
|
20
22
|
const PAYLOAD_CHANNELS = [
|
|
21
23
|
'cumulative_checkpoint',
|
|
@@ -35,20 +37,30 @@ const stateReadDuration = new Trend('state_read_duration', true);
|
|
|
35
37
|
const checkpointSaveDuration = new Trend('checkpoint_save', true);
|
|
36
38
|
const threadStorageBytes = new Trend('thread_storage_bytes', false);
|
|
37
39
|
|
|
38
|
-
const TURN_CONFIG: Omit<DeltaTurnsOptions, 'graphId'> = {
|
|
40
|
+
const TURN_CONFIG: Omit<DeltaTurnsOptions, 'graphId' | 'readOffset'> = {
|
|
39
41
|
migrateFromGraphId: __ENV.MIGRATE_FROM_GRAPH_ID || '',
|
|
40
42
|
migrateAfter: parseInt(__ENV.MIGRATE_AFTER || '0', 10),
|
|
41
43
|
expectDelta: (__ENV.EXPECT_DELTA || 'true') === 'true',
|
|
42
44
|
verifyEvery: parseInt(__ENV.VERIFY_EVERY || '50', 10),
|
|
45
|
+
storageEvery: parseInt(__ENV.STORAGE_EVERY || '0', 10),
|
|
43
46
|
// One bucket per cold read, so every row of the report is one sample per thread.
|
|
44
47
|
bucketSize: parseInt(__ENV.DEPTH_BUCKET || __ENV.VERIFY_EVERY || '50', 10),
|
|
45
48
|
};
|
|
46
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Every VU turns these in rotation, one thread each, so the cells are measured
|
|
52
|
+
* at the same depth seconds apart. Empty runs GRAPH_ID alone.
|
|
53
|
+
*/
|
|
54
|
+
const CELLS = parseCells(__ENV.DELTA_CELLS || '');
|
|
55
|
+
|
|
47
56
|
// Each k6 VU runs this module in its own context, so these are per VU.
|
|
48
|
-
|
|
49
|
-
let
|
|
57
|
+
const threads: Record<string, { threadId: string | null; turn: number }> = {};
|
|
58
|
+
let iteration = 0;
|
|
50
59
|
|
|
51
60
|
interface DeltaTurnsData {
|
|
61
|
+
cell: string;
|
|
62
|
+
turnMs: number;
|
|
63
|
+
tags: { depth: string; cell: string };
|
|
52
64
|
rawResponse: ReturnType<typeof http.post>;
|
|
53
65
|
plan: TurnPlan;
|
|
54
66
|
guardFailure: string | null;
|
|
@@ -69,18 +81,31 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
69
81
|
return failResult('checkpoint_size', responses) as BenchmarkResult<DeltaTurnsData>;
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
const cell: DeltaCell = CELLS.length > 0
|
|
85
|
+
? CELLS[iteration++ % CELLS.length]
|
|
86
|
+
: { name: benchmarkGraphOptions.graph_id, graphId: benchmarkGraphOptions.graph_id, expectDelta: TURN_CONFIG.expectDelta };
|
|
87
|
+
const own = (threads[cell.name] ??= { threadId: null, turn: 0 });
|
|
88
|
+
if (own.threadId === null) {
|
|
89
|
+
const ttlMinutes = parseInt(__ENV.THREAD_TTL_MINUTES || '0', 10);
|
|
90
|
+
const body = ttlMinutes > 0 ? { ttl: { strategy: 'delete', ttl: ttlMinutes } } : {};
|
|
91
|
+
const thread = http.post(`${baseUrl}/threads`, JSON.stringify(body), requestParams);
|
|
74
92
|
addResponse(responses, 'create_thread', thread);
|
|
75
93
|
if (thread.status !== 200) {
|
|
76
94
|
return failResult('create_thread', responses) as BenchmarkResult<DeltaTurnsData>;
|
|
77
95
|
}
|
|
78
|
-
threadId = (thread.json() as { thread_id: string }).thread_id;
|
|
79
|
-
turn = 0;
|
|
96
|
+
own.threadId = (thread.json() as { thread_id: string }).thread_id;
|
|
97
|
+
own.turn = 0;
|
|
80
98
|
}
|
|
99
|
+
const threadId = own.threadId;
|
|
81
100
|
|
|
82
|
-
turn += 1;
|
|
83
|
-
const plan = planTurn(turn, {
|
|
101
|
+
own.turn += 1;
|
|
102
|
+
const plan = planTurn(own.turn, {
|
|
103
|
+
...TURN_CONFIG,
|
|
104
|
+
graphId: cell.graphId,
|
|
105
|
+
expectDelta: cell.expectDelta,
|
|
106
|
+
readOffset: readOffset(__VU, parseInt(__ENV.LOAD_SIZE || '1', 10), TURN_CONFIG.verifyEvery),
|
|
107
|
+
});
|
|
108
|
+
const tags = { depth: plan.depthBucket, cell: cell.name };
|
|
84
109
|
const payload = JSON.stringify({
|
|
85
110
|
assistant_id: plan.graphId,
|
|
86
111
|
input: {},
|
|
@@ -97,14 +122,11 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
97
122
|
payload,
|
|
98
123
|
requestParams
|
|
99
124
|
);
|
|
100
|
-
|
|
125
|
+
const turnMs = Date.now() - startedAt;
|
|
101
126
|
addResponse(responses, 'wait', response);
|
|
102
127
|
const saveMs = response.status === 200 ? safeJson(response.body)?.save_ms : null;
|
|
103
128
|
if (typeof saveMs === 'number' && saveMs > 0) {
|
|
104
|
-
|
|
105
|
-
// turn is where a snapshot save shows; a percentile over the bucket hides it.
|
|
106
|
-
const rowTurn = plan.steps % TURN_CONFIG.bucketSize === 0 ? '1' : '0';
|
|
107
|
-
checkpointSaveDuration.add(saveMs, { depth: plan.depthBucket, row_turn: rowTurn });
|
|
129
|
+
checkpointSaveDuration.add(saveMs, tags);
|
|
108
130
|
}
|
|
109
131
|
|
|
110
132
|
let guardFailure: string | null = null;
|
|
@@ -120,7 +142,7 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
120
142
|
// a plain-channel read cost as much as a whole turn. The turn-2 guard
|
|
121
143
|
// read is at depth 2, not the bucket's end, so it is not timed.
|
|
122
144
|
if (state.status === 200 && plan.verify) {
|
|
123
|
-
stateReadDuration.add(state.timings.waiting,
|
|
145
|
+
stateReadDuration.add(state.timings.waiting, tags);
|
|
124
146
|
}
|
|
125
147
|
addResponse(responses, 'state', state);
|
|
126
148
|
const body = state.status === 200 ? safeJson(state.body) : null;
|
|
@@ -137,7 +159,7 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
137
159
|
drift = digestDrift(safeJson(response.body)?.payload_sha256, coldDigest(body.values));
|
|
138
160
|
}
|
|
139
161
|
}
|
|
140
|
-
if (plan.
|
|
162
|
+
if (plan.storage) {
|
|
141
163
|
// Servers before 0.16 have no storage endpoint. A 404 there is a missing
|
|
142
164
|
// sample, not a failed request: without this, one 404 per 50 turns is
|
|
143
165
|
// about 2% and trips the 1% error budget on every cell.
|
|
@@ -148,12 +170,12 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
148
170
|
addResponse(responses, 'storage', storage);
|
|
149
171
|
const total = storage.status === 200 ? safeJson(storage.body)?.total_bytes : null;
|
|
150
172
|
if (typeof total === 'number') {
|
|
151
|
-
threadStorageBytes.add(total, {
|
|
173
|
+
threadStorageBytes.add(total, { ...tags, graph: plan.graphId });
|
|
152
174
|
}
|
|
153
175
|
}
|
|
154
176
|
}
|
|
155
177
|
|
|
156
|
-
return okResult(responses, { rawResponse: response, plan, guardFailure, drift, stateStatus });
|
|
178
|
+
return okResult(responses, { cell: cell.name, turnMs, tags, rawResponse: response, plan, guardFailure, drift, stateStatus });
|
|
157
179
|
}
|
|
158
180
|
|
|
159
181
|
static validate(
|
|
@@ -203,7 +225,12 @@ export class DeltaTurns extends BenchmarkRunner {
|
|
|
203
225
|
);
|
|
204
226
|
// The thread is now at an unknown depth, so later turns would be tagged
|
|
205
227
|
// with a depth they do not have.
|
|
206
|
-
|
|
228
|
+
const cell = result.data?.cell;
|
|
229
|
+
if (cell && threads[cell]) threads[cell].threadId = null;
|
|
230
|
+
} else if (result.data) {
|
|
231
|
+
// The report counts these per bucket to tell which depth every user
|
|
232
|
+
// finished, so only a turn that passed every check counts.
|
|
233
|
+
turnDuration.add(result.data.turnMs, result.data.tags);
|
|
207
234
|
}
|
|
208
235
|
return success;
|
|
209
236
|
}
|
|
@@ -315,7 +315,10 @@ function moveLine(row, unit) {
|
|
|
315
315
|
export function capacityCell(summary) {
|
|
316
316
|
if (!summary) return "-";
|
|
317
317
|
if (summary.error) return "ERR";
|
|
318
|
-
|
|
318
|
+
const vus = String(summary.capacity?.targetVUs ?? 0);
|
|
319
|
+
// Passing the last step says only that the server is at least this fast.
|
|
320
|
+
const lastStep = summary.config?.numSteps;
|
|
321
|
+
return lastStep != null && summary.capacity?.step === lastStep ? `${vus}+` : vus;
|
|
319
322
|
}
|
|
320
323
|
|
|
321
324
|
function plural(n, word) {
|
|
@@ -396,6 +399,9 @@ export function formatAggregateTable(
|
|
|
396
399
|
if (failedParts.length > 0) {
|
|
397
400
|
lines.push(`*Failed:* ${failedParts.join(" · ")} · treat the table as incomplete`);
|
|
398
401
|
}
|
|
402
|
+
// hostRequest appends the response body, which can span lines; the detail is often on a later one.
|
|
403
|
+
const reasons = new Set(rows.map((row) => row.summary?.error?.replace(/\s+/g, " ").trim()).filter(Boolean));
|
|
404
|
+
if (reasons.size > 0) lines.push(`*Why:* ${[...reasons].join(" · ")}`);
|
|
399
405
|
if (regressed.length > 0) lines.push(`*Regressed:* ${regressed.map((row) => moveLine(row, unit)).join(" · ")}`);
|
|
400
406
|
if (bottlenecks.length > 0) lines.push(`*Bottlenecks:* ${bottlenecks.join(" · ")}`);
|
|
401
407
|
for (const warning of allWarnings) lines.push(`:warning: ${warning}`);
|
|
@@ -80,6 +80,12 @@ test("the posted cell is the load alone; the served rate lives in the thread", (
|
|
|
80
80
|
assert.equal(capacityCell({ capacity: { targetVUs: 900, successfulRunsPerSec: 366 } }), "900");
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
test("a cell that passed the last step reads as a floor, not a ceiling", () => {
|
|
84
|
+
const config = { numSteps: 13 };
|
|
85
|
+
assert.equal(capacityCell({ config, capacity: { step: 13, targetVUs: 70 } }), "70+");
|
|
86
|
+
assert.equal(capacityCell({ config, capacity: { step: 12, targetVUs: 65 } }), "65");
|
|
87
|
+
});
|
|
88
|
+
|
|
83
89
|
test("a failed cell renders as ERR in the posted table and is named in the Failed line", () => {
|
|
84
90
|
const deployments = [
|
|
85
91
|
{ slug: "dep", tiers: ["TIER_A", "TIER_B"] },
|
|
@@ -130,6 +136,7 @@ test("an incomplete run says so, a clean run says all quiet", () => {
|
|
|
130
136
|
assert.match(table, /^🔴 .* · 1 of 3 cells ran · dep TIER_A crashed, 1 never ran$/m);
|
|
131
137
|
assert.match(table, /^\*Failed:\* dep TIER_A stream \(ERR\) · dep TIER_A search never ran · treat the table as incomplete$/m);
|
|
132
138
|
assert.match(table.split("\n")[1], /^\*Failed:\*/, "what went wrong comes right after the verdict");
|
|
139
|
+
assert.match(table, /^\*Why:\* boom$/m);
|
|
133
140
|
|
|
134
141
|
|
|
135
142
|
const clean = formatAggregateTable(deployments, [
|
|
@@ -418,3 +425,18 @@ test("the CPU table fits a phone even with every component reporting", () => {
|
|
|
418
425
|
const view = formatServerView(deployments, summaries);
|
|
419
426
|
assert.ok(widestCodeLine(view) <= PHONE_WIDTH, `widest table line is ${widestCodeLine(view)}`);
|
|
420
427
|
});
|
|
428
|
+
|
|
429
|
+
test("tiers that crashed for the same reason name it once", () => {
|
|
430
|
+
const deployments = [{ slug: "dep", tiers: ["TIER_A", "TIER_B"] }];
|
|
431
|
+
const crash = (computeTier) =>
|
|
432
|
+
buildErrorSummary({ deploymentSlug: "dep", computeTier, benchmarkType: "wait_write" }, new Error("Deployment failed with status: BUILD_FAILED"));
|
|
433
|
+
const table = formatAggregateTable(deployments, [crash("TIER_A"), crash("TIER_B")]);
|
|
434
|
+
assert.match(table, /^\*Why:\* Deployment failed with status: BUILD_FAILED$/m);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
test("a crashed cell's multi-line error keeps its detail on the Why line", () => {
|
|
438
|
+
const deployments = [{ slug: "dep", tiers: ["TIER_A"] }];
|
|
439
|
+
const error = new Error('PATCH /resource-tiers failed: 409 {\n "detail": "Unable to resize the deployment database."\n}');
|
|
440
|
+
const table = formatAggregateTable(deployments, [buildErrorSummary({ deploymentSlug: "dep", computeTier: "TIER_A", benchmarkType: "wait_write" }, error)]);
|
|
441
|
+
assert.match(table, /^\*Why:\* PATCH \/resource-tiers failed: 409 \{ "detail": "Unable to resize the deployment database\." \}$/m);
|
|
442
|
+
});
|
|
@@ -549,11 +549,11 @@ wheels = [
|
|
|
549
549
|
|
|
550
550
|
[[package]]
|
|
551
551
|
name = "urllib3"
|
|
552
|
-
version = "2.
|
|
552
|
+
version = "2.8.0"
|
|
553
553
|
source = { registry = "https://pypi.org/simple" }
|
|
554
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
554
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" }
|
|
555
555
|
wheels = [
|
|
556
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
556
|
+
{ url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" },
|
|
557
557
|
]
|
|
558
558
|
|
|
559
559
|
[[package]]
|
|
@@ -217,9 +217,15 @@ function runName(run) {
|
|
|
217
217
|
return runnerShortName(run.benchmarkType);
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
function noResults(run) {
|
|
221
|
+
return run.revisionError
|
|
222
|
+
? `no results, the new revision failed: ${run.revisionError}`
|
|
223
|
+
: `no results produced, step finished as \`${run.stepOutcome}\``;
|
|
224
|
+
}
|
|
225
|
+
|
|
220
226
|
function failureReason(run) {
|
|
221
227
|
const metrics = run.summary?.metrics;
|
|
222
|
-
if (!metrics) return
|
|
228
|
+
if (!metrics) return noResults(run);
|
|
223
229
|
const crossed = describedThresholds(run.summary.thresholds, metrics).filter((t) => t.ok === false);
|
|
224
230
|
if (crossed.length > 0) return crossed.map((t) => t.breach).join(', ');
|
|
225
231
|
if (!metrics.successfulRuns) return 'no run succeeded';
|
|
@@ -356,7 +362,7 @@ function perRunDetail(runs, changesByRun, improved, load) {
|
|
|
356
362
|
for (const run of runs) {
|
|
357
363
|
const metrics = run.summary?.metrics;
|
|
358
364
|
if (!metrics) {
|
|
359
|
-
lines.push(`${runName(run)}:
|
|
365
|
+
lines.push(`${runName(run)}: ${noResults(run)}`);
|
|
360
366
|
continue;
|
|
361
367
|
}
|
|
362
368
|
const counts = `${count(metrics.totalRuns)} runs, ${count(metrics.failedRuns)} failed`;
|
|
@@ -427,6 +433,7 @@ export function collectRuns(resultsDir, historyDir) {
|
|
|
427
433
|
return {
|
|
428
434
|
benchmarkType,
|
|
429
435
|
stepOutcome: context.stepOutcome ?? (dir ? 'unknown' : 'missing'),
|
|
436
|
+
revisionError: context.revisionError,
|
|
430
437
|
summary: dir ? readSummary(findLatestSummary(dir)) : null,
|
|
431
438
|
load: { loadSize: context.loadSize, levels: context.levels, plateauDuration: context.plateauDuration },
|
|
432
439
|
history: historyDir ? loadDailyHistory(historyDir, `-${benchmarkType}-`) : [],
|