langgraph-api 0.8.5__tar.gz → 0.8.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.
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/PKG-INFO +1 -1
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/continuous/pyproject.toml +2 -2
- langgraph_api-0.8.7/langgraph_api/__init__.py +1 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/a2a.py +31 -1
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/meta.py +31 -19
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/cli.py +6 -11
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/http_metrics.py +5 -4
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/client.mts +15 -0
- langgraph_api-0.8.7/langgraph_api/js/src/utils/experiment-tracing.mts +51 -0
- langgraph_api-0.8.7/langgraph_api/js/yarn.lock +1321 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/metadata.py +1 -0
- langgraph_api-0.8.7/langgraph_api/release_tags.py +206 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/pyproject.toml +3 -3
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/uv.lock +30 -30
- langgraph_api-0.8.5/langgraph_api/__init__.py +0 -1
- langgraph_api-0.8.5/langgraph_api/js/yarn.lock +0 -1894
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/.gitignore +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/LICENSE +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/Makefile +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/README.md +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/.gitignore +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/Makefile +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/README.md +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/assistant.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/benchmarks.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/log-failure.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/meta_workload.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/stream_write.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/thread.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/types.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/benchmark-runners/wait_write.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/capacity_dd_report.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/capacity_k6.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/capacity_runner.mjs +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/capacity_slack_report.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/capacity_urls.mjs +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/clean-cli.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/clean.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/continuous/README.md +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/continuous/runner.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/continuous/uv.lock +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/graphs.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/mixed_workload_k6.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/mixed_workload_runner.mjs +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/package.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/ramp.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/reporting/dd_reporting.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/reporting/slack_slowest_runs.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/reporting/slack_summary.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/run_local.sh +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/staircase.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/staircase_step_k6.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/tsconfig.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/update-revision.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/benchmark/weather.js +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/constraints.txt +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/custom_store.sql +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/forbidden.txt +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/hatch_build.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/healthcheck.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph-cloud-debugging-20260210132856.zip +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/_checkpointer/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/_checkpointer/_adapter.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/_checkpointer/protocol.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/_factory_utils.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/assistants.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/_constants.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/_handlers.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/_models.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/_routes.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/mcp/_sanitizers.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/openapi.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/profile.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/runs.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/store.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/threads.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/api/ui.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/asgi_transport.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/asyncio.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/custom.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/errors.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/langsmith/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/langsmith/backend.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/langsmith/client.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/middleware.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/noop.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/auth/studio_user.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/cache.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/command.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/config/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/config/_parse.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/config/schemas.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/cron_scheduler.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/aes_json.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/context.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/custom.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/middleware.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/encryption/shared.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/errors.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/feature_flags.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/graph.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/client.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/assistants.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/cache.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/crons.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/runs.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/ops/threads.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/server.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/servicers/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/grpc/servicers/encryption.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/http.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/http_metrics_utils.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/.gitignore +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/.prettierrc +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/base.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/build.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/client.http.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/errors.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/global.d.ts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/package.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/remote.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/schema.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/graph.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/load.hooks.mjs +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/preload.mjs +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/utils/files.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/utils/importMap.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/src/utils/serde.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/sse.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/traceblock.mts +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/tsconfig.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/js/ui.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/lc_security/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/lc_security/exceptions.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/lc_security/policy.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/lc_security/transport.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/logging.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/metrics_datadog.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/middleware/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/middleware/ensure_store.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/middleware/http_logger.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/middleware/private_network.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/middleware/request_id.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/models/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/models/run.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/otel_context.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/patch.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/queue_entrypoint.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/route.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/schema.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/self_hosted_logs.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/self_hosted_metrics.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/serde.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/server.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/sse.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/state.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/store.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/stream.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/timing/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/timing/profiler.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/timing/timer.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/traceblock.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/tunneling/cloudflare.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/cache.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/config.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/errors.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/extract.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/future.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/headers.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/network.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/retriable_client.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/stream_codec.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/utils/uuids.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/validation.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/webhook.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_api/worker.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/checkpointer.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/_compat.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/config.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/durability.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/struct.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/conversion/value.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_grpc_common/serde.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_license/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_license/validation.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/__init__.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/checkpoint.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/database.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/lifespan.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/metrics.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/ops.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/queue.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/retry.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/routes.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/langgraph_runtime/store.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/logging.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/openapi.json +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/scripts/build_wheel.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/scripts/create_license.py +0 -0
- {langgraph_api-0.8.5 → langgraph_api-0.8.7}/scripts/run_a2a_tck.py +0 -0
|
@@ -4,8 +4,8 @@ version = "0.1.0"
|
|
|
4
4
|
description = "Continuous stress test for Agent Server"
|
|
5
5
|
requires-python = ">=3.13"
|
|
6
6
|
dependencies = [
|
|
7
|
-
"langgraph-sdk>=0.
|
|
8
|
-
"click>=8.3.
|
|
7
|
+
"langgraph-sdk>=0.3.13",
|
|
8
|
+
"click>=8.3.3",
|
|
9
9
|
"structlog>=24.1.0",
|
|
10
10
|
"datadog-api-client>=2.0.0",
|
|
11
11
|
"python-dateutil>=2.8.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.8.7"
|
|
@@ -552,6 +552,22 @@ def _create_interrupt_artifact(interrupts: list[dict[str, Any]]) -> dict[str, An
|
|
|
552
552
|
}
|
|
553
553
|
|
|
554
554
|
|
|
555
|
+
def _tool_result_data(it: dict[str, Any]) -> dict[str, Any] | None:
|
|
556
|
+
tool_call_id = it.get("tool_call_id")
|
|
557
|
+
if not isinstance(tool_call_id, str) or not tool_call_id:
|
|
558
|
+
return None
|
|
559
|
+
|
|
560
|
+
result: dict[str, Any] = {"toolCallId": tool_call_id}
|
|
561
|
+
content = it.get("content")
|
|
562
|
+
if content not in (None, ""):
|
|
563
|
+
result["content"] = content
|
|
564
|
+
for key in ("name", "status"):
|
|
565
|
+
value = it.get(key)
|
|
566
|
+
if isinstance(value, str) and value:
|
|
567
|
+
result[key] = value
|
|
568
|
+
return result
|
|
569
|
+
|
|
570
|
+
|
|
555
571
|
def _lc_stream_items_to_a2a_message(
|
|
556
572
|
items: list[dict[str, Any]],
|
|
557
573
|
*,
|
|
@@ -604,6 +620,9 @@ def _lc_stream_items_to_a2a_message(
|
|
|
604
620
|
tc = it.get("tool_calls")
|
|
605
621
|
if isinstance(tc, list) and tc:
|
|
606
622
|
extra_data.setdefault("tool_calls", tc)
|
|
623
|
+
tool_result = _tool_result_data(it)
|
|
624
|
+
if tool_result is not None:
|
|
625
|
+
extra_data.setdefault("tool_results", []).append(tool_result)
|
|
607
626
|
|
|
608
627
|
parts: list[dict[str, Any]] = []
|
|
609
628
|
if text_parts:
|
|
@@ -809,10 +828,21 @@ def _convert_messages_to_a2a_format(
|
|
|
809
828
|
else "ROLE_AGENT"
|
|
810
829
|
)
|
|
811
830
|
|
|
831
|
+
parts: list[dict[str, Any]] = [{"kind": "text", "text": str(content)}]
|
|
832
|
+
extra_data: dict[str, Any] = {}
|
|
833
|
+
tc = msg.get("tool_calls")
|
|
834
|
+
if isinstance(tc, list) and tc:
|
|
835
|
+
extra_data["tool_calls"] = tc
|
|
836
|
+
tool_result = _tool_result_data(msg)
|
|
837
|
+
if tool_result is not None:
|
|
838
|
+
extra_data["tool_results"] = [tool_result]
|
|
839
|
+
if extra_data:
|
|
840
|
+
parts.append({"kind": "data", "data": extra_data})
|
|
841
|
+
|
|
812
842
|
a2a_message = {
|
|
813
843
|
"kind": "message",
|
|
814
844
|
"role": a2a_role,
|
|
815
|
-
"parts":
|
|
845
|
+
"parts": parts,
|
|
816
846
|
"messageId": id,
|
|
817
847
|
"taskId": task_id,
|
|
818
848
|
"contextId": context_id,
|
|
@@ -47,9 +47,13 @@ def _merge_pool_stats(local: PoolStats, remote: PoolStats) -> PoolStats:
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def _pool_stats_to_prometheus_lines(
|
|
50
|
-
stats: PoolStats,
|
|
50
|
+
stats: PoolStats,
|
|
51
|
+
project_id: str | None,
|
|
52
|
+
revision_id: str | None,
|
|
53
|
+
deployment_type: str = "",
|
|
51
54
|
) -> list[str]:
|
|
52
55
|
"""Format merged pool stats as Prometheus text lines (same format as langgraph_runtime.database.pool_stats)."""
|
|
56
|
+
labels = f'project_id="{project_id}", revision_id="{revision_id}", deployment_type="{deployment_type}"'
|
|
53
57
|
lines = []
|
|
54
58
|
if "postgres" in stats:
|
|
55
59
|
pg = stats["postgres"]
|
|
@@ -57,19 +61,19 @@ def _pool_stats_to_prometheus_lines(
|
|
|
57
61
|
[
|
|
58
62
|
"# HELP lg_api_pg_pool_max The maximum size of the postgres connection pool.",
|
|
59
63
|
"# TYPE lg_api_pg_pool_max gauge",
|
|
60
|
-
f
|
|
64
|
+
f"lg_api_pg_pool_max{{{labels}}} {pg.get('pool_max', 0)}",
|
|
61
65
|
"# HELP lg_api_pg_pool_size Number of connections currently managed by the postgres connection pool (in the pool, given to clients, being prepared)",
|
|
62
66
|
"# TYPE lg_api_pg_pool_size gauge",
|
|
63
|
-
f
|
|
67
|
+
f"lg_api_pg_pool_size{{{labels}}} {pg.get('pool_size', 0)}",
|
|
64
68
|
"# HELP lg_api_pg_pool_available Number of connections currently idle in the postgres connection pool",
|
|
65
69
|
"# TYPE lg_api_pg_pool_available gauge",
|
|
66
|
-
f
|
|
70
|
+
f"lg_api_pg_pool_available{{{labels}}} {pg.get('pool_available', 0)}",
|
|
67
71
|
"# HELP lg_api_pg_pool_requests_queued Number of postgres connection requests queued because a postgres connection wasn't immediately available in the pool",
|
|
68
72
|
"# TYPE lg_api_pg_pool_requests_queued counter",
|
|
69
|
-
f
|
|
73
|
+
f"lg_api_pg_pool_requests_queued{{{labels}}} {pg.get('requests_queued', 0)}",
|
|
70
74
|
"# HELP lg_api_pg_pool_requests_errors Number of postgres connection requests resulting in an error (timeouts, queue full...)",
|
|
71
75
|
"# TYPE lg_api_pg_pool_requests_errors counter",
|
|
72
|
-
f
|
|
76
|
+
f"lg_api_pg_pool_requests_errors{{{labels}}} {pg.get('requests_errors', 0)}",
|
|
73
77
|
]
|
|
74
78
|
)
|
|
75
79
|
if "redis" in stats:
|
|
@@ -78,13 +82,13 @@ def _pool_stats_to_prometheus_lines(
|
|
|
78
82
|
[
|
|
79
83
|
"# HELP lg_api_redis_pool_available Number of connections currently idle in the redis connection pool",
|
|
80
84
|
"# TYPE lg_api_redis_pool_available gauge",
|
|
81
|
-
f
|
|
85
|
+
f"lg_api_redis_pool_available{{{labels}}} {rd.get('idle_connections', 0)}",
|
|
82
86
|
"# HELP lg_api_redis_pool_size Number of connections currently in use in the redis connection pool",
|
|
83
87
|
"# TYPE lg_api_redis_pool_size gauge",
|
|
84
|
-
f
|
|
88
|
+
f"lg_api_redis_pool_size{{{labels}}} {rd.get('in_use_connections', 0)}",
|
|
85
89
|
"# HELP lg_api_redis_pool_max The maximum size of the redis connection pool.",
|
|
86
90
|
"# TYPE lg_api_redis_pool_max gauge",
|
|
87
|
-
f
|
|
91
|
+
f"lg_api_redis_pool_max{{{labels}}} {rd.get('max_connections', 0)}",
|
|
88
92
|
]
|
|
89
93
|
)
|
|
90
94
|
return lines
|
|
@@ -111,7 +115,10 @@ async def meta_pool_stats(metrics_format: str) -> PoolStats | list[str]:
|
|
|
111
115
|
merged_pool_stats = _merge_pool_stats(local_pool_stats, grpc_pool_stats)
|
|
112
116
|
if metrics_format == "prometheus":
|
|
113
117
|
return _pool_stats_to_prometheus_lines(
|
|
114
|
-
merged_pool_stats,
|
|
118
|
+
merged_pool_stats,
|
|
119
|
+
metadata.PROJECT_ID,
|
|
120
|
+
metadata.HOST_REVISION_ID,
|
|
121
|
+
metadata.DEPLOYMENT_TYPE,
|
|
115
122
|
)
|
|
116
123
|
else:
|
|
117
124
|
return merged_pool_stats
|
|
@@ -154,7 +161,10 @@ async def meta_metrics(request: ApiRequest):
|
|
|
154
161
|
workers_available = worker_metrics["available"]
|
|
155
162
|
|
|
156
163
|
http_metrics = HTTP_METRICS_COLLECTOR.get_metrics(
|
|
157
|
-
metadata.PROJECT_ID,
|
|
164
|
+
metadata.PROJECT_ID,
|
|
165
|
+
metadata.HOST_REVISION_ID,
|
|
166
|
+
metrics_format,
|
|
167
|
+
metadata.DEPLOYMENT_TYPE,
|
|
158
168
|
)
|
|
159
169
|
|
|
160
170
|
merged_pool_stats = await meta_pool_stats(metrics_format)
|
|
@@ -175,23 +185,24 @@ async def meta_metrics(request: ApiRequest):
|
|
|
175
185
|
async with connect() as conn:
|
|
176
186
|
queue_stats = await Runs.stats(conn)
|
|
177
187
|
|
|
188
|
+
labels = f'project_id="{metadata.PROJECT_ID}", revision_id="{metadata.HOST_REVISION_ID}", deployment_type="{metadata.DEPLOYMENT_TYPE}"'
|
|
178
189
|
metrics.extend(
|
|
179
190
|
[
|
|
180
191
|
"# HELP lg_api_num_pending_runs The number of runs currently pending.",
|
|
181
192
|
"# TYPE lg_api_num_pending_runs gauge",
|
|
182
|
-
f
|
|
193
|
+
f"lg_api_num_pending_runs{{{labels}}} {queue_stats['n_pending']}",
|
|
183
194
|
"# HELP lg_api_num_running_runs The number of runs currently running.",
|
|
184
195
|
"# TYPE lg_api_num_running_runs gauge",
|
|
185
|
-
f
|
|
196
|
+
f"lg_api_num_running_runs{{{labels}}} {queue_stats['n_running']}",
|
|
186
197
|
"# HELP lg_api_pending_runs_wait_time_max The maximum time a run has been pending, in seconds.",
|
|
187
198
|
"# TYPE lg_api_pending_runs_wait_time_max gauge",
|
|
188
|
-
f
|
|
199
|
+
f"lg_api_pending_runs_wait_time_max{{{labels}}} {queue_stats.get('pending_runs_wait_time_max_secs') or 0}",
|
|
189
200
|
"# HELP lg_api_pending_runs_wait_time_med The median pending wait time across runs, in seconds.",
|
|
190
201
|
"# TYPE lg_api_pending_runs_wait_time_med gauge",
|
|
191
|
-
f
|
|
202
|
+
f"lg_api_pending_runs_wait_time_med{{{labels}}} {queue_stats.get('pending_runs_wait_time_med_secs') or 0}",
|
|
192
203
|
"# HELP lg_api_pending_unblocked_runs_wait_time_max The maximum time a run has been pending excluding runs blocked by another run on the same thread, in seconds.",
|
|
193
204
|
"# TYPE lg_api_pending_unblocked_runs_wait_time_max gauge",
|
|
194
|
-
f
|
|
205
|
+
f"lg_api_pending_unblocked_runs_wait_time_max{{{labels}}} {queue_stats.get('pending_unblocked_runs_wait_time_max_secs') or 0}",
|
|
195
206
|
]
|
|
196
207
|
)
|
|
197
208
|
except Exception as e:
|
|
@@ -200,17 +211,18 @@ async def meta_metrics(request: ApiRequest):
|
|
|
200
211
|
)
|
|
201
212
|
|
|
202
213
|
if config.N_JOBS_PER_WORKER > 0:
|
|
214
|
+
worker_labels = f'project_id="{metadata.PROJECT_ID}", revision_id="{metadata.HOST_REVISION_ID}", deployment_type="{metadata.DEPLOYMENT_TYPE}"'
|
|
203
215
|
metrics.extend(
|
|
204
216
|
[
|
|
205
217
|
"# HELP lg_api_workers_max The maximum number of workers available.",
|
|
206
218
|
"# TYPE lg_api_workers_max gauge",
|
|
207
|
-
f
|
|
219
|
+
f"lg_api_workers_max{{{worker_labels}}} {workers_max}",
|
|
208
220
|
"# HELP lg_api_workers_active The number of currently active workers.",
|
|
209
221
|
"# TYPE lg_api_workers_active gauge",
|
|
210
|
-
f
|
|
222
|
+
f"lg_api_workers_active{{{worker_labels}}} {workers_active}",
|
|
211
223
|
"# HELP lg_api_workers_available The number of available (idle) workers.",
|
|
212
224
|
"# TYPE lg_api_workers_available gauge",
|
|
213
|
-
f
|
|
225
|
+
f"lg_api_workers_available{{{worker_labels}}} {workers_available}",
|
|
214
226
|
]
|
|
215
227
|
)
|
|
216
228
|
|
|
@@ -94,6 +94,7 @@ def _is_port_available(host: str, port: int) -> bool:
|
|
|
94
94
|
"""Check if a port is available for binding."""
|
|
95
95
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
96
96
|
try:
|
|
97
|
+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
97
98
|
s.bind((host, port))
|
|
98
99
|
return True
|
|
99
100
|
except OSError:
|
|
@@ -150,17 +151,11 @@ def _resolve_server_url(
|
|
|
150
151
|
|
|
151
152
|
def _resolve_port(host: str, port: int | None) -> int:
|
|
152
153
|
"""Resolve the port to use for the server."""
|
|
153
|
-
if port is not None
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
f"Port {port} is already in use. Please specify a different port "
|
|
157
|
-
f"or omit the port argument to auto-discover an available one."
|
|
158
|
-
)
|
|
159
|
-
return port
|
|
160
|
-
if _is_port_available(host, DEFAULT_PORT):
|
|
161
|
-
return DEFAULT_PORT
|
|
154
|
+
requested = port if port is not None else DEFAULT_PORT
|
|
155
|
+
if _is_port_available(host, requested):
|
|
156
|
+
return requested
|
|
162
157
|
found = _find_open_port(host)
|
|
163
|
-
logger.
|
|
158
|
+
logger.warning(f"Port {requested} is already in use, using port {found} instead.")
|
|
164
159
|
return found
|
|
165
160
|
|
|
166
161
|
|
|
@@ -416,7 +411,7 @@ def main():
|
|
|
416
411
|
"--port",
|
|
417
412
|
type=int,
|
|
418
413
|
default=None,
|
|
419
|
-
help="Port to bind the server to (default: 2024
|
|
414
|
+
help="Port to bind the server to (default: 2024; auto-discovers another port if the requested one is in use)",
|
|
420
415
|
)
|
|
421
416
|
parser.add_argument("--no-reload", action="store_true", help="Disable auto-reload")
|
|
422
417
|
parser.add_argument(
|
|
@@ -84,6 +84,7 @@ class HTTPMetricsCollector:
|
|
|
84
84
|
project_id: str | None,
|
|
85
85
|
revision_id: str | None,
|
|
86
86
|
format: str = "prometheus",
|
|
87
|
+
deployment_type: str = "",
|
|
87
88
|
) -> dict | list[str]:
|
|
88
89
|
if format == "json":
|
|
89
90
|
return {
|
|
@@ -117,7 +118,7 @@ class HTTPMetricsCollector:
|
|
|
117
118
|
|
|
118
119
|
for (method, path, status), count in self._request_counts.items():
|
|
119
120
|
metrics.append(
|
|
120
|
-
f'lg_api_http_requests_total{{project_id="{project_id}", revision_id="{revision_id}", method="{method}", path="{path}", status="{status}"}} {count}'
|
|
121
|
+
f'lg_api_http_requests_total{{project_id="{project_id}", revision_id="{revision_id}", deployment_type="{deployment_type}", method="{method}", path="{path}", status="{status}"}} {count}'
|
|
121
122
|
)
|
|
122
123
|
|
|
123
124
|
# Histogram metrics
|
|
@@ -135,13 +136,13 @@ class HTTPMetricsCollector:
|
|
|
135
136
|
acc += bucket_count
|
|
136
137
|
bucket_label = self._histogram_bucket_labels[i]
|
|
137
138
|
metrics.append(
|
|
138
|
-
f'lg_api_http_requests_latency_seconds_bucket{{project_id="{project_id}", revision_id="{revision_id}", method="{method}", path="{path}", le="{bucket_label}"}} {acc}'
|
|
139
|
+
f'lg_api_http_requests_latency_seconds_bucket{{project_id="{project_id}", revision_id="{revision_id}", deployment_type="{deployment_type}", method="{method}", path="{path}", le="{bucket_label}"}} {acc}'
|
|
139
140
|
)
|
|
140
141
|
|
|
141
142
|
metrics.extend(
|
|
142
143
|
[
|
|
143
|
-
f'lg_api_http_requests_latency_seconds_sum{{project_id="{project_id}", revision_id="{revision_id}", method="{method}", path="{path}"}} {hist_data["sum"]:.6f}',
|
|
144
|
-
f'lg_api_http_requests_latency_seconds_count{{project_id="{project_id}", revision_id="{revision_id}", method="{method}", path="{path}"}} {hist_data["count"]}',
|
|
144
|
+
f'lg_api_http_requests_latency_seconds_sum{{project_id="{project_id}", revision_id="{revision_id}", deployment_type="{deployment_type}", method="{method}", path="{path}"}} {hist_data["sum"]:.6f}',
|
|
145
|
+
f'lg_api_http_requests_latency_seconds_count{{project_id="{project_id}", revision_id="{revision_id}", deployment_type="{deployment_type}", method="{method}", path="{path}"}} {hist_data["count"]}',
|
|
145
146
|
]
|
|
146
147
|
)
|
|
147
148
|
|
|
@@ -30,6 +30,7 @@ import * as fs from "node:fs/promises";
|
|
|
30
30
|
import * as path from "node:path";
|
|
31
31
|
import { serialiseAsDict, serializeError } from "./src/utils/serde.mjs";
|
|
32
32
|
import * as importMap from "./src/utils/importMap.mjs";
|
|
33
|
+
import { buildExperimentReplicas } from "./src/utils/experiment-tracing.mjs";
|
|
33
34
|
|
|
34
35
|
import { createLogger, format, transports } from "winston";
|
|
35
36
|
|
|
@@ -45,6 +46,8 @@ import {
|
|
|
45
46
|
} from "./src/graph.mts";
|
|
46
47
|
import { asyncExitHook, gracefulExit } from "exit-hook";
|
|
47
48
|
import { awaitAllCallbacks } from "@langchain/core/callbacks/promises";
|
|
49
|
+
import { LangChainTracer } from "@langchain/core/tracers/tracer_langchain";
|
|
50
|
+
import type { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
48
51
|
import { StatusCode } from "hono/utils/http-status";
|
|
49
52
|
import {
|
|
50
53
|
authenticate,
|
|
@@ -714,6 +717,17 @@ async function* streamEventsRequest(
|
|
|
714
717
|
config.metadata.langgraph_version = version;
|
|
715
718
|
}
|
|
716
719
|
|
|
720
|
+
// Mirror the Python worker's experiment-routing setup for JS graphs. The
|
|
721
|
+
// Python `tracing_context(replicas=...)` cannot cross the sidecar boundary,
|
|
722
|
+
// so build replicas from the same reserved configurable keys and attach a
|
|
723
|
+
// LangChainTracer carrying them. The framework skips its default tracer
|
|
724
|
+
// when one with name "langchain_tracer" is already present in
|
|
725
|
+
// config.callbacks (see @langchain/core callbacks/manager.js).
|
|
726
|
+
const replicas = buildExperimentReplicas(config.configurable);
|
|
727
|
+
const callbacks: BaseCallbackHandler[] | undefined = replicas
|
|
728
|
+
? [new LangChainTracer({ replicas })]
|
|
729
|
+
: undefined;
|
|
730
|
+
|
|
717
731
|
for await (const data of graph.streamEvents(input, {
|
|
718
732
|
...config,
|
|
719
733
|
version: "v2",
|
|
@@ -721,6 +735,7 @@ async function* streamEventsRequest(
|
|
|
721
735
|
subgraphs: payload.subgraphs,
|
|
722
736
|
interruptBefore,
|
|
723
737
|
interruptAfter,
|
|
738
|
+
...(callbacks ? { callbacks } : {}),
|
|
724
739
|
})) {
|
|
725
740
|
// TODO: upstream this fix to LangGraphJS
|
|
726
741
|
if (streamMode.length === 1 && !Array.isArray(data.data.chunk)) {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Helpers for routing studio-experiment runs to a separate LangSmith project
|
|
2
|
+
// when a JS graph is invoked via the Node sidecar.
|
|
3
|
+
//
|
|
4
|
+
// The Python worker (api/langgraph_api/stream.py) reads the run-creation
|
|
5
|
+
// payload's `langsmith_tracer` field and stores it under the reserved
|
|
6
|
+
// configurable keys `__langsmith_project__` / `__langsmith_example_id__`
|
|
7
|
+
// (see api/langgraph_api/models/run.py). For Python graphs it then wraps
|
|
8
|
+
// execution in `langsmith.tracing_context(replicas=[...])`. Python contextvars
|
|
9
|
+
// don't cross the HTTP boundary into the JS sidecar, so we read the same
|
|
10
|
+
// reserved keys here and produce an equivalent replica list that the JS
|
|
11
|
+
// sidecar can pass to a `LangChainTracer`.
|
|
12
|
+
|
|
13
|
+
export interface ExperimentReplica {
|
|
14
|
+
projectName: string;
|
|
15
|
+
updates?: { reference_example_id: string };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Build the LangSmith tracing replicas for a JS streamEvents call.
|
|
20
|
+
*
|
|
21
|
+
* Returns `undefined` when the run was not dispatched as part of a studio
|
|
22
|
+
* experiment (i.e. `__langsmith_project__` is not set). When set, returns
|
|
23
|
+
* two replicas mirroring the Python worker:
|
|
24
|
+
* 1. the experiment project (carrying `reference_example_id` when an
|
|
25
|
+
* example_id is present) — links runs to dataset rows in the experiment
|
|
26
|
+
* view.
|
|
27
|
+
* 2. the deployment's env-default project (`LANGSMITH_PROJECT` /
|
|
28
|
+
* `LANGCHAIN_PROJECT`) — keeps the deployment-level trace stream
|
|
29
|
+
* unchanged for non-experiment observability.
|
|
30
|
+
*/
|
|
31
|
+
export function buildExperimentReplicas(
|
|
32
|
+
configurable: Record<string, unknown> | undefined,
|
|
33
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
34
|
+
): ExperimentReplica[] | undefined {
|
|
35
|
+
const lsProject = configurable?.["__langsmith_project__"];
|
|
36
|
+
if (typeof lsProject !== "string" || lsProject.length === 0) return undefined;
|
|
37
|
+
|
|
38
|
+
const lsExampleId = configurable?.["__langsmith_example_id__"];
|
|
39
|
+
const envProject =
|
|
40
|
+
env.LANGSMITH_PROJECT ?? env.LANGCHAIN_PROJECT ?? "default";
|
|
41
|
+
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
projectName: lsProject,
|
|
45
|
+
...(typeof lsExampleId === "string" && lsExampleId.length > 0
|
|
46
|
+
? { updates: { reference_example_id: lsExampleId } }
|
|
47
|
+
: {}),
|
|
48
|
+
},
|
|
49
|
+
{ projectName: envProject },
|
|
50
|
+
];
|
|
51
|
+
}
|