langgraph-api 0.16.0rc2__tar.gz → 0.17.0.dev2__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.
Files changed (329) hide show
  1. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/PKG-INFO +2 -2
  2. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/README.md +3 -10
  3. langgraph_api-0.17.0.dev2/benchmark/REPORTS.md +181 -0
  4. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/threads_search_metadata.ts +5 -4
  5. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/capacity-ci.js +81 -132
  6. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/capacity-ci.test.js +50 -34
  7. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/daily-report.js +69 -98
  8. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/daily-report.test.js +96 -55
  9. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/delta-report.js +83 -99
  10. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/delta-report.test.js +60 -29
  11. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/history.js +19 -0
  12. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/history.test.js +9 -0
  13. langgraph_api-0.17.0.dev2/benchmark/runner-descriptions.js +21 -0
  14. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/slack.js +20 -0
  15. langgraph_api-0.17.0.dev2/langgraph_api/__init__.py +1 -0
  16. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/__init__.py +1 -1
  17. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/assistants.py +30 -75
  18. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/runs.py +9 -132
  19. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/store.py +17 -35
  20. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/threads.py +11 -70
  21. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/cron_scheduler.py +1 -27
  22. langgraph_api-0.17.0.dev2/langgraph_api/encryption/context.py +95 -0
  23. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/encryption/custom.py +1 -9
  24. langgraph_api-0.17.0.dev2/langgraph_api/encryption/middleware.py +350 -0
  25. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/encryption/shared.py +3 -30
  26. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/graph.py +29 -6
  27. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/__init__.py +3 -4
  28. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/threads.py +16 -50
  29. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/servicers/checkpointer.py +3 -2
  30. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/servicers/encryption.py +22 -172
  31. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/metadata.py +28 -0
  32. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/metrics_otlp.py +16 -0
  33. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/models/run.py +6 -28
  34. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/schema.py +0 -110
  35. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/store.py +64 -0
  36. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/worker.py +2 -18
  37. langgraph_api-0.17.0.dev2/langgraph_runtime/encryption.py +15 -0
  38. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/pyproject.toml +1 -1
  39. langgraph_api-0.16.0rc2/benchmark/runner-descriptions.js +0 -58
  40. langgraph_api-0.16.0rc2/langgraph_api/__init__.py +0 -1
  41. langgraph_api-0.16.0rc2/langgraph_api/encryption/context.py +0 -35
  42. langgraph_api-0.16.0rc2/langgraph_api/encryption/middleware.py +0 -766
  43. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/.gitignore +0 -0
  44. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/LICENSE +0 -0
  45. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/Makefile +0 -0
  46. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/README.md +0 -0
  47. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/.gitignore +0 -0
  48. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/Makefile +0 -0
  49. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/assistant.ts +0 -0
  50. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  51. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  52. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  53. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  54. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/classify-error.test.js +0 -0
  55. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/classify-error.ts +0 -0
  56. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/delta-turns-lib.test.js +0 -0
  57. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/delta-turns-lib.ts +0 -0
  58. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/delta_turns.ts +0 -0
  59. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  60. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/interrupt_resume.ts +0 -0
  61. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/log-failure.ts +0 -0
  62. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  63. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/store.ts +0 -0
  64. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/stream_write.ts +0 -0
  65. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/thread.ts +0 -0
  66. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  67. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/types.ts +0 -0
  68. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/benchmark-runners/wait_write.ts +0 -0
  69. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/clean-cli.js +0 -0
  70. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/clean.js +0 -0
  71. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/continuous/README.md +0 -0
  72. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/continuous/pyproject.toml +0 -0
  73. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/continuous/runner.py +0 -0
  74. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/continuous/uv.lock +0 -0
  75. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/graphs.js +0 -0
  76. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/host-v2.js +0 -0
  77. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/host-v2.test.js +0 -0
  78. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/multer.test.js +0 -0
  79. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/package.json +0 -0
  80. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/ramp.js +0 -0
  81. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/reporting/dd_reporting.py +0 -0
  82. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/server-metrics.js +0 -0
  83. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/server-metrics.test.js +0 -0
  84. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/staircase.py +0 -0
  85. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/staircase_step_k6.js +0 -0
  86. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/tsconfig.json +0 -0
  87. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/update-revision.js +0 -0
  88. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/weather.js +0 -0
  89. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/benchmark/yarn.lock +0 -0
  90. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/constraints.txt +0 -0
  91. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/custom_store.sql +0 -0
  92. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/forbidden.txt +0 -0
  93. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/hatch_build.py +0 -0
  94. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/healthcheck.py +0 -0
  95. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  96. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/_checkpointer/__init__.py +0 -0
  97. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/_checkpointer/_adapter.py +0 -0
  98. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/_checkpointer/protocol.py +0 -0
  99. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/_factory_utils.py +0 -0
  100. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2a.py +0 -0
  101. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui.py +0 -0
  102. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui_schemas/README.md +0 -0
  103. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui_schemas/client_capabilities.json +0 -0
  104. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui_schemas/client_data_model.json +0 -0
  105. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui_schemas/client_to_server.json +0 -0
  106. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/a2ui_schemas/server_to_client.json +0 -0
  107. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/event_streaming.py +0 -0
  108. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/__init__.py +0 -0
  109. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/_constants.py +0 -0
  110. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/_handlers.py +0 -0
  111. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/_models.py +0 -0
  112. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/_routes.py +0 -0
  113. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  114. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/meta.py +0 -0
  115. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/openapi.py +0 -0
  116. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/profile.py +0 -0
  117. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/api/ui.py +0 -0
  118. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/asgi_transport.py +0 -0
  119. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/asyncio.py +0 -0
  120. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/__init__.py +0 -0
  121. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/custom.py +0 -0
  122. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/errors.py +0 -0
  123. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/langsmith/__init__.py +0 -0
  124. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/langsmith/backend.py +0 -0
  125. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/langsmith/client.py +0 -0
  126. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/middleware.py +0 -0
  127. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/noop.py +0 -0
  128. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/auth/studio_user.py +0 -0
  129. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/beacon_data_plane_jwt_auth.py +0 -0
  130. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/cache.py +0 -0
  131. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/cli.py +0 -0
  132. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/command.py +0 -0
  133. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/config/__init__.py +0 -0
  134. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/config/_parse.py +0 -0
  135. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/config/schemas.py +0 -0
  136. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/encryption/__init__.py +0 -0
  137. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/encryption/aes_json.py +0 -0
  138. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/errors.py +0 -0
  139. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/__init__.py +0 -0
  140. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/capabilities.py +0 -0
  141. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/constants.py +0 -0
  142. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  143. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/namespace.py +0 -0
  144. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/service.py +0 -0
  145. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/session.py +0 -0
  146. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/state_normalizers.py +0 -0
  147. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/event_streaming/types.py +0 -0
  148. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/feature_flags.py +0 -0
  149. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/__init__.py +0 -0
  150. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/client.py +0 -0
  151. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  152. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/assistants.py +0 -0
  153. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/cache.py +0 -0
  154. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/crons.py +0 -0
  155. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/ops/runs.py +0 -0
  156. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/server.py +0 -0
  157. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/grpc/servicers/__init__.py +0 -0
  158. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/http.py +0 -0
  159. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/http_metrics.py +0 -0
  160. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/http_metrics_utils.py +0 -0
  161. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/.gitignore +0 -0
  162. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/.prettierrc +0 -0
  163. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/.yarnclean +0 -0
  164. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/__init__.py +0 -0
  165. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/base.py +0 -0
  166. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/build.mts +0 -0
  167. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/client.http.mts +0 -0
  168. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/client.mts +0 -0
  169. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/errors.py +0 -0
  170. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/global.d.ts +0 -0
  171. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/package.json +0 -0
  172. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/remote.py +0 -0
  173. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/schema.py +0 -0
  174. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/auth-mutations.mts +0 -0
  175. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/graph.mts +0 -0
  176. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/load.hooks.mjs +0 -0
  177. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/preload.mjs +0 -0
  178. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  179. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/utils/files.mts +0 -0
  180. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/utils/importMap.mts +0 -0
  181. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  182. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/src/utils/serde.mts +0 -0
  183. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/sse.py +0 -0
  184. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/traceblock.mts +0 -0
  185. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/tsconfig.json +0 -0
  186. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/ui.py +0 -0
  187. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/js/yarn.lock +0 -0
  188. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/lc_security/__init__.py +0 -0
  189. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/lc_security/exceptions.py +0 -0
  190. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/lc_security/policy.py +0 -0
  191. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/lc_security/transport.py +0 -0
  192. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/logging.py +0 -0
  193. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/metrics_collector.py +0 -0
  194. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/middleware/__init__.py +0 -0
  195. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/middleware/ensure_store.py +0 -0
  196. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/middleware/http_logger.py +0 -0
  197. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/middleware/private_network.py +0 -0
  198. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/middleware/request_id.py +0 -0
  199. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/models/__init__.py +0 -0
  200. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/otel_context.py +0 -0
  201. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/patch.py +0 -0
  202. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/queue_entrypoint.py +0 -0
  203. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/release_tags.py +0 -0
  204. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/route.py +0 -0
  205. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/runner/__init__.py +0 -0
  206. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/runner/__main__.py +0 -0
  207. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/self_hosted_logs.py +0 -0
  208. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/self_hosted_metrics.py +0 -0
  209. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/serde.py +0 -0
  210. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/server.py +0 -0
  211. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/sse.py +0 -0
  212. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/state.py +0 -0
  213. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/stream.py +0 -0
  214. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/stream_v2.py +0 -0
  215. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/timing/__init__.py +0 -0
  216. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/timing/profiler.py +0 -0
  217. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/timing/timer.py +0 -0
  218. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/traceblock.py +0 -0
  219. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/tracing_session.py +0 -0
  220. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/tunneling/cloudflare.py +0 -0
  221. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/__init__.py +0 -0
  222. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/cache.py +0 -0
  223. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/config.py +0 -0
  224. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/errors.py +0 -0
  225. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/extract.py +0 -0
  226. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/future.py +0 -0
  227. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/headers.py +0 -0
  228. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/network.py +0 -0
  229. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/retriable_client.py +0 -0
  230. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/stream_codec.py +0 -0
  231. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/utils/uuids.py +0 -0
  232. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/validation.py +0 -0
  233. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/webhook.py +0 -0
  234. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_api/worker_runtime.py +0 -0
  235. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/__init__.py +0 -0
  236. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/checkpointer.py +0 -0
  237. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/__init__.py +0 -0
  238. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/_compat.py +0 -0
  239. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
  240. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/config.py +0 -0
  241. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/durability.py +0 -0
  242. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/store.py +0 -0
  243. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/struct.py +0 -0
  244. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/conversion/value.py +0 -0
  245. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/__init__.py +0 -0
  246. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
  247. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
  248. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  249. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
  250. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  251. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
  252. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  253. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  254. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  255. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  256. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  257. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  258. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  259. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  260. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  261. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  262. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  263. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  264. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  265. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  266. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  267. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  268. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  269. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  270. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  271. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  272. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  273. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  274. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  275. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  276. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  277. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  278. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  279. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  280. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  281. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  282. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  283. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  284. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  285. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  286. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  287. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  288. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  289. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  290. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  291. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  292. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  293. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  294. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  295. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  296. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  297. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  298. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  299. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  300. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  301. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  302. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/runner_pb2.py +0 -0
  303. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/runner_pb2.pyi +0 -0
  304. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/runner_pb2_grpc.py +0 -0
  305. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/runner_pb2_grpc.pyi +0 -0
  306. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/store_pb2.py +0 -0
  307. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
  308. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
  309. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
  310. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/serde.py +0 -0
  311. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_grpc_common/store.py +0 -0
  312. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_license/__init__.py +0 -0
  313. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_license/validation.py +0 -0
  314. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/__init__.py +0 -0
  315. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/checkpoint.py +0 -0
  316. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/database.py +0 -0
  317. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/lifespan.py +0 -0
  318. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/metrics.py +0 -0
  319. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/ops.py +0 -0
  320. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/queue.py +0 -0
  321. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/retry.py +0 -0
  322. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/routes.py +0 -0
  323. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/langgraph_runtime/store.py +0 -0
  324. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/logging.json +0 -0
  325. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/openapi.json +0 -0
  326. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/scripts/build_wheel.py +0 -0
  327. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/scripts/create_license.py +0 -0
  328. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/scripts/run_a2a_tck.py +0 -0
  329. {langgraph_api-0.16.0rc2 → langgraph_api-0.17.0.dev2}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.16.0rc2
