langgraph-api 0.4.47__tar.gz → 0.5.7__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.
Potentially problematic release.
This version of langgraph-api might be problematic. Click here for more details.
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/Makefile +2 -2
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/PKG-INFO +5 -5
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/Makefile +5 -7
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/assistant.js +11 -7
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/benchmark-runner.js +1 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/burst.js +1 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/capacity_k6.js +6 -5
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/capacity_runner.mjs +114 -109
- langgraph_api-0.5.7/benchmark/capacity_urls.mjs +8 -0
- langgraph_api-0.5.7/benchmark/clean.js +150 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/ramp.js +16 -5
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/reporting/dd_reporting.py +9 -8
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/update-revision.js +5 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/constraints.txt +2 -2
- langgraph_api-0.5.7/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/assistants.py +65 -61
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/meta.py +6 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/threads.py +1 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/asgi_transport.py +1 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/custom.py +29 -24
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/config.py +56 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/graph.py +1 -1
- {langgraph_api-0.4.47/langgraph_api/grpc_ops → langgraph_api-0.5.7/langgraph_api/grpc}/client.py +91 -0
- langgraph_api-0.5.7/langgraph_api/grpc/config_conversion.py +228 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/core_api_pb2.py +275 -0
- {langgraph_api-0.4.47/langgraph_api/grpc_ops → langgraph_api-0.5.7/langgraph_api/grpc}/generated/core_api_pb2.pyi +20 -31
- {langgraph_api-0.4.47/langgraph_api/grpc_ops → langgraph_api-0.5.7/langgraph_api/grpc}/generated/core_api_pb2_grpc.py +2 -2
- langgraph_api-0.5.7/langgraph_api/grpc/generated/engine_common_pb2.py +185 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/engine_common_pb2.pyi +609 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/engine_common_pb2_grpc.py +24 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/enum_durability_pb2.py +37 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/enum_durability_pb2.pyi +16 -0
- langgraph_api-0.5.7/langgraph_api/grpc/generated/enum_durability_pb2_grpc.py +24 -0
- langgraph_api-0.5.7/langgraph_api/grpc/ops/__init__.py +180 -0
- langgraph_api-0.5.7/langgraph_api/grpc/ops/assistants.py +419 -0
- langgraph_api-0.5.7/langgraph_api/grpc/ops/threads.py +505 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/package.json +5 -5
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/graph.mts +20 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/yarn.lock +137 -187
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/queue_entrypoint.py +2 -2
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/route.py +14 -4
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/schema.py +2 -2
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/self_hosted_metrics.py +48 -2
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/serde.py +58 -14
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/worker.py +1 -1
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/pyproject.toml +12 -10
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/uv.lock +146 -146
- langgraph_api-0.4.47/benchmark/capacity_urls.mjs +0 -18
- langgraph_api-0.4.47/benchmark/clean.js +0 -87
- langgraph_api-0.4.47/langgraph_api/__init__.py +0 -1
- langgraph_api-0.4.47/langgraph_api/grpc_ops/generated/core_api_pb2.py +0 -276
- langgraph_api-0.4.47/langgraph_api/grpc_ops/ops.py +0 -1187
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/.gitignore +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/LICENSE +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/README.md +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/.gitignore +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/README.md +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/benchmarks.js +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/stream_write.js +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/wait_write.js +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/graphs.js +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/package.json +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/weather.js +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/forbidden.txt +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/healthcheck.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/a2a.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/mcp.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/cli.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/command.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/executor_entrypoint.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/feature_flags.py +0 -0
- {langgraph_api-0.4.47/langgraph_api/grpc_ops → langgraph_api-0.5.7/langgraph_api/grpc}/__init__.py +0 -0
- {langgraph_api-0.4.47/langgraph_api/grpc_ops → langgraph_api-0.5.7/langgraph_api/grpc}/generated/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/http.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/http_metrics.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/client.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/metadata.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/server.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/state.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/store.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/thread_ttl.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/logging.json +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/openapi.json +0 -0
- {langgraph_api-0.4.47 → langgraph_api-0.5.7}/scripts/create_license.py +0 -0
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# Environment variables
|
|
4
4
|
FF_USE_CORE_API ?= false
|
|
5
|
-
LANGSERVE_GRAPHS_ALL = '{"agent": "./tests/graphs/agent.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "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"}'
|
|
6
|
-
LANGSERVE_GRAPHS_AUTH = '{"agent": "./tests/graphs/agent.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"}'
|
|
5
|
+
LANGSERVE_GRAPHS_ALL = '{"agent": "./tests/graphs/agent.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "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","functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci"}'
|
|
6
|
+
LANGSERVE_GRAPHS_AUTH = '{"agent": "./tests/graphs/agent.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","functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci"}'
|
|
7
7
|
|
|
8
8
|
# Go server management
|
|
9
9
|
build-go-server:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-api
|
|
3
|
-
Version: 0.
|
|
4
|
-
Author-email:
|
|
3
|
+
Version: 0.5.7
|
|
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
|
|
@@ -12,10 +12,10 @@ Requires-Dist: grpcio<2.0.0,>=1.75.0
|
|
|
12
12
|
Requires-Dist: httpx>=0.25.0
|
|
13
13
|
Requires-Dist: jsonschema-rs<0.30,>=0.20.0
|
|
14
14
|
Requires-Dist: langchain-core>=0.3.64
|
|
15
|
-
Requires-Dist: langgraph-checkpoint
|
|
16
|
-
Requires-Dist: langgraph-runtime-inmem<0.
|
|
15
|
+
Requires-Dist: langgraph-checkpoint<4,>=3.0.1
|
|
16
|
+
Requires-Dist: langgraph-runtime-inmem<0.18.0,>=0.17.0
|
|
17
17
|
Requires-Dist: langgraph-sdk>=0.2.0
|
|
18
|
-
Requires-Dist: langgraph
|
|
18
|
+
Requires-Dist: langgraph<2,>=0.4.10
|
|
19
19
|
Requires-Dist: langsmith>=0.3.45
|
|
20
20
|
Requires-Dist: opentelemetry-api>=1.37.0
|
|
21
21
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.37.0
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# Benchmark commands
|
|
2
|
-
BASE_URL ?= https://
|
|
3
|
-
RAMP_START ?=
|
|
2
|
+
BASE_URL ?= https://benchmark-dr-s-2799835ad04b501a95044223ae72ced7.staging.langgraph.app
|
|
3
|
+
RAMP_START ?= 40
|
|
4
4
|
RAMP_END ?= 1000
|
|
5
5
|
RAMP_MULTIPLIER ?= 2
|
|
6
6
|
WAIT_SECONDS ?= 60
|
|
7
|
-
SUCCESS_THRESHOLD ?= 0.99
|
|
8
7
|
CLEAR_BETWEEN_STEPS ?= true
|
|
9
8
|
CLEAR_DELAY_SECONDS ?= 5
|
|
10
9
|
DATA_SIZE ?= 1000
|
|
11
10
|
DELAY ?= 0
|
|
12
|
-
EXPAND ?=
|
|
13
|
-
STEPS ?=
|
|
11
|
+
EXPAND ?= 1
|
|
12
|
+
STEPS ?= 100
|
|
14
13
|
|
|
15
14
|
benchmark-burst:
|
|
16
15
|
make benchmark-reset
|
|
@@ -21,14 +20,13 @@ benchmark-ramp:
|
|
|
21
20
|
k6 run --out json=raw_data_$(shell date +%Y-%m-%dT%H-%M-%S).json --system-tags=[] ramp.js
|
|
22
21
|
|
|
23
22
|
benchmark-capacity:
|
|
24
|
-
rm -f capacity_summary_t*.json
|
|
23
|
+
rm -f capacity_summary_t*.json capacity_raw_t*.json capacity_histogram_*.json
|
|
25
24
|
npm install
|
|
26
25
|
BASE_URL=$(BASE_URL) \
|
|
27
26
|
RAMP_START=$(RAMP_START) \
|
|
28
27
|
RAMP_END=$(RAMP_END) \
|
|
29
28
|
RAMP_MULTIPLIER=$(RAMP_MULTIPLIER) \
|
|
30
29
|
WAIT_SECONDS=$(WAIT_SECONDS) \
|
|
31
|
-
SUCCESS_THRESHOLD=$(SUCCESS_THRESHOLD) \
|
|
32
30
|
CLEAR_BETWEEN_STEPS=$(CLEAR_BETWEEN_STEPS) \
|
|
33
31
|
CLEAR_DELAY_SECONDS=$(CLEAR_DELAY_SECONDS) \
|
|
34
32
|
DATA_SIZE=$(DATA_SIZE) \
|
|
@@ -9,7 +9,7 @@ export class Assistant extends BenchmarkRunner {
|
|
|
9
9
|
*/
|
|
10
10
|
static run(baseUrl, requestParams) {
|
|
11
11
|
const graph_id = 'benchmark';
|
|
12
|
-
let metadata = { description: `Test benchmark assistant ${crypto.randomUUID()}
|
|
12
|
+
let metadata = { description: `Test benchmark assistant ${crypto.randomUUID()}`, created_by: 'benchmark' };
|
|
13
13
|
|
|
14
14
|
// Create an assistant
|
|
15
15
|
const createPayload = JSON.stringify({ graph_id, metadata });
|
|
@@ -36,7 +36,8 @@ export class Assistant extends BenchmarkRunner {
|
|
|
36
36
|
const countResponse = http.post(`${baseUrl}/assistants/count`, countPayload, requestParams);
|
|
37
37
|
|
|
38
38
|
// Delete the assistant
|
|
39
|
-
http.del(`${baseUrl}/assistants/${assistantId}`, requestParams);
|
|
39
|
+
const deleteResponse = http.del(`${baseUrl}/assistants/${assistantId}`, "{}", requestParams);
|
|
40
|
+
|
|
40
41
|
return {
|
|
41
42
|
assistantId,
|
|
42
43
|
searchResponse,
|
|
@@ -44,6 +45,7 @@ export class Assistant extends BenchmarkRunner {
|
|
|
44
45
|
patchResponse,
|
|
45
46
|
getResponse2,
|
|
46
47
|
countResponse,
|
|
48
|
+
deleteResponse,
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -57,22 +59,24 @@ export class Assistant extends BenchmarkRunner {
|
|
|
57
59
|
'Patch response contains the correct assistant': (r) => r.patchResponse.json().assistant_id === result.assistantId,
|
|
58
60
|
'Get response 2 contains the correct assistant': (r) => r.getResponse2.json().assistant_id === result.assistantId,
|
|
59
61
|
'Get response 2 contains the new description': (r) => r.getResponse2.json().metadata.description != result.getResponse.json().metadata.description && result.getResponse2.json().metadata.description === result.patchResponse.json().metadata.description,
|
|
62
|
+
'Get response 2 contains the correct created_by': (r) => r.getResponse2.json().metadata.created_by === 'benchmark',
|
|
60
63
|
'Count response contains the correct number of assistants': (r) => parseInt(r.countResponse.json()) === 1,
|
|
64
|
+
'Delete response is successful': (r) => r.deleteResponse.status === 204,
|
|
61
65
|
});
|
|
62
66
|
} catch (error) {
|
|
63
67
|
console.log(`Unknown error checking response: ${error.message}`);
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
if (!success) {
|
|
67
|
-
if (result.searchResponse.status
|
|
71
|
+
if (result.searchResponse.status == 502 || result.getResponse.status == 502 || result.patchResponse.status == 502 || result.getResponse2.status == 502 || result.countResponse.status == 502 || result.deleteResponse.status == 502) {
|
|
68
72
|
errorMetrics.server_errors.add(1);
|
|
69
|
-
console.log(`Server error: ${result.searchResponse.status}, ${result.getResponse.status}, ${result.patchResponse.status}, ${result.getResponse2.status}, ${result.countResponse.status}`);
|
|
70
|
-
} else if (result.searchResponse.status === 408 || result.getResponse.status === 408 || result.patchResponse.status === 408 || result.getResponse2.status === 408 || result.countResponse.status === 408) {
|
|
73
|
+
console.log(`Server error: ${result.searchResponse.status}, ${result.getResponse.status}, ${result.patchResponse.status}, ${result.getResponse2.status}, ${result.countResponse.status}, ${result.deleteResponse.status}`);
|
|
74
|
+
} else if (result.searchResponse.status === 408 || result.getResponse.status === 408 || result.patchResponse.status === 408 || result.getResponse2.status === 408 || result.countResponse.status === 408 || result.deleteResponse.status === 408) {
|
|
71
75
|
errorMetrics.timeout_errors.add(1);
|
|
72
|
-
console.log(`Timeout error: ${result.searchResponse.error}, ${result.getResponse.error}, ${result.patchResponse.error}, ${result.getResponse2.error}, ${result.countResponse.error}`);
|
|
76
|
+
console.log(`Timeout error: ${result.searchResponse.error}, ${result.getResponse.error}, ${result.patchResponse.error}, ${result.getResponse2.error}, ${result.countResponse.error}, ${result.deleteResponse.error}`);
|
|
73
77
|
} else {
|
|
74
78
|
errorMetrics.other_errors.add(1);
|
|
75
|
-
console.log(`Other error: ${result.searchResponse.body}, ${result.getResponse.body}, ${result.patchResponse.body}, ${result.getResponse2.body}, ${result.countResponse.body}`);
|
|
79
|
+
console.log(`Other error: ${result.searchResponse.body}, ${result.getResponse.body}, ${result.patchResponse.body}, ${result.getResponse2.body}, ${result.countResponse.body}, ${result.deleteResponse.body}`);
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
return success;
|
{langgraph_api-0.4.47 → langgraph_api-0.5.7}/benchmark/benchmark-runners/benchmark-runner.js
RENAMED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
export class BenchmarkRunner {
|
|
5
5
|
/**
|
|
6
6
|
* Run the benchmark type.
|
|
7
|
-
* @param {string} baseUrl - The base URL of the
|
|
7
|
+
* @param {string} baseUrl - The base URL of the Agent Server.
|
|
8
8
|
* @param {any} requestParams - The parameters to use for the request. Includes headers and other config like timeout.
|
|
9
9
|
* @param {any} benchmarkGraphOptions - The options for the benchmark graph.
|
|
10
10
|
* @returns {any} - The result of the benchmark type. This format will vary by benchmark type.
|
|
@@ -13,7 +13,7 @@ const serverErrors = new Counter('server_errors');
|
|
|
13
13
|
const otherErrors = new Counter('other_errors');
|
|
14
14
|
const burstSuccessRate = new Rate('burst_success_rate');
|
|
15
15
|
|
|
16
|
-
// URL of your
|
|
16
|
+
// URL of your Agent Server
|
|
17
17
|
const BASE_URL = __ENV.BASE_URL || 'http://localhost:9123';
|
|
18
18
|
// LangSmith API key only needed with a custom server endpoint
|
|
19
19
|
const LANGSMITH_API_KEY = __ENV.LANGSMITH_API_KEY;
|
|
@@ -19,7 +19,6 @@ const LANGSMITH_API_KEY = __ENV.LANGSMITH_API_KEY;
|
|
|
19
19
|
|
|
20
20
|
const TARGET = parseInt(__ENV.TARGET || '10');
|
|
21
21
|
const WAIT_SECONDS = parseInt(__ENV.WAIT_SECONDS || '60');
|
|
22
|
-
const SUCCESS_THRESHOLD = parseFloat(__ENV.SUCCESS_THRESHOLD || '0.99');
|
|
23
22
|
|
|
24
23
|
// Agent params
|
|
25
24
|
const DATA_SIZE = parseInt(__ENV.DATA_SIZE || '1000');
|
|
@@ -37,9 +36,6 @@ export const options = {
|
|
|
37
36
|
maxDuration: `${Math.max(WAIT_SECONDS + 120, 150)}s`,
|
|
38
37
|
},
|
|
39
38
|
},
|
|
40
|
-
thresholds: {
|
|
41
|
-
'capacity_success_rate': [`rate>=${SUCCESS_THRESHOLD}`],
|
|
42
|
-
},
|
|
43
39
|
};
|
|
44
40
|
|
|
45
41
|
function headers() {
|
|
@@ -171,7 +167,12 @@ export function handleSummary(data) {
|
|
|
171
167
|
const successRate = total > 0 ? (succ / total) * 100 : 0;
|
|
172
168
|
|
|
173
169
|
function withStats(metric) {
|
|
174
|
-
if (!data.metrics[metric]?.values) return {
|
|
170
|
+
if (!data.metrics[metric]?.values) return {
|
|
171
|
+
avg: null,
|
|
172
|
+
p50: null,
|
|
173
|
+
p95: null,
|
|
174
|
+
max: null,
|
|
175
|
+
};
|
|
175
176
|
const vals = data.metrics[metric].values;
|
|
176
177
|
return {
|
|
177
178
|
avg: vals.avg ? vals.avg / 1000 : null,
|
|
@@ -32,6 +32,11 @@ function envFloat(name, def) {
|
|
|
32
32
|
return Number.isFinite(n) ? n : def;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function slugifyTimestamp(ts) {
|
|
36
|
+
const raw = ts ?? new Date().toISOString();
|
|
37
|
+
return raw.replace(/:/g, '-').replace(/\..+/, '');
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
const BASE_URL = process.env.BASE_URL;
|
|
36
41
|
const LANGSMITH_API_KEY = process.env.LANGSMITH_API_KEY;
|
|
37
42
|
|
|
@@ -39,7 +44,6 @@ const RAMP_START = envInt('RAMP_START', 10);
|
|
|
39
44
|
const RAMP_END = envInt('RAMP_END', 1000);
|
|
40
45
|
const RAMP_MULTIPLIER = envFloat('RAMP_MULTIPLIER', 10);
|
|
41
46
|
const WAIT_SECONDS = envInt('WAIT_SECONDS', 60);
|
|
42
|
-
const SUCCESS_THRESHOLD = envFloat('SUCCESS_THRESHOLD', 0.99);
|
|
43
47
|
const CLEAR_BETWEEN_STEPS = envBool('CLEAR_BETWEEN_STEPS', true);
|
|
44
48
|
const CLEAR_DELAY_SECONDS = envInt('CLEAR_DELAY_SECONDS', 5);
|
|
45
49
|
|
|
@@ -107,7 +111,6 @@ function runK6(target) {
|
|
|
107
111
|
LANGSMITH_API_KEY,
|
|
108
112
|
TARGET: String(target),
|
|
109
113
|
WAIT_SECONDS: String(WAIT_SECONDS),
|
|
110
|
-
SUCCESS_THRESHOLD: String(SUCCESS_THRESHOLD),
|
|
111
114
|
DATA_SIZE: String(DATA_SIZE),
|
|
112
115
|
DELAY: String(DELAY),
|
|
113
116
|
EXPAND: String(EXPAND),
|
|
@@ -140,89 +143,95 @@ function loadSummaryForTarget(target) {
|
|
|
140
143
|
|
|
141
144
|
async function main() {
|
|
142
145
|
let n = RAMP_START;
|
|
143
|
-
let lastSuccess = null; // { target, avgDurationSeconds, successRate }
|
|
144
|
-
let failedStep = null; // { target, successRate }
|
|
145
146
|
|
|
146
147
|
while (n <= RAMP_END) {
|
|
147
|
-
|
|
148
|
+
const currentTarget = n;
|
|
149
|
+
console.log(`\n=== Capacity step: N=${currentTarget} ===`);
|
|
148
150
|
if (CLEAR_BETWEEN_STEPS) {
|
|
149
151
|
console.log('Clearing threads before step...');
|
|
150
152
|
await cleanThreads();
|
|
151
153
|
}
|
|
152
154
|
|
|
155
|
+
let stageTimestamp = null;
|
|
156
|
+
let runDurationHistogram = null;
|
|
157
|
+
let histogramSampleCount = 0;
|
|
158
|
+
|
|
153
159
|
try {
|
|
154
|
-
const { rawOut, ts } = runK6(
|
|
160
|
+
const { rawOut, ts } = runK6(currentTarget);
|
|
161
|
+
stageTimestamp = ts;
|
|
155
162
|
try {
|
|
156
|
-
await generateHistogramsForStage(rawOut
|
|
163
|
+
const histogramResult = await generateHistogramsForStage(rawOut);
|
|
164
|
+
runDurationHistogram = histogramResult?.runDurationHistogramSeconds ?? null;
|
|
165
|
+
histogramSampleCount = histogramResult?.sampleCount ?? 0;
|
|
157
166
|
} catch (e) {
|
|
158
|
-
console.error(`Failed to generate histograms for N=${
|
|
167
|
+
console.error(`Failed to generate histograms for N=${currentTarget}:`, e?.message || e);
|
|
159
168
|
}
|
|
160
169
|
} catch (e) {
|
|
161
|
-
console.error(`k6 run failed at N=${
|
|
170
|
+
console.error(`k6 run failed at N=${currentTarget}:`, e?.message || e);
|
|
162
171
|
// Treat as failure for this step
|
|
163
172
|
}
|
|
164
173
|
|
|
165
|
-
let
|
|
166
|
-
let avgDurationSeconds = null;
|
|
174
|
+
let summary = null;
|
|
167
175
|
try {
|
|
168
|
-
|
|
169
|
-
const s = summary?.metrics?.successRate; // percent
|
|
170
|
-
successRate = Number.isFinite(s) ? s / 100 : 0;
|
|
171
|
-
avgDurationSeconds = summary?.metrics?.runDuration?.avg ?? null;
|
|
172
|
-
console.log(`Step N=${n} successRate=${(successRate * 100).toFixed(2)}% avgDur=${avgDurationSeconds ?? 'n/a'}s`);
|
|
176
|
+
summary = loadSummaryForTarget(currentTarget);
|
|
173
177
|
} catch (e) {
|
|
174
|
-
console.error(`Failed to read summary for N=${
|
|
178
|
+
console.error(`Failed to read summary for N=${currentTarget}:`, e?.message || e);
|
|
175
179
|
}
|
|
176
180
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
n = next;
|
|
181
|
+
const metrics = summary?.metrics ?? {};
|
|
182
|
+
const successRatePercent = metrics?.successRate ?? null;
|
|
183
|
+
const avgDurationSeconds = metrics?.runDuration?.avg ?? null;
|
|
184
|
+
|
|
185
|
+
const hasSuccessRate = Number.isFinite(successRatePercent);
|
|
186
|
+
const hasAvgDuration = Number.isFinite(avgDurationSeconds);
|
|
187
|
+
if (hasSuccessRate && hasAvgDuration) {
|
|
188
|
+
console.log(`Step N=${currentTarget} successRate=${successRatePercent.toFixed(2)}% avgDur=${avgDurationSeconds.toFixed(3)}s`);
|
|
186
189
|
} else {
|
|
187
|
-
|
|
190
|
+
console.log(`Step N=${currentTarget} summary incomplete`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const effectiveTimestamp = summary?.timestamp ?? stageTimestamp ?? slugifyTimestamp();
|
|
194
|
+
|
|
195
|
+
if (Array.isArray(runDurationHistogram) && runDurationHistogram.length > 0) {
|
|
196
|
+
const histogramLog = {
|
|
197
|
+
timestamp: effectiveTimestamp,
|
|
198
|
+
baseUrl: BASE_URL,
|
|
199
|
+
baseUrlName: baseUrlToBaseUrlName[BASE_URL],
|
|
200
|
+
target: currentTarget,
|
|
201
|
+
waitSeconds: WAIT_SECONDS,
|
|
202
|
+
dataSize: DATA_SIZE,
|
|
203
|
+
delay: DELAY,
|
|
204
|
+
expand: EXPAND,
|
|
205
|
+
steps: STEPS,
|
|
206
|
+
metric: 'run_duration_seconds',
|
|
207
|
+
histogram: {
|
|
208
|
+
unit: 'seconds',
|
|
209
|
+
buckets: runDurationHistogram,
|
|
210
|
+
sampleCount: histogramSampleCount,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
const histogramFile = `capacity_histogram_t${currentTarget}_${slugifyTimestamp(effectiveTimestamp)}.json`;
|
|
214
|
+
writeFileSync(join(process.cwd(), histogramFile), JSON.stringify(histogramLog, null, 2));
|
|
215
|
+
console.log(JSON.stringify(histogramLog));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (currentTarget >= RAMP_END) {
|
|
219
|
+
console.log('Reached final ramp target; stopping.');
|
|
188
220
|
break;
|
|
189
221
|
}
|
|
190
|
-
}
|
|
191
222
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
waitSeconds: WAIT_SECONDS,
|
|
199
|
-
threshold: SUCCESS_THRESHOLD,
|
|
200
|
-
last_success_target: lastSuccess?.target ?? 0,
|
|
201
|
-
last_success_avg_duration_seconds: lastSuccess?.avgDurationSeconds ?? null,
|
|
202
|
-
last_success_rate: lastSuccess?.successRate ?? null,
|
|
203
|
-
failed_target: failedStep?.target ?? null,
|
|
204
|
-
failed_success_rate: failedStep?.successRate ?? null,
|
|
205
|
-
failed_avg_duration_seconds: failedStep?.avgDurationSeconds ?? null,
|
|
206
|
-
};
|
|
207
|
-
const fname = `capacity_report_${ts}.json`;
|
|
208
|
-
writeFileSync(join(process.cwd(), fname), JSON.stringify(report, null, 2));
|
|
223
|
+
const next = Math.floor(currentTarget * RAMP_MULTIPLIER);
|
|
224
|
+
if (next > RAMP_END) {
|
|
225
|
+
n = RAMP_END;
|
|
226
|
+
} else {
|
|
227
|
+
n = next;
|
|
228
|
+
}
|
|
209
229
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
`last_success_avg_duration_seconds=${report.last_success_avg_duration_seconds}`,
|
|
215
|
-
`failed_target=${report.failed_target}`,
|
|
216
|
-
`failed_success_rate=${report.failed_success_rate}`,
|
|
217
|
-
`failed_avg_duration_seconds=${report.failed_avg_duration_seconds}`,
|
|
218
|
-
].join('\n');
|
|
219
|
-
writeFileSync(process.env.GITHUB_OUTPUT, `${out}\n`, { flag: 'a' });
|
|
230
|
+
if (n <= currentTarget) {
|
|
231
|
+
console.log('Next ramp value would not increase; stopping.');
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
220
234
|
}
|
|
221
|
-
|
|
222
|
-
console.log('=== Capacity Benchmark Report ===');
|
|
223
|
-
console.log(`Last successful step: ${report.last_success_target}`);
|
|
224
|
-
console.log(`Average duration (s) at success: ${report.last_success_avg_duration_seconds}`);
|
|
225
|
-
console.log(`Failed step: ${report.failed_target} with success rate: ${report.failed_success_rate}`);
|
|
226
235
|
}
|
|
227
236
|
|
|
228
237
|
main().catch((e) => {
|
|
@@ -230,8 +239,47 @@ main().catch((e) => {
|
|
|
230
239
|
process.exit(1);
|
|
231
240
|
});
|
|
232
241
|
|
|
242
|
+
function buildHistogramBuckets(valuesSeconds, bucketCount = 12) {
|
|
243
|
+
if (!Array.isArray(valuesSeconds) || valuesSeconds.length === 0) return [];
|
|
244
|
+
const min = Math.min(...valuesSeconds);
|
|
245
|
+
const max = Math.max(...valuesSeconds);
|
|
246
|
+
if (!Number.isFinite(min) || !Number.isFinite(max)) return [];
|
|
247
|
+
if (min === max) {
|
|
248
|
+
return [{
|
|
249
|
+
start: Number(min.toFixed(6)),
|
|
250
|
+
end: Number(max.toFixed(6)),
|
|
251
|
+
count: valuesSeconds.length,
|
|
252
|
+
}];
|
|
253
|
+
}
|
|
254
|
+
const width = (max - min) / bucketCount;
|
|
255
|
+
if (width === 0) {
|
|
256
|
+
return [{
|
|
257
|
+
start: Number(min.toFixed(6)),
|
|
258
|
+
end: Number(max.toFixed(6)),
|
|
259
|
+
count: valuesSeconds.length,
|
|
260
|
+
}];
|
|
261
|
+
}
|
|
262
|
+
const buckets = Array.from({ length: bucketCount }, (_, i) => ({
|
|
263
|
+
start: min + i * width,
|
|
264
|
+
end: i === bucketCount - 1 ? max : min + (i + 1) * width,
|
|
265
|
+
count: 0,
|
|
266
|
+
}));
|
|
267
|
+
for (const v of valuesSeconds) {
|
|
268
|
+
if (!Number.isFinite(v)) continue;
|
|
269
|
+
let idx = Math.floor((v - min) / width);
|
|
270
|
+
if (idx < 0) idx = 0;
|
|
271
|
+
if (idx >= bucketCount) idx = bucketCount - 1;
|
|
272
|
+
buckets[idx].count += 1;
|
|
273
|
+
}
|
|
274
|
+
return buckets.map((b, i) => ({
|
|
275
|
+
start: Number(b.start.toFixed(6)),
|
|
276
|
+
end: Number(b.end.toFixed(6)),
|
|
277
|
+
count: b.count,
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
|
|
233
281
|
// Build and save histogram charts for one stage from raw K6 JSON
|
|
234
|
-
async function generateHistogramsForStage(rawFile
|
|
282
|
+
async function generateHistogramsForStage(rawFile) {
|
|
235
283
|
// Parse streaming JSONL from k6 --out json
|
|
236
284
|
const metrics = {
|
|
237
285
|
run_duration: [],
|
|
@@ -261,52 +309,9 @@ async function generateHistogramsForStage(rawFile, target, ts) {
|
|
|
261
309
|
rl.on('error', reject);
|
|
262
310
|
});
|
|
263
311
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const avgReturnS = avg(metrics.run_return_duration) / 1000;
|
|
270
|
-
const parts = [avgInsertionS, avgPickupS, avgOssS, avgReturnS];
|
|
271
|
-
const totalParts = parts.reduce((a, b) => a + b, 0);
|
|
272
|
-
if (totalParts > 0) {
|
|
273
|
-
const chart = new QuickChart();
|
|
274
|
-
chart.setWidth(700);
|
|
275
|
-
chart.setHeight(500);
|
|
276
|
-
chart.setFormat('png');
|
|
277
|
-
chart.setConfig({
|
|
278
|
-
type: 'pie',
|
|
279
|
-
data: {
|
|
280
|
-
labels: ['Insertion', 'Pickup', 'OSS', 'Return'],
|
|
281
|
-
datasets: [{
|
|
282
|
-
label: `Breakdown of Run Duration (N=${target})`,
|
|
283
|
-
data: parts.map((v) => Number(v.toFixed(4))),
|
|
284
|
-
backgroundColor: [
|
|
285
|
-
'rgba(255, 99, 132, 0.6)',
|
|
286
|
-
'rgba(54, 162, 235, 0.6)',
|
|
287
|
-
'rgba(255, 206, 86, 0.6)',
|
|
288
|
-
'rgba(75, 192, 192, 0.6)',
|
|
289
|
-
],
|
|
290
|
-
borderColor: [
|
|
291
|
-
'rgba(255, 99, 132, 1)',
|
|
292
|
-
'rgba(54, 162, 235, 1)',
|
|
293
|
-
'rgba(255, 206, 86, 1)',
|
|
294
|
-
'rgba(75, 192, 192, 1)',
|
|
295
|
-
],
|
|
296
|
-
borderWidth: 1,
|
|
297
|
-
}],
|
|
298
|
-
},
|
|
299
|
-
options: {
|
|
300
|
-
plugins: {
|
|
301
|
-
title: { display: true, text: `Run Duration Breakdown (s) — N=${target}` },
|
|
302
|
-
legend: { position: 'right' },
|
|
303
|
-
tooltip: { callbacks: { label: (ctx) => `${ctx.label}: ${ctx.parsed.toFixed(3)}s` } },
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
});
|
|
307
|
-
const pieBuf = await chart.toBinary();
|
|
308
|
-
const piePath = join(process.cwd(), `capacity_pie_breakdown_t${target}_${ts}.png`);
|
|
309
|
-
writeFileSync(piePath, pieBuf);
|
|
310
|
-
console.log(`Saved pie chart: ${piePath}`);
|
|
311
|
-
}
|
|
312
|
+
const runDurationSeconds = metrics.run_duration.map((v) => v / 1000);
|
|
313
|
+
return {
|
|
314
|
+
runDurationHistogramSeconds: buildHistogramBuckets(runDurationSeconds),
|
|
315
|
+
sampleCount: runDurationSeconds.length,
|
|
316
|
+
};
|
|
312
317
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const baseUrlToBaseUrlName = {
|
|
2
|
+
'https://benchmark-s-6d17010be8a25023a9eab0a688d29c05.staging.langgraph.app': 's',
|
|
3
|
+
'https://benchmark-m-fd2e770a72f55324b6c59f2664a56d32.staging.langgraph.app': 'm',
|
|
4
|
+
'https://benchmark-l-d655833b3cba5fc8a703c95f20045831.staging.langgraph.app': 'l',
|
|
5
|
+
'https://benchmark-dr-s-2799835ad04b501a95044223ae72ced7.staging.langgraph.app': 'dr-s',
|
|
6
|
+
'https://benchmark-dr-m-ec079ea9f20e5655ab35a4ebc1a0ade8.staging.langgraph.app': 'dr-m',
|
|
7
|
+
'https://benchmark-dr-l-e996bbdcfbf15c9e8f547ab74fae93d2.staging.langgraph.app': 'dr-l'
|
|
8
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Delete all threads and runs from the last benchmark run for consistent tests
|
|
3
|
+
* The default benchmark server has a thread TTL of one hour that should clean things up too so this doesn't run too long.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// URL of your Agent Server
|
|
7
|
+
const BASE_URL = process.env.BASE_URL || 'http://localhost:9123';
|
|
8
|
+
// LangSmith API key only needed with a custom server endpoint
|
|
9
|
+
const LANGSMITH_API_KEY = process.env.LANGSMITH_API_KEY;
|
|
10
|
+
|
|
11
|
+
async function clean() {
|
|
12
|
+
try {
|
|
13
|
+
await cleanAssistants();
|
|
14
|
+
await cleanThreads();
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error('Fatal error during cleanup:', error.message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function cleanAssistants() {
|
|
22
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
23
|
+
if (LANGSMITH_API_KEY) {
|
|
24
|
+
headers['x-api-key'] = LANGSMITH_API_KEY;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const searchUrl = `${BASE_URL}/assistants/search`;
|
|
28
|
+
let totalDeleted = 0;
|
|
29
|
+
|
|
30
|
+
console.log('Starting assistant cleanup...');
|
|
31
|
+
|
|
32
|
+
while (true) {
|
|
33
|
+
// Get the next page of assistants
|
|
34
|
+
console.log('Searching for assistants...');
|
|
35
|
+
const searchResponse = await fetch(searchUrl, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers,
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
limit: 1000,
|
|
40
|
+
metadata: {
|
|
41
|
+
created_by: 'benchmark' // NOTE: Super important to not clean up the assistants created by the system
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (!searchResponse.ok) {
|
|
47
|
+
throw new Error(`Search request failed: ${searchResponse.status} ${searchResponse.statusText}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const assistants = await searchResponse.json();
|
|
51
|
+
|
|
52
|
+
// If no assistants found, we're done
|
|
53
|
+
if (!assistants || assistants.length === 0) {
|
|
54
|
+
console.log('No more assistants found.');
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(`Found ${assistants.length} assistants to delete`);
|
|
59
|
+
|
|
60
|
+
// Delete each assistant
|
|
61
|
+
for (const assistant of assistants) {
|
|
62
|
+
try {
|
|
63
|
+
const deleteUrl = `${BASE_URL}/assistants/${assistant.assistant_id}`;
|
|
64
|
+
const deleteResponse = await fetch(deleteUrl, {
|
|
65
|
+
method: 'DELETE',
|
|
66
|
+
headers
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (!deleteResponse.ok) {
|
|
70
|
+
console.error(`Failed to delete assistant ${assistant.assistant_id}: ${deleteResponse.status} ${deleteResponse.statusText}`);
|
|
71
|
+
} else {
|
|
72
|
+
totalDeleted++;
|
|
73
|
+
}
|
|
74
|
+
} catch (deleteError) {
|
|
75
|
+
console.error(`Error deleting assistant ${assistant.assistant_id}:`, deleteError.message);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`Deleted ${assistants.length} assistants in this batch`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log(`Assistant cleanup completed. Total assistants deleted: ${totalDeleted}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async function cleanThreads() {
|
|
87
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
88
|
+
if (LANGSMITH_API_KEY) {
|
|
89
|
+
headers['x-api-key'] = LANGSMITH_API_KEY;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const searchUrl = `${BASE_URL}/threads/search`;
|
|
93
|
+
let totalDeleted = 0;
|
|
94
|
+
|
|
95
|
+
console.log('Starting thread cleanup...');
|
|
96
|
+
|
|
97
|
+
while (true) {
|
|
98
|
+
// Get the next page of threads
|
|
99
|
+
console.log('Searching for threads...');
|
|
100
|
+
const searchResponse = await fetch(searchUrl, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers,
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
limit: 1000
|
|
105
|
+
})
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (!searchResponse.ok) {
|
|
109
|
+
throw new Error(`Search request failed: ${searchResponse.status} ${searchResponse.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const threads = await searchResponse.json();
|
|
113
|
+
|
|
114
|
+
// If no threads found, we're done
|
|
115
|
+
if (!threads || threads.length === 0) {
|
|
116
|
+
console.log('No more threads found.');
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log(`Found ${threads.length} threads to delete`);
|
|
121
|
+
|
|
122
|
+
// Delete each thread
|
|
123
|
+
for (const thread of threads) {
|
|
124
|
+
try {
|
|
125
|
+
const deleteUrl = `${BASE_URL}/threads/${thread.thread_id}`;
|
|
126
|
+
const deleteResponse = await fetch(deleteUrl, {
|
|
127
|
+
method: 'DELETE',
|
|
128
|
+
headers
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
if (!deleteResponse.ok) {
|
|
132
|
+
console.error(`Failed to delete thread ${thread.thread_id}: ${deleteResponse.status} ${deleteResponse.statusText}`);
|
|
133
|
+
} else {
|
|
134
|
+
totalDeleted++;
|
|
135
|
+
}
|
|
136
|
+
} catch (deleteError) {
|
|
137
|
+
console.error(`Error deleting thread ${thread.thread_id}:`, deleteError.message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log(`Deleted ${threads.length} threads in this batch`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log(`Thread cleanup completed. Total threads deleted: ${totalDeleted}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
clean().catch(error => {
|
|
148
|
+
console.error('Unhandled error:', error.message);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|