3
+ Version: 0.17.0.dev2
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
@@ -17,7 +17,7 @@ Requires-Dist: jsonschema-rs<0.45,>=0.20.0
17
17
  Requires-Dist: langchain-core>=0.3.64
18
18
  Requires-Dist: langchain-protocol<0.1,>=0.0.18
19
19
  Requires-Dist: langgraph-checkpoint<5,>=3.0.1
20
- Requires-Dist: langgraph-runtime-inmem<0.37.0.dev0,>=0.36.0.dev0
20
+ Requires-Dist: langgraph-runtime-inmem<0.38.0.dev0,>=0.37.0.dev0
21
21
  Requires-Dist: langgraph-sdk>=0.4.4
22
22
  Requires-Dist: langgraph<2,>=0.4.10
23
23
  Requires-Dist: langsmith[otel]>=0.6.3
@@ -132,8 +132,8 @@ thread depth. `delta_turns` measures it: one thread per VU, one turn per iterati
132
132
  `benchmark-delta.yml` runs four cells nightly, 20 users for 25 minutes each, 1 KB appended per turn (`CHECKPOINT_SIZE`): plain channel, then
133
133
  delta snapshotting every 50 (`benchmark_delta_freq`, the deepagents setting), 500
134
134
  (`benchmark_delta_500`) and 1000 (`benchmark_delta`, the library default). `delta-report.js` posts
135
- a headline table (non-delta vs delta at 50: read, write, storage by depth) and one table per metric
136
- across the three frequencies. The messages and migration cells stay manual. Run the cells one at a time and compare `turn_duration` by depth. Both sides get slower
135
+ one row per cell (write, read and storage at the deepest turn every cell reached) and puts
136
+ the by-depth tables in the thread. The messages and migration cells stay manual. Run the cells one at a time and compare `turn_duration` by depth. Both sides get slower
137
137
  with depth for different reasons, the control by re-writing a growing value and delta by
138
138
  replaying more writes, so the deliverable is which curve is worse and where they cross.
139
139
 
@@ -209,14 +209,7 @@ Each cell also records the deployment's own view of its window (queue and API po
209
209
 
210
210
  ### Slack reports
211
211
 
212
- Every report follows one shape so the channel reads the same way each morning, on a phone as well as a desktop:
213
-
214
- - The first line is the verdict: a dot (green quiet, yellow something regressed or a bottleneck or errors, red something failed), the report name and date, `manual run` when dispatched by hand, the API version, and a clause saying what needs attention. The second line says what the benchmark is, for a reader outside the team.
215
- - Then `Failed`, `Regressed`, `Improved` and `Bottlenecks` or `Errors` lines, worst first. `Regressed` prints `none` rather than going quiet.
216
- - One table per deployment, about 40 characters wide so it fits a phone, with `▲ better` / `▼ worse` markers on cells that left their usual range.
217
- - One legend line (pass rule, arrows, dot colors), then a link to the thread, which holds the per-cell or per-run numbers and the longer *How to read*, and to the run's artifacts.
218
-
219
- Both reports compare tonight with the previous scheduled nights (`history.js`, artifacts fetched with `gh`). A figure is flagged only when it leaves that cell's own observed range, and only once five same-kind nights exist; before that the table says how many nights it has. The daily benchmark posts one digest per workflow once its last runner finishes (`daily-report.js`, fed by each runner's artifact), not one message per runner. The delta-channel report (`delta-report.js`) keeps the plain-vs-delta table in the channel and puts the snapshot-frequency sweep in the thread.
212
+ What each post means, for a reader outside the team, is in [REPORTS.md](REPORTS.md); every post links to its section. The channel message carries only the verdict, the lines that need attention and a small table per deployment (with a p95 trend on the daily ones), each fitting a phone; the numbers behind it go to the thread.
220
213
 
221
214
  Local commands:
222
215
 
@@ -0,0 +1,181 @@
1
+ # Reading the benchmark reports
2
+
3
+ The LGP Benchmark Reporter posts four benchmark reports to #test-reports-lsd.
4
+ Each post keeps to the numbers; this page explains what they mean. Every post
5
+ links to its own section below with "What is this?". The weekly image-pull post
6
+ in the same channel is separate and not covered here.
7
+
8
+ ## Reading any report
9
+
10
+ - **The dot.** 🟢 nothing to look at. 🟡 look at it: a regression, 10 or more
11
+ failed requests, a bottleneck, a correctness check or a warning line. 🔴 something failed: a
12
+ run crossed its pass bar, or never produced results.
13
+ - **The first line** is the verdict: report, date, `manual run` when someone
14
+ dispatched it by hand, the API version that was tested, and what needs
15
+ attention.
16
+ - **Failed / Errors / Regressed / Bottlenecks** lines only appear when there is
17
+ something to say, worst first.
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 and delta, where ▲ better and ▼ worse also
21
+ mark the cell in the table. The usual range is half the spread
22
+ between the best and worst of those nights, and never less than 10%, so a
23
+ series that swings 40% night to night is not flagged for moving 15%.
24
+ Flags start once five nights of history exist; until then the post says how
25
+ many it has.
26
+ - **The thread** holds the full numbers: per-run or per-cell detail and
27
+ improvements with before and after values; the daily threads also give the
28
+ load that ran.
29
+ - **Run** opens the GitHub Actions run, with the raw k6 summaries and charts.
30
+ - `-` in a cell means there is no number: the run produced no results, nothing
31
+ succeeded, or no thread reached that depth.
32
+
33
+ ## Daily benchmark
34
+
35
+ **Question it answers:** did latency or errors change for the three core
36
+ request paths, compared with the recent nights?
37
+
38
+ **How it runs.** [k6](https://k6.io/docs/) starts virtual users (simulated
39
+ clients). Each one repeats one request path as fast as the server answers: it
40
+ sends a request, waits for the response, then sends the next (a "closed
41
+ model"). Users are added in two steps of 60 s, then held for 5 minutes. Each
42
+ path runs as its own k6 run against the benchmark staging deployment. Every
43
+ scheduled night starts from a fresh revision of that deployment; it runs the
44
+ server version staging is on, which is the API version in the first line.
45
+
46
+ | Row | Runner | What one iteration does | Users |
47
+ |---|---|---|---|
48
+ | `wait` | `wait_write` | start a run and wait for its result (`POST /runs/wait`): run execution and checkpointing | 1,000 |
49
+ | `stream` | `stream_write` | start a run and read its event stream to the end (`POST /runs/stream`) | 1,000 |
50
+ | `search` | `threads_search` | create two threads, set their metadata, then search for them by it: database and metadata search | 300 |
51
+
52
+ Tables use the one-word row names so they fit a phone; the lines above the
53
+ table use the runner names.
54
+
55
+ `threads_search` does not delete the threads it creates; the deployment's
56
+ 60-minute thread TTL removes them, so each night searches a table of about
57
+ that run's threads, not a growing history.
58
+
59
+ **The table.**
60
+
61
+ - `p95 s`: 95% of iterations finished within this many seconds tonight. When
62
+ it left its usual range, the Regressed or Improved line says so, with the
63
+ before and after.
64
+ - `last 10`: p95 over the same 10 nights the flags use, oldest on the left,
65
+ tonight on the right. Taller is slower. Each row has its own scale, so a full
66
+ bar means that runner's slowest night of the ten, not a number of seconds:
67
+ compare a row with itself, not with the row below. The bars never stretch
68
+ small noise to full height, so a real step stands out.
69
+
70
+ **Pass bar.** Request errors under 1%, p95 under 13 s, and more than 99% of
71
+ iterations succeeding. Missing any of them fails the run and turns the dot red.
72
+
73
+ **Errors line.** Failed requests by HTTP status, and how many nights in a row
74
+ that runner has had any, as `N+` when every fetched night had them, since the
75
+ streak then started before the history does. 10 or more in one night turn the dot yellow even when
76
+ the run passes.
77
+
78
+ **Thread.** Average, p95 and p95 of successful iterations only; run and
79
+ failure counts; every figure against the 9 nights before tonight, including average
80
+ latency and run count (run count follows latency under a fixed user count, so
81
+ it is shown but never flagged).
82
+
83
+ ## Scale to zero
84
+
85
+ The daily benchmark against a second deployment that scales to zero when
86
+ idle. Scheduled runs redeploy it first, so the first minute includes the cold
87
+ start; a manual run skips the redeploy unless it is asked for. 200 users per
88
+ path instead of the daily's 1,000 (300 for search), and the pass bar is p95
89
+ under 25 s to allow for the cold start. Read it like the [daily benchmark](#daily-benchmark).
90
+
91
+ ## Capacity
92
+
93
+ **Question it answers:** how much traffic can each deployment size handle
94
+ before it breaks its latency target, and what runs out first?
95
+
96
+ **How it runs.** Two staging deployments, one dedicated and one serverless,
97
+ are resized to each tier (L, M, S) in turn. For each tier and path, k6 sends a
98
+ fixed request rate regardless of how fast the server answers (an "open
99
+ model", the way real traffic arrives), and raises it every 60 s: dedicated by
100
+ 50 req/s starting at 50, serverless by 5 starting at 10.
101
+
102
+ **The table.** Each cell is the highest request rate the tier held for two
103
+ steps while staying on target: at least 99% success, p50 at most 3 s, p95 at
104
+ most 10 s. `0` means no step met the target, `ERR` means the cell crashed,
105
+ `-` means it never ran.
106
+
107
+ **Bottlenecks.** A component (queue, api, database, redis) running at or over
108
+ 95% of its CPU request during the steps the tier passed. That is what stops
109
+ the tier going higher. Over 100% means it is bursting above its request.
110
+
111
+ **Keep in mind.** The graph is one step with no LLM call, so this measures the
112
+ server's own ceiling, not a customer workload. Every tier starts at one queue
113
+ pod and autoscales during a cell, so a capacity number is partly a pod-count
114
+ number.
115
+
116
+ **Thread.** Improvements with before and after values, then per deployment
117
+ two small tables grouped by tier: peak CPU as % of the pod's request, and pods
118
+ at the start and end of the cell. Both cover the whole cell, including steps
119
+ that failed. Last, the request rate actually served at the top step.
120
+
121
+ ## Delta channel
122
+
123
+ **Question it answers:** as a thread grows to thousands of turns, does
124
+ `DeltaChannel` keep reads and writes cheaper than a plain channel, and how
125
+ much storage does it save?
126
+
127
+ **Background.** A plain channel saves the whole value at every checkpoint. A
128
+ `DeltaChannel` saves only what changed, plus a full snapshot every N turns,
129
+ and rebuilds the value on read by replaying the changes since the last
130
+ snapshot. That moves cost from write to read, and read cost grows with the
131
+ distance to the last snapshot.
132
+
133
+ **How it runs.** 20 k6 users, one thread each, for 25 minutes. Every
134
+ iteration adds one turn to the user's thread (`POST /runs/wait`), appending
135
+ 1 KB to its state, so threads reach about 1,500 turns. Every 50 turns each user also does a cold state read
136
+ (`GET /threads/{id}/state`) and reads the thread's storage size
137
+ (`GET /threads/{id}/storage`). Four cells run the same graph logic:
138
+
139
+ | Row | Channel |
140
+ |---|---|
141
+ | `non-delta` | plain channel, the control |
142
+ | `snap 50` | delta, snapshot every 50 turns (the deepagents setting) |
143
+ | `snap 500` | delta, snapshot every 500 turns |
144
+ | `snap 1000` | delta, snapshot every 1000 turns (the library default) |
145
+
146
+ **The table.** One row per cell at the deepest turn every cell has a cold read
147
+ for, named in the header (`at 1400`). A slower cell gets less deep in 25
148
+ minutes, so the table stops where the slowest one did; the thread says how far
149
+ each cell got. Values are seconds, except `KB`.
150
+
151
+ - `write`: median checkpoint save at that turn, timed by the worker as the
152
+ gap between the graph's two steps, with saves made synchronous so nothing
153
+ overlaps it. `-` with a note means the deployed benchmark graph is too old
154
+ to report it.
155
+ - `read`: median cold state read at that turn, timed to the server's first
156
+ byte, so sending the state back is not counted.
157
+ - `KB`: storage the thread occupies at the deepest turn. Missing when the
158
+ deployment's API predates the storage endpoint.
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.
173
+
174
+ ## Changing a report
175
+
176
+ The builders are `daily-report.js` (daily and scale to zero),
177
+ `capacity-ci.js --aggregate` and `delta-report.js`, all posting through
178
+ `slack.js`. The daily workflows post one digest after their last runner finishes, built from each runner's artifact. History comes from previous scheduled runs' artifacts via
179
+ `history.js`. Each has a `*.test.js` beside it (`npm test`). A dispatch of the
180
+ workflow with `post_to_slack` reproduces a post: about 30 minutes for the
181
+ daily reports, about 2 hours for delta and capacity.
@@ -13,11 +13,12 @@ interface ThreadsSearchMetadataData {
13
13
  }
14
14
 
15
15
  /**
16
- * Delete the threads each iteration creates, or leave them to accumulate.
16
+ * Delete the threads each iteration creates, or leave them to the deployment.
17
17
  *
18
- * Off by default: letting the table grow is how this benchmark shows whether
19
- * search degrades as thread count rises, and it is the realistic case since
20
- * deployments do not delete threads per request.
18
+ * Off by default, since deployments do not delete threads per request. The
19
+ * nightly deployments' 60-minute thread TTL (langgraph.json in
20
+ * langgraph-server-benchmarks) removes them after the run, so the table holds
21
+ * about one run's threads rather than growing night over night.
21
22
  *
22
23
  * The capacity staircase turns it on, because there the table grows *while*
23
24
  * load is ramping, so a slower step cannot be attributed to load or to size.
@@ -18,7 +18,7 @@ import {
18
18
  requireApiKey,
19
19
  setResourceTiers,
20
20
  } from "./host-v2.js";
21
- import { RUNNERS, readApiVersion } from "./daily-report.js";
21
+ import { RUNNERS } from "./daily-report.js";
22
22
  import {
23
23
  MIN_HISTORY_NIGHTS,
24
24
  cellKey,
@@ -26,14 +26,9 @@ import {
26
26
  formatMove,
27
27
  loadCapacityHistory,
28
28
  } from "./history.js";
29
- import {
30
- describeRunnerBriefly,
31
- runnerColumnName,
32
- runnerGloss,
33
- runnerShortName,
34
- } from "./runner-descriptions.js";
29
+ import { runnerColumnName, runnerShortName } from "./runner-descriptions.js";
35
30
  import { cellWindow, peakCpu, podRange, summarizeServerMetrics } from "./server-metrics.js";
36
- import { dotFor, postReport } from "./slack.js";
31
+ import { dotFor, footer, postReport } from "./slack.js";
37
32
 
38
33
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
39
34
 
@@ -86,11 +81,6 @@ function unitFor(executor) {
86
81
  return executor === OPEN_MODEL ? "req/s" : "users";
87
82
  }
88
83
 
89
- // Mirrors staircase.py's SLO defaults, for the report header only. Kept here
90
- // rather than parsed out of a summary so the header still renders when every
91
- // cell failed and there is no config to read.
92
- const SLO = { minSuccessRate: 99, maxP50Ms: 3000, maxP95Ms: 10000 };
93
-
94
84
  /**
95
85
  * Parse a comma-separated allowlist from an env var.
96
86
  *
@@ -332,23 +322,6 @@ function plural(n, word) {
332
322
  return `${n} ${word}${n === 1 ? "" : "s"}`;
333
323
  }
334
324
 
335
- function stepSecondsOf(summaries) {
336
- const seen = [...new Set(
337
- summaries.map((s) => s.config?.plateauDurationSeconds).filter((v) => v != null).map(String),
338
- )];
339
- if (seen.length === 0) return STAIRCASE_PLATEAU_DURATION;
340
- return seen.sort((a, b) => Number(a) - Number(b)).join("/");
341
- }
342
-
343
- /** A dispatch can override the configured geometry; the report describes the run. */
344
- function geometryOf(deployment, cells) {
345
- const ran = ranGeometry(cells) ?? deployment.staircase ?? {};
346
- return {
347
- start: Number(ran.startLoad ?? STAIRCASE_START_LOAD),
348
- step: Number(ran.stepSize ?? STAIRCASE_STEP_SIZE),
349
- };
350
- }
351
-
352
325
  function capacityTable(deployment, rows, unit) {
353
326
  const labels = deployment.tiers.map((tier) => tierLabel(deployment, tier));
354
327
  const labelWidth = Math.max(2, ...labels.map((l) => l.length)) + 1;
@@ -391,7 +364,6 @@ export function formatAggregateTable(
391
364
  const regressed = rows.filter((row) => row.change && !row.change.better);
392
365
  const improved = rows.filter((row) => row.change?.better);
393
366
  const bottlenecks = bottleneckLines(rows);
394
- const checked = analysed.some((a) => a.nights >= MIN_HISTORY_NIGHTS);
395
367
  const allWarnings = [...warnings, ...toolOverheadWarnings(summaries)];
396
368
 
397
369
  const executor = executorOf(summaries);
@@ -414,7 +386,6 @@ export function formatAggregateTable(
414
386
  });
415
387
  const lines = [
416
388
  `${dot} *Capacity · ${date}*${manual ? " · manual run" : ""}${apiVersion ? ` · API ${apiVersion}` : ""} · ${ran} · ${verdict.join(", ")}`,
417
- describeCapacity(analysed, summaries, executor),
418
389
  ];
419
390
 
420
391
  const failedParts = crashed.map((tier) => tier.detail);
@@ -425,57 +396,25 @@ export function formatAggregateTable(
425
396
  if (failedParts.length > 0) {
426
397
  lines.push(`*Failed:* ${failedParts.join(" · ")} · treat the table as incomplete`);
427
398
  }
428
-
429
- if (!checked) {
430
- const nights = Math.max(...analysed.map((a) => a.nights));
431
- lines.push(`*Regressed:* not checked, ${nights} of ${MIN_HISTORY_NIGHTS} nights of history`);
432
- } else {
433
- lines.push(`*Regressed:* ${regressed.length > 0 ? regressed.map((row) => moveLine(row, unit)).join(" · ") : "none"}`);
434
- if (improved.length > 0) lines.push(`*Improved:* ${improved.map((row) => moveLine(row, unit)).join(" · ")}`);
435
- }
436
- lines.push(`*Bottlenecks:* ${bottlenecks.length > 0 ? bottlenecks.join(" · ") : "none reported"}`);
399
+ if (regressed.length > 0) lines.push(`*Regressed:* ${regressed.map((row) => moveLine(row, unit)).join(" · ")}`);
400
+ if (bottlenecks.length > 0) lines.push(`*Bottlenecks:* ${bottlenecks.join(" · ")}`);
437
401
  for (const warning of allWarnings) lines.push(`:warning: ${warning}`);
438
402
 
439
403
  for (const { deployment, rows: deploymentRows, nights } of analysed) {
440
404
  lines.push("", ...capacityTable(deployment, deploymentRows, unitFor(executorOf(deploymentRows.map((r) => r.summary).filter(Boolean)))));
441
- if (checked && nights < MIN_HISTORY_NIGHTS) {
405
+ if (nights < MIN_HISTORY_NIGHTS) {
442
406
  lines.push(`_${nights} of ${MIN_HISTORY_NIGHTS} nights of history, no change flags yet_`);
443
407
  }
444
408
  }
445
-
446
- lines.push(
447
- "",
448
- `▲ better ▼ worse than the last ${MIN_HISTORY_NIGHTS}+ nights · \`0\` no step passed · \`ERR\` crashed · \`-\` never ran · 🟢 quiet · 🟡 regression or bottleneck · 🔴 cells failed`,
449
- );
450
409
  return lines.join("\n");
451
410
  }
452
411
 
453
- function describeCapacity(analysed, summaries, executor) {
454
- const open = executor === OPEN_MODEL;
455
- const unit = unitFor(executor);
456
- const climb = analysed
457
- .map(({ deployment, rows }) => {
458
- const cells = indexCells([deployment], rows.map((r) => r.summary).filter(Boolean))[deployment.slug] ?? {};
459
- const { start, step } = geometryOf(deployment, cells);
460
- return `+${step} from ${start} (${deploymentName(deployment).toLowerCase()})`;
461
- })
462
- .join(" or ");
463
- const where = analysed.length === 1 ? "one staging deployment" : `${analysed.length} staging deployments`;
464
- return (
465
- `k6 ${open ? "open-model" : "closed-model"} staircase, ${where} resized per tier: ${open ? "request rate" : "virtual users"} ${climb} every ${stepSecondsOf(summaries)} s, per path: ${RUNNERS.map(runnerGloss).join(", ")}. ` +
466
- `Cell = highest ${unit} where success ≥ ${SLO.minSuccessRate}%, p50 ≤ ${SLO.maxP50Ms / 1000} s, p95 ≤ ${SLO.maxP95Ms / 1000} s held for two steps. ` +
467
- "One-step graph, no LLM: server ceiling, not customer traffic."
468
- );
469
- }
470
-
471
- export function howToRead() {
472
- return [
473
- "*How to read*",
474
- `• *Tests:* ${RUNNERS.map((r) => `${runnerColumnName(r)} = ${describeRunnerBriefly(r)}`).join(" · ")}.`,
475
- `• *Regressed / Improved:* a cell outside its own usual range over the last ${MIN_HISTORY_NIGHTS}+ nights measured the same way.`,
476
- `• *Bottleneck:* a component at or over ${BOTTLENECK_CPU_PCT}% of its CPU request while the tier held its top step. It is what stops the tier going higher.`,
477
- "• Graph is one step, no LLM, so this is server overhead, not a customer workload.",
478
- ].join("\n");
412
+ export function formatImprovements(deployments, summaries, history = {}) {
413
+ const byDeployment = indexCells(deployments, summaries);
414
+ const rows = deployments.flatMap((d) => analyseDeployment(d, byDeployment[d.slug] ?? {}, history).rows);
415
+ const unit = unitFor(executorOf(summaries));
416
+ const improved = rows.filter((row) => row.change?.better);
417
+ return improved.length > 0 ? `*Improved:* ${improved.map((row) => moveLine(row, unit)).join(" · ")}` : null;
479
418
  }
480
419
 
481
420
  function servedRate(summary) {
@@ -485,20 +424,19 @@ function servedRate(summary) {
485
424
  return ceiling != null ? `0 (ceiling ${Math.round(ceiling)})` : "-";
486
425
  }
487
426
 
488
- function serverColumns(summaries) {
489
- const columns = [];
490
- for (const [label, name] of COMPONENTS) {
491
- const groups = summaries.map((s) => s?.serverMetrics?.groups?.[label]).filter(Boolean);
492
- if (groups.length === 0) continue;
493
- if (groups.some(podRange)) columns.push({ label, kind: "pods", width: 7 });
494
- if (groups.some((g) => peakCpu(g) != null)) columns.push({ label, kind: "cpu", width: 6 });
495
- }
496
- return columns;
427
+ function serverColumns(summaries, kind) {
428
+ const has = kind === "pods" ? podRange : (g) => peakCpu(g) != null;
429
+ return COMPONENTS.map(([label]) => label).filter((label) =>
430
+ summaries.some((s) => {
431
+ const group = s?.serverMetrics?.groups?.[label];
432
+ return group && has(group);
433
+ }),
434
+ );
497
435
  }
498
436
 
499
- function serverCell(summary, column) {
500
- const group = summary?.serverMetrics?.groups?.[column.label];
501
- if (column.kind === "pods") {
437
+ function serverCell(summary, label, kind) {
438
+ const group = summary?.serverMetrics?.groups?.[label];
439
+ if (kind === "pods") {
502
440
  const range = podRange(group);
503
441
  return range ? `${range.min}→${range.max}` : "-";
504
442
  }
@@ -506,6 +444,29 @@ function serverCell(summary, column) {
506
444
  return cpu != null ? String(Math.round(cpu)) : "-";
507
445
  }
508
446
 
447
+ // Tier rows head their runners so each line fits PHONE_WIDTH; a "L search" label column would not.
448
+ function serverTable(deployment, cells, kind) {
449
+ const present = deployment.tiers.flatMap((tier) => RUNNERS.map((r) => cells[tier]?.[r]).filter((s) => s?.serverMetrics));
450
+ const columns = serverColumns(present, kind);
451
+ if (columns.length === 0) return null;
452
+ const labelWidth = Math.max(...RUNNERS.map((r) => runnerColumnName(r).length)) + 1;
453
+ const widths = columns.map((label) =>
454
+ Math.max(label.length, ...present.map((s) => serverCell(s, label, kind).length)) + 1,
455
+ );
456
+ const lines = ["```", `${"".padEnd(labelWidth)}${columns.map((label, i) => label.padStart(widths[i])).join("")}`];
457
+ for (const tier of deployment.tiers) {
458
+ const runners = RUNNERS.filter((r) => cells[tier]?.[r]?.serverMetrics);
459
+ if (runners.length === 0) continue;
460
+ lines.push(tierLabel(deployment, tier));
461
+ for (const runner of runners) {
462
+ const row = columns.map((label, i) => serverCell(cells[tier][runner], label, kind).padStart(widths[i]));
463
+ lines.push(`${` ${runnerColumnName(runner)}`.padEnd(labelWidth)}${row.join("")}`);
464
+ }
465
+ }
466
+ lines.push("```");
467
+ return lines.join("\n");
468
+ }
469
+
509
470
  export function formatServerView(deployments, summaries) {
510
471
  const byDeployment = indexCells(deployments, summaries);
511
472
  const blocks = [];
@@ -517,39 +478,23 @@ export function formatServerView(deployments, summaries) {
517
478
  .map((tier) => `${tierLabel(deployment, tier)} ${RUNNERS.map((r) => servedRate(cells[tier]?.[r])).join(" / ")}`)
518
479
  .join(" · ");
519
480
  const servedLine = `Runs/sec actually served at the top step, as ${RUNNERS.map(runnerColumnName).join(" / ")}: ${served}`;
520
- // The served rate is k6's; the pod and CPU columns are the dashboard's, which is best effort.
521
- const columns = serverColumns(present);
522
- if (columns.length === 0) {
523
- blocks.push(`*${deploymentName(deployment)}*\n${servedLine}`);
524
- continue;
525
- }
526
- const labelWidth = Math.max(...deployment.tiers.map((t) => tierLabel(deployment, t).length)) + 8;
527
- const spans = [];
528
- for (const column of columns) {
529
- const last = spans[spans.length - 1];
530
- if (last && last.label === column.label) last.width += column.width;
531
- else spans.push({ label: column.label, width: column.width });
532
- }
533
- const lines = [
534
- `*${deploymentName(deployment)}*`,
535
- "```",
536
- `${"".padEnd(labelWidth)}${spans.map((s) => s.label.padStart(s.width)).join("")}`,
537
- `${"".padEnd(labelWidth)}${columns.map((c) => c.kind.padStart(c.width)).join("")}`,
538
- ];
539
- for (const tier of deployment.tiers) {
540
- for (const runner of RUNNERS) {
541
- const summary = cells[tier]?.[runner];
542
- if (!summary?.serverMetrics) continue;
543
- const label = `${tierLabel(deployment, tier)} ${runnerColumnName(runner)}`;
544
- lines.push(`${label.padEnd(labelWidth)}${columns.map((c) => serverCell(summary, c).padStart(c.width)).join("")}`);
545
- }
546
- }
547
- lines.push("```", servedLine);
548
- blocks.push(lines.join("\n"));
481
+ // The served rate is k6's; the pod and CPU tables are the dashboard's, which is best effort.
482
+ const cpu = serverTable(deployment, cells, "cpu");
483
+ const pods = serverTable(deployment, cells, "pods");
484
+ blocks.push(
485
+ [
486
+ `*${deploymentName(deployment)}*`,
487
+ cpu ? `_CPU, % of request_\n${cpu}` : null,
488
+ pods ? `_Pods, start → end_\n${pods}` : null,
489
+ servedLine,
490
+ ]
491
+ .filter(Boolean)
492
+ .join("\n"),
493
+ );
549
494
  }
550
495
  if (blocks.length === 0) return null;
551
496
  return [
552
- "*Pods and CPU per cell*, peak over the whole cell including the steps that failed. Pods are start → end. CPU is % of the pod's request, so over 100 means bursting above it.",
497
+ "*Pods and CPU per cell*, peak over the whole cell including the steps that failed. CPU over 100 means bursting above the pod's request.",
553
498
  ...blocks,
554
499
  ].join("\n\n");
555
500
  }
@@ -570,19 +515,6 @@ function toolOverheadWarnings(summaries) {
570
515
  return lines;
571
516
  }
572
517
 
573
- /** A dispatch can override the configured geometry; the report describes the run. */
574
- function ranGeometry(cells) {
575
- for (const byRunner of Object.values(cells)) {
576
- for (const summary of Object.values(byRunner)) {
577
- const config = summary?.config;
578
- if (config?.startLoad != null && config?.stepSize != null && config?.numSteps != null) {
579
- return config;
580
- }
581
- }
582
- }
583
- return null;
584
- }
585
-
586
518
  function warningsPathFor(deploymentSlug) {
587
519
  return path.join(__dirname, `staircase_warnings_${deploymentSlug}.json`);
588
520
  }
@@ -911,6 +843,22 @@ function collectSummaries(directory) {
911
843
  );
912
844
  }
913
845
 
846
+ /** The checked-out repo is usually ahead of staging, so the version comes from the deployments. */
847
+ export async function deployedVersion(deployments, fetchImpl = fetch) {
848
+ const versions = await Promise.all(
849
+ deployments.map(async ({ baseUrl }) => {
850
+ try {
851
+ const response = await fetchImpl(`${baseUrl}/info`, { signal: AbortSignal.timeout(15000) });
852
+ return response.ok ? ((await response.json())?.version ?? null) : null;
853
+ } catch {
854
+ return null;
855
+ }
856
+ }),
857
+ );
858
+ const known = [...new Set(versions.filter(Boolean))];
859
+ return known.length > 0 ? known.join("/") : null;
860
+ }
861
+
914
862
  async function runAggregate(summariesDir, { postToSlack, historyDir }) {
915
863
  const summaries = collectSummaries(summariesDir);
916
864
  const warnings = collectWarnings(summariesDir);
@@ -921,12 +869,13 @@ async function runAggregate(summariesDir, { postToSlack, historyDir }) {
921
869
  warnings,
922
870
  new Date(),
923
871
  history,
924
- process.env.API_VERSION || readApiVersion(),
872
+ await deployedVersion(CAPACITY_DEPLOYMENTS),
925
873
  process.env.MANUAL === "true",
926
874
  );
927
- const artifactUrl = process.env.GITHUB_RUN_URL;
928
- text += `\n*Thread:* pods and CPU per cell, and how to read${artifactUrl ? ` · <${artifactUrl}|Artifacts:> raw k6 summaries` : ""}`;
929
- const thread = [[formatServerView(CAPACITY_DEPLOYMENTS, summaries), howToRead()].filter(Boolean).join("\n\n")];
875
+ text += `\n\n${footer("capacity", process.env.GITHUB_RUN_URL)}`;
876
+ const thread = [
877
+ [formatImprovements(CAPACITY_DEPLOYMENTS, summaries, history), formatServerView(CAPACITY_DEPLOYMENTS, summaries)].filter(Boolean).join("\n\n"),
878
+ ];
930
879
  if (postToSlack) {
931
880
  await postReport({ text, thread });
932
881
  } else {